@jstn-sdk/rcs 0.1.0 → 0.1.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 (1736) hide show
  1. package/README.md +142 -102
  2. package/dist/agents/definitions.d.ts.map +1 -1
  3. package/dist/agents/definitions.js +0 -101
  4. package/dist/agents/definitions.js.map +1 -1
  5. package/dist/blueprint/runtime.d.ts +52 -0
  6. package/dist/blueprint/runtime.d.ts.map +1 -0
  7. package/dist/{ralplan → blueprint}/runtime.js +19 -19
  8. package/dist/blueprint/runtime.js.map +1 -0
  9. package/dist/catalog/reader.d.ts.map +1 -1
  10. package/dist/catalog/reader.js +8 -2
  11. package/dist/catalog/reader.js.map +1 -1
  12. package/dist/catalog/schema.js +1 -1
  13. package/dist/catalog/schema.js.map +1 -1
  14. package/dist/cli/forge.d.ts +17 -0
  15. package/dist/cli/{ralph.d.ts.map → forge.d.ts.map} +1 -1
  16. package/dist/cli/{ralph.js → forge.js} +82 -82
  17. package/dist/cli/{ralph.js.map → forge.js.map} +1 -1
  18. package/dist/cli/index.d.ts +1 -1
  19. package/dist/cli/index.js +15 -15
  20. package/dist/cli/setup.d.ts.map +1 -1
  21. package/dist/cli/setup.js +2 -3
  22. package/dist/cli/setup.js.map +1 -1
  23. package/dist/cli/star-prompt.js +2 -2
  24. package/dist/cli/star-prompt.js.map +1 -1
  25. package/dist/cli/state.js +1 -1
  26. package/dist/cli/team.d.ts.map +1 -1
  27. package/dist/cli/team.js +3 -2
  28. package/dist/cli/team.js.map +1 -1
  29. package/dist/cli/tmux-hook.d.ts.map +1 -1
  30. package/dist/cli/tmux-hook.js +9 -1
  31. package/dist/cli/tmux-hook.js.map +1 -1
  32. package/dist/config/generator.d.ts +1 -1
  33. package/dist/config/generator.d.ts.map +1 -1
  34. package/dist/config/generator.js +1 -1
  35. package/dist/config/generator.js.map +1 -1
  36. package/dist/forge/contract.d.ts +17 -0
  37. package/dist/{ralph → forge}/contract.d.ts.map +1 -1
  38. package/dist/{ralph → forge}/contract.js +16 -16
  39. package/dist/{ralph → forge}/contract.js.map +1 -1
  40. package/dist/{ralph → forge}/persistence.d.ts +5 -5
  41. package/dist/{ralph → forge}/persistence.d.ts.map +1 -1
  42. package/dist/{ralph → forge}/persistence.js +7 -6
  43. package/dist/forge/persistence.js.map +1 -0
  44. package/dist/hooks/agents-overlay.d.ts +1 -1
  45. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  46. package/dist/hooks/agents-overlay.js +37 -31
  47. package/dist/hooks/agents-overlay.js.map +1 -1
  48. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  49. package/dist/hooks/extensibility/dispatcher.js +82 -14
  50. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  51. package/dist/hooks/keyword-detector.d.ts +8 -8
  52. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  53. package/dist/hooks/keyword-detector.js +94 -64
  54. package/dist/hooks/keyword-detector.js.map +1 -1
  55. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  56. package/dist/hooks/keyword-registry.js +9 -11
  57. package/dist/hooks/keyword-registry.js.map +1 -1
  58. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  59. package/dist/hooks/prompt-guidance-contract.js +10 -21
  60. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  61. package/dist/hooks/task-size-detector.js +2 -2
  62. package/dist/hooks/task-size-detector.js.map +1 -1
  63. package/dist/hooks/triage-state.d.ts +1 -1
  64. package/dist/hooks/triage-state.js +1 -1
  65. package/dist/hud/colors.d.ts +2 -2
  66. package/dist/hud/colors.js +2 -2
  67. package/dist/hud/render.js +21 -21
  68. package/dist/hud/render.js.map +1 -1
  69. package/dist/hud/state.d.ts +3 -3
  70. package/dist/hud/state.d.ts.map +1 -1
  71. package/dist/hud/state.js +18 -15
  72. package/dist/hud/state.js.map +1 -1
  73. package/dist/hud/types.d.ts +6 -6
  74. package/dist/hud/types.d.ts.map +1 -1
  75. package/dist/mcp/bootstrap.d.ts.map +1 -1
  76. package/dist/mcp/bootstrap.js +36 -2
  77. package/dist/mcp/bootstrap.js.map +1 -1
  78. package/dist/mcp/state-paths.d.ts +1 -0
  79. package/dist/mcp/state-paths.d.ts.map +1 -1
  80. package/dist/mcp/state-paths.js +4 -1
  81. package/dist/mcp/state-paths.js.map +1 -1
  82. package/dist/mcp/state-server.d.ts +4 -4
  83. package/dist/mcp/state-server.js +2 -2
  84. package/dist/mcp/state-server.js.map +1 -1
  85. package/dist/modes/base.d.ts +2 -2
  86. package/dist/modes/base.d.ts.map +1 -1
  87. package/dist/modes/base.js +29 -26
  88. package/dist/modes/base.js.map +1 -1
  89. package/dist/notifications/reply-listener.d.ts.map +1 -1
  90. package/dist/notifications/reply-listener.js +7 -1
  91. package/dist/notifications/reply-listener.js.map +1 -1
  92. package/dist/notifications/tmux.d.ts.map +1 -1
  93. package/dist/notifications/tmux.js +39 -6
  94. package/dist/notifications/tmux.js.map +1 -1
  95. package/dist/pipeline/index.d.ts +7 -6
  96. package/dist/pipeline/index.d.ts.map +1 -1
  97. package/dist/pipeline/index.js +5 -4
  98. package/dist/pipeline/index.js.map +1 -1
  99. package/dist/pipeline/orchestrator.d.ts +5 -5
  100. package/dist/pipeline/orchestrator.js +25 -25
  101. package/dist/pipeline/orchestrator.js.map +1 -1
  102. package/dist/pipeline/stages/blueprint.d.ts +25 -0
  103. package/dist/pipeline/stages/blueprint.d.ts.map +1 -0
  104. package/dist/pipeline/stages/{ralplan.js → blueprint.js} +16 -16
  105. package/dist/pipeline/stages/blueprint.js.map +1 -0
  106. package/dist/pipeline/stages/code-review.d.ts +2 -2
  107. package/dist/pipeline/stages/code-review.js +6 -6
  108. package/dist/pipeline/stages/code-review.js.map +1 -1
  109. package/dist/pipeline/stages/forge-verify.d.ts +50 -0
  110. package/dist/pipeline/stages/forge-verify.d.ts.map +1 -0
  111. package/dist/pipeline/stages/{ralph-verify.js → forge-verify.js} +21 -24
  112. package/dist/pipeline/stages/forge-verify.js.map +1 -0
  113. package/dist/pipeline/stages/team-exec.d.ts +1 -1
  114. package/dist/pipeline/stages/team-exec.js +19 -19
  115. package/dist/pipeline/stages/team-exec.js.map +1 -1
  116. package/dist/pipeline/types.d.ts +12 -12
  117. package/dist/pipeline/types.d.ts.map +1 -1
  118. package/dist/pipeline/types.js +1 -1
  119. package/dist/planning/artifacts.d.ts +3 -4
  120. package/dist/planning/artifacts.d.ts.map +1 -1
  121. package/dist/planning/artifacts.js +2 -3
  122. package/dist/planning/artifacts.js.map +1 -1
  123. package/dist/question/policy.js +1 -1
  124. package/dist/runtime/bridge.d.ts.map +1 -1
  125. package/dist/runtime/bridge.js +70 -13
  126. package/dist/runtime/bridge.js.map +1 -1
  127. package/dist/scripts/codex-native-hook.js +30 -30
  128. package/dist/scripts/codex-native-hook.js.map +1 -1
  129. package/dist/scripts/eval/eval-cross-server-party-flow.d.ts +3 -0
  130. package/dist/scripts/eval/eval-cross-server-party-flow.d.ts.map +1 -0
  131. package/dist/scripts/eval/eval-cross-server-party-flow.js +12 -0
  132. package/dist/scripts/eval/eval-cross-server-party-flow.js.map +1 -0
  133. package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts +3 -0
  134. package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts.map +1 -0
  135. package/dist/scripts/eval/eval-gui-onboarding-clarity.js +17 -0
  136. package/dist/scripts/eval/eval-gui-onboarding-clarity.js.map +1 -0
  137. package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts +3 -0
  138. package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts.map +1 -0
  139. package/dist/scripts/eval/eval-liveops-reward-loop-balance.js +12 -0
  140. package/dist/scripts/eval/eval-liveops-reward-loop-balance.js.map +1 -0
  141. package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts +3 -0
  142. package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts.map +1 -0
  143. package/dist/scripts/eval/eval-profile-datastore-recovery.js +17 -0
  144. package/dist/scripts/eval/eval-profile-datastore-recovery.js.map +1 -0
  145. package/dist/scripts/eval/eval-remote-contract-hardening.d.ts +3 -0
  146. package/dist/scripts/eval/eval-remote-contract-hardening.d.ts.map +1 -0
  147. package/dist/scripts/eval/eval-remote-contract-hardening.js +17 -0
  148. package/dist/scripts/eval/eval-remote-contract-hardening.js.map +1 -0
  149. package/dist/scripts/notify-fallback-watcher.js +140 -139
  150. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  151. package/dist/scripts/notify-hook/forge-session-resume.d.ts +23 -0
  152. package/dist/scripts/notify-hook/{ralph-session-resume.d.ts.map → forge-session-resume.d.ts.map} +1 -1
  153. package/dist/scripts/notify-hook/{ralph-session-resume.js → forge-session-resume.js} +37 -36
  154. package/dist/scripts/notify-hook/{ralph-session-resume.js.map → forge-session-resume.js.map} +1 -1
  155. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  156. package/dist/scripts/notify-hook/team-dispatch.js +34 -4
  157. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  158. package/dist/scripts/notify-hook/visual-verdict.js +3 -3
  159. package/dist/scripts/notify-hook.js +9 -9
  160. package/dist/scripts/run-test-files.js +1 -1
  161. package/dist/scripts/run-test-files.js.map +1 -1
  162. package/dist/scripts/surface-taxonomy.d.ts +23 -0
  163. package/dist/scripts/surface-taxonomy.d.ts.map +1 -0
  164. package/dist/scripts/surface-taxonomy.js +271 -0
  165. package/dist/scripts/surface-taxonomy.js.map +1 -0
  166. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  167. package/dist/scripts/sync-plugin-mirror.js +5 -4
  168. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  169. package/dist/scripts/tmux-hook-engine.d.ts +1 -1
  170. package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
  171. package/dist/scripts/tmux-hook-engine.js +29 -20
  172. package/dist/scripts/tmux-hook-engine.js.map +1 -1
  173. package/dist/state/operations.d.ts +1 -1
  174. package/dist/state/operations.d.ts.map +1 -1
  175. package/dist/state/operations.js +18 -18
  176. package/dist/state/operations.js.map +1 -1
  177. package/dist/state/skill-active.d.ts +13 -1
  178. package/dist/state/skill-active.d.ts.map +1 -1
  179. package/dist/state/skill-active.js +38 -17
  180. package/dist/state/skill-active.js.map +1 -1
  181. package/dist/state/workflow-transition.d.ts +6 -5
  182. package/dist/state/workflow-transition.d.ts.map +1 -1
  183. package/dist/state/workflow-transition.js +27 -15
  184. package/dist/state/workflow-transition.js.map +1 -1
  185. package/dist/team/contracts.d.ts +1 -1
  186. package/dist/team/contracts.js +2 -2
  187. package/dist/team/followup-planner.d.ts +2 -2
  188. package/dist/team/followup-planner.d.ts.map +1 -1
  189. package/dist/team/followup-planner.js +16 -14
  190. package/dist/team/followup-planner.js.map +1 -1
  191. package/dist/team/idle-nudge.d.ts.map +1 -1
  192. package/dist/team/idle-nudge.js +3 -2
  193. package/dist/team/idle-nudge.js.map +1 -1
  194. package/dist/team/leader-activity.js +1 -1
  195. package/dist/team/model-contract.d.ts.map +1 -1
  196. package/dist/team/model-contract.js +4 -1
  197. package/dist/team/model-contract.js.map +1 -1
  198. package/dist/team/orchestrator.js +4 -4
  199. package/dist/team/orchestrator.js.map +1 -1
  200. package/dist/team/role-router.js +3 -3
  201. package/dist/team/role-router.js.map +1 -1
  202. package/dist/team/state/dispatch.d.ts.map +1 -1
  203. package/dist/team/state/dispatch.js +4 -1
  204. package/dist/team/state/dispatch.js.map +1 -1
  205. package/dist/team/tmux-session.d.ts +4 -0
  206. package/dist/team/tmux-session.d.ts.map +1 -1
  207. package/dist/team/tmux-session.js +42 -9
  208. package/dist/team/tmux-session.js.map +1 -1
  209. package/dist/team/worktree.d.ts +1 -1
  210. package/dist/utils/platform-command.d.ts.map +1 -1
  211. package/dist/utils/platform-command.js +9 -0
  212. package/dist/utils/platform-command.js.map +1 -1
  213. package/dist/verification/verifier.d.ts +1 -1
  214. package/dist/verification/verifier.js +2 -2
  215. package/docs/STATE_MODEL.md +24 -24
  216. package/docs/agents.html +8 -16
  217. package/docs/archive/README.md +15 -0
  218. package/docs/{prompt-migration-changelog.md → archive/prompt-migration-changelog.md} +0 -11
  219. package/docs/{release-body-0.9.0.md → archive/release-body-0.9.0.md} +6 -24
  220. package/docs/{release-body-0.9.1.md → archive/release-body-0.9.1.md} +3 -3
  221. package/docs/codex-native-hooks.md +4 -4
  222. package/docs/contracts/forge-cancel-contract.md +20 -0
  223. package/docs/contracts/forge-state-contract.md +52 -0
  224. package/docs/contracts/multi-state-transition-contract.md +5 -5
  225. package/docs/contracts/multi-state-transition-review.md +3 -3
  226. package/docs/contracts/repo-aware-team-dag-decomposition.md +1 -1
  227. package/docs/contracts/rust-runtime-thin-adapter-contract.md +1 -1
  228. package/docs/contracts/team-startup-dispatch-latency.md +1 -1
  229. package/docs/getting-started.html +6 -1
  230. package/docs/guidance-schema.md +6 -3
  231. package/docs/index.html +55 -4
  232. package/docs/integrations.html +4 -3
  233. package/docs/issues/team-forge-followup-team.md +38 -0
  234. package/docs/openclaw-integration.md +2 -2
  235. package/docs/prompt-guidance-contract.md +11 -11
  236. package/docs/prs/{dev-deprecate-team-ralph.md → dev-deprecate-team-forge.md} +27 -27
  237. package/docs/prs/{dev-fix-ralph-live-pane-invariant.md → dev-fix-forge-live-pane-invariant.md} +7 -7
  238. package/docs/prs/{dev-team-ralph-workflow-positioning.md → dev-team-forge-workflow-positioning.md} +7 -7
  239. package/docs/qa/forge-persistence-gate.md +20 -0
  240. package/docs/qa/rust-runtime-thin-adapter-gate.md +31 -40
  241. package/docs/readme/README.de.md +13 -0
  242. package/docs/readme/README.el.md +13 -0
  243. package/docs/readme/README.es.md +13 -0
  244. package/docs/readme/README.fr.md +13 -0
  245. package/docs/readme/README.it.md +13 -0
  246. package/docs/readme/README.ja.md +13 -0
  247. package/docs/readme/README.ko.md +13 -0
  248. package/docs/readme/README.pl.md +13 -0
  249. package/docs/readme/README.pt.md +13 -0
  250. package/docs/readme/README.ru.md +13 -0
  251. package/docs/readme/README.tr.md +13 -0
  252. package/docs/readme/README.uk.md +13 -0
  253. package/docs/readme/README.vi.md +13 -0
  254. package/docs/readme/README.zh-TW.md +13 -0
  255. package/docs/readme/README.zh.md +13 -0
  256. package/docs/readme/rcs-cover.svg +75 -0
  257. package/docs/reference/canonical-vocabulary.md +106 -0
  258. package/docs/reference/forge-parity-matrix.md +26 -0
  259. package/docs/reference/forge-upstream-baseline.md +32 -0
  260. package/docs/reference/rcs-config-schema-routing.md +5 -5
  261. package/docs/reference/roblox-pre-action-protocol.md +4 -0
  262. package/docs/reference/roblox-taxonomy-migration-plan.md +46 -0
  263. package/docs/reference/roblox-workspace-standard.md +83 -0
  264. package/docs/reference/robloxstudio-mcp-compatibility.md +117 -0
  265. package/docs/reference/semantic-design-system.md +110 -0
  266. package/docs/reference/surface-map.md +131 -0
  267. package/docs/reference/team-allocation-rebalance-policy.md +1 -1
  268. package/docs/release-notes-v0.1.0.md +1 -1
  269. package/docs/release-notes-v0.1.1.md +49 -0
  270. package/docs/reports/open-prs-dev-readiness-2026-04-09.md +2 -2
  271. package/docs/shared/agent-tiers.md +3 -3
  272. package/docs/skills.html +10 -12
  273. package/docs/troubleshooting.md +1 -1
  274. package/package.json +20 -13
  275. package/plugins/roblox-ai-os-creator-skills/.codex-plugin/plugin.json +1 -1
  276. package/plugins/roblox-ai-os-creator-skills/docs/reference/roblox-pre-action-protocol.md +4 -0
  277. package/plugins/roblox-ai-os-creator-skills/skills/ai-slop-cleaner/SKILL.md +14 -7
  278. package/plugins/roblox-ai-os-creator-skills/skills/analyze/SKILL.md +9 -2
  279. package/plugins/roblox-ai-os-creator-skills/skills/ask-claude/SKILL.md +7 -0
  280. package/plugins/roblox-ai-os-creator-skills/skills/ask-gemini/SKILL.md +7 -0
  281. package/plugins/roblox-ai-os-creator-skills/skills/autoforge/SKILL.md +7 -0
  282. package/plugins/roblox-ai-os-creator-skills/skills/autopilot/SKILL.md +48 -41
  283. package/plugins/roblox-ai-os-creator-skills/skills/autoresearch/SKILL.md +8 -1
  284. package/plugins/roblox-ai-os-creator-skills/skills/blueprint/SKILL.md +227 -9
  285. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-loop/SKILL.md +7 -0
  286. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-psych/SKILL.md +7 -0
  287. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-retention/SKILL.md +7 -0
  288. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-social/SKILL.md +7 -0
  289. package/plugins/roblox-ai-os-creator-skills/skills/brief/SKILL.md +7 -0
  290. package/plugins/roblox-ai-os-creator-skills/skills/brief-audience/SKILL.md +7 -0
  291. package/plugins/roblox-ai-os-creator-skills/skills/brief-motivation/SKILL.md +7 -0
  292. package/plugins/roblox-ai-os-creator-skills/skills/cancel/SKILL.md +59 -52
  293. package/plugins/roblox-ai-os-creator-skills/skills/code-review/SKILL.md +30 -24
  294. package/plugins/roblox-ai-os-creator-skills/skills/configure-notifications/SKILL.md +7 -0
  295. package/plugins/roblox-ai-os-creator-skills/skills/crew/SKILL.md +7 -0
  296. package/plugins/roblox-ai-os-creator-skills/skills/deep-interview/SKILL.md +25 -18
  297. package/plugins/roblox-ai-os-creator-skills/skills/doctor/SKILL.md +7 -0
  298. package/plugins/roblox-ai-os-creator-skills/skills/forge/SKILL.md +174 -11
  299. package/plugins/roblox-ai-os-creator-skills/skills/forge-community/SKILL.md +7 -0
  300. package/plugins/roblox-ai-os-creator-skills/skills/forge-daily-loop/SKILL.md +7 -0
  301. package/plugins/roblox-ai-os-creator-skills/skills/forge-event-loop/SKILL.md +7 -0
  302. package/plugins/roblox-ai-os-creator-skills/skills/forge-fomo/SKILL.md +7 -0
  303. package/plugins/roblox-ai-os-creator-skills/skills/forge-mastery/SKILL.md +7 -0
  304. package/plugins/roblox-ai-os-creator-skills/skills/forge-progression/SKILL.md +7 -0
  305. package/plugins/roblox-ai-os-creator-skills/skills/forge-reward-loop/SKILL.md +7 -0
  306. package/plugins/roblox-ai-os-creator-skills/skills/forge-status/SKILL.md +7 -0
  307. package/plugins/roblox-ai-os-creator-skills/skills/help/SKILL.md +8 -1
  308. package/plugins/roblox-ai-os-creator-skills/skills/hud/SKILL.md +16 -9
  309. package/plugins/roblox-ai-os-creator-skills/skills/note/SKILL.md +8 -1
  310. package/plugins/roblox-ai-os-creator-skills/skills/pipeline/SKILL.md +18 -11
  311. package/plugins/roblox-ai-os-creator-skills/skills/plan/SKILL.md +36 -29
  312. package/plugins/roblox-ai-os-creator-skills/skills/rcs-setup/SKILL.md +8 -1
  313. package/plugins/roblox-ai-os-creator-skills/skills/security-review/SKILL.md +120 -236
  314. package/plugins/roblox-ai-os-creator-skills/skills/skill/SKILL.md +20 -13
  315. package/plugins/roblox-ai-os-creator-skills/skills/team/SKILL.md +17 -11
  316. package/plugins/roblox-ai-os-creator-skills/skills/trace/SKILL.md +7 -0
  317. package/plugins/roblox-ai-os-creator-skills/skills/ultraqa/SKILL.md +10 -3
  318. package/plugins/roblox-ai-os-creator-skills/skills/ultrawork/SKILL.md +19 -12
  319. package/plugins/roblox-ai-os-creator-skills/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
  320. package/plugins/roblox-ai-os-creator-skills/skills/visual-verdict/SKILL.md +9 -2
  321. package/plugins/roblox-ai-os-creator-skills/skills/wiki/SKILL.md +10 -3
  322. package/plugins/roblox-ai-os-creator-skills/skills/worker/SKILL.md +16 -7
  323. package/plugins/roblox-ai-os-creator-skills/templates/roblox/pre-action-plan.md +1 -0
  324. package/prompts/analyst.md +7 -0
  325. package/prompts/architect.md +11 -4
  326. package/prompts/build-fixer.md +7 -0
  327. package/prompts/code-reviewer.md +9 -2
  328. package/prompts/code-simplifier.md +4 -0
  329. package/prompts/critic.md +13 -6
  330. package/prompts/debugger.md +8 -1
  331. package/prompts/dependency-expert.md +8 -1
  332. package/prompts/designer.md +20 -10
  333. package/prompts/executor.md +7 -0
  334. package/prompts/explore-harness.md +7 -0
  335. package/prompts/explore.md +7 -0
  336. package/prompts/git-master.md +8 -1
  337. package/prompts/planner.md +10 -3
  338. package/prompts/researcher.md +7 -0
  339. package/prompts/security-reviewer.md +76 -92
  340. package/prompts/sisyphus-lite.md +7 -0
  341. package/prompts/team-executor.md +7 -0
  342. package/prompts/team-orchestrator.md +9 -2
  343. package/prompts/test-engineer.md +11 -3
  344. package/prompts/verifier.md +7 -0
  345. package/prompts/vision.md +9 -2
  346. package/prompts/writer.md +11 -4
  347. package/skills/.agents/skills/roblox-animations/SKILL.md +220 -0
  348. package/skills/.agents/skills/roblox-datastores/SKILL.md +219 -0
  349. package/skills/.agents/skills/roblox-gui/SKILL.md +192 -0
  350. package/skills/.agents/skills/roblox-monetization/SKILL.md +208 -0
  351. package/skills/.agents/skills/roblox-performance/SKILL.md +230 -0
  352. package/skills/.agents/skills/roblox-remote-events/SKILL.md +199 -0
  353. package/skills/.agents/skills/roblox-security/SKILL.md +236 -0
  354. package/skills/ai-slop-cleaner/SKILL.md +14 -7
  355. package/skills/analyze/SKILL.md +9 -2
  356. package/skills/ask-claude/SKILL.md +7 -0
  357. package/skills/ask-gemini/SKILL.md +7 -0
  358. package/skills/autoforge/SKILL.md +7 -0
  359. package/skills/autopilot/SKILL.md +48 -41
  360. package/skills/autoresearch/SKILL.md +8 -1
  361. package/skills/blueprint/SKILL.md +227 -9
  362. package/skills/blueprint-loop/SKILL.md +7 -0
  363. package/skills/blueprint-psych/SKILL.md +7 -0
  364. package/skills/blueprint-retention/SKILL.md +7 -0
  365. package/skills/blueprint-social/SKILL.md +7 -0
  366. package/skills/brief/SKILL.md +7 -0
  367. package/skills/brief-audience/SKILL.md +7 -0
  368. package/skills/brief-motivation/SKILL.md +7 -0
  369. package/skills/build-fix/SKILL.md +9 -2
  370. package/skills/cancel/SKILL.md +59 -52
  371. package/skills/code-review/SKILL.md +30 -24
  372. package/skills/configure-notifications/SKILL.md +7 -0
  373. package/skills/crew/SKILL.md +7 -0
  374. package/skills/deep-interview/SKILL.md +25 -18
  375. package/skills/deepsearch/SKILL.md +7 -0
  376. package/skills/doctor/SKILL.md +7 -0
  377. package/skills/ecomode/SKILL.md +9 -2
  378. package/skills/forge/SKILL.md +174 -11
  379. package/skills/forge-community/SKILL.md +7 -0
  380. package/skills/forge-daily-loop/SKILL.md +7 -0
  381. package/skills/forge-event-loop/SKILL.md +7 -0
  382. package/skills/forge-fomo/SKILL.md +7 -0
  383. package/skills/{ralph-init → forge-init}/SKILL.md +20 -13
  384. package/skills/forge-mastery/SKILL.md +7 -0
  385. package/skills/forge-progression/SKILL.md +7 -0
  386. package/skills/forge-reward-loop/SKILL.md +7 -0
  387. package/skills/forge-status/SKILL.md +7 -0
  388. package/skills/git-master/SKILL.md +7 -0
  389. package/skills/help/SKILL.md +8 -1
  390. package/skills/hud/SKILL.md +16 -9
  391. package/skills/note/SKILL.md +8 -1
  392. package/skills/pipeline/SKILL.md +18 -11
  393. package/skills/plan/SKILL.md +36 -29
  394. package/skills/rcs-setup/SKILL.md +8 -1
  395. package/skills/review/SKILL.md +7 -0
  396. package/skills/security-review/SKILL.md +120 -236
  397. package/skills/skill/SKILL.md +20 -13
  398. package/skills/skills-lock.json +47 -0
  399. package/skills/swarm/SKILL.md +8 -1
  400. package/skills/tdd/SKILL.md +7 -0
  401. package/skills/team/SKILL.md +17 -11
  402. package/skills/trace/SKILL.md +7 -0
  403. package/skills/ultraqa/SKILL.md +10 -3
  404. package/skills/ultrawork/SKILL.md +19 -12
  405. package/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
  406. package/skills/visual-verdict/SKILL.md +9 -2
  407. package/skills/web-clone/SKILL.md +14 -7
  408. package/skills/wiki/SKILL.md +10 -3
  409. package/skills/worker/SKILL.md +16 -7
  410. package/src/scripts/__tests__/codex-native-hook.test.ts +386 -319
  411. package/src/scripts/__tests__/run-test-files.test.ts +6 -4
  412. package/src/scripts/__tests__/verify-native-agents.test.ts +16 -16
  413. package/src/scripts/codex-native-hook.ts +34 -34
  414. package/src/scripts/eval/eval-cross-server-party-flow.ts +14 -0
  415. package/src/scripts/eval/eval-gui-onboarding-clarity.ts +20 -0
  416. package/src/scripts/eval/eval-liveops-reward-loop-balance.ts +14 -0
  417. package/src/scripts/eval/eval-profile-datastore-recovery.ts +20 -0
  418. package/src/scripts/eval/eval-remote-contract-hardening.ts +20 -0
  419. package/src/scripts/notify-fallback-watcher.ts +147 -146
  420. package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +24 -10
  421. package/src/scripts/notify-hook/{ralph-session-resume.ts → forge-session-resume.ts} +45 -43
  422. package/src/scripts/notify-hook/team-dispatch.ts +31 -4
  423. package/src/scripts/notify-hook/visual-verdict.ts +3 -3
  424. package/src/scripts/notify-hook.ts +10 -10
  425. package/src/scripts/run-test-files.ts +1 -1
  426. package/src/scripts/surface-taxonomy.ts +316 -0
  427. package/src/scripts/sync-plugin-mirror.ts +5 -4
  428. package/src/scripts/tmux-hook-engine.ts +31 -19
  429. package/templates/AGENTS.md +24 -15
  430. package/templates/catalog-manifest.json +5 -88
  431. package/templates/roblox/pre-action-plan.md +1 -0
  432. package/templates/roblox/robloxstudio-mcp.codex.json +18 -0
  433. package/templates/roblox/robloxstudio-mcp.windows.json +22 -0
  434. package/dist/adapt/__tests__/foundation.test.d.ts +0 -2
  435. package/dist/adapt/__tests__/foundation.test.d.ts.map +0 -1
  436. package/dist/adapt/__tests__/foundation.test.js +0 -171
  437. package/dist/adapt/__tests__/foundation.test.js.map +0 -1
  438. package/dist/adapt/__tests__/hermes.test.d.ts +0 -2
  439. package/dist/adapt/__tests__/hermes.test.d.ts.map +0 -1
  440. package/dist/adapt/__tests__/hermes.test.js +0 -137
  441. package/dist/adapt/__tests__/hermes.test.js.map +0 -1
  442. package/dist/agents/__tests__/definitions.test.d.ts +0 -2
  443. package/dist/agents/__tests__/definitions.test.d.ts.map +0 -1
  444. package/dist/agents/__tests__/definitions.test.js +0 -62
  445. package/dist/agents/__tests__/definitions.test.js.map +0 -1
  446. package/dist/agents/__tests__/native-config.test.d.ts +0 -2
  447. package/dist/agents/__tests__/native-config.test.d.ts.map +0 -1
  448. package/dist/agents/__tests__/native-config.test.js +0 -278
  449. package/dist/agents/__tests__/native-config.test.js.map +0 -1
  450. package/dist/autoresearch/__tests__/contracts.test.d.ts +0 -2
  451. package/dist/autoresearch/__tests__/contracts.test.d.ts.map +0 -1
  452. package/dist/autoresearch/__tests__/contracts.test.js +0 -127
  453. package/dist/autoresearch/__tests__/contracts.test.js.map +0 -1
  454. package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts +0 -2
  455. package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts.map +0 -1
  456. package/dist/autoresearch/__tests__/runtime-parity-extra.test.js +0 -356
  457. package/dist/autoresearch/__tests__/runtime-parity-extra.test.js.map +0 -1
  458. package/dist/autoresearch/__tests__/runtime.test.d.ts +0 -2
  459. package/dist/autoresearch/__tests__/runtime.test.d.ts.map +0 -1
  460. package/dist/autoresearch/__tests__/runtime.test.js +0 -218
  461. package/dist/autoresearch/__tests__/runtime.test.js.map +0 -1
  462. package/dist/autoresearch/__tests__/skill-validation.test.d.ts +0 -2
  463. package/dist/autoresearch/__tests__/skill-validation.test.d.ts.map +0 -1
  464. package/dist/autoresearch/__tests__/skill-validation.test.js +0 -91
  465. package/dist/autoresearch/__tests__/skill-validation.test.js.map +0 -1
  466. package/dist/catalog/__tests__/generator.test.d.ts +0 -2
  467. package/dist/catalog/__tests__/generator.test.d.ts.map +0 -1
  468. package/dist/catalog/__tests__/generator.test.js +0 -49
  469. package/dist/catalog/__tests__/generator.test.js.map +0 -1
  470. package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts +0 -2
  471. package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts.map +0 -1
  472. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +0 -83
  473. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +0 -1
  474. package/dist/catalog/__tests__/schema.test.d.ts +0 -2
  475. package/dist/catalog/__tests__/schema.test.d.ts.map +0 -1
  476. package/dist/catalog/__tests__/schema.test.js +0 -91
  477. package/dist/catalog/__tests__/schema.test.js.map +0 -1
  478. package/dist/cli/__tests__/adapt-help.test.d.ts +0 -2
  479. package/dist/cli/__tests__/adapt-help.test.d.ts.map +0 -1
  480. package/dist/cli/__tests__/adapt-help.test.js +0 -37
  481. package/dist/cli/__tests__/adapt-help.test.js.map +0 -1
  482. package/dist/cli/__tests__/adapt.test.d.ts +0 -2
  483. package/dist/cli/__tests__/adapt.test.d.ts.map +0 -1
  484. package/dist/cli/__tests__/adapt.test.js +0 -62
  485. package/dist/cli/__tests__/adapt.test.js.map +0 -1
  486. package/dist/cli/__tests__/agents-init.test.d.ts +0 -2
  487. package/dist/cli/__tests__/agents-init.test.d.ts.map +0 -1
  488. package/dist/cli/__tests__/agents-init.test.js +0 -184
  489. package/dist/cli/__tests__/agents-init.test.js.map +0 -1
  490. package/dist/cli/__tests__/agents.test.d.ts +0 -2
  491. package/dist/cli/__tests__/agents.test.d.ts.map +0 -1
  492. package/dist/cli/__tests__/agents.test.js +0 -137
  493. package/dist/cli/__tests__/agents.test.js.map +0 -1
  494. package/dist/cli/__tests__/ask.test.d.ts +0 -2
  495. package/dist/cli/__tests__/ask.test.d.ts.map +0 -1
  496. package/dist/cli/__tests__/ask.test.js +0 -265
  497. package/dist/cli/__tests__/ask.test.js.map +0 -1
  498. package/dist/cli/__tests__/autoresearch-guided.test.d.ts +0 -2
  499. package/dist/cli/__tests__/autoresearch-guided.test.d.ts.map +0 -1
  500. package/dist/cli/__tests__/autoresearch-guided.test.js +0 -365
  501. package/dist/cli/__tests__/autoresearch-guided.test.js.map +0 -1
  502. package/dist/cli/__tests__/autoresearch.test.d.ts +0 -2
  503. package/dist/cli/__tests__/autoresearch.test.d.ts.map +0 -1
  504. package/dist/cli/__tests__/autoresearch.test.js +0 -203
  505. package/dist/cli/__tests__/autoresearch.test.js.map +0 -1
  506. package/dist/cli/__tests__/catalog-contract.test.d.ts +0 -2
  507. package/dist/cli/__tests__/catalog-contract.test.d.ts.map +0 -1
  508. package/dist/cli/__tests__/catalog-contract.test.js +0 -18
  509. package/dist/cli/__tests__/catalog-contract.test.js.map +0 -1
  510. package/dist/cli/__tests__/cleanup.test.d.ts +0 -2
  511. package/dist/cli/__tests__/cleanup.test.d.ts.map +0 -1
  512. package/dist/cli/__tests__/cleanup.test.js +0 -419
  513. package/dist/cli/__tests__/cleanup.test.js.map +0 -1
  514. package/dist/cli/__tests__/codex-plugin-layout.test.d.ts +0 -2
  515. package/dist/cli/__tests__/codex-plugin-layout.test.d.ts.map +0 -1
  516. package/dist/cli/__tests__/codex-plugin-layout.test.js +0 -210
  517. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +0 -1
  518. package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts +0 -2
  519. package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts.map +0 -1
  520. package/dist/cli/__tests__/doctor-context-window-warning.test.js +0 -122
  521. package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +0 -1
  522. package/dist/cli/__tests__/doctor-invalid-config.test.d.ts +0 -2
  523. package/dist/cli/__tests__/doctor-invalid-config.test.d.ts.map +0 -1
  524. package/dist/cli/__tests__/doctor-invalid-config.test.js +0 -52
  525. package/dist/cli/__tests__/doctor-invalid-config.test.js.map +0 -1
  526. package/dist/cli/__tests__/doctor-team.test.d.ts +0 -2
  527. package/dist/cli/__tests__/doctor-team.test.d.ts.map +0 -1
  528. package/dist/cli/__tests__/doctor-team.test.js +0 -299
  529. package/dist/cli/__tests__/doctor-team.test.js.map +0 -1
  530. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts +0 -2
  531. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts.map +0 -1
  532. package/dist/cli/__tests__/doctor-warning-copy.test.js +0 -438
  533. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +0 -1
  534. package/dist/cli/__tests__/error-handling-warnings.test.d.ts +0 -2
  535. package/dist/cli/__tests__/error-handling-warnings.test.d.ts.map +0 -1
  536. package/dist/cli/__tests__/error-handling-warnings.test.js +0 -52
  537. package/dist/cli/__tests__/error-handling-warnings.test.js.map +0 -1
  538. package/dist/cli/__tests__/exec.test.d.ts +0 -2
  539. package/dist/cli/__tests__/exec.test.d.ts.map +0 -1
  540. package/dist/cli/__tests__/exec.test.js +0 -213
  541. package/dist/cli/__tests__/exec.test.js.map +0 -1
  542. package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts +0 -2
  543. package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts.map +0 -1
  544. package/dist/cli/__tests__/explore-windows-diagnostics.test.js +0 -17
  545. package/dist/cli/__tests__/explore-windows-diagnostics.test.js.map +0 -1
  546. package/dist/cli/__tests__/explore.test.d.ts +0 -2
  547. package/dist/cli/__tests__/explore.test.d.ts.map +0 -1
  548. package/dist/cli/__tests__/explore.test.js +0 -1090
  549. package/dist/cli/__tests__/explore.test.js.map +0 -1
  550. package/dist/cli/__tests__/hooks.test.d.ts +0 -2
  551. package/dist/cli/__tests__/hooks.test.d.ts.map +0 -1
  552. package/dist/cli/__tests__/hooks.test.js +0 -55
  553. package/dist/cli/__tests__/hooks.test.js.map +0 -1
  554. package/dist/cli/__tests__/index.test.d.ts +0 -2
  555. package/dist/cli/__tests__/index.test.d.ts.map +0 -1
  556. package/dist/cli/__tests__/index.test.js +0 -2259
  557. package/dist/cli/__tests__/index.test.js.map +0 -1
  558. package/dist/cli/__tests__/launch-fallback.test.d.ts +0 -2
  559. package/dist/cli/__tests__/launch-fallback.test.d.ts.map +0 -1
  560. package/dist/cli/__tests__/launch-fallback.test.js +0 -661
  561. package/dist/cli/__tests__/launch-fallback.test.js.map +0 -1
  562. package/dist/cli/__tests__/lifecycle-notifications.test.d.ts +0 -2
  563. package/dist/cli/__tests__/lifecycle-notifications.test.d.ts.map +0 -1
  564. package/dist/cli/__tests__/lifecycle-notifications.test.js +0 -48
  565. package/dist/cli/__tests__/lifecycle-notifications.test.js.map +0 -1
  566. package/dist/cli/__tests__/list.test.d.ts +0 -2
  567. package/dist/cli/__tests__/list.test.d.ts.map +0 -1
  568. package/dist/cli/__tests__/list.test.js +0 -38
  569. package/dist/cli/__tests__/list.test.js.map +0 -1
  570. package/dist/cli/__tests__/mcp-parity.test.d.ts +0 -2
  571. package/dist/cli/__tests__/mcp-parity.test.d.ts.map +0 -1
  572. package/dist/cli/__tests__/mcp-parity.test.js +0 -228
  573. package/dist/cli/__tests__/mcp-parity.test.js.map +0 -1
  574. package/dist/cli/__tests__/mcp-serve.test.d.ts +0 -2
  575. package/dist/cli/__tests__/mcp-serve.test.d.ts.map +0 -1
  576. package/dist/cli/__tests__/mcp-serve.test.js +0 -64
  577. package/dist/cli/__tests__/mcp-serve.test.js.map +0 -1
  578. package/dist/cli/__tests__/native-assets.test.d.ts +0 -2
  579. package/dist/cli/__tests__/native-assets.test.d.ts.map +0 -1
  580. package/dist/cli/__tests__/native-assets.test.js +0 -308
  581. package/dist/cli/__tests__/native-assets.test.js.map +0 -1
  582. package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts +0 -2
  583. package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts.map +0 -1
  584. package/dist/cli/__tests__/native-hook-dispatch-contract.test.js +0 -11
  585. package/dist/cli/__tests__/native-hook-dispatch-contract.test.js.map +0 -1
  586. package/dist/cli/__tests__/nested-help-routing.test.d.ts +0 -2
  587. package/dist/cli/__tests__/nested-help-routing.test.d.ts.map +0 -1
  588. package/dist/cli/__tests__/nested-help-routing.test.js +0 -96
  589. package/dist/cli/__tests__/nested-help-routing.test.js.map +0 -1
  590. package/dist/cli/__tests__/package-bin-contract.test.d.ts +0 -2
  591. package/dist/cli/__tests__/package-bin-contract.test.d.ts.map +0 -1
  592. package/dist/cli/__tests__/package-bin-contract.test.js +0 -177
  593. package/dist/cli/__tests__/package-bin-contract.test.js.map +0 -1
  594. package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts +0 -3
  595. package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts.map +0 -1
  596. package/dist/cli/__tests__/packaged-explore-harness-lock.js +0 -67
  597. package/dist/cli/__tests__/packaged-explore-harness-lock.js.map +0 -1
  598. package/dist/cli/__tests__/packaged-script-resolution.test.d.ts +0 -2
  599. package/dist/cli/__tests__/packaged-script-resolution.test.d.ts.map +0 -1
  600. package/dist/cli/__tests__/packaged-script-resolution.test.js +0 -19
  601. package/dist/cli/__tests__/packaged-script-resolution.test.js.map +0 -1
  602. package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts +0 -2
  603. package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts.map +0 -1
  604. package/dist/cli/__tests__/prompt-skill-sanitization.test.js +0 -48
  605. package/dist/cli/__tests__/prompt-skill-sanitization.test.js.map +0 -1
  606. package/dist/cli/__tests__/question.test.d.ts +0 -2
  607. package/dist/cli/__tests__/question.test.d.ts.map +0 -1
  608. package/dist/cli/__tests__/question.test.js +0 -633
  609. package/dist/cli/__tests__/question.test.js.map +0 -1
  610. package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts +0 -2
  611. package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts.map +0 -1
  612. package/dist/cli/__tests__/ralph-deslop-contract.test.js +0 -28
  613. package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +0 -1
  614. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts +0 -2
  615. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts.map +0 -1
  616. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +0 -24
  617. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +0 -1
  618. package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts +0 -2
  619. package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts.map +0 -1
  620. package/dist/cli/__tests__/ralph-prd-smoke.test.js +0 -167
  621. package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +0 -1
  622. package/dist/cli/__tests__/ralph.test.d.ts +0 -2
  623. package/dist/cli/__tests__/ralph.test.d.ts.map +0 -1
  624. package/dist/cli/__tests__/ralph.test.js +0 -256
  625. package/dist/cli/__tests__/ralph.test.js.map +0 -1
  626. package/dist/cli/__tests__/resume.test.d.ts +0 -2
  627. package/dist/cli/__tests__/resume.test.d.ts.map +0 -1
  628. package/dist/cli/__tests__/resume.test.js +0 -84
  629. package/dist/cli/__tests__/resume.test.js.map +0 -1
  630. package/dist/cli/__tests__/session-scoped-runtime.test.d.ts +0 -2
  631. package/dist/cli/__tests__/session-scoped-runtime.test.d.ts.map +0 -1
  632. package/dist/cli/__tests__/session-scoped-runtime.test.js +0 -146
  633. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +0 -1
  634. package/dist/cli/__tests__/session-search-help.test.d.ts +0 -2
  635. package/dist/cli/__tests__/session-search-help.test.d.ts.map +0 -1
  636. package/dist/cli/__tests__/session-search-help.test.js +0 -76
  637. package/dist/cli/__tests__/session-search-help.test.js.map +0 -1
  638. package/dist/cli/__tests__/session-search.test.d.ts +0 -2
  639. package/dist/cli/__tests__/session-search.test.d.ts.map +0 -1
  640. package/dist/cli/__tests__/session-search.test.js +0 -77
  641. package/dist/cli/__tests__/session-search.test.js.map +0 -1
  642. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts +0 -2
  643. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts.map +0 -1
  644. package/dist/cli/__tests__/setup-agents-overwrite.test.js +0 -457
  645. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +0 -1
  646. package/dist/cli/__tests__/setup-gh-star.test.d.ts +0 -2
  647. package/dist/cli/__tests__/setup-gh-star.test.d.ts.map +0 -1
  648. package/dist/cli/__tests__/setup-gh-star.test.js +0 -67
  649. package/dist/cli/__tests__/setup-gh-star.test.js.map +0 -1
  650. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts +0 -2
  651. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts.map +0 -1
  652. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +0 -189
  653. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +0 -1
  654. package/dist/cli/__tests__/setup-install-mode.test.d.ts +0 -2
  655. package/dist/cli/__tests__/setup-install-mode.test.d.ts.map +0 -1
  656. package/dist/cli/__tests__/setup-install-mode.test.js +0 -873
  657. package/dist/cli/__tests__/setup-install-mode.test.js.map +0 -1
  658. package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts +0 -2
  659. package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts.map +0 -1
  660. package/dist/cli/__tests__/setup-prompts-overwrite.test.js +0 -191
  661. package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +0 -1
  662. package/dist/cli/__tests__/setup-refresh.test.d.ts +0 -2
  663. package/dist/cli/__tests__/setup-refresh.test.d.ts.map +0 -1
  664. package/dist/cli/__tests__/setup-refresh.test.js +0 -591
  665. package/dist/cli/__tests__/setup-refresh.test.js.map +0 -1
  666. package/dist/cli/__tests__/setup-scope.test.d.ts +0 -2
  667. package/dist/cli/__tests__/setup-scope.test.d.ts.map +0 -1
  668. package/dist/cli/__tests__/setup-scope.test.js +0 -340
  669. package/dist/cli/__tests__/setup-scope.test.js.map +0 -1
  670. package/dist/cli/__tests__/setup-skill-validation.test.d.ts +0 -2
  671. package/dist/cli/__tests__/setup-skill-validation.test.d.ts.map +0 -1
  672. package/dist/cli/__tests__/setup-skill-validation.test.js +0 -44
  673. package/dist/cli/__tests__/setup-skill-validation.test.js.map +0 -1
  674. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts +0 -2
  675. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts.map +0 -1
  676. package/dist/cli/__tests__/setup-skills-overwrite.test.js +0 -295
  677. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +0 -1
  678. package/dist/cli/__tests__/sidecar.test.d.ts +0 -2
  679. package/dist/cli/__tests__/sidecar.test.d.ts.map +0 -1
  680. package/dist/cli/__tests__/sidecar.test.js +0 -24
  681. package/dist/cli/__tests__/sidecar.test.js.map +0 -1
  682. package/dist/cli/__tests__/sparkshell-cli.test.d.ts +0 -2
  683. package/dist/cli/__tests__/sparkshell-cli.test.d.ts.map +0 -1
  684. package/dist/cli/__tests__/sparkshell-cli.test.js +0 -400
  685. package/dist/cli/__tests__/sparkshell-cli.test.js.map +0 -1
  686. package/dist/cli/__tests__/sparkshell-packaging.test.d.ts +0 -2
  687. package/dist/cli/__tests__/sparkshell-packaging.test.d.ts.map +0 -1
  688. package/dist/cli/__tests__/sparkshell-packaging.test.js +0 -74
  689. package/dist/cli/__tests__/sparkshell-packaging.test.js.map +0 -1
  690. package/dist/cli/__tests__/star-prompt.test.d.ts +0 -2
  691. package/dist/cli/__tests__/star-prompt.test.d.ts.map +0 -1
  692. package/dist/cli/__tests__/star-prompt.test.js +0 -172
  693. package/dist/cli/__tests__/star-prompt.test.js.map +0 -1
  694. package/dist/cli/__tests__/state.test.d.ts +0 -2
  695. package/dist/cli/__tests__/state.test.d.ts.map +0 -1
  696. package/dist/cli/__tests__/state.test.js +0 -46
  697. package/dist/cli/__tests__/state.test.js.map +0 -1
  698. package/dist/cli/__tests__/team-decompose.test.d.ts +0 -2
  699. package/dist/cli/__tests__/team-decompose.test.d.ts.map +0 -1
  700. package/dist/cli/__tests__/team-decompose.test.js +0 -133
  701. package/dist/cli/__tests__/team-decompose.test.js.map +0 -1
  702. package/dist/cli/__tests__/team.test.d.ts +0 -2
  703. package/dist/cli/__tests__/team.test.d.ts.map +0 -1
  704. package/dist/cli/__tests__/team.test.js +0 -1820
  705. package/dist/cli/__tests__/team.test.js.map +0 -1
  706. package/dist/cli/__tests__/uninstall.test.d.ts +0 -2
  707. package/dist/cli/__tests__/uninstall.test.d.ts.map +0 -1
  708. package/dist/cli/__tests__/uninstall.test.js +0 -766
  709. package/dist/cli/__tests__/uninstall.test.js.map +0 -1
  710. package/dist/cli/__tests__/update.test.d.ts +0 -2
  711. package/dist/cli/__tests__/update.test.d.ts.map +0 -1
  712. package/dist/cli/__tests__/update.test.js +0 -589
  713. package/dist/cli/__tests__/update.test.js.map +0 -1
  714. package/dist/cli/__tests__/version-sync-contract.test.d.ts +0 -2
  715. package/dist/cli/__tests__/version-sync-contract.test.d.ts.map +0 -1
  716. package/dist/cli/__tests__/version-sync-contract.test.js +0 -41
  717. package/dist/cli/__tests__/version-sync-contract.test.js.map +0 -1
  718. package/dist/cli/__tests__/version.test.d.ts +0 -2
  719. package/dist/cli/__tests__/version.test.d.ts.map +0 -1
  720. package/dist/cli/__tests__/version.test.js +0 -21
  721. package/dist/cli/__tests__/version.test.js.map +0 -1
  722. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +0 -2
  723. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +0 -1
  724. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +0 -31
  725. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +0 -1
  726. package/dist/cli/ralph.d.ts +0 -17
  727. package/dist/compat/__tests__/doctor-contract.test.d.ts +0 -2
  728. package/dist/compat/__tests__/doctor-contract.test.d.ts.map +0 -1
  729. package/dist/compat/__tests__/doctor-contract.test.js +0 -108
  730. package/dist/compat/__tests__/doctor-contract.test.js.map +0 -1
  731. package/dist/compat/__tests__/rust-runtime-compat.test.d.ts +0 -2
  732. package/dist/compat/__tests__/rust-runtime-compat.test.d.ts.map +0 -1
  733. package/dist/compat/__tests__/rust-runtime-compat.test.js +0 -218
  734. package/dist/compat/__tests__/rust-runtime-compat.test.js.map +0 -1
  735. package/dist/config/__tests__/codex-hooks.test.d.ts +0 -2
  736. package/dist/config/__tests__/codex-hooks.test.d.ts.map +0 -1
  737. package/dist/config/__tests__/codex-hooks.test.js +0 -77
  738. package/dist/config/__tests__/codex-hooks.test.js.map +0 -1
  739. package/dist/config/__tests__/generator-idempotent.test.d.ts +0 -2
  740. package/dist/config/__tests__/generator-idempotent.test.d.ts.map +0 -1
  741. package/dist/config/__tests__/generator-idempotent.test.js +0 -882
  742. package/dist/config/__tests__/generator-idempotent.test.js.map +0 -1
  743. package/dist/config/__tests__/generator-notify.test.d.ts +0 -2
  744. package/dist/config/__tests__/generator-notify.test.d.ts.map +0 -1
  745. package/dist/config/__tests__/generator-notify.test.js +0 -343
  746. package/dist/config/__tests__/generator-notify.test.js.map +0 -1
  747. package/dist/config/__tests__/generator-status-line-presets.test.d.ts +0 -2
  748. package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +0 -1
  749. package/dist/config/__tests__/generator-status-line-presets.test.js +0 -203
  750. package/dist/config/__tests__/generator-status-line-presets.test.js.map +0 -1
  751. package/dist/config/__tests__/mcp-registry.test.d.ts +0 -2
  752. package/dist/config/__tests__/mcp-registry.test.d.ts.map +0 -1
  753. package/dist/config/__tests__/mcp-registry.test.js +0 -190
  754. package/dist/config/__tests__/mcp-registry.test.js.map +0 -1
  755. package/dist/config/__tests__/models.test.d.ts +0 -2
  756. package/dist/config/__tests__/models.test.d.ts.map +0 -1
  757. package/dist/config/__tests__/models.test.js +0 -224
  758. package/dist/config/__tests__/models.test.js.map +0 -1
  759. package/dist/config/__tests__/wiki-config-contract.test.d.ts +0 -2
  760. package/dist/config/__tests__/wiki-config-contract.test.d.ts.map +0 -1
  761. package/dist/config/__tests__/wiki-config-contract.test.js +0 -19
  762. package/dist/config/__tests__/wiki-config-contract.test.js.map +0 -1
  763. package/dist/document-refresh/__tests__/enforcer.test.d.ts +0 -2
  764. package/dist/document-refresh/__tests__/enforcer.test.d.ts.map +0 -1
  765. package/dist/document-refresh/__tests__/enforcer.test.js +0 -128
  766. package/dist/document-refresh/__tests__/enforcer.test.js.map +0 -1
  767. package/dist/hooks/__tests__/agents-overlay.test.d.ts +0 -8
  768. package/dist/hooks/__tests__/agents-overlay.test.d.ts.map +0 -1
  769. package/dist/hooks/__tests__/agents-overlay.test.js +0 -644
  770. package/dist/hooks/__tests__/agents-overlay.test.js.map +0 -1
  771. package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts +0 -2
  772. package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts.map +0 -1
  773. package/dist/hooks/__tests__/analyze-routing-contract.test.js +0 -45
  774. package/dist/hooks/__tests__/analyze-routing-contract.test.js.map +0 -1
  775. package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts +0 -2
  776. package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts.map +0 -1
  777. package/dist/hooks/__tests__/analyze-skill-contract.test.js +0 -48
  778. package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +0 -1
  779. package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts +0 -2
  780. package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts.map +0 -1
  781. package/dist/hooks/__tests__/anti-slop-workflow.test.js +0 -146
  782. package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +0 -1
  783. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts +0 -2
  784. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts.map +0 -1
  785. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +0 -37
  786. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +0 -1
  787. package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts +0 -2
  788. package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts.map +0 -1
  789. package/dist/hooks/__tests__/clawhip-event-contract.test.js +0 -37
  790. package/dist/hooks/__tests__/clawhip-event-contract.test.js.map +0 -1
  791. package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts +0 -2
  792. package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts.map +0 -1
  793. package/dist/hooks/__tests__/code-review-skill-contract.test.js +0 -56
  794. package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +0 -1
  795. package/dist/hooks/__tests__/codebase-map.test.d.ts +0 -8
  796. package/dist/hooks/__tests__/codebase-map.test.d.ts.map +0 -1
  797. package/dist/hooks/__tests__/codebase-map.test.js +0 -218
  798. package/dist/hooks/__tests__/codebase-map.test.js.map +0 -1
  799. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +0 -18
  800. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +0 -1
  801. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +0 -234
  802. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +0 -1
  803. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +0 -2
  804. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +0 -1
  805. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +0 -20
  806. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +0 -1
  807. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts +0 -2
  808. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts.map +0 -1
  809. package/dist/hooks/__tests__/deep-interview-contract.test.js +0 -213
  810. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +0 -1
  811. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts +0 -2
  812. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts.map +0 -1
  813. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js +0 -43
  814. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js.map +0 -1
  815. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts +0 -2
  816. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts.map +0 -1
  817. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js +0 -38
  818. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js.map +0 -1
  819. package/dist/hooks/__tests__/explore-routing.test.d.ts +0 -2
  820. package/dist/hooks/__tests__/explore-routing.test.d.ts.map +0 -1
  821. package/dist/hooks/__tests__/explore-routing.test.js +0 -43
  822. package/dist/hooks/__tests__/explore-routing.test.js.map +0 -1
  823. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts +0 -2
  824. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts.map +0 -1
  825. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +0 -69
  826. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +0 -1
  827. package/dist/hooks/__tests__/keyword-detector.test.d.ts +0 -2
  828. package/dist/hooks/__tests__/keyword-detector.test.d.ts.map +0 -1
  829. package/dist/hooks/__tests__/keyword-detector.test.js +0 -1716
  830. package/dist/hooks/__tests__/keyword-detector.test.js.map +0 -1
  831. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts +0 -2
  832. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts.map +0 -1
  833. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +0 -3898
  834. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +0 -1
  835. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts +0 -2
  836. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts.map +0 -1
  837. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +0 -786
  838. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +0 -1
  839. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts +0 -2
  840. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts.map +0 -1
  841. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +0 -2397
  842. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +0 -1
  843. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts +0 -2
  844. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts.map +0 -1
  845. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +0 -160
  846. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +0 -1
  847. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +0 -2
  848. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +0 -1
  849. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +0 -1178
  850. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +0 -1
  851. package/dist/hooks/__tests__/notify-hook-modules.test.d.ts +0 -9
  852. package/dist/hooks/__tests__/notify-hook-modules.test.d.ts.map +0 -1
  853. package/dist/hooks/__tests__/notify-hook-modules.test.js +0 -529
  854. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +0 -1
  855. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts +0 -2
  856. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts.map +0 -1
  857. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js +0 -14
  858. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js.map +0 -1
  859. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +0 -2
  860. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +0 -1
  861. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +0 -682
  862. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +0 -1
  863. package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts +0 -9
  864. package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts.map +0 -1
  865. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +0 -255
  866. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +0 -1
  867. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +0 -2
  868. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +0 -1
  869. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +0 -162
  870. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +0 -1
  871. package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts +0 -2
  872. package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts.map +0 -1
  873. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +0 -301
  874. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +0 -1
  875. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts +0 -2
  876. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts.map +0 -1
  877. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +0 -1510
  878. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +0 -1
  879. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts +0 -2
  880. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts.map +0 -1
  881. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +0 -2879
  882. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +0 -1
  883. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts +0 -2
  884. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts.map +0 -1
  885. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +0 -228
  886. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +0 -1
  887. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts +0 -2
  888. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +0 -1
  889. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +0 -35
  890. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +0 -1
  891. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts +0 -2
  892. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts.map +0 -1
  893. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +0 -1589
  894. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +0 -1
  895. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts +0 -10
  896. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts.map +0 -1
  897. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
  898. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +0 -1
  899. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts +0 -11
  900. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts.map +0 -1
  901. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js +0 -266
  902. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +0 -1
  903. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts +0 -2
  904. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts.map +0 -1
  905. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +0 -895
  906. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +0 -1
  907. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts +0 -2
  908. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts.map +0 -1
  909. package/dist/hooks/__tests__/openclaw-setup-contract.test.js +0 -61
  910. package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +0 -1
  911. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts +0 -2
  912. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts.map +0 -1
  913. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +0 -40
  914. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +0 -1
  915. package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts +0 -2
  916. package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts.map +0 -1
  917. package/dist/hooks/__tests__/prompt-guidance-catalog.test.js +0 -11
  918. package/dist/hooks/__tests__/prompt-guidance-catalog.test.js.map +0 -1
  919. package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts +0 -2
  920. package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts.map +0 -1
  921. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +0 -38
  922. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +0 -1
  923. package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts +0 -2
  924. package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts.map +0 -1
  925. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +0 -48
  926. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +0 -1
  927. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts +0 -2
  928. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts.map +0 -1
  929. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js +0 -11
  930. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js.map +0 -1
  931. package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts +0 -5
  932. package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts.map +0 -1
  933. package/dist/hooks/__tests__/prompt-guidance-test-helpers.js +0 -34
  934. package/dist/hooks/__tests__/prompt-guidance-test-helpers.js.map +0 -1
  935. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts +0 -2
  936. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts.map +0 -1
  937. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +0 -65
  938. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +0 -1
  939. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts +0 -2
  940. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts.map +0 -1
  941. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js +0 -38
  942. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js.map +0 -1
  943. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +0 -2
  944. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +0 -1
  945. package/dist/hooks/__tests__/prompt-refactor-contract.test.js +0 -22
  946. package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +0 -1
  947. package/dist/hooks/__tests__/prompt-team-routing.test.d.ts +0 -2
  948. package/dist/hooks/__tests__/prompt-team-routing.test.d.ts.map +0 -1
  949. package/dist/hooks/__tests__/prompt-team-routing.test.js +0 -49
  950. package/dist/hooks/__tests__/prompt-team-routing.test.js.map +0 -1
  951. package/dist/hooks/__tests__/session.test.d.ts +0 -2
  952. package/dist/hooks/__tests__/session.test.d.ts.map +0 -1
  953. package/dist/hooks/__tests__/session.test.js +0 -322
  954. package/dist/hooks/__tests__/session.test.js.map +0 -1
  955. package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts +0 -2
  956. package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts.map +0 -1
  957. package/dist/hooks/__tests__/skill-guidance-contract.test.js +0 -29
  958. package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +0 -1
  959. package/dist/hooks/__tests__/task-size-detector.test.d.ts +0 -2
  960. package/dist/hooks/__tests__/task-size-detector.test.d.ts.map +0 -1
  961. package/dist/hooks/__tests__/task-size-detector.test.js +0 -330
  962. package/dist/hooks/__tests__/task-size-detector.test.js.map +0 -1
  963. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts +0 -2
  964. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts.map +0 -1
  965. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +0 -28
  966. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +0 -1
  967. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts +0 -2
  968. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts.map +0 -1
  969. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js +0 -24
  970. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js.map +0 -1
  971. package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts +0 -2
  972. package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts.map +0 -1
  973. package/dist/hooks/__tests__/tmux-hook-engine.test.js +0 -403
  974. package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +0 -1
  975. package/dist/hooks/__tests__/triage-config.test.d.ts +0 -2
  976. package/dist/hooks/__tests__/triage-config.test.d.ts.map +0 -1
  977. package/dist/hooks/__tests__/triage-config.test.js +0 -211
  978. package/dist/hooks/__tests__/triage-config.test.js.map +0 -1
  979. package/dist/hooks/__tests__/triage-heuristic.test.d.ts +0 -2
  980. package/dist/hooks/__tests__/triage-heuristic.test.d.ts.map +0 -1
  981. package/dist/hooks/__tests__/triage-heuristic.test.js +0 -285
  982. package/dist/hooks/__tests__/triage-heuristic.test.js.map +0 -1
  983. package/dist/hooks/__tests__/triage-state.test.d.ts +0 -2
  984. package/dist/hooks/__tests__/triage-state.test.d.ts.map +0 -1
  985. package/dist/hooks/__tests__/triage-state.test.js +0 -426
  986. package/dist/hooks/__tests__/triage-state.test.js.map +0 -1
  987. package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts +0 -2
  988. package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts.map +0 -1
  989. package/dist/hooks/__tests__/visual-ralph-skill.test.js +0 -44
  990. package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +0 -1
  991. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts +0 -2
  992. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts.map +0 -1
  993. package/dist/hooks/__tests__/visual-verdict-loop.test.js +0 -35
  994. package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +0 -1
  995. package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts +0 -2
  996. package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts.map +0 -1
  997. package/dist/hooks/__tests__/wiki-docs-contract.test.js +0 -34
  998. package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +0 -1
  999. package/dist/hooks/code-simplifier/__tests__/index.test.d.ts +0 -2
  1000. package/dist/hooks/code-simplifier/__tests__/index.test.d.ts.map +0 -1
  1001. package/dist/hooks/code-simplifier/__tests__/index.test.js +0 -187
  1002. package/dist/hooks/code-simplifier/__tests__/index.test.js.map +0 -1
  1003. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts +0 -2
  1004. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts.map +0 -1
  1005. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +0 -242
  1006. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +0 -1
  1007. package/dist/hooks/extensibility/__tests__/events.test.d.ts +0 -2
  1008. package/dist/hooks/extensibility/__tests__/events.test.d.ts.map +0 -1
  1009. package/dist/hooks/extensibility/__tests__/events.test.js +0 -125
  1010. package/dist/hooks/extensibility/__tests__/events.test.js.map +0 -1
  1011. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts +0 -2
  1012. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts.map +0 -1
  1013. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js +0 -153
  1014. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js.map +0 -1
  1015. package/dist/hooks/extensibility/__tests__/loader.test.d.ts +0 -2
  1016. package/dist/hooks/extensibility/__tests__/loader.test.d.ts.map +0 -1
  1017. package/dist/hooks/extensibility/__tests__/loader.test.js +0 -254
  1018. package/dist/hooks/extensibility/__tests__/loader.test.js.map +0 -1
  1019. package/dist/hooks/extensibility/__tests__/logging.test.d.ts +0 -2
  1020. package/dist/hooks/extensibility/__tests__/logging.test.d.ts.map +0 -1
  1021. package/dist/hooks/extensibility/__tests__/logging.test.js +0 -74
  1022. package/dist/hooks/extensibility/__tests__/logging.test.js.map +0 -1
  1023. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts +0 -2
  1024. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts.map +0 -1
  1025. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +0 -202
  1026. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +0 -1
  1027. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts +0 -2
  1028. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts.map +0 -1
  1029. package/dist/hooks/extensibility/__tests__/runtime.test.js +0 -198
  1030. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +0 -1
  1031. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts +0 -2
  1032. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts.map +0 -1
  1033. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js +0 -32
  1034. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js.map +0 -1
  1035. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts +0 -2
  1036. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts.map +0 -1
  1037. package/dist/hooks/extensibility/__tests__/sdk.test.js +0 -479
  1038. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +0 -1
  1039. package/dist/hud/__tests__/authority.test.d.ts +0 -2
  1040. package/dist/hud/__tests__/authority.test.d.ts.map +0 -1
  1041. package/dist/hud/__tests__/authority.test.js +0 -56
  1042. package/dist/hud/__tests__/authority.test.js.map +0 -1
  1043. package/dist/hud/__tests__/colors.test.d.ts +0 -2
  1044. package/dist/hud/__tests__/colors.test.d.ts.map +0 -1
  1045. package/dist/hud/__tests__/colors.test.js +0 -92
  1046. package/dist/hud/__tests__/colors.test.js.map +0 -1
  1047. package/dist/hud/__tests__/hud-tmux-injection.test.d.ts +0 -10
  1048. package/dist/hud/__tests__/hud-tmux-injection.test.d.ts.map +0 -1
  1049. package/dist/hud/__tests__/hud-tmux-injection.test.js +0 -150
  1050. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +0 -1
  1051. package/dist/hud/__tests__/index.test.d.ts +0 -2
  1052. package/dist/hud/__tests__/index.test.d.ts.map +0 -1
  1053. package/dist/hud/__tests__/index.test.js +0 -180
  1054. package/dist/hud/__tests__/index.test.js.map +0 -1
  1055. package/dist/hud/__tests__/reconcile.test.d.ts +0 -2
  1056. package/dist/hud/__tests__/reconcile.test.d.ts.map +0 -1
  1057. package/dist/hud/__tests__/reconcile.test.js +0 -125
  1058. package/dist/hud/__tests__/reconcile.test.js.map +0 -1
  1059. package/dist/hud/__tests__/render.test.d.ts +0 -2
  1060. package/dist/hud/__tests__/render.test.d.ts.map +0 -1
  1061. package/dist/hud/__tests__/render.test.js +0 -573
  1062. package/dist/hud/__tests__/render.test.js.map +0 -1
  1063. package/dist/hud/__tests__/state.test.d.ts +0 -2
  1064. package/dist/hud/__tests__/state.test.d.ts.map +0 -1
  1065. package/dist/hud/__tests__/state.test.js +0 -618
  1066. package/dist/hud/__tests__/state.test.js.map +0 -1
  1067. package/dist/hud/__tests__/types.test.d.ts +0 -2
  1068. package/dist/hud/__tests__/types.test.d.ts.map +0 -1
  1069. package/dist/hud/__tests__/types.test.js +0 -79
  1070. package/dist/hud/__tests__/types.test.js.map +0 -1
  1071. package/dist/hud/__tests__/watch.test.d.ts +0 -2
  1072. package/dist/hud/__tests__/watch.test.d.ts.map +0 -1
  1073. package/dist/hud/__tests__/watch.test.js +0 -63
  1074. package/dist/hud/__tests__/watch.test.js.map +0 -1
  1075. package/dist/mcp/__tests__/bootstrap.test.d.ts +0 -2
  1076. package/dist/mcp/__tests__/bootstrap.test.d.ts.map +0 -1
  1077. package/dist/mcp/__tests__/bootstrap.test.js +0 -207
  1078. package/dist/mcp/__tests__/bootstrap.test.js.map +0 -1
  1079. package/dist/mcp/__tests__/code-intel-server.test.d.ts +0 -2
  1080. package/dist/mcp/__tests__/code-intel-server.test.d.ts.map +0 -1
  1081. package/dist/mcp/__tests__/code-intel-server.test.js +0 -70
  1082. package/dist/mcp/__tests__/code-intel-server.test.js.map +0 -1
  1083. package/dist/mcp/__tests__/memory-server.test.d.ts +0 -2
  1084. package/dist/mcp/__tests__/memory-server.test.d.ts.map +0 -1
  1085. package/dist/mcp/__tests__/memory-server.test.js +0 -36
  1086. package/dist/mcp/__tests__/memory-server.test.js.map +0 -1
  1087. package/dist/mcp/__tests__/memory-validation.test.d.ts +0 -2
  1088. package/dist/mcp/__tests__/memory-validation.test.d.ts.map +0 -1
  1089. package/dist/mcp/__tests__/memory-validation.test.js +0 -29
  1090. package/dist/mcp/__tests__/memory-validation.test.js.map +0 -1
  1091. package/dist/mcp/__tests__/path-traversal.test.d.ts +0 -2
  1092. package/dist/mcp/__tests__/path-traversal.test.d.ts.map +0 -1
  1093. package/dist/mcp/__tests__/path-traversal.test.js +0 -83
  1094. package/dist/mcp/__tests__/path-traversal.test.js.map +0 -1
  1095. package/dist/mcp/__tests__/server-lifecycle.test.d.ts +0 -2
  1096. package/dist/mcp/__tests__/server-lifecycle.test.d.ts.map +0 -1
  1097. package/dist/mcp/__tests__/server-lifecycle.test.js +0 -260
  1098. package/dist/mcp/__tests__/server-lifecycle.test.js.map +0 -1
  1099. package/dist/mcp/__tests__/state-paths.test.d.ts +0 -2
  1100. package/dist/mcp/__tests__/state-paths.test.d.ts.map +0 -1
  1101. package/dist/mcp/__tests__/state-paths.test.js +0 -209
  1102. package/dist/mcp/__tests__/state-paths.test.js.map +0 -1
  1103. package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts +0 -2
  1104. package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts.map +0 -1
  1105. package/dist/mcp/__tests__/state-server-ralph-phase.test.js +0 -109
  1106. package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +0 -1
  1107. package/dist/mcp/__tests__/state-server-schema.test.d.ts +0 -2
  1108. package/dist/mcp/__tests__/state-server-schema.test.d.ts.map +0 -1
  1109. package/dist/mcp/__tests__/state-server-schema.test.js +0 -29
  1110. package/dist/mcp/__tests__/state-server-schema.test.js.map +0 -1
  1111. package/dist/mcp/__tests__/state-server-team-tools.test.d.ts +0 -2
  1112. package/dist/mcp/__tests__/state-server-team-tools.test.d.ts.map +0 -1
  1113. package/dist/mcp/__tests__/state-server-team-tools.test.js +0 -35
  1114. package/dist/mcp/__tests__/state-server-team-tools.test.js.map +0 -1
  1115. package/dist/mcp/__tests__/state-server.test.d.ts +0 -2
  1116. package/dist/mcp/__tests__/state-server.test.d.ts.map +0 -1
  1117. package/dist/mcp/__tests__/state-server.test.js +0 -965
  1118. package/dist/mcp/__tests__/state-server.test.js.map +0 -1
  1119. package/dist/mcp/__tests__/trace-server.test.d.ts +0 -2
  1120. package/dist/mcp/__tests__/trace-server.test.d.ts.map +0 -1
  1121. package/dist/mcp/__tests__/trace-server.test.js +0 -119
  1122. package/dist/mcp/__tests__/trace-server.test.js.map +0 -1
  1123. package/dist/mcp/__tests__/wiki-server.test.d.ts +0 -2
  1124. package/dist/mcp/__tests__/wiki-server.test.d.ts.map +0 -1
  1125. package/dist/mcp/__tests__/wiki-server.test.js +0 -30
  1126. package/dist/mcp/__tests__/wiki-server.test.js.map +0 -1
  1127. package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts +0 -2
  1128. package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts.map +0 -1
  1129. package/dist/modes/__tests__/base-autoresearch-contract.test.js +0 -123
  1130. package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +0 -1
  1131. package/dist/modes/__tests__/base-multi-state-compat.test.d.ts +0 -2
  1132. package/dist/modes/__tests__/base-multi-state-compat.test.d.ts.map +0 -1
  1133. package/dist/modes/__tests__/base-multi-state-compat.test.js +0 -38
  1134. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +0 -1
  1135. package/dist/modes/__tests__/base-ralph-contract.test.d.ts +0 -2
  1136. package/dist/modes/__tests__/base-ralph-contract.test.d.ts.map +0 -1
  1137. package/dist/modes/__tests__/base-ralph-contract.test.js +0 -64
  1138. package/dist/modes/__tests__/base-ralph-contract.test.js.map +0 -1
  1139. package/dist/modes/__tests__/base-session-scope.test.d.ts +0 -2
  1140. package/dist/modes/__tests__/base-session-scope.test.d.ts.map +0 -1
  1141. package/dist/modes/__tests__/base-session-scope.test.js +0 -98
  1142. package/dist/modes/__tests__/base-session-scope.test.js.map +0 -1
  1143. package/dist/modes/__tests__/base-tmux-pane.test.d.ts +0 -2
  1144. package/dist/modes/__tests__/base-tmux-pane.test.d.ts.map +0 -1
  1145. package/dist/modes/__tests__/base-tmux-pane.test.js +0 -39
  1146. package/dist/modes/__tests__/base-tmux-pane.test.js.map +0 -1
  1147. package/dist/notifications/__tests__/config.test.d.ts +0 -2
  1148. package/dist/notifications/__tests__/config.test.d.ts.map +0 -1
  1149. package/dist/notifications/__tests__/config.test.js +0 -269
  1150. package/dist/notifications/__tests__/config.test.js.map +0 -1
  1151. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +0 -2
  1152. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +0 -1
  1153. package/dist/notifications/__tests__/custom-alias-enablement.test.js +0 -84
  1154. package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +0 -1
  1155. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +0 -5
  1156. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +0 -1
  1157. package/dist/notifications/__tests__/dispatch-cooldown.test.js +0 -100
  1158. package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +0 -1
  1159. package/dist/notifications/__tests__/dispatcher.test.d.ts +0 -2
  1160. package/dist/notifications/__tests__/dispatcher.test.d.ts.map +0 -1
  1161. package/dist/notifications/__tests__/dispatcher.test.js +0 -202
  1162. package/dist/notifications/__tests__/dispatcher.test.js.map +0 -1
  1163. package/dist/notifications/__tests__/formatter.test.d.ts +0 -2
  1164. package/dist/notifications/__tests__/formatter.test.d.ts.map +0 -1
  1165. package/dist/notifications/__tests__/formatter.test.js +0 -270
  1166. package/dist/notifications/__tests__/formatter.test.js.map +0 -1
  1167. package/dist/notifications/__tests__/hook-config.test.d.ts +0 -5
  1168. package/dist/notifications/__tests__/hook-config.test.d.ts.map +0 -1
  1169. package/dist/notifications/__tests__/hook-config.test.js +0 -139
  1170. package/dist/notifications/__tests__/hook-config.test.js.map +0 -1
  1171. package/dist/notifications/__tests__/idle-cooldown.test.d.ts +0 -5
  1172. package/dist/notifications/__tests__/idle-cooldown.test.d.ts.map +0 -1
  1173. package/dist/notifications/__tests__/idle-cooldown.test.js +0 -209
  1174. package/dist/notifications/__tests__/idle-cooldown.test.js.map +0 -1
  1175. package/dist/notifications/__tests__/index.test.d.ts +0 -2
  1176. package/dist/notifications/__tests__/index.test.d.ts.map +0 -1
  1177. package/dist/notifications/__tests__/index.test.js +0 -188
  1178. package/dist/notifications/__tests__/index.test.js.map +0 -1
  1179. package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts +0 -2
  1180. package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts.map +0 -1
  1181. package/dist/notifications/__tests__/lifecycle-dedupe.test.js +0 -86
  1182. package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +0 -1
  1183. package/dist/notifications/__tests__/notifier.test.d.ts +0 -2
  1184. package/dist/notifications/__tests__/notifier.test.d.ts.map +0 -1
  1185. package/dist/notifications/__tests__/notifier.test.js +0 -239
  1186. package/dist/notifications/__tests__/notifier.test.js.map +0 -1
  1187. package/dist/notifications/__tests__/profiles.test.d.ts +0 -2
  1188. package/dist/notifications/__tests__/profiles.test.d.ts.map +0 -1
  1189. package/dist/notifications/__tests__/profiles.test.js +0 -404
  1190. package/dist/notifications/__tests__/profiles.test.js.map +0 -1
  1191. package/dist/notifications/__tests__/reply-config.test.d.ts +0 -2
  1192. package/dist/notifications/__tests__/reply-config.test.d.ts.map +0 -1
  1193. package/dist/notifications/__tests__/reply-config.test.js +0 -79
  1194. package/dist/notifications/__tests__/reply-config.test.js.map +0 -1
  1195. package/dist/notifications/__tests__/reply-listener.test.d.ts +0 -2
  1196. package/dist/notifications/__tests__/reply-listener.test.d.ts.map +0 -1
  1197. package/dist/notifications/__tests__/reply-listener.test.js +0 -723
  1198. package/dist/notifications/__tests__/reply-listener.test.js.map +0 -1
  1199. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts +0 -2
  1200. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts.map +0 -1
  1201. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +0 -93
  1202. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +0 -1
  1203. package/dist/notifications/__tests__/session-registry.test.d.ts +0 -2
  1204. package/dist/notifications/__tests__/session-registry.test.d.ts.map +0 -1
  1205. package/dist/notifications/__tests__/session-registry.test.js +0 -234
  1206. package/dist/notifications/__tests__/session-registry.test.js.map +0 -1
  1207. package/dist/notifications/__tests__/session-status.test.d.ts +0 -2
  1208. package/dist/notifications/__tests__/session-status.test.d.ts.map +0 -1
  1209. package/dist/notifications/__tests__/session-status.test.js +0 -249
  1210. package/dist/notifications/__tests__/session-status.test.js.map +0 -1
  1211. package/dist/notifications/__tests__/temp-mode.test.d.ts +0 -2
  1212. package/dist/notifications/__tests__/temp-mode.test.d.ts.map +0 -1
  1213. package/dist/notifications/__tests__/temp-mode.test.js +0 -172
  1214. package/dist/notifications/__tests__/temp-mode.test.js.map +0 -1
  1215. package/dist/notifications/__tests__/template-engine.test.d.ts +0 -5
  1216. package/dist/notifications/__tests__/template-engine.test.d.ts.map +0 -1
  1217. package/dist/notifications/__tests__/template-engine.test.js +0 -158
  1218. package/dist/notifications/__tests__/template-engine.test.js.map +0 -1
  1219. package/dist/notifications/__tests__/tmux-detector.test.d.ts +0 -2
  1220. package/dist/notifications/__tests__/tmux-detector.test.d.ts.map +0 -1
  1221. package/dist/notifications/__tests__/tmux-detector.test.js +0 -208
  1222. package/dist/notifications/__tests__/tmux-detector.test.js.map +0 -1
  1223. package/dist/notifications/__tests__/tmux.test.d.ts +0 -2
  1224. package/dist/notifications/__tests__/tmux.test.d.ts.map +0 -1
  1225. package/dist/notifications/__tests__/tmux.test.js +0 -285
  1226. package/dist/notifications/__tests__/tmux.test.js.map +0 -1
  1227. package/dist/notifications/__tests__/verbosity.test.d.ts +0 -2
  1228. package/dist/notifications/__tests__/verbosity.test.d.ts.map +0 -1
  1229. package/dist/notifications/__tests__/verbosity.test.js +0 -237
  1230. package/dist/notifications/__tests__/verbosity.test.js.map +0 -1
  1231. package/dist/openclaw/__tests__/config.test.d.ts +0 -6
  1232. package/dist/openclaw/__tests__/config.test.d.ts.map +0 -1
  1233. package/dist/openclaw/__tests__/config.test.js +0 -344
  1234. package/dist/openclaw/__tests__/config.test.js.map +0 -1
  1235. package/dist/openclaw/__tests__/dispatcher.test.d.ts +0 -5
  1236. package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +0 -1
  1237. package/dist/openclaw/__tests__/dispatcher.test.js +0 -169
  1238. package/dist/openclaw/__tests__/dispatcher.test.js.map +0 -1
  1239. package/dist/openclaw/__tests__/index.test.d.ts +0 -6
  1240. package/dist/openclaw/__tests__/index.test.d.ts.map +0 -1
  1241. package/dist/openclaw/__tests__/index.test.js +0 -382
  1242. package/dist/openclaw/__tests__/index.test.js.map +0 -1
  1243. package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
  1244. package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
  1245. package/dist/pipeline/__tests__/orchestrator.test.js +0 -505
  1246. package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
  1247. package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
  1248. package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
  1249. package/dist/pipeline/__tests__/stages.test.js +0 -754
  1250. package/dist/pipeline/__tests__/stages.test.js.map +0 -1
  1251. package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
  1252. package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
  1253. package/dist/pipeline/stages/ralph-verify.js.map +0 -1
  1254. package/dist/pipeline/stages/ralplan.d.ts +0 -25
  1255. package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
  1256. package/dist/pipeline/stages/ralplan.js.map +0 -1
  1257. package/dist/planning/__tests__/artifacts.test.d.ts +0 -2
  1258. package/dist/planning/__tests__/artifacts.test.d.ts.map +0 -1
  1259. package/dist/planning/__tests__/artifacts.test.js +0 -544
  1260. package/dist/planning/__tests__/artifacts.test.js.map +0 -1
  1261. package/dist/question/__tests__/client.test.d.ts +0 -2
  1262. package/dist/question/__tests__/client.test.d.ts.map +0 -1
  1263. package/dist/question/__tests__/client.test.js +0 -90
  1264. package/dist/question/__tests__/client.test.js.map +0 -1
  1265. package/dist/question/__tests__/deep-interview.test.d.ts +0 -2
  1266. package/dist/question/__tests__/deep-interview.test.d.ts.map +0 -1
  1267. package/dist/question/__tests__/deep-interview.test.js +0 -209
  1268. package/dist/question/__tests__/deep-interview.test.js.map +0 -1
  1269. package/dist/question/__tests__/policy.test.d.ts +0 -2
  1270. package/dist/question/__tests__/policy.test.d.ts.map +0 -1
  1271. package/dist/question/__tests__/policy.test.js +0 -107
  1272. package/dist/question/__tests__/policy.test.js.map +0 -1
  1273. package/dist/question/__tests__/renderer.test.d.ts +0 -2
  1274. package/dist/question/__tests__/renderer.test.d.ts.map +0 -1
  1275. package/dist/question/__tests__/renderer.test.js +0 -707
  1276. package/dist/question/__tests__/renderer.test.js.map +0 -1
  1277. package/dist/question/__tests__/state.test.d.ts +0 -2
  1278. package/dist/question/__tests__/state.test.d.ts.map +0 -1
  1279. package/dist/question/__tests__/state.test.js +0 -102
  1280. package/dist/question/__tests__/state.test.js.map +0 -1
  1281. package/dist/question/__tests__/types.test.d.ts +0 -2
  1282. package/dist/question/__tests__/types.test.d.ts.map +0 -1
  1283. package/dist/question/__tests__/types.test.js +0 -65
  1284. package/dist/question/__tests__/types.test.js.map +0 -1
  1285. package/dist/question/__tests__/ui.test.d.ts +0 -2
  1286. package/dist/question/__tests__/ui.test.d.ts.map +0 -1
  1287. package/dist/question/__tests__/ui.test.js +0 -446
  1288. package/dist/question/__tests__/ui.test.js.map +0 -1
  1289. package/dist/ralph/__tests__/persistence.test.d.ts +0 -2
  1290. package/dist/ralph/__tests__/persistence.test.d.ts.map +0 -1
  1291. package/dist/ralph/__tests__/persistence.test.js +0 -116
  1292. package/dist/ralph/__tests__/persistence.test.js.map +0 -1
  1293. package/dist/ralph/contract.d.ts +0 -17
  1294. package/dist/ralph/persistence.js.map +0 -1
  1295. package/dist/ralplan/__tests__/runtime.test.d.ts +0 -2
  1296. package/dist/ralplan/__tests__/runtime.test.d.ts.map +0 -1
  1297. package/dist/ralplan/__tests__/runtime.test.js +0 -165
  1298. package/dist/ralplan/__tests__/runtime.test.js.map +0 -1
  1299. package/dist/ralplan/runtime.d.ts +0 -52
  1300. package/dist/ralplan/runtime.d.ts.map +0 -1
  1301. package/dist/ralplan/runtime.js.map +0 -1
  1302. package/dist/runtime/__tests__/bridge.test.d.ts +0 -2
  1303. package/dist/runtime/__tests__/bridge.test.d.ts.map +0 -1
  1304. package/dist/runtime/__tests__/bridge.test.js +0 -194
  1305. package/dist/runtime/__tests__/bridge.test.js.map +0 -1
  1306. package/dist/runtime/__tests__/run-loop.test.d.ts +0 -2
  1307. package/dist/runtime/__tests__/run-loop.test.d.ts.map +0 -1
  1308. package/dist/runtime/__tests__/run-loop.test.js +0 -35
  1309. package/dist/runtime/__tests__/run-loop.test.js.map +0 -1
  1310. package/dist/runtime/__tests__/run-outcome.test.d.ts +0 -2
  1311. package/dist/runtime/__tests__/run-outcome.test.d.ts.map +0 -1
  1312. package/dist/runtime/__tests__/run-outcome.test.js +0 -102
  1313. package/dist/runtime/__tests__/run-outcome.test.js.map +0 -1
  1314. package/dist/runtime/__tests__/run-state.test.d.ts +0 -2
  1315. package/dist/runtime/__tests__/run-state.test.d.ts.map +0 -1
  1316. package/dist/runtime/__tests__/run-state.test.js +0 -37
  1317. package/dist/runtime/__tests__/run-state.test.js.map +0 -1
  1318. package/dist/scripts/__tests__/codex-native-hook.test.d.ts +0 -2
  1319. package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +0 -1
  1320. package/dist/scripts/__tests__/codex-native-hook.test.js +0 -6788
  1321. package/dist/scripts/__tests__/codex-native-hook.test.js.map +0 -1
  1322. package/dist/scripts/__tests__/generate-release-body.test.d.ts +0 -2
  1323. package/dist/scripts/__tests__/generate-release-body.test.d.ts.map +0 -1
  1324. package/dist/scripts/__tests__/generate-release-body.test.js +0 -233
  1325. package/dist/scripts/__tests__/generate-release-body.test.js.map +0 -1
  1326. package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts +0 -2
  1327. package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts.map +0 -1
  1328. package/dist/scripts/__tests__/hook-derived-watcher.test.js +0 -195
  1329. package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +0 -1
  1330. package/dist/scripts/__tests__/postinstall.test.d.ts +0 -2
  1331. package/dist/scripts/__tests__/postinstall.test.d.ts.map +0 -1
  1332. package/dist/scripts/__tests__/postinstall.test.js +0 -92
  1333. package/dist/scripts/__tests__/postinstall.test.js.map +0 -1
  1334. package/dist/scripts/__tests__/prompt-inventory.test.d.ts +0 -2
  1335. package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +0 -1
  1336. package/dist/scripts/__tests__/prompt-inventory.test.js +0 -56
  1337. package/dist/scripts/__tests__/prompt-inventory.test.js.map +0 -1
  1338. package/dist/scripts/__tests__/run-test-files.test.d.ts +0 -2
  1339. package/dist/scripts/__tests__/run-test-files.test.d.ts.map +0 -1
  1340. package/dist/scripts/__tests__/run-test-files.test.js +0 -62
  1341. package/dist/scripts/__tests__/run-test-files.test.js.map +0 -1
  1342. package/dist/scripts/__tests__/smoke-packed-install.test.d.ts +0 -2
  1343. package/dist/scripts/__tests__/smoke-packed-install.test.d.ts.map +0 -1
  1344. package/dist/scripts/__tests__/smoke-packed-install.test.js +0 -135
  1345. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +0 -1
  1346. package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts +0 -2
  1347. package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts.map +0 -1
  1348. package/dist/scripts/__tests__/test-reply-listener-live.test.js +0 -82
  1349. package/dist/scripts/__tests__/test-reply-listener-live.test.js.map +0 -1
  1350. package/dist/scripts/__tests__/verify-native-agents.test.d.ts +0 -2
  1351. package/dist/scripts/__tests__/verify-native-agents.test.d.ts.map +0 -1
  1352. package/dist/scripts/__tests__/verify-native-agents.test.js +0 -166
  1353. package/dist/scripts/__tests__/verify-native-agents.test.js.map +0 -1
  1354. package/dist/scripts/eval/eval-candidate-handoff.d.ts +0 -2
  1355. package/dist/scripts/eval/eval-candidate-handoff.d.ts.map +0 -1
  1356. package/dist/scripts/eval/eval-candidate-handoff.js +0 -11
  1357. package/dist/scripts/eval/eval-candidate-handoff.js.map +0 -1
  1358. package/dist/scripts/eval/eval-cli-discoverability.d.ts +0 -3
  1359. package/dist/scripts/eval/eval-cli-discoverability.d.ts.map +0 -1
  1360. package/dist/scripts/eval/eval-cli-discoverability.js +0 -37
  1361. package/dist/scripts/eval/eval-cli-discoverability.js.map +0 -1
  1362. package/dist/scripts/eval/eval-fresh-run-tagging.d.ts +0 -2
  1363. package/dist/scripts/eval/eval-fresh-run-tagging.d.ts.map +0 -1
  1364. package/dist/scripts/eval/eval-fresh-run-tagging.js +0 -11
  1365. package/dist/scripts/eval/eval-fresh-run-tagging.js.map +0 -1
  1366. package/dist/scripts/eval/eval-help-consistency.d.ts +0 -2
  1367. package/dist/scripts/eval/eval-help-consistency.d.ts.map +0 -1
  1368. package/dist/scripts/eval/eval-help-consistency.js +0 -12
  1369. package/dist/scripts/eval/eval-help-consistency.js.map +0 -1
  1370. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts +0 -2
  1371. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts.map +0 -1
  1372. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js +0 -31
  1373. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js.map +0 -1
  1374. package/dist/scripts/eval/eval-parity-smoke.d.ts +0 -2
  1375. package/dist/scripts/eval/eval-parity-smoke.d.ts.map +0 -1
  1376. package/dist/scripts/eval/eval-parity-smoke.js +0 -23
  1377. package/dist/scripts/eval/eval-parity-smoke.js.map +0 -1
  1378. package/dist/scripts/eval/eval-parity-sweep.d.ts +0 -2
  1379. package/dist/scripts/eval/eval-parity-sweep.d.ts.map +0 -1
  1380. package/dist/scripts/eval/eval-parity-sweep.js +0 -29
  1381. package/dist/scripts/eval/eval-parity-sweep.js.map +0 -1
  1382. package/dist/scripts/eval/eval-resume-dirty-guard.d.ts +0 -2
  1383. package/dist/scripts/eval/eval-resume-dirty-guard.d.ts.map +0 -1
  1384. package/dist/scripts/eval/eval-resume-dirty-guard.js +0 -11
  1385. package/dist/scripts/eval/eval-resume-dirty-guard.js.map +0 -1
  1386. package/dist/scripts/eval/eval-security-path-traversal.d.ts +0 -3
  1387. package/dist/scripts/eval/eval-security-path-traversal.d.ts.map +0 -1
  1388. package/dist/scripts/eval/eval-security-path-traversal.js +0 -35
  1389. package/dist/scripts/eval/eval-security-path-traversal.js.map +0 -1
  1390. package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts +0 -2
  1391. package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts.map +0 -1
  1392. package/dist/scripts/notify-hook/__tests__/operational-events.test.js +0 -24
  1393. package/dist/scripts/notify-hook/__tests__/operational-events.test.js.map +0 -1
  1394. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +0 -2
  1395. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +0 -1
  1396. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +0 -153
  1397. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +0 -1
  1398. package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -22
  1399. package/dist/session-history/__tests__/search.test.d.ts +0 -2
  1400. package/dist/session-history/__tests__/search.test.d.ts.map +0 -1
  1401. package/dist/session-history/__tests__/search.test.js +0 -150
  1402. package/dist/session-history/__tests__/search.test.js.map +0 -1
  1403. package/dist/sidecar/__tests__/boundary.test.d.ts +0 -2
  1404. package/dist/sidecar/__tests__/boundary.test.d.ts.map +0 -1
  1405. package/dist/sidecar/__tests__/boundary.test.js +0 -48
  1406. package/dist/sidecar/__tests__/boundary.test.js.map +0 -1
  1407. package/dist/sidecar/__tests__/collector.test.d.ts +0 -2
  1408. package/dist/sidecar/__tests__/collector.test.d.ts.map +0 -1
  1409. package/dist/sidecar/__tests__/collector.test.js +0 -162
  1410. package/dist/sidecar/__tests__/collector.test.js.map +0 -1
  1411. package/dist/sidecar/__tests__/render.test.d.ts +0 -2
  1412. package/dist/sidecar/__tests__/render.test.d.ts.map +0 -1
  1413. package/dist/sidecar/__tests__/render.test.js +0 -67
  1414. package/dist/sidecar/__tests__/render.test.js.map +0 -1
  1415. package/dist/sidecar/__tests__/tmux.test.d.ts +0 -2
  1416. package/dist/sidecar/__tests__/tmux.test.d.ts.map +0 -1
  1417. package/dist/sidecar/__tests__/tmux.test.js +0 -30
  1418. package/dist/sidecar/__tests__/tmux.test.js.map +0 -1
  1419. package/dist/sidecar/__tests__/watch.test.d.ts +0 -2
  1420. package/dist/sidecar/__tests__/watch.test.d.ts.map +0 -1
  1421. package/dist/sidecar/__tests__/watch.test.js +0 -42
  1422. package/dist/sidecar/__tests__/watch.test.js.map +0 -1
  1423. package/dist/state/__tests__/mode-state-context.test.d.ts +0 -2
  1424. package/dist/state/__tests__/mode-state-context.test.d.ts.map +0 -1
  1425. package/dist/state/__tests__/mode-state-context.test.js +0 -35
  1426. package/dist/state/__tests__/mode-state-context.test.js.map +0 -1
  1427. package/dist/state/__tests__/operations-ralph-phase.test.d.ts +0 -2
  1428. package/dist/state/__tests__/operations-ralph-phase.test.d.ts.map +0 -1
  1429. package/dist/state/__tests__/operations-ralph-phase.test.js +0 -103
  1430. package/dist/state/__tests__/operations-ralph-phase.test.js.map +0 -1
  1431. package/dist/state/__tests__/operations.test.d.ts +0 -2
  1432. package/dist/state/__tests__/operations.test.d.ts.map +0 -1
  1433. package/dist/state/__tests__/operations.test.js +0 -439
  1434. package/dist/state/__tests__/operations.test.js.map +0 -1
  1435. package/dist/state/__tests__/path-traversal.test.d.ts +0 -2
  1436. package/dist/state/__tests__/path-traversal.test.d.ts.map +0 -1
  1437. package/dist/state/__tests__/path-traversal.test.js +0 -49
  1438. package/dist/state/__tests__/path-traversal.test.js.map +0 -1
  1439. package/dist/state/__tests__/skill-active.test.d.ts +0 -2
  1440. package/dist/state/__tests__/skill-active.test.d.ts.map +0 -1
  1441. package/dist/state/__tests__/skill-active.test.js +0 -160
  1442. package/dist/state/__tests__/skill-active.test.js.map +0 -1
  1443. package/dist/state/__tests__/workflow-transition.test.d.ts +0 -2
  1444. package/dist/state/__tests__/workflow-transition.test.d.ts.map +0 -1
  1445. package/dist/state/__tests__/workflow-transition.test.js +0 -77
  1446. package/dist/state/__tests__/workflow-transition.test.js.map +0 -1
  1447. package/dist/subagents/__tests__/tracker.test.d.ts +0 -2
  1448. package/dist/subagents/__tests__/tracker.test.d.ts.map +0 -1
  1449. package/dist/subagents/__tests__/tracker.test.js +0 -47
  1450. package/dist/subagents/__tests__/tracker.test.js.map +0 -1
  1451. package/dist/team/__tests__/allocation-policy.test.d.ts +0 -2
  1452. package/dist/team/__tests__/allocation-policy.test.d.ts.map +0 -1
  1453. package/dist/team/__tests__/allocation-policy.test.js +0 -111
  1454. package/dist/team/__tests__/allocation-policy.test.js.map +0 -1
  1455. package/dist/team/__tests__/api-interop.test.d.ts +0 -2
  1456. package/dist/team/__tests__/api-interop.test.d.ts.map +0 -1
  1457. package/dist/team/__tests__/api-interop.test.js +0 -2262
  1458. package/dist/team/__tests__/api-interop.test.js.map +0 -1
  1459. package/dist/team/__tests__/commit-hygiene.test.d.ts +0 -2
  1460. package/dist/team/__tests__/commit-hygiene.test.d.ts.map +0 -1
  1461. package/dist/team/__tests__/commit-hygiene.test.js +0 -93
  1462. package/dist/team/__tests__/commit-hygiene.test.js.map +0 -1
  1463. package/dist/team/__tests__/cross-rebase-smoke.test.d.ts +0 -2
  1464. package/dist/team/__tests__/cross-rebase-smoke.test.d.ts.map +0 -1
  1465. package/dist/team/__tests__/cross-rebase-smoke.test.js +0 -161
  1466. package/dist/team/__tests__/cross-rebase-smoke.test.js.map +0 -1
  1467. package/dist/team/__tests__/current-task-baseline.test.d.ts +0 -2
  1468. package/dist/team/__tests__/current-task-baseline.test.d.ts.map +0 -1
  1469. package/dist/team/__tests__/current-task-baseline.test.js +0 -87
  1470. package/dist/team/__tests__/current-task-baseline.test.js.map +0 -1
  1471. package/dist/team/__tests__/delegation-policy.test.d.ts +0 -2
  1472. package/dist/team/__tests__/delegation-policy.test.d.ts.map +0 -1
  1473. package/dist/team/__tests__/delegation-policy.test.js +0 -69
  1474. package/dist/team/__tests__/delegation-policy.test.js.map +0 -1
  1475. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +0 -2
  1476. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +0 -1
  1477. package/dist/team/__tests__/delivery-e2e-smoke.test.js +0 -679
  1478. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +0 -1
  1479. package/dist/team/__tests__/events.test.d.ts +0 -2
  1480. package/dist/team/__tests__/events.test.d.ts.map +0 -1
  1481. package/dist/team/__tests__/events.test.js +0 -313
  1482. package/dist/team/__tests__/events.test.js.map +0 -1
  1483. package/dist/team/__tests__/followup-planner.test.d.ts +0 -2
  1484. package/dist/team/__tests__/followup-planner.test.d.ts.map +0 -1
  1485. package/dist/team/__tests__/followup-planner.test.js +0 -84
  1486. package/dist/team/__tests__/followup-planner.test.js.map +0 -1
  1487. package/dist/team/__tests__/hardening-e2e.test.d.ts +0 -2
  1488. package/dist/team/__tests__/hardening-e2e.test.d.ts.map +0 -1
  1489. package/dist/team/__tests__/hardening-e2e.test.js +0 -98
  1490. package/dist/team/__tests__/hardening-e2e.test.js.map +0 -1
  1491. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +0 -2
  1492. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +0 -1
  1493. package/dist/team/__tests__/hook-primary-e2e-contract.test.js +0 -78
  1494. package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +0 -1
  1495. package/dist/team/__tests__/idle-nudge.test.d.ts +0 -2
  1496. package/dist/team/__tests__/idle-nudge.test.d.ts.map +0 -1
  1497. package/dist/team/__tests__/idle-nudge.test.js +0 -230
  1498. package/dist/team/__tests__/idle-nudge.test.js.map +0 -1
  1499. package/dist/team/__tests__/leader-activity.test.d.ts +0 -2
  1500. package/dist/team/__tests__/leader-activity.test.d.ts.map +0 -1
  1501. package/dist/team/__tests__/leader-activity.test.js +0 -261
  1502. package/dist/team/__tests__/leader-activity.test.js.map +0 -1
  1503. package/dist/team/__tests__/mcp-comm.test.d.ts +0 -2
  1504. package/dist/team/__tests__/mcp-comm.test.d.ts.map +0 -1
  1505. package/dist/team/__tests__/mcp-comm.test.js +0 -289
  1506. package/dist/team/__tests__/mcp-comm.test.js.map +0 -1
  1507. package/dist/team/__tests__/model-contract.test.d.ts +0 -2
  1508. package/dist/team/__tests__/model-contract.test.d.ts.map +0 -1
  1509. package/dist/team/__tests__/model-contract.test.js +0 -171
  1510. package/dist/team/__tests__/model-contract.test.js.map +0 -1
  1511. package/dist/team/__tests__/orchestrator.test.d.ts +0 -2
  1512. package/dist/team/__tests__/orchestrator.test.d.ts.map +0 -1
  1513. package/dist/team/__tests__/orchestrator.test.js +0 -111
  1514. package/dist/team/__tests__/orchestrator.test.js.map +0 -1
  1515. package/dist/team/__tests__/phase-controller.test.d.ts +0 -2
  1516. package/dist/team/__tests__/phase-controller.test.d.ts.map +0 -1
  1517. package/dist/team/__tests__/phase-controller.test.js +0 -50
  1518. package/dist/team/__tests__/phase-controller.test.js.map +0 -1
  1519. package/dist/team/__tests__/rebalance-policy.test.d.ts +0 -2
  1520. package/dist/team/__tests__/rebalance-policy.test.d.ts.map +0 -1
  1521. package/dist/team/__tests__/rebalance-policy.test.js +0 -168
  1522. package/dist/team/__tests__/rebalance-policy.test.js.map +0 -1
  1523. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +0 -2
  1524. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +0 -1
  1525. package/dist/team/__tests__/repo-aware-decomposition.test.js +0 -136
  1526. package/dist/team/__tests__/repo-aware-decomposition.test.js.map +0 -1
  1527. package/dist/team/__tests__/role-router.test.d.ts +0 -2
  1528. package/dist/team/__tests__/role-router.test.d.ts.map +0 -1
  1529. package/dist/team/__tests__/role-router.test.js +0 -263
  1530. package/dist/team/__tests__/role-router.test.js.map +0 -1
  1531. package/dist/team/__tests__/runtime-cli.test.d.ts +0 -2
  1532. package/dist/team/__tests__/runtime-cli.test.d.ts.map +0 -1
  1533. package/dist/team/__tests__/runtime-cli.test.js +0 -304
  1534. package/dist/team/__tests__/runtime-cli.test.js.map +0 -1
  1535. package/dist/team/__tests__/runtime.test.d.ts +0 -2
  1536. package/dist/team/__tests__/runtime.test.d.ts.map +0 -1
  1537. package/dist/team/__tests__/runtime.test.js +0 -5734
  1538. package/dist/team/__tests__/runtime.test.js.map +0 -1
  1539. package/dist/team/__tests__/scaling.test.d.ts +0 -2
  1540. package/dist/team/__tests__/scaling.test.d.ts.map +0 -1
  1541. package/dist/team/__tests__/scaling.test.js +0 -1005
  1542. package/dist/team/__tests__/scaling.test.js.map +0 -1
  1543. package/dist/team/__tests__/shutdown-fallback.test.d.ts +0 -2
  1544. package/dist/team/__tests__/shutdown-fallback.test.d.ts.map +0 -1
  1545. package/dist/team/__tests__/shutdown-fallback.test.js +0 -125
  1546. package/dist/team/__tests__/shutdown-fallback.test.js.map +0 -1
  1547. package/dist/team/__tests__/state-root.test.d.ts +0 -2
  1548. package/dist/team/__tests__/state-root.test.d.ts.map +0 -1
  1549. package/dist/team/__tests__/state-root.test.js +0 -195
  1550. package/dist/team/__tests__/state-root.test.js.map +0 -1
  1551. package/dist/team/__tests__/state.test.d.ts +0 -2
  1552. package/dist/team/__tests__/state.test.d.ts.map +0 -1
  1553. package/dist/team/__tests__/state.test.js +0 -1859
  1554. package/dist/team/__tests__/state.test.js.map +0 -1
  1555. package/dist/team/__tests__/team-identity.test.d.ts +0 -2
  1556. package/dist/team/__tests__/team-identity.test.d.ts.map +0 -1
  1557. package/dist/team/__tests__/team-identity.test.js +0 -166
  1558. package/dist/team/__tests__/team-identity.test.js.map +0 -1
  1559. package/dist/team/__tests__/team-ops-contract.test.d.ts +0 -2
  1560. package/dist/team/__tests__/team-ops-contract.test.d.ts.map +0 -1
  1561. package/dist/team/__tests__/team-ops-contract.test.js +0 -96
  1562. package/dist/team/__tests__/team-ops-contract.test.js.map +0 -1
  1563. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +0 -2
  1564. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +0 -1
  1565. package/dist/team/__tests__/tmux-claude-workers-demo.test.js +0 -191
  1566. package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +0 -1
  1567. package/dist/team/__tests__/tmux-session.test.d.ts +0 -2
  1568. package/dist/team/__tests__/tmux-session.test.d.ts.map +0 -1
  1569. package/dist/team/__tests__/tmux-session.test.js +0 -3785
  1570. package/dist/team/__tests__/tmux-session.test.js.map +0 -1
  1571. package/dist/team/__tests__/tmux-test-fixture.d.ts +0 -20
  1572. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +0 -1
  1573. package/dist/team/__tests__/tmux-test-fixture.js +0 -152
  1574. package/dist/team/__tests__/tmux-test-fixture.js.map +0 -1
  1575. package/dist/team/__tests__/tmux-test-fixture.test.d.ts +0 -2
  1576. package/dist/team/__tests__/tmux-test-fixture.test.d.ts.map +0 -1
  1577. package/dist/team/__tests__/tmux-test-fixture.test.js +0 -113
  1578. package/dist/team/__tests__/tmux-test-fixture.test.js.map +0 -1
  1579. package/dist/team/__tests__/worker-bootstrap.test.d.ts +0 -2
  1580. package/dist/team/__tests__/worker-bootstrap.test.d.ts.map +0 -1
  1581. package/dist/team/__tests__/worker-bootstrap.test.js +0 -685
  1582. package/dist/team/__tests__/worker-bootstrap.test.js.map +0 -1
  1583. package/dist/team/__tests__/worker-runtime-identity.test.d.ts +0 -2
  1584. package/dist/team/__tests__/worker-runtime-identity.test.d.ts.map +0 -1
  1585. package/dist/team/__tests__/worker-runtime-identity.test.js +0 -250
  1586. package/dist/team/__tests__/worker-runtime-identity.test.js.map +0 -1
  1587. package/dist/team/__tests__/worktree.test.d.ts +0 -2
  1588. package/dist/team/__tests__/worktree.test.d.ts.map +0 -1
  1589. package/dist/team/__tests__/worktree.test.js +0 -317
  1590. package/dist/team/__tests__/worktree.test.js.map +0 -1
  1591. package/dist/utils/__tests__/agents-md.test.d.ts +0 -2
  1592. package/dist/utils/__tests__/agents-md.test.d.ts.map +0 -1
  1593. package/dist/utils/__tests__/agents-md.test.js +0 -52
  1594. package/dist/utils/__tests__/agents-md.test.js.map +0 -1
  1595. package/dist/utils/__tests__/agents-model-table.test.d.ts +0 -2
  1596. package/dist/utils/__tests__/agents-model-table.test.d.ts.map +0 -1
  1597. package/dist/utils/__tests__/agents-model-table.test.js +0 -104
  1598. package/dist/utils/__tests__/agents-model-table.test.js.map +0 -1
  1599. package/dist/utils/__tests__/dep-versions.test.d.ts +0 -2
  1600. package/dist/utils/__tests__/dep-versions.test.d.ts.map +0 -1
  1601. package/dist/utils/__tests__/dep-versions.test.js +0 -46
  1602. package/dist/utils/__tests__/dep-versions.test.js.map +0 -1
  1603. package/dist/utils/__tests__/package.test.d.ts +0 -2
  1604. package/dist/utils/__tests__/package.test.d.ts.map +0 -1
  1605. package/dist/utils/__tests__/package.test.js +0 -21
  1606. package/dist/utils/__tests__/package.test.js.map +0 -1
  1607. package/dist/utils/__tests__/paths.test.d.ts +0 -2
  1608. package/dist/utils/__tests__/paths.test.d.ts.map +0 -1
  1609. package/dist/utils/__tests__/paths.test.js +0 -541
  1610. package/dist/utils/__tests__/paths.test.js.map +0 -1
  1611. package/dist/utils/__tests__/platform-command.test.d.ts +0 -2
  1612. package/dist/utils/__tests__/platform-command.test.d.ts.map +0 -1
  1613. package/dist/utils/__tests__/platform-command.test.js +0 -410
  1614. package/dist/utils/__tests__/platform-command.test.js.map +0 -1
  1615. package/dist/utils/__tests__/repo-deps.test.d.ts +0 -2
  1616. package/dist/utils/__tests__/repo-deps.test.d.ts.map +0 -1
  1617. package/dist/utils/__tests__/repo-deps.test.js +0 -71
  1618. package/dist/utils/__tests__/repo-deps.test.js.map +0 -1
  1619. package/dist/verification/__tests__/ci-rust-gates.test.d.ts +0 -2
  1620. package/dist/verification/__tests__/ci-rust-gates.test.d.ts.map +0 -1
  1621. package/dist/verification/__tests__/ci-rust-gates.test.js +0 -89
  1622. package/dist/verification/__tests__/ci-rust-gates.test.js.map +0 -1
  1623. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts +0 -2
  1624. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts.map +0 -1
  1625. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +0 -54
  1626. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +0 -1
  1627. package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts +0 -2
  1628. package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts.map +0 -1
  1629. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +0 -73
  1630. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +0 -1
  1631. package/dist/verification/__tests__/native-release-manifest.test.d.ts +0 -2
  1632. package/dist/verification/__tests__/native-release-manifest.test.d.ts.map +0 -1
  1633. package/dist/verification/__tests__/native-release-manifest.test.js +0 -80
  1634. package/dist/verification/__tests__/native-release-manifest.test.js.map +0 -1
  1635. package/dist/verification/__tests__/pr-check-workflow.test.d.ts +0 -2
  1636. package/dist/verification/__tests__/pr-check-workflow.test.d.ts.map +0 -1
  1637. package/dist/verification/__tests__/pr-check-workflow.test.js +0 -27
  1638. package/dist/verification/__tests__/pr-check-workflow.test.js.map +0 -1
  1639. package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts +0 -2
  1640. package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts.map +0 -1
  1641. package/dist/verification/__tests__/ralph-persistence-gate.test.js +0 -55
  1642. package/dist/verification/__tests__/ralph-persistence-gate.test.js.map +0 -1
  1643. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts +0 -2
  1644. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts.map +0 -1
  1645. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js +0 -32
  1646. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js.map +0 -1
  1647. package/dist/verification/__tests__/verifier.test.d.ts +0 -2
  1648. package/dist/verification/__tests__/verifier.test.d.ts.map +0 -1
  1649. package/dist/verification/__tests__/verifier.test.js +0 -113
  1650. package/dist/verification/__tests__/verifier.test.js.map +0 -1
  1651. package/dist/visual/__tests__/verdict.test.d.ts +0 -2
  1652. package/dist/visual/__tests__/verdict.test.d.ts.map +0 -1
  1653. package/dist/visual/__tests__/verdict.test.js +0 -81
  1654. package/dist/visual/__tests__/verdict.test.js.map +0 -1
  1655. package/dist/wiki/__tests__/cjk-tokenize.test.d.ts +0 -12
  1656. package/dist/wiki/__tests__/cjk-tokenize.test.d.ts.map +0 -1
  1657. package/dist/wiki/__tests__/cjk-tokenize.test.js +0 -139
  1658. package/dist/wiki/__tests__/cjk-tokenize.test.js.map +0 -1
  1659. package/dist/wiki/__tests__/crlf-parse.test.d.ts +0 -2
  1660. package/dist/wiki/__tests__/crlf-parse.test.d.ts.map +0 -1
  1661. package/dist/wiki/__tests__/crlf-parse.test.js +0 -24
  1662. package/dist/wiki/__tests__/crlf-parse.test.js.map +0 -1
  1663. package/dist/wiki/__tests__/escape-newline.test.d.ts +0 -2
  1664. package/dist/wiki/__tests__/escape-newline.test.d.ts.map +0 -1
  1665. package/dist/wiki/__tests__/escape-newline.test.js +0 -45
  1666. package/dist/wiki/__tests__/escape-newline.test.js.map +0 -1
  1667. package/dist/wiki/__tests__/ingest.test.d.ts +0 -5
  1668. package/dist/wiki/__tests__/ingest.test.d.ts.map +0 -1
  1669. package/dist/wiki/__tests__/ingest.test.js +0 -181
  1670. package/dist/wiki/__tests__/ingest.test.js.map +0 -1
  1671. package/dist/wiki/__tests__/lint.test.d.ts +0 -5
  1672. package/dist/wiki/__tests__/lint.test.d.ts.map +0 -1
  1673. package/dist/wiki/__tests__/lint.test.js +0 -163
  1674. package/dist/wiki/__tests__/lint.test.js.map +0 -1
  1675. package/dist/wiki/__tests__/query.test.d.ts +0 -5
  1676. package/dist/wiki/__tests__/query.test.d.ts.map +0 -1
  1677. package/dist/wiki/__tests__/query.test.js +0 -141
  1678. package/dist/wiki/__tests__/query.test.js.map +0 -1
  1679. package/dist/wiki/__tests__/reserved-file-guard.test.d.ts +0 -2
  1680. package/dist/wiki/__tests__/reserved-file-guard.test.d.ts.map +0 -1
  1681. package/dist/wiki/__tests__/reserved-file-guard.test.js +0 -44
  1682. package/dist/wiki/__tests__/reserved-file-guard.test.js.map +0 -1
  1683. package/dist/wiki/__tests__/session-hooks.test.d.ts +0 -5
  1684. package/dist/wiki/__tests__/session-hooks.test.d.ts.map +0 -1
  1685. package/dist/wiki/__tests__/session-hooks.test.js +0 -36
  1686. package/dist/wiki/__tests__/session-hooks.test.js.map +0 -1
  1687. package/dist/wiki/__tests__/slug-nonascii.test.d.ts +0 -2
  1688. package/dist/wiki/__tests__/slug-nonascii.test.d.ts.map +0 -1
  1689. package/dist/wiki/__tests__/slug-nonascii.test.js +0 -30
  1690. package/dist/wiki/__tests__/slug-nonascii.test.js.map +0 -1
  1691. package/dist/wiki/__tests__/storage.test.d.ts +0 -5
  1692. package/dist/wiki/__tests__/storage.test.d.ts.map +0 -1
  1693. package/dist/wiki/__tests__/storage.test.js +0 -278
  1694. package/dist/wiki/__tests__/storage.test.js.map +0 -1
  1695. package/dist/wiki/__tests__/test-helpers.d.ts +0 -31
  1696. package/dist/wiki/__tests__/test-helpers.d.ts.map +0 -1
  1697. package/dist/wiki/__tests__/test-helpers.js +0 -108
  1698. package/dist/wiki/__tests__/test-helpers.js.map +0 -1
  1699. package/docs/contracts/ralph-cancel-contract.md +0 -23
  1700. package/docs/contracts/ralph-state-contract.md +0 -95
  1701. package/docs/issues/team-ralph-followup-team.md +0 -38
  1702. package/docs/qa/ralph-persistence-gate.md +0 -59
  1703. package/docs/reference/ralph-parity-matrix.md +0 -25
  1704. package/docs/reference/ralph-upstream-baseline.md +0 -34
  1705. package/plugins/roblox-ai-os-creator-skills/skills/ralph/SKILL.md +0 -269
  1706. package/plugins/roblox-ai-os-creator-skills/skills/ralplan/SKILL.md +0 -162
  1707. package/prompts/api-reviewer.md +0 -113
  1708. package/prompts/information-architect.md +0 -226
  1709. package/prompts/performance-reviewer.md +0 -109
  1710. package/prompts/product-analyst.md +0 -304
  1711. package/prompts/product-manager.md +0 -245
  1712. package/prompts/qa-tester.md +0 -124
  1713. package/prompts/quality-reviewer.md +0 -123
  1714. package/prompts/quality-strategist.md +0 -274
  1715. package/prompts/style-reviewer.md +0 -102
  1716. package/prompts/ux-researcher.md +0 -327
  1717. package/skills/frontend-ui-ux/SKILL.md +0 -34
  1718. package/skills/ralph/SKILL.md +0 -269
  1719. package/skills/ralplan/SKILL.md +0 -162
  1720. package/src/scripts/eval/eval-adaptive-sort-optimization.py +0 -24
  1721. package/src/scripts/eval/eval-candidate-handoff.ts +0 -8
  1722. package/src/scripts/eval/eval-cli-discoverability.ts +0 -40
  1723. package/src/scripts/eval/eval-fresh-run-tagging.ts +0 -8
  1724. package/src/scripts/eval/eval-help-consistency.ts +0 -11
  1725. package/src/scripts/eval/eval-in-action-cat-shellout-demo.ts +0 -31
  1726. package/src/scripts/eval/eval-ml-kaggle-model-optimization.py +0 -29
  1727. package/src/scripts/eval/eval-noisy-bayesopt-highdim.py +0 -44
  1728. package/src/scripts/eval/eval-noisy-latent-subspace-discovery.py +0 -44
  1729. package/src/scripts/eval/eval-parity-smoke.ts +0 -20
  1730. package/src/scripts/eval/eval-parity-sweep.ts +0 -26
  1731. package/src/scripts/eval/eval-resume-dirty-guard.ts +0 -8
  1732. package/src/scripts/eval/eval-security-path-traversal.ts +0 -38
  1733. package/src/scripts/run-autoresearch-showcase.sh +0 -75
  1734. /package/docs/{migration-mainline-post-v0.4.4.md → archive/migration-mainline-post-v0.4.4.md} +0 -0
  1735. /package/docs/{qa-plan-0.4.2.md → archive/qa-plan-0.4.2.md} +0 -0
  1736. /package/docs/{qa-report-0.4.2.md → archive/qa-report-0.4.2.md} +0 -0
@@ -1,2397 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { spawnSync } from 'node:child_process';
4
- import { chmod, mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
5
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
- import { tmpdir } from 'node:os';
7
- import { join } from 'node:path';
8
- import { buildTmuxSessionName } from '../../cli/index.js';
9
- const NOTIFY_HOOK_SCRIPT = new URL('../../../dist/scripts/notify-hook.js', import.meta.url);
10
- const DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS = ['yes', 'y', 'proceed', 'continue', 'ok', 'sure', 'go ahead', 'next i should'];
11
- const NEXT_I_SHOULD_RESPONSE = 'Next I should update the focused tests.';
12
- const DEFAULT_AUTO_NUDGE_RESPONSE = 'continue with the current task only if it is already authorized';
13
- async function withTempWorkingDir(run) {
14
- const cwd = await mkdtemp(join(tmpdir(), 'rcs-auto-nudge-'));
15
- try {
16
- await run(cwd);
17
- }
18
- finally {
19
- await rm(cwd, { recursive: true, force: true });
20
- }
21
- }
22
- async function writeJson(path, value) {
23
- await writeFile(path, JSON.stringify(value, null, 2));
24
- }
25
- function readLinuxStartTicks(pid) {
26
- try {
27
- const stat = readFileSync(`/proc/${pid}/stat`, 'utf-8');
28
- const commandEnd = stat.lastIndexOf(')');
29
- if (commandEnd === -1)
30
- return null;
31
- const remainder = stat.slice(commandEnd + 1).trim();
32
- const fields = remainder.split(/\s+/);
33
- if (fields.length <= 19)
34
- return null;
35
- const startTicks = Number(fields[19]);
36
- return Number.isFinite(startTicks) ? startTicks : null;
37
- }
38
- catch {
39
- return null;
40
- }
41
- }
42
- function readLinuxCmdline(pid) {
43
- try {
44
- const raw = readFileSync(`/proc/${pid}/cmdline`);
45
- const text = raw.toString('utf-8').replace(/\0+/g, ' ').trim();
46
- return text.length > 0 ? text : null;
47
- }
48
- catch {
49
- return null;
50
- }
51
- }
52
- async function writeManagedSessionState(stateDir, cwd) {
53
- await writeJson(join(stateDir, 'session.json'), {
54
- session_id: 'sess-managed',
55
- started_at: new Date().toISOString(),
56
- cwd,
57
- pid: process.pid,
58
- platform: process.platform,
59
- pid_start_ticks: readLinuxStartTicks(process.pid),
60
- pid_cmdline: readLinuxCmdline(process.pid),
61
- });
62
- }
63
- async function writeWorkerIdentityFixture(stateRoot, cwd, teamName, workerName) {
64
- const workerDir = join(stateRoot, 'team', teamName, 'workers', workerName);
65
- await mkdir(workerDir, { recursive: true });
66
- await writeJson(join(workerDir, 'identity.json'), {
67
- name: workerName,
68
- index: Number(workerName.replace(/^worker-/, '')) || 1,
69
- role: 'executor',
70
- assigned_tasks: [],
71
- worktree_path: cwd,
72
- team_state_root: stateRoot,
73
- });
74
- }
75
- function escapeRegex(value) {
76
- return value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
77
- }
78
- function defaultAutoNudgePattern(targetPane) {
79
- return new RegExp(`send-keys -t ${escapeRegex(targetPane)} -l ${escapeRegex(DEFAULT_AUTO_NUDGE_RESPONSE)} \\[RCS_TMUX_INJECT\\]`);
80
- }
81
- /**
82
- * Build a fake tmux binary that logs all invocations and optionally returns
83
- * capture-pane content from RCS_TEST_CAPTURE_FILE.
84
- */
85
- function buildFakeTmux(tmuxLogPath, paneInMode = '0') {
86
- return `#!/usr/bin/env bash
87
- set -eu
88
- echo "$@" >> "${tmuxLogPath}"
89
- cmd="\$1"
90
- shift || true
91
- if [[ "\$cmd" == "capture-pane" ]]; then
92
- if [[ -n "\${RCS_TEST_CAPTURE_FILE:-}" && -f "\${RCS_TEST_CAPTURE_FILE}" ]]; then
93
- cat "\${RCS_TEST_CAPTURE_FILE}"
94
- fi
95
- exit 0
96
- fi
97
- if [[ "\$cmd" == "send-keys" ]]; then
98
- exit 0
99
- fi
100
- if [[ "\$cmd" == "display-message" ]]; then
101
- target=""
102
- format=""
103
- while [[ "\$#" -gt 0 ]]; do
104
- case "\$1" in
105
- -p) shift ;;
106
- -t) target="\$2"; shift 2 ;;
107
- *) format="\$1"; shift ;;
108
- esac
109
- done
110
- if [[ "\$format" == "#{pane_in_mode}" ]]; then
111
- echo "${paneInMode}"
112
- exit 0
113
- fi
114
- if [[ "\$format" == "#{pane_current_command}" && "\$target" == "%99" ]]; then
115
- echo "node"
116
- exit 0
117
- fi
118
- if [[ "\$format" == "#{pane_start_command}" && "\$target" == "%99" ]]; then
119
- echo "codex --model gpt-5"
120
- exit 0
121
- fi
122
- if [[ "\$format" == "#S" ]]; then
123
- echo "${'${RCS_TEST_TMUX_SESSION_NAME:-devsess}'}"
124
- exit 0
125
- fi
126
- exit 0
127
- fi
128
- if [[ "\$cmd" == "list-panes" ]]; then
129
- target=""
130
- while [[ "\$#" -gt 0 ]]; do
131
- case "\$1" in
132
- -t) target="\$2"; shift 2 ;;
133
- *) shift ;;
134
- esac
135
- done
136
- if [[ -n "\$target" && "\$target" == "${'${RCS_TEST_TMUX_SESSION_NAME:-devsess}'}" ]]; then
137
- printf '%%99\t1\tnode\tcodex --model gpt-5\n'
138
- exit 0
139
- fi
140
- echo "%1 12345"
141
- exit 0
142
- fi
143
- exit 0
144
- `;
145
- }
146
- function runNotifyHook(cwd, fakeBinDir, codexHome, payloadOverrides = {}, extraEnv = {}) {
147
- if (extraEnv.RCS_TEST_UNMANAGED_SESSION !== '1' && !extraEnv.RCS_TEAM_WORKER) {
148
- const sessionPath = join(cwd, '.rcs', 'state', 'session.json');
149
- const sessionState = {
150
- session_id: 'sess-managed',
151
- started_at: new Date().toISOString(),
152
- cwd,
153
- pid: process.pid,
154
- platform: process.platform,
155
- pid_start_ticks: readLinuxStartTicks(process.pid),
156
- pid_cmdline: readLinuxCmdline(process.pid),
157
- };
158
- writeFileSync(sessionPath, JSON.stringify(sessionState, null, 2));
159
- }
160
- const payload = {
161
- cwd,
162
- type: 'agent-turn-complete',
163
- 'thread-id': 'thread-test',
164
- 'turn-id': `turn-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`,
165
- ...(extraEnv.RCS_TEST_UNMANAGED_SESSION !== '1' && !extraEnv.RCS_TEAM_WORKER ? { 'session-id': 'sess-managed' } : {}),
166
- 'input-messages': ['test'],
167
- 'last-assistant-message': 'done',
168
- ...payloadOverrides,
169
- };
170
- return spawnSync(process.execPath, [NOTIFY_HOOK_SCRIPT.pathname, JSON.stringify(payload)], {
171
- encoding: 'utf8',
172
- timeout: 15_000,
173
- env: {
174
- ...process.env,
175
- PATH: `${fakeBinDir}:${process.env.PATH || ''}`,
176
- CODEX_HOME: codexHome,
177
- ...(extraEnv.RCS_TEST_UNMANAGED_SESSION !== '1' && !extraEnv.RCS_TEAM_WORKER ? { RCS_SESSION_ID: 'sess-managed' } : {}),
178
- ...(extraEnv.RCS_TEST_UNMANAGED_SESSION !== '1' && !extraEnv.RCS_TEAM_WORKER ? { RCS_TEST_TMUX_SESSION_NAME: buildTmuxSessionName(cwd, 'sess-managed') } : {}),
179
- TMUX_PANE: '%99',
180
- TMUX: '1',
181
- RCS_TEAM_WORKER: '',
182
- RCS_TEAM_LEADER_NUDGE_MS: '9999999',
183
- RCS_TEAM_LEADER_STALE_MS: '9999999',
184
- ...extraEnv,
185
- },
186
- });
187
- }
188
- describe('notify-hook auto-nudge', () => {
189
- it('does not nudge immediately by default before a real stall window elapses', async () => {
190
- await withTempWorkingDir(async (cwd) => {
191
- const rcsDir = join(cwd, '.rcs');
192
- const stateDir = join(rcsDir, 'state');
193
- const logsDir = join(rcsDir, 'logs');
194
- const codexHome = join(cwd, 'codex-home');
195
- const fakeBinDir = join(cwd, 'fake-bin');
196
- const tmuxLogPath = join(cwd, 'tmux.log');
197
- await mkdir(logsDir, { recursive: true });
198
- await mkdir(stateDir, { recursive: true });
199
- await mkdir(codexHome, { recursive: true });
200
- await mkdir(fakeBinDir, { recursive: true });
201
- await writeJson(join(codexHome, '.rcs-config.json'), {
202
- autoNudge: { enabled: true, delaySec: 0 },
203
- });
204
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
205
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
206
- await writeManagedSessionState(stateDir, cwd);
207
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
208
- await mkdir(sessionStateDir, { recursive: true });
209
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
210
- 'last-assistant-message': 'I analyzed the code. Keep going and finish the focused cleanup.',
211
- });
212
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
213
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
214
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
215
- const nudgeState = JSON.parse(await readFile(join(sessionStateDir, 'auto-nudge-state.json'), 'utf-8'));
216
- assert.equal(nudgeState.nudgeCount, 0);
217
- assert.ok(nudgeState.pendingSignature);
218
- assert.ok(nudgeState.pendingSince);
219
- });
220
- });
221
- it('sends nudge when stall pattern detected in last-assistant-message', async () => {
222
- await withTempWorkingDir(async (cwd) => {
223
- const rcsDir = join(cwd, '.rcs');
224
- const stateDir = join(rcsDir, 'state');
225
- const logsDir = join(rcsDir, 'logs');
226
- const codexHome = join(cwd, 'codex-home');
227
- const fakeBinDir = join(cwd, 'fake-bin');
228
- const tmuxLogPath = join(cwd, 'tmux.log');
229
- await mkdir(logsDir, { recursive: true });
230
- await mkdir(stateDir, { recursive: true });
231
- await mkdir(codexHome, { recursive: true });
232
- await mkdir(fakeBinDir, { recursive: true });
233
- // Config: enabled, delaySec=0 for fast tests
234
- await writeJson(join(codexHome, '.rcs-config.json'), {
235
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
236
- });
237
- await writeManagedSessionState(stateDir, cwd);
238
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
239
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
240
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
241
- 'last-assistant-message': 'I analyzed the code. Keep going and finish the focused cleanup.',
242
- });
243
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
244
- assert.ok(existsSync(tmuxLogPath), 'tmux should have been called');
245
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
246
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'should send nudge response with injection marker');
247
- // Codex CLI needs C-m sent twice with a delay for reliable submission
248
- const cmMatches = tmuxLog.match(/send-keys -t %99 C-m/g);
249
- assert.ok(cmMatches && cmMatches.length >= 2, `should send C-m twice, got ${cmMatches?.length ?? 0}`);
250
- });
251
- });
252
- it('does not auto-nudge planning-phase skill state into execution', async () => {
253
- await withTempWorkingDir(async (cwd) => {
254
- const rcsDir = join(cwd, '.rcs');
255
- const stateDir = join(rcsDir, 'state');
256
- const logsDir = join(rcsDir, 'logs');
257
- const codexHome = join(cwd, 'codex-home');
258
- const fakeBinDir = join(cwd, 'fake-bin');
259
- const tmuxLogPath = join(cwd, 'tmux.log');
260
- await mkdir(logsDir, { recursive: true });
261
- await mkdir(stateDir, { recursive: true });
262
- await mkdir(codexHome, { recursive: true });
263
- await mkdir(fakeBinDir, { recursive: true });
264
- await writeJson(join(codexHome, '.rcs-config.json'), {
265
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
266
- });
267
- await writeManagedSessionState(stateDir, cwd);
268
- await writeJson(join(stateDir, 'skill-active-state.json'), {
269
- active: true,
270
- skill: 'analyze',
271
- keyword: 'investigate',
272
- phase: 'planning',
273
- source: 'keyword-detector',
274
- });
275
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
276
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
277
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
278
- 'last-assistant-message': 'I can continue with the plan from here.',
279
- });
280
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
281
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
282
- assert.doesNotMatch(tmuxLog, /send-keys -t %99 -l/, 'planning-phase prompts should not be auto-nudged');
283
- const skillState = JSON.parse(await readFile(join(stateDir, 'skill-active-state.json'), 'utf-8'));
284
- assert.equal(skillState.phase, 'planning');
285
- });
286
- });
287
- it('respects `.rcs/tmux-hook.json` enabled:false and skips auto-nudge injection', async () => {
288
- await withTempWorkingDir(async (cwd) => {
289
- const rcsDir = join(cwd, '.rcs');
290
- const stateDir = join(rcsDir, 'state');
291
- const logsDir = join(rcsDir, 'logs');
292
- const codexHome = join(cwd, 'codex-home');
293
- const fakeBinDir = join(cwd, 'fake-bin');
294
- const tmuxLogPath = join(cwd, 'tmux.log');
295
- await mkdir(logsDir, { recursive: true });
296
- await mkdir(stateDir, { recursive: true });
297
- await mkdir(codexHome, { recursive: true });
298
- await mkdir(fakeBinDir, { recursive: true });
299
- await writeJson(join(codexHome, '.rcs-config.json'), {
300
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
301
- });
302
- await writeJson(join(rcsDir, 'tmux-hook.json'), {
303
- enabled: false,
304
- target: { type: 'pane', value: '%99' },
305
- });
306
- await writeManagedSessionState(stateDir, cwd);
307
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
308
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
309
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
310
- 'last-assistant-message': 'I analyzed the code. If you want me to make these changes, let me know.',
311
- });
312
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
313
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
314
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
315
- });
316
- });
317
- it('does not auto-nudge plain tmux Codex sessions that only inherit RCS session env', async () => {
318
- await withTempWorkingDir(async (cwd) => {
319
- const rcsDir = join(cwd, '.rcs');
320
- const stateDir = join(rcsDir, 'state');
321
- const logsDir = join(rcsDir, 'logs');
322
- const codexHome = join(cwd, 'codex-home');
323
- const fakeBinDir = join(cwd, 'fake-bin');
324
- const tmuxLogPath = join(cwd, 'tmux.log');
325
- await mkdir(logsDir, { recursive: true });
326
- await mkdir(stateDir, { recursive: true });
327
- await mkdir(codexHome, { recursive: true });
328
- await mkdir(fakeBinDir, { recursive: true });
329
- await writeJson(join(codexHome, '.rcs-config.json'), {
330
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
331
- });
332
- const sleeper = spawnSync('bash', ['-lc', 'sleep 5 >/dev/null 2>&1 & echo $!'], { encoding: 'utf8' });
333
- assert.equal(sleeper.status, 0, sleeper.stderr || sleeper.stdout);
334
- const sleeperPid = Number((sleeper.stdout || '').trim());
335
- assert.ok(Number.isFinite(sleeperPid) && sleeperPid > 1, 'expected helper pid');
336
- await writeJson(join(stateDir, 'session.json'), {
337
- session_id: 'sess-managed',
338
- started_at: new Date().toISOString(),
339
- cwd,
340
- pid: sleeperPid,
341
- platform: process.platform,
342
- pid_start_ticks: readLinuxStartTicks(sleeperPid),
343
- pid_cmdline: readLinuxCmdline(sleeperPid),
344
- });
345
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
346
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
347
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
348
- 'session-id': 'sess-managed',
349
- 'last-assistant-message': 'I analyzed the code. If you want me to make these changes, let me know.',
350
- }, {
351
- RCS_SESSION_ID: 'sess-managed',
352
- RCS_TEST_UNMANAGED_SESSION: '1',
353
- });
354
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
355
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
356
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
357
- });
358
- });
359
- it('does not auto-nudge plain tmux Codex sessions that are not RCS-managed', async () => {
360
- await withTempWorkingDir(async (cwd) => {
361
- const rcsDir = join(cwd, '.rcs');
362
- const stateDir = join(rcsDir, 'state');
363
- const logsDir = join(rcsDir, 'logs');
364
- const codexHome = join(cwd, 'codex-home');
365
- const fakeBinDir = join(cwd, 'fake-bin');
366
- const tmuxLogPath = join(cwd, 'tmux.log');
367
- await mkdir(logsDir, { recursive: true });
368
- await mkdir(stateDir, { recursive: true });
369
- await mkdir(codexHome, { recursive: true });
370
- await mkdir(fakeBinDir, { recursive: true });
371
- await writeJson(join(codexHome, '.rcs-config.json'), {
372
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
373
- });
374
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
375
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
376
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
377
- 'last-assistant-message': 'I analyzed the code. If you want me to make these changes, let me know.',
378
- }, {
379
- RCS_TEST_UNMANAGED_SESSION: '1',
380
- });
381
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
382
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
383
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
384
- });
385
- });
386
- it('does not auto-nudge when payload session-id disagrees with the managed tmux session identity', async () => {
387
- await withTempWorkingDir(async (cwd) => {
388
- const rcsDir = join(cwd, '.rcs');
389
- const stateDir = join(rcsDir, 'state');
390
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
391
- const logsDir = join(rcsDir, 'logs');
392
- const codexHome = join(cwd, 'codex-home');
393
- const fakeBinDir = join(cwd, 'fake-bin');
394
- const tmuxLogPath = join(cwd, 'tmux.log');
395
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
396
- await mkdir(logsDir, { recursive: true });
397
- await mkdir(stateDir, { recursive: true });
398
- await mkdir(sessionStateDir, { recursive: true });
399
- await mkdir(codexHome, { recursive: true });
400
- await mkdir(fakeBinDir, { recursive: true });
401
- await writeJson(join(codexHome, '.rcs-config.json'), {
402
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
403
- });
404
- await writeManagedSessionState(stateDir, cwd);
405
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
406
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
407
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
408
- 'session-id': 'sess-other',
409
- 'last-assistant-message': 'I analyzed the code. If you want me to make these changes, let me know.',
410
- }, {
411
- RCS_SESSION_ID: 'sess-managed',
412
- RCS_TEST_TMUX_SESSION_NAME: managedSessionName,
413
- });
414
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
415
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
416
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
417
- });
418
- });
419
- it('does not auto-nudge when tmux session naming drifts from the current RCS session id', async () => {
420
- await withTempWorkingDir(async (cwd) => {
421
- const rcsDir = join(cwd, '.rcs');
422
- const stateDir = join(rcsDir, 'state');
423
- const logsDir = join(rcsDir, 'logs');
424
- const codexHome = join(cwd, 'codex-home');
425
- const fakeBinDir = join(cwd, 'fake-bin');
426
- const tmuxLogPath = join(cwd, 'tmux.log');
427
- const expectedManagedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
428
- const mismatchedDetachedSessionName = buildTmuxSessionName(cwd, 'sess-legacy-detached');
429
- await mkdir(logsDir, { recursive: true });
430
- await mkdir(stateDir, { recursive: true });
431
- await mkdir(codexHome, { recursive: true });
432
- await mkdir(fakeBinDir, { recursive: true });
433
- await writeJson(join(codexHome, '.rcs-config.json'), {
434
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
435
- });
436
- await writeManagedSessionState(stateDir, cwd);
437
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
438
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
439
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
440
- 'session-id': 'sess-managed',
441
- 'last-assistant-message': 'I analyzed the code. If you want me to make these changes, let me know.',
442
- }, {
443
- RCS_SESSION_ID: 'sess-managed',
444
- RCS_TEST_TMUX_SESSION_NAME: mismatchedDetachedSessionName,
445
- });
446
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
447
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
448
- assert.match(tmuxLog, new RegExp(`list-panes -s -t ${escapeRegex(expectedManagedSessionName)}`), 'should resolve panes against the current RCS session identity, not the drifted tmux session name');
449
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
450
- });
451
- });
452
- it('sends nudge via capture-pane fallback when payload has no stall pattern', async () => {
453
- await withTempWorkingDir(async (cwd) => {
454
- const rcsDir = join(cwd, '.rcs');
455
- const stateDir = join(rcsDir, 'state');
456
- const logsDir = join(rcsDir, 'logs');
457
- const codexHome = join(cwd, 'codex-home');
458
- const fakeBinDir = join(cwd, 'fake-bin');
459
- const tmuxLogPath = join(cwd, 'tmux.log');
460
- const captureFile = join(cwd, 'capture-output.txt');
461
- await mkdir(logsDir, { recursive: true });
462
- await mkdir(stateDir, { recursive: true });
463
- await mkdir(codexHome, { recursive: true });
464
- await mkdir(fakeBinDir, { recursive: true });
465
- await writeJson(join(codexHome, '.rcs-config.json'), {
466
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
467
- });
468
- await writeManagedSessionState(stateDir, cwd);
469
- // capture-pane will return content with a stall pattern
470
- await writeFile(captureFile, 'Here are the results.\nKeep going and finish the implementation.\n› ');
471
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
472
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
473
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
474
- 'last-assistant-message': 'clean output with no stall',
475
- }, {
476
- RCS_TEST_CAPTURE_FILE: captureFile,
477
- });
478
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
479
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
480
- assert.match(tmuxLog, /capture-pane/, 'should have tried capture-pane');
481
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'should send nudge via capture-pane fallback with marker');
482
- });
483
- });
484
- it('does not nudge from PASS/FAIL-style test output captured from the pane', async () => {
485
- await withTempWorkingDir(async (cwd) => {
486
- const rcsDir = join(cwd, '.rcs');
487
- const stateDir = join(rcsDir, 'state');
488
- const logsDir = join(rcsDir, 'logs');
489
- const codexHome = join(cwd, 'codex-home');
490
- const fakeBinDir = join(cwd, 'fake-bin');
491
- const tmuxLogPath = join(cwd, 'tmux.log');
492
- const captureFile = join(cwd, 'capture-output.txt');
493
- await mkdir(logsDir, { recursive: true });
494
- await mkdir(stateDir, { recursive: true });
495
- await mkdir(codexHome, { recursive: true });
496
- await mkdir(fakeBinDir, { recursive: true });
497
- await writeJson(join(codexHome, '.rcs-config.json'), {
498
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
499
- });
500
- await writeManagedSessionState(stateDir, cwd);
501
- await writeFile(captureFile, [
502
- 'PASS should continue with the next step when approvals are present',
503
- 'FAIL aborts the branch cleanly when the worker exits early',
504
- 'Test Suites: 1 failed, 1 total',
505
- ].join('\n'));
506
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
507
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
508
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
509
- 'last-assistant-message': 'clean output with no stall',
510
- }, {
511
- RCS_TEST_CAPTURE_FILE: captureFile,
512
- });
513
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
514
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
515
- assert.match(tmuxLog, /capture-pane/, 'should still inspect capture-pane output');
516
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'PASS/FAIL-style test output must not trigger a nudge');
517
- });
518
- });
519
- it('auto-nudges from active mode state by upgrading an anchored shell pane to the sibling codex pane', async () => {
520
- await withTempWorkingDir(async (cwd) => {
521
- const rcsDir = join(cwd, '.rcs');
522
- const stateDir = join(rcsDir, 'state');
523
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
524
- const logsDir = join(rcsDir, 'logs');
525
- const codexHome = join(cwd, 'codex-home');
526
- const fakeBinDir = join(cwd, 'fake-bin');
527
- const tmuxLogPath = join(cwd, 'tmux.log');
528
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
529
- await mkdir(logsDir, { recursive: true });
530
- await mkdir(stateDir, { recursive: true });
531
- await mkdir(sessionStateDir, { recursive: true });
532
- await mkdir(codexHome, { recursive: true });
533
- await mkdir(fakeBinDir, { recursive: true });
534
- await writeJson(join(codexHome, '.rcs-config.json'), {
535
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
536
- });
537
- await writeManagedSessionState(stateDir, cwd);
538
- await writeJson(join(sessionStateDir, 'ralph-state.json'), {
539
- active: true,
540
- tmux_pane_id: '%99',
541
- });
542
- const fakeTmux = `#!/usr/bin/env bash
543
- set -eu
544
- echo "$@" >> "${tmuxLogPath}"
545
- cmd="$1"
546
- shift || true
547
- if [[ "$cmd" == "display-message" ]]; then
548
- target=""
549
- format=""
550
- while [[ "$#" -gt 0 ]]; do
551
- case "$1" in
552
- -p) shift ;;
553
- -t) target="$2"; shift 2 ;;
554
- *) format="$1"; shift ;;
555
- esac
556
- done
557
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
558
- echo "sh"
559
- exit 0
560
- fi
561
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%100" ]]; then
562
- echo "node"
563
- exit 0
564
- fi
565
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%100" ]]; then
566
- echo "codex --model gpt-5"
567
- exit 0
568
- fi
569
- if [[ "$format" == "#{pane_in_mode}" && "$target" == "%100" ]]; then
570
- echo "0"
571
- exit 0
572
- fi
573
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
574
- echo "${managedSessionName}"
575
- exit 0
576
- fi
577
- exit 0
578
- fi
579
- if [[ "$cmd" == "list-panes" ]]; then
580
- target=""
581
- while [[ "$#" -gt 0 ]]; do
582
- case "$1" in
583
- -t) target="$2"; shift 2 ;;
584
- *) shift ;;
585
- esac
586
- done
587
- if [[ "$target" == "${managedSessionName}" ]]; then
588
- printf "%%99\t0\tsh\tbash\n%%100\t1\tnode\tcodex --model gpt-5\n"
589
- exit 0
590
- fi
591
- echo "%1 12345"
592
- exit 0
593
- fi
594
- if [[ "$cmd" == "capture-pane" ]]; then
595
- printf "How can I help?\n› "
596
- exit 0
597
- fi
598
- if [[ "$cmd" == "send-keys" ]]; then
599
- exit 0
600
- fi
601
- exit 0
602
- `;
603
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
604
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
605
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
606
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
607
- }, {
608
- TMUX_PANE: '',
609
- });
610
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
611
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
612
- assert.match(tmuxLog, defaultAutoNudgePattern('%100'), 'should upgrade anchored shell pane to sibling codex pane');
613
- });
614
- });
615
- it('keeps a verified codex anchor from active mode state even when a sibling codex pane is focused', async () => {
616
- await withTempWorkingDir(async (cwd) => {
617
- const rcsDir = join(cwd, '.rcs');
618
- const stateDir = join(rcsDir, 'state');
619
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
620
- const logsDir = join(rcsDir, 'logs');
621
- const codexHome = join(cwd, 'codex-home');
622
- const fakeBinDir = join(cwd, 'fake-bin');
623
- const tmuxLogPath = join(cwd, 'tmux.log');
624
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
625
- await mkdir(logsDir, { recursive: true });
626
- await mkdir(stateDir, { recursive: true });
627
- await mkdir(sessionStateDir, { recursive: true });
628
- await mkdir(codexHome, { recursive: true });
629
- await mkdir(fakeBinDir, { recursive: true });
630
- await writeJson(join(codexHome, '.rcs-config.json'), {
631
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
632
- });
633
- await writeManagedSessionState(stateDir, cwd);
634
- await writeJson(join(sessionStateDir, 'ralph-state.json'), {
635
- active: true,
636
- tmux_pane_id: '%99',
637
- });
638
- const fakeTmux = `#!/usr/bin/env bash
639
- set -eu
640
- echo "$@" >> "${tmuxLogPath}"
641
- cmd="$1"
642
- shift || true
643
- if [[ "$cmd" == "display-message" ]]; then
644
- target=""
645
- format=""
646
- while [[ "$#" -gt 0 ]]; do
647
- case "$1" in
648
- -p) shift ;;
649
- -t) target="$2"; shift 2 ;;
650
- *) format="$1"; shift ;;
651
- esac
652
- done
653
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
654
- echo "codex"
655
- exit 0
656
- fi
657
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%99" ]]; then
658
- echo "codex"
659
- exit 0
660
- fi
661
- if [[ "$format" == "#{pane_in_mode}" && "$target" == "%99" ]]; then
662
- echo "0"
663
- exit 0
664
- fi
665
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
666
- echo "${managedSessionName}"
667
- exit 0
668
- fi
669
- exit 0
670
- fi
671
- if [[ "$cmd" == "list-panes" ]]; then
672
- target=""
673
- while [[ "$#" -gt 0 ]]; do
674
- case "$1" in
675
- -t) target="$2"; shift 2 ;;
676
- *) shift ;;
677
- esac
678
- done
679
- if [[ "$target" == "${managedSessionName}" ]]; then
680
- printf "%%99\t0\tcodex\tcodex\\n%%100\t1\tcodex\tcodex\\n"
681
- exit 0
682
- fi
683
- echo "%1 12345"
684
- exit 0
685
- fi
686
- if [[ "$cmd" == "capture-pane" ]]; then
687
- printf "How can I help?\\n› "
688
- exit 0
689
- fi
690
- if [[ "$cmd" == "send-keys" ]]; then
691
- exit 0
692
- fi
693
- exit 0
694
- `;
695
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
696
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
697
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
698
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
699
- }, {
700
- TMUX_PANE: '',
701
- });
702
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
703
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
704
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'should keep the verified codex anchor');
705
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%100'), 'should not jump to the focused sibling codex pane');
706
- });
707
- });
708
- it('upgrades a node shell anchor from active mode state to the sibling codex pane', async () => {
709
- await withTempWorkingDir(async (cwd) => {
710
- const rcsDir = join(cwd, '.rcs');
711
- const stateDir = join(rcsDir, 'state');
712
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
713
- const logsDir = join(rcsDir, 'logs');
714
- const codexHome = join(cwd, 'codex-home');
715
- const fakeBinDir = join(cwd, 'fake-bin');
716
- const tmuxLogPath = join(cwd, 'tmux.log');
717
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
718
- await mkdir(logsDir, { recursive: true });
719
- await mkdir(stateDir, { recursive: true });
720
- await mkdir(sessionStateDir, { recursive: true });
721
- await mkdir(codexHome, { recursive: true });
722
- await mkdir(fakeBinDir, { recursive: true });
723
- await writeJson(join(codexHome, '.rcs-config.json'), {
724
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
725
- });
726
- await writeManagedSessionState(stateDir, cwd);
727
- await writeJson(join(sessionStateDir, 'ralph-state.json'), {
728
- active: true,
729
- tmux_pane_id: '%99',
730
- });
731
- const fakeTmux = `#!/usr/bin/env bash
732
- set -eu
733
- echo "$@" >> "${tmuxLogPath}"
734
- cmd="$1"
735
- shift || true
736
- if [[ "$cmd" == "display-message" ]]; then
737
- target=""
738
- format=""
739
- while [[ "$#" -gt 0 ]]; do
740
- case "$1" in
741
- -p) shift ;;
742
- -t) target="$2"; shift 2 ;;
743
- *) format="$1"; shift ;;
744
- esac
745
- done
746
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
747
- echo "node"
748
- exit 0
749
- fi
750
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%99" ]]; then
751
- echo "bash"
752
- exit 0
753
- fi
754
- if [[ "$format" == "#{pane_in_mode}" && "$target" == "%100" ]]; then
755
- echo "0"
756
- exit 0
757
- fi
758
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
759
- echo "${managedSessionName}"
760
- exit 0
761
- fi
762
- exit 0
763
- fi
764
- if [[ "$cmd" == "list-panes" ]]; then
765
- target=""
766
- while [[ "$#" -gt 0 ]]; do
767
- case "$1" in
768
- -t) target="$2"; shift 2 ;;
769
- *) shift ;;
770
- esac
771
- done
772
- if [[ "$target" == "${managedSessionName}" ]]; then
773
- printf "%%99\t0\tnode\tbash\\n%%100\t1\tnode\tcodex --model gpt-5\\n"
774
- exit 0
775
- fi
776
- echo "%1 12345"
777
- exit 0
778
- fi
779
- if [[ "$cmd" == "capture-pane" ]]; then
780
- printf "How can I help?\\n› "
781
- exit 0
782
- fi
783
- if [[ "$cmd" == "send-keys" ]]; then
784
- exit 0
785
- fi
786
- exit 0
787
- `;
788
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
789
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
790
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
791
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
792
- }, {
793
- TMUX_PANE: '',
794
- });
795
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
796
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
797
- assert.match(tmuxLog, defaultAutoNudgePattern('%100'), 'should upgrade the node shell anchor to the sibling codex pane');
798
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'node shell anchor should not be retained');
799
- });
800
- });
801
- it('upgrades a shell-degraded codex anchor from active mode state to the sibling codex pane', async () => {
802
- await withTempWorkingDir(async (cwd) => {
803
- const rcsDir = join(cwd, '.rcs');
804
- const stateDir = join(rcsDir, 'state');
805
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
806
- const logsDir = join(rcsDir, 'logs');
807
- const codexHome = join(cwd, 'codex-home');
808
- const fakeBinDir = join(cwd, 'fake-bin');
809
- const tmuxLogPath = join(cwd, 'tmux.log');
810
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
811
- await mkdir(logsDir, { recursive: true });
812
- await mkdir(stateDir, { recursive: true });
813
- await mkdir(sessionStateDir, { recursive: true });
814
- await mkdir(codexHome, { recursive: true });
815
- await mkdir(fakeBinDir, { recursive: true });
816
- await writeJson(join(codexHome, '.rcs-config.json'), {
817
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
818
- });
819
- await writeManagedSessionState(stateDir, cwd);
820
- await writeJson(join(sessionStateDir, 'ralph-state.json'), {
821
- active: true,
822
- tmux_pane_id: '%99',
823
- });
824
- const fakeTmux = `#!/usr/bin/env bash
825
- set -eu
826
- echo "$@" >> "${tmuxLogPath}"
827
- cmd="$1"
828
- shift || true
829
- if [[ "$cmd" == "display-message" ]]; then
830
- target=""
831
- format=""
832
- while [[ "$#" -gt 0 ]]; do
833
- case "$1" in
834
- -p) shift ;;
835
- -t) target="$2"; shift 2 ;;
836
- *) format="$1"; shift ;;
837
- esac
838
- done
839
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
840
- echo "bash"
841
- exit 0
842
- fi
843
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%99" ]]; then
844
- echo "codex --model gpt-5"
845
- exit 0
846
- fi
847
- if [[ "$format" == "#{pane_in_mode}" && "$target" == "%100" ]]; then
848
- echo "0"
849
- exit 0
850
- fi
851
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
852
- echo "${managedSessionName}"
853
- exit 0
854
- fi
855
- exit 0
856
- fi
857
- if [[ "$cmd" == "list-panes" ]]; then
858
- target=""
859
- while [[ "$#" -gt 0 ]]; do
860
- case "$1" in
861
- -t) target="$2"; shift 2 ;;
862
- *) shift ;;
863
- esac
864
- done
865
- if [[ "$target" == "${managedSessionName}" ]]; then
866
- printf "%%99\t1\tbash\tcodex --model gpt-5\\n%%100\t0\tnode\tcodex --model gpt-5\\n"
867
- exit 0
868
- fi
869
- echo "%1 12345"
870
- exit 0
871
- fi
872
- if [[ "$cmd" == "capture-pane" ]]; then
873
- printf "How can I help?\\n› "
874
- exit 0
875
- fi
876
- if [[ "$cmd" == "send-keys" ]]; then
877
- exit 0
878
- fi
879
- exit 0
880
- `;
881
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
882
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
883
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
884
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
885
- }, {
886
- TMUX_PANE: '',
887
- });
888
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
889
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
890
- assert.match(tmuxLog, defaultAutoNudgePattern('%100'), 'should upgrade the shell-degraded codex anchor to the sibling codex pane');
891
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'shell-degraded codex anchor should not be retained');
892
- });
893
- });
894
- it('fails closed when a shell-degraded codex anchor has no live sibling pane', async () => {
895
- await withTempWorkingDir(async (cwd) => {
896
- const rcsDir = join(cwd, '.rcs');
897
- const stateDir = join(rcsDir, 'state');
898
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
899
- const logsDir = join(rcsDir, 'logs');
900
- const codexHome = join(cwd, 'codex-home');
901
- const fakeBinDir = join(cwd, 'fake-bin');
902
- const tmuxLogPath = join(cwd, 'tmux.log');
903
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
904
- await mkdir(logsDir, { recursive: true });
905
- await mkdir(stateDir, { recursive: true });
906
- await mkdir(sessionStateDir, { recursive: true });
907
- await mkdir(codexHome, { recursive: true });
908
- await mkdir(fakeBinDir, { recursive: true });
909
- await writeJson(join(codexHome, '.rcs-config.json'), {
910
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
911
- });
912
- await writeManagedSessionState(stateDir, cwd);
913
- await writeJson(join(sessionStateDir, 'ralph-state.json'), {
914
- active: true,
915
- tmux_pane_id: '%99',
916
- });
917
- const fakeTmux = `#!/usr/bin/env bash
918
- set -eu
919
- echo "$@" >> "${tmuxLogPath}"
920
- cmd="$1"
921
- shift || true
922
- if [[ "$cmd" == "display-message" ]]; then
923
- target=""
924
- format=""
925
- while [[ "$#" -gt 0 ]]; do
926
- case "$1" in
927
- -p) shift ;;
928
- -t) target="$2"; shift 2 ;;
929
- *) format="$1"; shift ;;
930
- esac
931
- done
932
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
933
- echo "bash"
934
- exit 0
935
- fi
936
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%99" ]]; then
937
- echo "codex --model gpt-5"
938
- exit 0
939
- fi
940
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
941
- echo "${managedSessionName}"
942
- exit 0
943
- fi
944
- exit 0
945
- fi
946
- if [[ "$cmd" == "list-panes" ]]; then
947
- target=""
948
- while [[ "$#" -gt 0 ]]; do
949
- case "$1" in
950
- -t) target="$2"; shift 2 ;;
951
- *) shift ;;
952
- esac
953
- done
954
- if [[ "$target" == "${managedSessionName}" ]]; then
955
- printf "%%99\t1\tbash\tcodex --model gpt-5\\n%%100\t0\tbash\tbash\\n"
956
- exit 0
957
- fi
958
- echo "%1 12345"
959
- exit 0
960
- fi
961
- if [[ "$cmd" == "capture-pane" ]]; then
962
- printf "How can I help?\\n› "
963
- exit 0
964
- fi
965
- if [[ "$cmd" == "send-keys" ]]; then
966
- exit 0
967
- fi
968
- exit 0
969
- `;
970
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
971
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
972
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
973
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
974
- }, {
975
- TMUX_PANE: '',
976
- });
977
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
978
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
979
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'shell-degraded codex anchor should not be retained without a live sibling');
980
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%100'), 'no live sibling should keep auto-nudge from sending input');
981
- });
982
- });
983
- it('still auto-nudges in team-worker context using the worker state root', async () => {
984
- await withTempWorkingDir(async (cwd) => {
985
- const workerStateRoot = join(cwd, 'leader-state-root');
986
- const logsDir = join(cwd, '.rcs', 'logs');
987
- const codexHome = join(cwd, 'codex-home');
988
- const fakeBinDir = join(cwd, 'fake-bin');
989
- const tmuxLogPath = join(cwd, 'tmux.log');
990
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
991
- await mkdir(logsDir, { recursive: true });
992
- await mkdir(workerStateRoot, { recursive: true });
993
- await mkdir(codexHome, { recursive: true });
994
- await mkdir(fakeBinDir, { recursive: true });
995
- await writeWorkerIdentityFixture(workerStateRoot, cwd, 'auto-nudge', 'worker-1');
996
- await writeJson(join(codexHome, '.rcs-config.json'), {
997
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
998
- });
999
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1000
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1001
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1002
- 'last-assistant-message': 'I can continue with the worker follow-up from here.',
1003
- }, {
1004
- RCS_TEAM_WORKER: 'auto-nudge/worker-1',
1005
- RCS_TEAM_STATE_ROOT: workerStateRoot,
1006
- });
1007
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1008
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1009
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'team-worker context should still send auto-nudge');
1010
- const nudgeStatePath = join(workerStateRoot, 'auto-nudge-state.json');
1011
- assert.ok(existsSync(nudgeStatePath), 'worker state root should receive auto-nudge state');
1012
- });
1013
- });
1014
- it('fails closed in team-worker context when the worker state root lacks a valid identity', async () => {
1015
- await withTempWorkingDir(async (cwd) => {
1016
- const localStateRoot = join(cwd, '.rcs', 'state');
1017
- const codexHome = join(cwd, 'codex-home');
1018
- const fakeBinDir = join(cwd, 'fake-bin');
1019
- const tmuxLogPath = join(cwd, 'tmux.log');
1020
- await mkdir(localStateRoot, { recursive: true });
1021
- await mkdir(codexHome, { recursive: true });
1022
- await mkdir(fakeBinDir, { recursive: true });
1023
- await writeJson(join(codexHome, '.rcs-config.json'), {
1024
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1025
- });
1026
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1027
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1028
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1029
- 'last-assistant-message': 'I can continue with the worker follow-up from here.',
1030
- }, {
1031
- RCS_TEAM_WORKER: 'auto-nudge/worker-1',
1032
- RCS_TEAM_STATE_ROOT: '',
1033
- });
1034
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1035
- assert.equal(existsSync(join(localStateRoot, 'auto-nudge-state.json')), false, 'unvalidated worker cwd state root must not receive auto-nudge state');
1036
- assert.equal(existsSync(join(localStateRoot, 'team', 'auto-nudge', 'workers', 'worker-1', 'heartbeat.json')), false, 'unvalidated worker cwd state root must not receive heartbeat state');
1037
- if (existsSync(tmuxLogPath)) {
1038
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1039
- assert.doesNotMatch(tmuxLog, /send-keys/, 'unvalidated worker state root must not inject auto-nudge input');
1040
- }
1041
- });
1042
- });
1043
- it('still auto-nudges from the stored worker pane when TMUX_PANE is missing and the worker pane looks shell-degraded', async () => {
1044
- await withTempWorkingDir(async (cwd) => {
1045
- const workerStateRoot = join(cwd, 'leader-state-root');
1046
- const logsDir = join(cwd, '.rcs', 'logs');
1047
- const codexHome = join(cwd, 'codex-home');
1048
- const fakeBinDir = join(cwd, 'fake-bin');
1049
- const tmuxLogPath = join(cwd, 'tmux.log');
1050
- await mkdir(logsDir, { recursive: true });
1051
- await mkdir(workerStateRoot, { recursive: true });
1052
- await mkdir(codexHome, { recursive: true });
1053
- await mkdir(fakeBinDir, { recursive: true });
1054
- await writeWorkerIdentityFixture(workerStateRoot, cwd, 'auto-nudge', 'worker-1');
1055
- await writeJson(join(codexHome, '.rcs-config.json'), {
1056
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1057
- });
1058
- await writeJson(join(workerStateRoot, 'ralph-state.json'), {
1059
- active: true,
1060
- tmux_pane_id: '%99',
1061
- });
1062
- const fakeTmux = `#!/usr/bin/env bash
1063
- set -eu
1064
- echo "$@" >> "${tmuxLogPath}"
1065
- cmd="$1"
1066
- shift || true
1067
- if [[ "$cmd" == "display-message" ]]; then
1068
- target=""
1069
- format=""
1070
- while [[ "$#" -gt 0 ]]; do
1071
- case "$1" in
1072
- -p) shift ;;
1073
- -t) target="$2"; shift 2 ;;
1074
- *) format="$1"; shift ;;
1075
- esac
1076
- done
1077
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
1078
- echo "bash"
1079
- exit 0
1080
- fi
1081
- if [[ "$format" == "#{pane_start_command}" && "$target" == "%99" ]]; then
1082
- echo "codex --model gpt-5"
1083
- exit 0
1084
- fi
1085
- if [[ "$format" == "#{pane_in_mode}" && "$target" == "%99" ]]; then
1086
- echo "0"
1087
- exit 0
1088
- fi
1089
- exit 0
1090
- fi
1091
- if [[ "$cmd" == "capture-pane" ]]; then
1092
- printf "How can I help?\\n› "
1093
- exit 0
1094
- fi
1095
- if [[ "$cmd" == "send-keys" ]]; then
1096
- exit 0
1097
- fi
1098
- if [[ "$cmd" == "list-panes" ]]; then
1099
- echo "%1 12345"
1100
- exit 0
1101
- fi
1102
- exit 0
1103
- `;
1104
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
1105
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1106
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1107
- 'last-assistant-message': 'I can continue with the worker follow-up from here.',
1108
- }, {
1109
- RCS_TEAM_WORKER: 'auto-nudge/worker-1',
1110
- RCS_TEAM_STATE_ROOT: workerStateRoot,
1111
- TMUX_PANE: '',
1112
- });
1113
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1114
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1115
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'worker fallback should keep using the stored pane when TMUX_PANE is absent');
1116
- });
1117
- });
1118
- it('does not nudge when no stall pattern is present', async () => {
1119
- await withTempWorkingDir(async (cwd) => {
1120
- const rcsDir = join(cwd, '.rcs');
1121
- const stateDir = join(rcsDir, 'state');
1122
- const logsDir = join(rcsDir, 'logs');
1123
- const codexHome = join(cwd, 'codex-home');
1124
- const fakeBinDir = join(cwd, 'fake-bin');
1125
- const tmuxLogPath = join(cwd, 'tmux.log');
1126
- await mkdir(logsDir, { recursive: true });
1127
- await mkdir(stateDir, { recursive: true });
1128
- await mkdir(codexHome, { recursive: true });
1129
- await mkdir(fakeBinDir, { recursive: true });
1130
- await writeJson(join(codexHome, '.rcs-config.json'), {
1131
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1132
- });
1133
- await writeManagedSessionState(stateDir, cwd);
1134
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1135
- await mkdir(sessionStateDir, { recursive: true });
1136
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1137
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1138
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1139
- 'last-assistant-message': 'I completed the refactoring. All tests pass.',
1140
- });
1141
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1142
- if (existsSync(tmuxLogPath)) {
1143
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1144
- assert.doesNotMatch(tmuxLog, new RegExp(`send-keys -t %99 -l ${escapeRegex(DEFAULT_AUTO_NUDGE_RESPONSE)}`), 'should NOT send nudge');
1145
- }
1146
- });
1147
- });
1148
- it('logs agent_not_running with pane_current_command when the target pane is a shell', async () => {
1149
- await withTempWorkingDir(async (cwd) => {
1150
- const rcsDir = join(cwd, '.rcs');
1151
- const stateDir = join(rcsDir, 'state');
1152
- const logsDir = join(rcsDir, 'logs');
1153
- const codexHome = join(cwd, 'codex-home');
1154
- const fakeBinDir = join(cwd, 'fake-bin');
1155
- const tmuxLogPath = join(cwd, 'tmux.log');
1156
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
1157
- await mkdir(logsDir, { recursive: true });
1158
- await mkdir(stateDir, { recursive: true });
1159
- await mkdir(codexHome, { recursive: true });
1160
- await mkdir(fakeBinDir, { recursive: true });
1161
- await writeJson(join(codexHome, '.rcs-config.json'), {
1162
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1163
- });
1164
- const fakeTmux = `#!/usr/bin/env bash
1165
- set -eu
1166
- echo "$@" >> "${tmuxLogPath}"
1167
- cmd="$1"
1168
- shift || true
1169
- if [[ "$cmd" == "display-message" ]]; then
1170
- target=""
1171
- format=""
1172
- while (($#)); do
1173
- case "$1" in
1174
- -p) shift ;;
1175
- -t) target="$2"; shift 2 ;;
1176
- *) format="$1"; shift ;;
1177
- esac
1178
- done
1179
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
1180
- echo "zsh"
1181
- exit 0
1182
- fi
1183
- exit 0
1184
- fi
1185
- if [[ "$cmd" == "capture-pane" ]]; then
1186
- printf "Would you like me to continue?\\n"
1187
- exit 0
1188
- fi
1189
- if [[ "$cmd" == "send-keys" ]]; then
1190
- exit 0
1191
- fi
1192
- if [[ "$cmd" == "list-panes" ]]; then
1193
- echo "%1 12345"
1194
- exit 0
1195
- fi
1196
- exit 0
1197
- `;
1198
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
1199
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1200
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1201
- 'last-assistant-message': 'Would you like me to continue?',
1202
- });
1203
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1204
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1205
- assert.ok(tmuxLog.includes('display-message -p -t %99 #S'), 'should inspect the managed anchor pane before deciding');
1206
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'shell pane should not receive auto-nudge injection');
1207
- });
1208
- });
1209
- it('falls back to the sibling codex pane when TMUX_PANE is a managed non-agent shell pane', async () => {
1210
- await withTempWorkingDir(async (cwd) => {
1211
- const rcsDir = join(cwd, '.rcs');
1212
- const stateDir = join(rcsDir, 'state');
1213
- const logsDir = join(rcsDir, 'logs');
1214
- const codexHome = join(cwd, 'codex-home');
1215
- const fakeBinDir = join(cwd, 'fake-bin');
1216
- const tmuxLogPath = join(cwd, 'tmux.log');
1217
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
1218
- await mkdir(logsDir, { recursive: true });
1219
- await mkdir(stateDir, { recursive: true });
1220
- await mkdir(codexHome, { recursive: true });
1221
- await mkdir(fakeBinDir, { recursive: true });
1222
- await writeJson(join(codexHome, '.rcs-config.json'), {
1223
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1224
- });
1225
- const fakeTmux = `#!/usr/bin/env bash
1226
- set -eu
1227
- echo "$@" >> "${tmuxLogPath}"
1228
- cmd="$1"
1229
- shift || true
1230
- if [[ "$cmd" == "display-message" ]]; then
1231
- target=""
1232
- format=""
1233
- while (($#)); do
1234
- case "$1" in
1235
- -p) shift ;;
1236
- -t) target="$2"; shift 2 ;;
1237
- *) format="$1"; shift ;;
1238
- esac
1239
- done
1240
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%99" ]]; then
1241
- echo "sh"
1242
- exit 0
1243
- fi
1244
- if [[ "$format" == "#{pane_current_command}" && "$target" == "%100" ]]; then
1245
- echo "node"
1246
- exit 0
1247
- fi
1248
- if [[ "$format" == "#S" && "$target" == "%99" ]]; then
1249
- echo "${managedSessionName}"
1250
- exit 0
1251
- fi
1252
- if [[ "$format" == "#S" && "$target" == "%100" ]]; then
1253
- echo "${managedSessionName}"
1254
- exit 0
1255
- fi
1256
- if [[ "$format" == "#{pane_current_path}" && "$target" == "%99" ]]; then
1257
- echo "${cwd}"
1258
- exit 0
1259
- fi
1260
- if [[ "$format" == "#{pane_current_path}" && "$target" == "%100" ]]; then
1261
- echo "${cwd}"
1262
- exit 0
1263
- fi
1264
- exit 0
1265
- fi
1266
- if [[ "$cmd" == "capture-pane" ]]; then
1267
- printf "› keep going\\n\\n• keep going\\n\\n› Implement {feature}\\n\\n gpt-5.5 high · dev · 98%% left\\n"
1268
- exit 0
1269
- fi
1270
- if [[ "$cmd" == "send-keys" ]]; then
1271
- exit 0
1272
- fi
1273
- if [[ "$cmd" == "list-panes" ]]; then
1274
- target=""
1275
- while (($#)); do
1276
- case "$1" in
1277
- -t) target="$2"; shift 2 ;;
1278
- *) shift ;;
1279
- esac
1280
- done
1281
- if [[ "$target" == "${managedSessionName}" ]]; then
1282
- printf "%%99\t1\tsh\tbash\\n%%100\t0\tnode\tcodex --model gpt-5\\n"
1283
- exit 0
1284
- fi
1285
- echo "%1 12345"
1286
- exit 0
1287
- fi
1288
- exit 0
1289
- `;
1290
- await writeFile(join(fakeBinDir, 'tmux'), fakeTmux);
1291
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1292
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1293
- 'last-assistant-message': 'keep going',
1294
- });
1295
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1296
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1297
- assert.match(tmuxLog, /display-message -p #S/);
1298
- assert.ok(tmuxLog.includes('display-message -p -t %99 #S'), 'should inspect the anchored shell pane before upgrading');
1299
- assert.match(tmuxLog, defaultAutoNudgePattern('%100'));
1300
- });
1301
- });
1302
- it('logs scroll_active and avoids send-keys when auto-nudge target pane is in copy-mode', async () => {
1303
- await withTempWorkingDir(async (cwd) => {
1304
- const rcsDir = join(cwd, '.rcs');
1305
- const stateDir = join(rcsDir, 'state');
1306
- const logsDir = join(rcsDir, 'logs');
1307
- const codexHome = join(cwd, 'codex-home');
1308
- const fakeBinDir = join(cwd, 'fake-bin');
1309
- const tmuxLogPath = join(cwd, 'tmux.log');
1310
- const managedSessionName = buildTmuxSessionName(cwd, 'sess-managed');
1311
- await mkdir(logsDir, { recursive: true });
1312
- await mkdir(stateDir, { recursive: true });
1313
- await mkdir(codexHome, { recursive: true });
1314
- await mkdir(fakeBinDir, { recursive: true });
1315
- await writeJson(join(codexHome, '.rcs-config.json'), {
1316
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1317
- });
1318
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath, '1'));
1319
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1320
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1321
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
1322
- });
1323
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1324
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1325
- assert.match(tmuxLog, /display-message -p #S/);
1326
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'copy-mode pane should not receive auto-nudge injection');
1327
- });
1328
- });
1329
- it('does not nudge when pane capture shows an active task despite stall-like assistant text', async () => {
1330
- await withTempWorkingDir(async (cwd) => {
1331
- const rcsDir = join(cwd, '.rcs');
1332
- const stateDir = join(rcsDir, 'state');
1333
- const logsDir = join(rcsDir, 'logs');
1334
- const codexHome = join(cwd, 'codex-home');
1335
- const fakeBinDir = join(cwd, 'fake-bin');
1336
- const tmuxLogPath = join(cwd, 'tmux.log');
1337
- const captureFile = join(cwd, 'capture-output.txt');
1338
- await mkdir(logsDir, { recursive: true });
1339
- await mkdir(stateDir, { recursive: true });
1340
- await mkdir(codexHome, { recursive: true });
1341
- await mkdir(fakeBinDir, { recursive: true });
1342
- await writeJson(join(codexHome, '.rcs-config.json'), {
1343
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1344
- });
1345
- await writeFile(captureFile, [
1346
- 'Working...',
1347
- '• Running tests (3m 12s • esc to interrupt)',
1348
- '',
1349
- ].join('\n'));
1350
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1351
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1352
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1353
- 'last-assistant-message': 'Would you like me to continue with the next step?',
1354
- }, {
1355
- RCS_TEST_CAPTURE_FILE: captureFile,
1356
- });
1357
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1358
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1359
- assert.match(tmuxLog, /display-message -p #S/);
1360
- assert.match(tmuxLog, /capture-pane -t %99/, 'busy pane detection should inspect capture output');
1361
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'), 'busy pane should not receive auto-nudge injection');
1362
- });
1363
- });
1364
- it('respects enabled=false configuration', async () => {
1365
- await withTempWorkingDir(async (cwd) => {
1366
- const rcsDir = join(cwd, '.rcs');
1367
- const stateDir = join(rcsDir, 'state');
1368
- const logsDir = join(rcsDir, 'logs');
1369
- const codexHome = join(cwd, 'codex-home');
1370
- const fakeBinDir = join(cwd, 'fake-bin');
1371
- const tmuxLogPath = join(cwd, 'tmux.log');
1372
- await mkdir(logsDir, { recursive: true });
1373
- await mkdir(stateDir, { recursive: true });
1374
- await mkdir(codexHome, { recursive: true });
1375
- await mkdir(fakeBinDir, { recursive: true });
1376
- // Explicitly disabled
1377
- await writeJson(join(codexHome, '.rcs-config.json'), {
1378
- autoNudge: { enabled: false, delaySec: 0 },
1379
- });
1380
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1381
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1382
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1383
- 'last-assistant-message': 'Would you like me to proceed?',
1384
- });
1385
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1386
- if (existsSync(tmuxLogPath)) {
1387
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1388
- assert.doesNotMatch(tmuxLog, /send-keys -t %99 -l/, 'should NOT send nudge when disabled');
1389
- }
1390
- });
1391
- });
1392
- it('deduplicates semantic proceed-style variants on the same turn', async () => {
1393
- await withTempWorkingDir(async (cwd) => {
1394
- const rcsDir = join(cwd, '.rcs');
1395
- const stateDir = join(rcsDir, 'state');
1396
- const logsDir = join(rcsDir, 'logs');
1397
- const codexHome = join(cwd, 'codex-home');
1398
- const fakeBinDir = join(cwd, 'fake-bin');
1399
- const tmuxLogPath = join(cwd, 'tmux.log');
1400
- await mkdir(logsDir, { recursive: true });
1401
- await mkdir(stateDir, { recursive: true });
1402
- await mkdir(codexHome, { recursive: true });
1403
- await mkdir(fakeBinDir, { recursive: true });
1404
- await writeJson(join(codexHome, '.rcs-config.json'), {
1405
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, ttlMs: 0 },
1406
- });
1407
- await writeManagedSessionState(stateDir, cwd);
1408
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1409
- await mkdir(sessionStateDir, { recursive: true });
1410
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1411
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1412
- const sharedTurnId = 'semantic-dedup-turn';
1413
- const first = runNotifyHook(cwd, fakeBinDir, codexHome, {
1414
- 'turn-id': sharedTurnId,
1415
- 'last-assistant-message': 'Keep going and finish the cleanup from here.',
1416
- });
1417
- assert.equal(first.status, 0, `first hook failed: ${first.stderr || first.stdout}`);
1418
- const second = runNotifyHook(cwd, fakeBinDir, codexHome, {
1419
- 'turn-id': sharedTurnId,
1420
- 'last-assistant-message': 'Continue with the cleanup from here.',
1421
- });
1422
- assert.equal(second.status, 0, `second hook failed: ${second.stderr || second.stdout}`);
1423
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1424
- assert.equal((tmuxLog.match(new RegExp(defaultAutoNudgePattern('%99').source, 'g')) || []).length, 1);
1425
- const nudgeState = JSON.parse(await readFile(join(sessionStateDir, 'auto-nudge-state.json'), 'utf-8'));
1426
- assert.equal(nudgeState.nudgeCount, 1);
1427
- assert.match(nudgeState.lastSignature, /^hud:1\|.*\|stall:proceed_intent$/);
1428
- });
1429
- });
1430
- it('applies TTL suppression between similar nudges and allows a later retry after TTL', async () => {
1431
- await withTempWorkingDir(async (cwd) => {
1432
- const rcsDir = join(cwd, '.rcs');
1433
- const stateDir = join(rcsDir, 'state');
1434
- const logsDir = join(rcsDir, 'logs');
1435
- const codexHome = join(cwd, 'codex-home');
1436
- const fakeBinDir = join(cwd, 'fake-bin');
1437
- const tmuxLogPath = join(cwd, 'tmux.log');
1438
- await mkdir(logsDir, { recursive: true });
1439
- await mkdir(stateDir, { recursive: true });
1440
- await mkdir(codexHome, { recursive: true });
1441
- await mkdir(fakeBinDir, { recursive: true });
1442
- await writeJson(join(codexHome, '.rcs-config.json'), {
1443
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, ttlMs: 5000 },
1444
- });
1445
- await writeManagedSessionState(stateDir, cwd);
1446
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1447
- await mkdir(sessionStateDir, { recursive: true });
1448
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1449
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1450
- const first = runNotifyHook(cwd, fakeBinDir, codexHome, {
1451
- 'turn-id': 'cooldown-turn-1',
1452
- 'last-assistant-message': 'Continue with the implementation from here.',
1453
- });
1454
- assert.equal(first.status, 0, `first hook failed: ${first.stderr || first.stdout}`);
1455
- const second = runNotifyHook(cwd, fakeBinDir, codexHome, {
1456
- 'turn-id': 'cooldown-turn-2',
1457
- 'last-assistant-message': 'I can also move forward with the implementation.',
1458
- });
1459
- assert.equal(second.status, 0, `second hook failed: ${second.stderr || second.stdout}`);
1460
- let tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1461
- assert.equal((tmuxLog.match(new RegExp(defaultAutoNudgePattern('%99').source, 'g')) || []).length, 1);
1462
- const nudgeStatePath = join(sessionStateDir, 'auto-nudge-state.json');
1463
- const nudgeStateBeforeThird = JSON.parse(await readFile(nudgeStatePath, 'utf-8'));
1464
- await writeJson(nudgeStatePath, {
1465
- ...nudgeStateBeforeThird,
1466
- lastNudgeAt: '2026-03-01T00:00:00.000Z',
1467
- });
1468
- const third = runNotifyHook(cwd, fakeBinDir, codexHome, {
1469
- 'turn-id': 'cooldown-turn-3',
1470
- 'last-assistant-message': 'Keep going and finish the focused tests.',
1471
- });
1472
- assert.equal(third.status, 0, `third hook failed: ${third.stderr || third.stdout}`);
1473
- tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1474
- assert.equal((tmuxLog.match(new RegExp(defaultAutoNudgePattern('%99').source, 'g')) || []).length, 2);
1475
- const nudgeState = JSON.parse(await readFile(nudgeStatePath, 'utf-8'));
1476
- assert.equal(nudgeState.nudgeCount, 2);
1477
- assert.equal(nudgeState.lastSemanticSignature, 'stall:proceed_intent');
1478
- });
1479
- });
1480
- it('does not resend the exact same stalled turn after TTL expiry', async () => {
1481
- await withTempWorkingDir(async (cwd) => {
1482
- const rcsDir = join(cwd, '.rcs');
1483
- const stateDir = join(rcsDir, 'state');
1484
- const logsDir = join(rcsDir, 'logs');
1485
- const codexHome = join(cwd, 'codex-home');
1486
- const fakeBinDir = join(cwd, 'fake-bin');
1487
- const tmuxLogPath = join(cwd, 'tmux.log');
1488
- const lastTurnAt = '2026-03-01T00:00:00.000Z';
1489
- const lastMessage = 'Keep going and finish the cleanup from here.';
1490
- await mkdir(logsDir, { recursive: true });
1491
- await mkdir(stateDir, { recursive: true });
1492
- await mkdir(codexHome, { recursive: true });
1493
- await mkdir(fakeBinDir, { recursive: true });
1494
- await writeJson(join(codexHome, '.rcs-config.json'), {
1495
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, ttlMs: 5000 },
1496
- });
1497
- await writeManagedSessionState(stateDir, cwd);
1498
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1499
- await mkdir(sessionStateDir, { recursive: true });
1500
- await writeJson(join(sessionStateDir, 'hud-state.json'), {
1501
- last_turn_at: lastTurnAt,
1502
- turn_count: 1,
1503
- last_agent_output: lastMessage,
1504
- });
1505
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1506
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1507
- const first = runNotifyHook(cwd, fakeBinDir, codexHome, {
1508
- 'turn-id': 'stalled-turn-1',
1509
- 'last-assistant-message': lastMessage,
1510
- });
1511
- assert.equal(first.status, 0, `first hook failed: ${first.stderr || first.stdout}`);
1512
- const nudgeStatePath = join(sessionStateDir, 'auto-nudge-state.json');
1513
- const firstState = JSON.parse(await readFile(nudgeStatePath, 'utf-8'));
1514
- await writeJson(nudgeStatePath, {
1515
- ...firstState,
1516
- lastNudgeAt: '2026-03-01T00:00:10.000Z',
1517
- });
1518
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1519
- 'turn-id': 'stalled-turn-1',
1520
- 'last-assistant-message': lastMessage,
1521
- });
1522
- assert.equal(result.status, 0, `second hook failed: ${result.stderr || result.stdout}`);
1523
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
1524
- assert.equal((tmuxLog.match(new RegExp(defaultAutoNudgePattern('%99').source, 'g')) || []).length, 1);
1525
- const nudgeState = JSON.parse(await readFile(nudgeStatePath, 'utf-8'));
1526
- assert.equal(nudgeState.nudgeCount, 1);
1527
- assert.equal(nudgeState.lastSignature, firstState.lastSignature);
1528
- });
1529
- });
1530
- it('ignores non-turn-complete payloads so the same stalled reply cannot re-nudge without a new Codex boundary', async () => {
1531
- await withTempWorkingDir(async (cwd) => {
1532
- const rcsDir = join(cwd, '.rcs');
1533
- const stateDir = join(rcsDir, 'state');
1534
- const logsDir = join(rcsDir, 'logs');
1535
- const codexHome = join(cwd, 'codex-home');
1536
- const fakeBinDir = join(cwd, 'fake-bin');
1537
- const tmuxLogPath = join(cwd, 'tmux.log');
1538
- const lastMessage = 'Keep going and finish the cleanup from here.';
1539
- await mkdir(logsDir, { recursive: true });
1540
- await mkdir(stateDir, { recursive: true });
1541
- await mkdir(codexHome, { recursive: true });
1542
- await mkdir(fakeBinDir, { recursive: true });
1543
- await writeJson(join(codexHome, '.rcs-config.json'), {
1544
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, ttlMs: 0 },
1545
- });
1546
- await writeManagedSessionState(stateDir, cwd);
1547
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1548
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1549
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1550
- const first = runNotifyHook(cwd, fakeBinDir, codexHome, {
1551
- type: 'agent-turn-complete',
1552
- 'turn-id': 'turn-complete-1',
1553
- 'last-assistant-message': lastMessage,
1554
- });
1555
- assert.equal(first.status, 0, `first hook failed: ${first.stderr || first.stdout}`);
1556
- const second = runNotifyHook(cwd, fakeBinDir, codexHome, {
1557
- type: 'function_call_output',
1558
- 'turn-id': 'function-call-output-1',
1559
- 'last-assistant-message': lastMessage,
1560
- });
1561
- assert.equal(second.status, 0, `second hook failed: ${second.stderr || second.stdout}`);
1562
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1563
- assert.equal((tmuxLog.match(new RegExp(defaultAutoNudgePattern('%99').source, 'g')) || []).length, 1);
1564
- const hudState = JSON.parse(await readFile(join(sessionStateDir, 'hud-state.json'), 'utf-8'));
1565
- assert.equal(hudState.turn_count, 1);
1566
- const nudgeState = JSON.parse(await readFile(join(sessionStateDir, 'auto-nudge-state.json'), 'utf-8'));
1567
- assert.equal(nudgeState.nudgeCount, 1);
1568
- assert.match(nudgeState.lastSignature, /^hud:1\|.*\|stall:proceed_intent$/);
1569
- });
1570
- });
1571
- it('uses custom response from config', async () => {
1572
- await withTempWorkingDir(async (cwd) => {
1573
- const rcsDir = join(cwd, '.rcs');
1574
- const stateDir = join(rcsDir, 'state');
1575
- const logsDir = join(rcsDir, 'logs');
1576
- const codexHome = join(cwd, 'codex-home');
1577
- const fakeBinDir = join(cwd, 'fake-bin');
1578
- const tmuxLogPath = join(cwd, 'tmux.log');
1579
- await mkdir(logsDir, { recursive: true });
1580
- await mkdir(stateDir, { recursive: true });
1581
- await mkdir(codexHome, { recursive: true });
1582
- await mkdir(fakeBinDir, { recursive: true });
1583
- await writeJson(join(codexHome, '.rcs-config.json'), {
1584
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, response: 'continue now' },
1585
- });
1586
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1587
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1588
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1589
- 'last-assistant-message': 'Keep going and implement this feature.',
1590
- });
1591
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1592
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1593
- assert.match(tmuxLog, /send-keys -t %99 -l continue now \[RCS_TMUX_INJECT\]/, 'should use custom response with marker');
1594
- });
1595
- });
1596
- it('tracks nudge count in auto-nudge-state.json', async () => {
1597
- await withTempWorkingDir(async (cwd) => {
1598
- const rcsDir = join(cwd, '.rcs');
1599
- const stateDir = join(rcsDir, 'state');
1600
- const logsDir = join(rcsDir, 'logs');
1601
- const codexHome = join(cwd, 'codex-home');
1602
- const fakeBinDir = join(cwd, 'fake-bin');
1603
- const tmuxLogPath = join(cwd, 'tmux.log');
1604
- await mkdir(logsDir, { recursive: true });
1605
- await mkdir(stateDir, { recursive: true });
1606
- await mkdir(codexHome, { recursive: true });
1607
- await mkdir(fakeBinDir, { recursive: true });
1608
- await writeJson(join(codexHome, '.rcs-config.json'), {
1609
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1610
- });
1611
- await writeManagedSessionState(stateDir, cwd);
1612
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1613
- await mkdir(sessionStateDir, { recursive: true });
1614
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1615
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1616
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1617
- 'last-assistant-message': 'Keep going and finish the focused cleanup.',
1618
- });
1619
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1620
- const nudgeStatePath = join(sessionStateDir, 'auto-nudge-state.json');
1621
- assert.ok(existsSync(nudgeStatePath), 'auto-nudge-state.json should be created');
1622
- const nudgeState = JSON.parse(await readFile(nudgeStatePath, 'utf-8'));
1623
- assert.equal(nudgeState.nudgeCount, 1, 'nudge count should be 1');
1624
- assert.ok(nudgeState.lastNudgeAt, 'should have lastNudgeAt timestamp');
1625
- });
1626
- });
1627
- it('writes skill-active-state.json when keyword activation is detected', async () => {
1628
- await withTempWorkingDir(async (cwd) => {
1629
- const rcsDir = join(cwd, '.rcs');
1630
- const stateDir = join(rcsDir, 'state');
1631
- const logsDir = join(rcsDir, 'logs');
1632
- const codexHome = join(cwd, 'codex-home');
1633
- const fakeBinDir = join(cwd, 'fake-bin');
1634
- await mkdir(logsDir, { recursive: true });
1635
- await mkdir(stateDir, { recursive: true });
1636
- await mkdir(codexHome, { recursive: true });
1637
- await mkdir(fakeBinDir, { recursive: true });
1638
- await writeJson(join(codexHome, '.rcs-config.json'), {
1639
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1640
- });
1641
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
1642
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1643
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1644
- 'input-messages': ['please use $autopilot for this task'],
1645
- 'last-assistant-message': 'Here is the plan I will follow.',
1646
- });
1647
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1648
- const skillStatePath = join(stateDir, 'skill-active-state.json');
1649
- assert.ok(existsSync(skillStatePath), 'skill-active-state.json should be created');
1650
- const skillState = JSON.parse(await readFile(skillStatePath, 'utf-8'));
1651
- assert.equal(skillState.skill, 'autopilot');
1652
- assert.equal(skillState.phase, 'ralplan');
1653
- assert.equal(skillState.active, true);
1654
- });
1655
- });
1656
- it('disables auto-nudge entirely when deep-interview mode state is active', async () => {
1657
- await withTempWorkingDir(async (cwd) => {
1658
- const rcsDir = join(cwd, '.rcs');
1659
- const stateDir = join(rcsDir, 'state');
1660
- const logsDir = join(rcsDir, 'logs');
1661
- const codexHome = join(cwd, 'codex-home');
1662
- const fakeBinDir = join(cwd, 'fake-bin');
1663
- const tmuxLogPath = join(cwd, 'tmux.log');
1664
- await mkdir(logsDir, { recursive: true });
1665
- await mkdir(stateDir, { recursive: true });
1666
- await mkdir(codexHome, { recursive: true });
1667
- await mkdir(fakeBinDir, { recursive: true });
1668
- await writeJson(join(codexHome, '.rcs-config.json'), {
1669
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1670
- });
1671
- await writeJson(join(stateDir, 'deep-interview-state.json'), {
1672
- active: true,
1673
- mode: 'deep-interview',
1674
- current_phase: 'deep-interview',
1675
- });
1676
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1677
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1678
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1679
- 'last-assistant-message': 'Would you like me to continue?',
1680
- });
1681
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1682
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
1683
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
1684
- });
1685
- });
1686
- it('disables auto-nudge when only skill-active-state carries the deep-interview input lock', async () => {
1687
- await withTempWorkingDir(async (cwd) => {
1688
- const rcsDir = join(cwd, '.rcs');
1689
- const stateDir = join(rcsDir, 'state');
1690
- const logsDir = join(rcsDir, 'logs');
1691
- const codexHome = join(cwd, 'codex-home');
1692
- const fakeBinDir = join(cwd, 'fake-bin');
1693
- const tmuxLogPath = join(cwd, 'tmux.log');
1694
- await mkdir(logsDir, { recursive: true });
1695
- await mkdir(stateDir, { recursive: true });
1696
- await mkdir(codexHome, { recursive: true });
1697
- await mkdir(fakeBinDir, { recursive: true });
1698
- await writeJson(join(codexHome, '.rcs-config.json'), {
1699
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1700
- });
1701
- await writeManagedSessionState(stateDir, cwd);
1702
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1703
- await mkdir(sessionStateDir, { recursive: true });
1704
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
1705
- version: 1,
1706
- active: true,
1707
- skill: 'deep-interview',
1708
- keyword: 'deep interview',
1709
- phase: 'executing',
1710
- activated_at: '2026-02-25T00:00:00.000Z',
1711
- updated_at: '2026-02-25T00:00:00.000Z',
1712
- source: 'keyword-detector',
1713
- input_lock: {
1714
- active: true,
1715
- scope: 'deep-interview-auto-approval',
1716
- acquired_at: '2026-02-25T00:00:00.000Z',
1717
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
1718
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
1719
- },
1720
- });
1721
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1722
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1723
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1724
- 'last-assistant-message': 'Would you like me to continue?',
1725
- });
1726
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1727
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8').catch(() => '');
1728
- assert.doesNotMatch(tmuxLog, defaultAutoNudgePattern('%99'));
1729
- });
1730
- });
1731
- it('acquires the deep-interview input lock when deep-interview activates', async () => {
1732
- await withTempWorkingDir(async (cwd) => {
1733
- const rcsDir = join(cwd, '.rcs');
1734
- const stateDir = join(rcsDir, 'state');
1735
- const logsDir = join(rcsDir, 'logs');
1736
- const codexHome = join(cwd, 'codex-home');
1737
- const fakeBinDir = join(cwd, 'fake-bin');
1738
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1739
- await mkdir(logsDir, { recursive: true });
1740
- await mkdir(stateDir, { recursive: true });
1741
- await mkdir(codexHome, { recursive: true });
1742
- await mkdir(fakeBinDir, { recursive: true });
1743
- await writeJson(join(codexHome, '.rcs-config.json'), {
1744
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1745
- });
1746
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
1747
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1748
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1749
- 'input-messages': ['please run a deep interview first'],
1750
- 'last-assistant-message': 'Round 1 | Target: Goal Clarity',
1751
- });
1752
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1753
- const skillState = JSON.parse(await readFile(join(stateDir, 'skill-active-state.json'), 'utf-8'));
1754
- assert.equal(skillState.skill, 'deep-interview');
1755
- assert.equal(skillState.input_lock?.active, true);
1756
- assert.deepEqual(skillState.input_lock?.blocked_inputs, DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS);
1757
- assert.match(skillState.input_lock?.message || '', /Deep interview is active/i);
1758
- const modeState = JSON.parse(await readFile(join(sessionStateDir, 'deep-interview-state.json'), 'utf-8'));
1759
- assert.equal(modeState.active, true);
1760
- assert.equal(modeState.mode, 'deep-interview');
1761
- assert.equal(modeState.current_phase, 'intent-first');
1762
- assert.equal(modeState.input_lock?.active, true);
1763
- });
1764
- });
1765
- it('releases deep-interview mode state on normal completion without waiting for later keyword input', async () => {
1766
- await withTempWorkingDir(async (cwd) => {
1767
- const rcsDir = join(cwd, '.rcs');
1768
- const stateDir = join(rcsDir, 'state');
1769
- const logsDir = join(rcsDir, 'logs');
1770
- const codexHome = join(cwd, 'codex-home');
1771
- const fakeBinDir = join(cwd, 'fake-bin');
1772
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1773
- await mkdir(logsDir, { recursive: true });
1774
- await mkdir(stateDir, { recursive: true });
1775
- await mkdir(codexHome, { recursive: true });
1776
- await mkdir(fakeBinDir, { recursive: true });
1777
- await writeJson(join(codexHome, '.rcs-config.json'), {
1778
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
1779
- });
1780
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
1781
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1782
- const activated = runNotifyHook(cwd, fakeBinDir, codexHome, {
1783
- 'input-messages': ['please run a deep interview first'],
1784
- 'last-assistant-message': 'Round 1 | Target: Goal Clarity',
1785
- });
1786
- assert.equal(activated.status, 0, `activation hook failed: ${activated.stderr || activated.stdout}`);
1787
- const completed = runNotifyHook(cwd, fakeBinDir, codexHome, {
1788
- 'input-messages': ['continue'],
1789
- 'last-assistant-message': 'Interview completed. Final summary ready.',
1790
- });
1791
- assert.equal(completed.status, 0, `completion hook failed: ${completed.stderr || completed.stdout}`);
1792
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
1793
- assert.equal(skillState.active, false);
1794
- assert.equal(skillState.phase, 'completing');
1795
- assert.equal(skillState.input_lock?.active, false);
1796
- assert.equal(skillState.input_lock?.exit_reason, 'success');
1797
- assert.ok(skillState.input_lock?.released_at);
1798
- const modeState = JSON.parse(await readFile(join(sessionStateDir, 'deep-interview-state.json'), 'utf-8'));
1799
- assert.equal(modeState.active, false);
1800
- assert.equal(modeState.current_phase, 'completing');
1801
- assert.ok(modeState.completed_at);
1802
- assert.equal(modeState.input_lock?.active, false);
1803
- assert.equal(modeState.input_lock?.exit_reason, 'success');
1804
- assert.ok(modeState.input_lock?.released_at);
1805
- });
1806
- });
1807
- for (const blockedResponse of ['yes', 'y', 'proceed', 'continue', 'ok', 'sure', 'go ahead']) {
1808
- it(`blocks deep-interview auto-approval injection for "${blockedResponse}"`, async () => {
1809
- await withTempWorkingDir(async (cwd) => {
1810
- const rcsDir = join(cwd, '.rcs');
1811
- const stateDir = join(rcsDir, 'state');
1812
- const logsDir = join(rcsDir, 'logs');
1813
- const codexHome = join(cwd, 'codex-home');
1814
- const fakeBinDir = join(cwd, 'fake-bin');
1815
- const tmuxLogPath = join(cwd, 'tmux.log');
1816
- await mkdir(logsDir, { recursive: true });
1817
- await mkdir(stateDir, { recursive: true });
1818
- await mkdir(codexHome, { recursive: true });
1819
- await mkdir(fakeBinDir, { recursive: true });
1820
- await writeJson(join(codexHome, '.rcs-config.json'), {
1821
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, response: blockedResponse },
1822
- });
1823
- await writeJson(join(stateDir, 'skill-active-state.json'), {
1824
- version: 1,
1825
- active: true,
1826
- skill: 'deep-interview',
1827
- keyword: 'deep interview',
1828
- phase: 'planning',
1829
- activated_at: '2026-02-25T00:00:00.000Z',
1830
- updated_at: '2026-02-25T00:00:00.000Z',
1831
- source: 'keyword-detector',
1832
- input_lock: {
1833
- active: true,
1834
- scope: 'deep-interview-auto-approval',
1835
- acquired_at: '2026-02-25T00:00:00.000Z',
1836
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
1837
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
1838
- },
1839
- });
1840
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1841
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1842
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1843
- 'last-assistant-message': 'Keep going and finish the cleanup.',
1844
- });
1845
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1846
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1847
- assert.doesNotMatch(tmuxLog, /Deep interview is active; auto-approval shortcuts are blocked until the interview finishes\. \[RCS_TMUX_INJECT\]/);
1848
- assert.equal(tmuxLog.includes(`send-keys -t %99 -l ${blockedResponse} [RCS_TMUX_INJECT]`), false);
1849
- });
1850
- });
1851
- }
1852
- it('suppresses deep-interview auto-approval without injecting tmux input', async () => {
1853
- await withTempWorkingDir(async (cwd) => {
1854
- const rcsDir = join(cwd, '.rcs');
1855
- const stateDir = join(rcsDir, 'state');
1856
- const logsDir = join(rcsDir, 'logs');
1857
- const codexHome = join(cwd, 'codex-home');
1858
- const fakeBinDir = join(cwd, 'fake-bin');
1859
- const tmuxLogPath = join(cwd, 'tmux.log');
1860
- await mkdir(logsDir, { recursive: true });
1861
- await mkdir(stateDir, { recursive: true });
1862
- await mkdir(codexHome, { recursive: true });
1863
- await mkdir(fakeBinDir, { recursive: true });
1864
- await writeJson(join(codexHome, '.rcs-config.json'), {
1865
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, response: 'yes' },
1866
- });
1867
- await writeJson(join(stateDir, 'skill-active-state.json'), {
1868
- version: 1,
1869
- active: true,
1870
- skill: 'deep-interview',
1871
- keyword: 'deep interview',
1872
- phase: 'planning',
1873
- activated_at: '2026-02-25T00:00:00.000Z',
1874
- updated_at: '2026-02-25T00:00:00.000Z',
1875
- source: 'keyword-detector',
1876
- input_lock: {
1877
- active: true,
1878
- scope: 'deep-interview-auto-approval',
1879
- acquired_at: '2026-02-25T00:00:00.000Z',
1880
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
1881
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
1882
- },
1883
- });
1884
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1885
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1886
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1887
- 'last-assistant-message': 'Keep going and finish the cleanup.',
1888
- });
1889
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1890
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1891
- assert.doesNotMatch(tmuxLog, /send-keys -t %99 -l Deep interview is active; auto-approval shortcuts are blocked until the interview finishes\. \[RCS_TMUX_INJECT\]/);
1892
- });
1893
- });
1894
- it('blocks deep-interview auto-approval injection for actionable "Next I should ..." replies', async () => {
1895
- await withTempWorkingDir(async (cwd) => {
1896
- const rcsDir = join(cwd, '.rcs');
1897
- const stateDir = join(rcsDir, 'state');
1898
- const logsDir = join(rcsDir, 'logs');
1899
- const codexHome = join(cwd, 'codex-home');
1900
- const fakeBinDir = join(cwd, 'fake-bin');
1901
- const tmuxLogPath = join(cwd, 'tmux.log');
1902
- await mkdir(logsDir, { recursive: true });
1903
- await mkdir(stateDir, { recursive: true });
1904
- await mkdir(codexHome, { recursive: true });
1905
- await mkdir(fakeBinDir, { recursive: true });
1906
- await writeJson(join(codexHome, '.rcs-config.json'), {
1907
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, response: NEXT_I_SHOULD_RESPONSE },
1908
- });
1909
- await writeJson(join(stateDir, 'skill-active-state.json'), {
1910
- version: 1,
1911
- active: true,
1912
- skill: 'deep-interview',
1913
- keyword: 'deep interview',
1914
- phase: 'planning',
1915
- activated_at: '2026-02-25T00:00:00.000Z',
1916
- updated_at: '2026-02-25T00:00:00.000Z',
1917
- source: 'keyword-detector',
1918
- input_lock: {
1919
- active: true,
1920
- scope: 'deep-interview-auto-approval',
1921
- acquired_at: '2026-02-25T00:00:00.000Z',
1922
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
1923
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
1924
- },
1925
- });
1926
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1927
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1928
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1929
- 'last-assistant-message': 'Would you like me to continue?',
1930
- });
1931
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1932
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1933
- assert.doesNotMatch(tmuxLog, /Deep interview is active; auto-approval shortcuts are blocked until the interview finishes\. \[RCS_TMUX_INJECT\]/);
1934
- assert.equal(tmuxLog.includes(`send-keys -t %99 -l ${NEXT_I_SHOULD_RESPONSE} [RCS_TMUX_INJECT]`), false);
1935
- });
1936
- });
1937
- it('allows non-blocked custom deep-interview auto-nudge responses to continue', async () => {
1938
- await withTempWorkingDir(async (cwd) => {
1939
- const rcsDir = join(cwd, '.rcs');
1940
- const stateDir = join(rcsDir, 'state');
1941
- const logsDir = join(rcsDir, 'logs');
1942
- const codexHome = join(cwd, 'codex-home');
1943
- const fakeBinDir = join(cwd, 'fake-bin');
1944
- const tmuxLogPath = join(cwd, 'tmux.log');
1945
- const capturePath = join(cwd, 'capture.txt');
1946
- const customResponse = 'advance with the next interview question';
1947
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
1948
- await mkdir(logsDir, { recursive: true });
1949
- await mkdir(stateDir, { recursive: true });
1950
- await mkdir(codexHome, { recursive: true });
1951
- await mkdir(fakeBinDir, { recursive: true });
1952
- await writeJson(join(codexHome, '.rcs-config.json'), {
1953
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0, response: customResponse },
1954
- });
1955
- await writeManagedSessionState(stateDir, cwd);
1956
- await mkdir(sessionStateDir, { recursive: true });
1957
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
1958
- version: 1,
1959
- active: true,
1960
- skill: 'deep-interview',
1961
- keyword: 'deep interview',
1962
- phase: 'executing',
1963
- activated_at: '2026-02-25T00:00:00.000Z',
1964
- updated_at: '2026-02-25T00:00:00.000Z',
1965
- source: 'keyword-detector',
1966
- input_lock: {
1967
- active: true,
1968
- scope: 'deep-interview-auto-approval',
1969
- acquired_at: '2026-02-25T00:00:00.000Z',
1970
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
1971
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
1972
- },
1973
- });
1974
- await writeFile(capturePath, 'OpenAI Codex\n› ');
1975
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
1976
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
1977
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
1978
- 'last-assistant-message': 'Keep going and finish the cleanup.',
1979
- }, {
1980
- RCS_TEST_CAPTURE_FILE: capturePath,
1981
- });
1982
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
1983
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1984
- assert.match(tmuxLog, new RegExp(`send-keys -t %99 -l ${customResponse} \\[RCS_TMUX_INJECT\\]`), 'should allow a non-blocked continuation response during deep interview');
1985
- });
1986
- });
1987
- it('keeps autoresearch active when assistant claims completion without validator evidence', async () => {
1988
- await withTempWorkingDir(async (cwd) => {
1989
- const rcsDir = join(cwd, '.rcs');
1990
- const stateDir = join(rcsDir, 'state');
1991
- const logsDir = join(rcsDir, 'logs');
1992
- const codexHome = join(cwd, 'codex-home');
1993
- const fakeBinDir = join(cwd, 'fake-bin');
1994
- const tmuxLogPath = join(cwd, 'tmux.log');
1995
- await mkdir(logsDir, { recursive: true });
1996
- await mkdir(stateDir, { recursive: true });
1997
- await mkdir(codexHome, { recursive: true });
1998
- await mkdir(fakeBinDir, { recursive: true });
1999
- await writeJson(join(codexHome, '.rcs-config.json'), {
2000
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2001
- });
2002
- await writeManagedSessionState(stateDir, cwd);
2003
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2004
- await mkdir(sessionStateDir, { recursive: true });
2005
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2006
- active: true,
2007
- skill: 'autoresearch',
2008
- keyword: '$autoresearch',
2009
- phase: 'executing',
2010
- source: 'keyword-detector',
2011
- session_id: 'sess-managed',
2012
- });
2013
- await writeJson(join(sessionStateDir, 'autoresearch-state.json'), {
2014
- active: true,
2015
- mode: 'autoresearch',
2016
- current_phase: 'executing',
2017
- session_id: 'sess-managed',
2018
- validation_mode: 'mission-validator-script',
2019
- mission_validator_command: 'node scripts/validate.js',
2020
- completion_artifact_path: '.rcs/specs/autoresearch-demo/completion.json',
2021
- });
2022
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
2023
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2024
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2025
- 'last-assistant-message': 'All tests pass. Completed with summary.',
2026
- });
2027
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2028
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2029
- assert.equal(skillState.active, true);
2030
- assert.equal(skillState.phase, 'executing');
2031
- assert.equal(skillState.autoresearch_completion_reason, 'missing_or_invalid_completion_artifact');
2032
- });
2033
- });
2034
- it('completes autoresearch when validator artifact passes', async () => {
2035
- await withTempWorkingDir(async (cwd) => {
2036
- const rcsDir = join(cwd, '.rcs');
2037
- const stateDir = join(rcsDir, 'state');
2038
- const logsDir = join(rcsDir, 'logs');
2039
- const codexHome = join(cwd, 'codex-home');
2040
- const fakeBinDir = join(cwd, 'fake-bin');
2041
- const tmuxLogPath = join(cwd, 'tmux.log');
2042
- const specDir = join(cwd, '.rcs', 'specs', 'autoresearch-demo');
2043
- await mkdir(logsDir, { recursive: true });
2044
- await mkdir(stateDir, { recursive: true });
2045
- await mkdir(codexHome, { recursive: true });
2046
- await mkdir(fakeBinDir, { recursive: true });
2047
- await mkdir(specDir, { recursive: true });
2048
- await writeJson(join(codexHome, '.rcs-config.json'), {
2049
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2050
- });
2051
- await writeManagedSessionState(stateDir, cwd);
2052
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2053
- await mkdir(sessionStateDir, { recursive: true });
2054
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2055
- active: true,
2056
- skill: 'autoresearch',
2057
- keyword: '$autoresearch',
2058
- phase: 'reviewing',
2059
- source: 'keyword-detector',
2060
- session_id: 'sess-managed',
2061
- });
2062
- await writeJson(join(sessionStateDir, 'autoresearch-state.json'), {
2063
- active: true,
2064
- mode: 'autoresearch',
2065
- current_phase: 'reviewing',
2066
- session_id: 'sess-managed',
2067
- validation_mode: 'mission-validator-script',
2068
- mission_validator_command: 'node scripts/validate.js',
2069
- completion_artifact_path: '.rcs/specs/autoresearch-demo/completion.json',
2070
- });
2071
- await writeJson(join(specDir, 'completion.json'), {
2072
- status: 'passed',
2073
- passed: true,
2074
- });
2075
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
2076
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2077
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2078
- 'last-assistant-message': 'Completed with final summary after validator pass.',
2079
- });
2080
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2081
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2082
- assert.equal(skillState.active, false);
2083
- assert.equal(skillState.phase, 'completing');
2084
- assert.equal(skillState.autoresearch_completion_reason, 'validator_passed');
2085
- });
2086
- });
2087
- it('releases the deep-interview input lock on success', async () => {
2088
- await withTempWorkingDir(async (cwd) => {
2089
- const rcsDir = join(cwd, '.rcs');
2090
- const stateDir = join(rcsDir, 'state');
2091
- const logsDir = join(rcsDir, 'logs');
2092
- const codexHome = join(cwd, 'codex-home');
2093
- const fakeBinDir = join(cwd, 'fake-bin');
2094
- await mkdir(logsDir, { recursive: true });
2095
- await mkdir(stateDir, { recursive: true });
2096
- await mkdir(codexHome, { recursive: true });
2097
- await mkdir(fakeBinDir, { recursive: true });
2098
- await writeJson(join(codexHome, '.rcs-config.json'), {
2099
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2100
- });
2101
- await writeManagedSessionState(stateDir, cwd);
2102
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2103
- await mkdir(sessionStateDir, { recursive: true });
2104
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2105
- version: 1,
2106
- active: true,
2107
- skill: 'deep-interview',
2108
- keyword: 'deep interview',
2109
- phase: 'planning',
2110
- activated_at: '2026-02-25T00:00:00.000Z',
2111
- updated_at: '2026-02-25T00:00:00.000Z',
2112
- source: 'keyword-detector',
2113
- input_lock: {
2114
- active: true,
2115
- scope: 'deep-interview-auto-approval',
2116
- acquired_at: '2026-02-25T00:00:00.000Z',
2117
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
2118
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
2119
- },
2120
- });
2121
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
2122
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2123
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2124
- 'last-assistant-message': 'Interview completed. Final summary ready.',
2125
- });
2126
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2127
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2128
- assert.equal(skillState.active, false);
2129
- assert.equal(skillState.phase, 'completing');
2130
- assert.equal(skillState.input_lock?.active, false);
2131
- assert.ok(skillState.input_lock?.released_at);
2132
- assert.equal(skillState.input_lock?.exit_reason, 'success');
2133
- });
2134
- });
2135
- it('does not release deep-interview state from generic progress prose', async () => {
2136
- await withTempWorkingDir(async (cwd) => {
2137
- const rcsDir = join(cwd, '.rcs');
2138
- const stateDir = join(rcsDir, 'state');
2139
- const logsDir = join(rcsDir, 'logs');
2140
- const codexHome = join(cwd, 'codex-home');
2141
- const fakeBinDir = join(cwd, 'fake-bin');
2142
- await mkdir(logsDir, { recursive: true });
2143
- await mkdir(stateDir, { recursive: true });
2144
- await mkdir(codexHome, { recursive: true });
2145
- await mkdir(fakeBinDir, { recursive: true });
2146
- await writeJson(join(codexHome, '.rcs-config.json'), {
2147
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2148
- });
2149
- await writeManagedSessionState(stateDir, cwd);
2150
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2151
- await mkdir(sessionStateDir, { recursive: true });
2152
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2153
- version: 1,
2154
- active: true,
2155
- skill: 'deep-interview',
2156
- keyword: 'deep interview',
2157
- phase: 'executing',
2158
- activated_at: '2026-02-25T00:00:00.000Z',
2159
- updated_at: '2026-02-25T00:00:00.000Z',
2160
- source: 'keyword-detector',
2161
- input_lock: {
2162
- active: true,
2163
- scope: 'deep-interview-auto-approval',
2164
- acquired_at: '2026-02-25T00:00:00.000Z',
2165
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
2166
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
2167
- },
2168
- });
2169
- await writeJson(join(sessionStateDir, 'deep-interview-state.json'), {
2170
- active: true,
2171
- mode: 'deep-interview',
2172
- current_phase: 'intent-first',
2173
- started_at: '2026-02-25T00:00:00.000Z',
2174
- updated_at: '2026-02-25T00:00:00.000Z',
2175
- });
2176
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
2177
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2178
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2179
- 'last-assistant-message': 'Summary so far: done with the first round of questions.',
2180
- });
2181
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2182
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2183
- assert.equal(skillState.active, true);
2184
- assert.notEqual(skillState.phase, 'completing');
2185
- assert.equal(skillState.input_lock?.active, true);
2186
- assert.equal(skillState.input_lock?.released_at || '', '');
2187
- assert.equal(skillState.input_lock?.exit_reason || '', '');
2188
- const modeState = JSON.parse(await readFile(join(sessionStateDir, 'deep-interview-state.json'), 'utf-8'));
2189
- assert.equal(modeState.active, true);
2190
- assert.equal(modeState.current_phase, 'intent-first');
2191
- assert.equal(modeState.completed_at || '', '');
2192
- });
2193
- });
2194
- it('releases the deep-interview input lock on error', async () => {
2195
- await withTempWorkingDir(async (cwd) => {
2196
- const rcsDir = join(cwd, '.rcs');
2197
- const stateDir = join(rcsDir, 'state');
2198
- const logsDir = join(rcsDir, 'logs');
2199
- const codexHome = join(cwd, 'codex-home');
2200
- const fakeBinDir = join(cwd, 'fake-bin');
2201
- await mkdir(logsDir, { recursive: true });
2202
- await mkdir(stateDir, { recursive: true });
2203
- await mkdir(codexHome, { recursive: true });
2204
- await mkdir(fakeBinDir, { recursive: true });
2205
- await writeJson(join(codexHome, '.rcs-config.json'), {
2206
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2207
- });
2208
- await writeManagedSessionState(stateDir, cwd);
2209
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2210
- await mkdir(sessionStateDir, { recursive: true });
2211
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2212
- version: 1,
2213
- active: true,
2214
- skill: 'deep-interview',
2215
- keyword: 'deep interview',
2216
- phase: 'planning',
2217
- activated_at: '2026-02-25T00:00:00.000Z',
2218
- updated_at: '2026-02-25T00:00:00.000Z',
2219
- source: 'keyword-detector',
2220
- input_lock: {
2221
- active: true,
2222
- scope: 'deep-interview-auto-approval',
2223
- acquired_at: '2026-02-25T00:00:00.000Z',
2224
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
2225
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
2226
- },
2227
- });
2228
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
2229
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2230
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2231
- 'last-assistant-message': 'Deep interview failed with error: unable to continue.',
2232
- });
2233
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2234
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2235
- assert.equal(skillState.active, false);
2236
- assert.equal(skillState.phase, 'completing');
2237
- assert.equal(skillState.input_lock?.active, false);
2238
- assert.ok(skillState.input_lock?.released_at);
2239
- assert.equal(skillState.input_lock?.exit_reason, 'error');
2240
- });
2241
- });
2242
- it('releases the deep-interview input lock on abort', async () => {
2243
- await withTempWorkingDir(async (cwd) => {
2244
- const rcsDir = join(cwd, '.rcs');
2245
- const stateDir = join(rcsDir, 'state');
2246
- const logsDir = join(rcsDir, 'logs');
2247
- const codexHome = join(cwd, 'codex-home');
2248
- const fakeBinDir = join(cwd, 'fake-bin');
2249
- await mkdir(logsDir, { recursive: true });
2250
- await mkdir(stateDir, { recursive: true });
2251
- await mkdir(codexHome, { recursive: true });
2252
- await mkdir(fakeBinDir, { recursive: true });
2253
- await writeJson(join(codexHome, '.rcs-config.json'), {
2254
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2255
- });
2256
- await writeManagedSessionState(stateDir, cwd);
2257
- const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
2258
- await mkdir(sessionStateDir, { recursive: true });
2259
- await writeJson(join(sessionStateDir, 'skill-active-state.json'), {
2260
- version: 1,
2261
- active: true,
2262
- skill: 'deep-interview',
2263
- keyword: 'deep interview',
2264
- phase: 'planning',
2265
- activated_at: '2026-02-25T00:00:00.000Z',
2266
- updated_at: '2026-02-25T00:00:00.000Z',
2267
- source: 'keyword-detector',
2268
- input_lock: {
2269
- active: true,
2270
- scope: 'deep-interview-auto-approval',
2271
- acquired_at: '2026-02-25T00:00:00.000Z',
2272
- blocked_inputs: DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS,
2273
- message: 'Deep interview is active; auto-approval shortcuts are blocked until the interview finishes.',
2274
- },
2275
- });
2276
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
2277
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2278
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2279
- 'input-messages': ['abort'],
2280
- 'last-assistant-message': 'Stopping interview now.',
2281
- });
2282
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2283
- const skillState = JSON.parse(await readFile(join(sessionStateDir, 'skill-active-state.json'), 'utf-8'));
2284
- assert.equal(skillState.skill, 'deep-interview');
2285
- assert.equal(skillState.active, false);
2286
- assert.equal(skillState.phase, 'completing');
2287
- assert.equal(skillState.input_lock?.active, false);
2288
- assert.ok(skillState.input_lock?.released_at);
2289
- });
2290
- });
2291
- it('uses custom patterns from config', async () => {
2292
- await withTempWorkingDir(async (cwd) => {
2293
- const rcsDir = join(cwd, '.rcs');
2294
- const stateDir = join(rcsDir, 'state');
2295
- const logsDir = join(rcsDir, 'logs');
2296
- const codexHome = join(cwd, 'codex-home');
2297
- const fakeBinDir = join(cwd, 'fake-bin');
2298
- const tmuxLogPath = join(cwd, 'tmux.log');
2299
- await mkdir(logsDir, { recursive: true });
2300
- await mkdir(stateDir, { recursive: true });
2301
- await mkdir(codexHome, { recursive: true });
2302
- await mkdir(fakeBinDir, { recursive: true });
2303
- // Custom patterns that replace defaults
2304
- await writeJson(join(codexHome, '.rcs-config.json'), {
2305
- autoNudge: {
2306
- enabled: true,
2307
- delaySec: 0,
2308
- stallMs: 0,
2309
- patterns: ['awaiting approval'],
2310
- },
2311
- });
2312
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
2313
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2314
- // Default pattern should NOT trigger with custom config
2315
- const result1 = runNotifyHook(cwd, fakeBinDir, codexHome, {
2316
- 'last-assistant-message': 'Keep going and finish the focused cleanup.',
2317
- });
2318
- assert.equal(result1.status, 0);
2319
- if (existsSync(tmuxLogPath)) {
2320
- const log1 = await readFile(tmuxLogPath, 'utf-8');
2321
- assert.doesNotMatch(log1, /send-keys -t %99 -l/, 'default pattern should not match with custom config');
2322
- }
2323
- // Clean tmux log for second run
2324
- if (existsSync(tmuxLogPath)) {
2325
- await writeFile(tmuxLogPath, '');
2326
- }
2327
- // Custom pattern should trigger
2328
- const result2 = runNotifyHook(cwd, fakeBinDir, codexHome, {
2329
- 'last-assistant-message': 'Changes ready. Awaiting approval before applying.',
2330
- });
2331
- assert.equal(result2.status, 0);
2332
- const log2 = await readFile(tmuxLogPath, 'utf-8');
2333
- assert.match(log2, defaultAutoNudgePattern('%99'), 'custom pattern should trigger nudge with marker');
2334
- });
2335
- });
2336
- it('defaults to enabled when no config file exists', async () => {
2337
- await withTempWorkingDir(async (cwd) => {
2338
- const rcsDir = join(cwd, '.rcs');
2339
- const stateDir = join(rcsDir, 'state');
2340
- const logsDir = join(rcsDir, 'logs');
2341
- const codexHome = join(cwd, 'codex-home');
2342
- const fakeBinDir = join(cwd, 'fake-bin');
2343
- const tmuxLogPath = join(cwd, 'tmux.log');
2344
- await mkdir(logsDir, { recursive: true });
2345
- await mkdir(stateDir, { recursive: true });
2346
- await mkdir(codexHome, { recursive: true });
2347
- await mkdir(fakeBinDir, { recursive: true });
2348
- // No .rcs-config.json at all — should use defaults (enabled=true, stallMs=5000)
2349
- await writeJson(join(codexHome, '.rcs-config.json'), {
2350
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2351
- });
2352
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
2353
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2354
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2355
- 'last-assistant-message': 'Keep going and fix the remaining issues.',
2356
- });
2357
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2358
- assert.ok(existsSync(tmuxLogPath), 'tmux should be called with defaults');
2359
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
2360
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'should nudge with default config and marker');
2361
- });
2362
- });
2363
- it('can still resolve the managed session pane when TMUX_PANE is not set', async () => {
2364
- await withTempWorkingDir(async (cwd) => {
2365
- const rcsDir = join(cwd, '.rcs');
2366
- const stateDir = join(rcsDir, 'state');
2367
- const logsDir = join(rcsDir, 'logs');
2368
- const codexHome = join(cwd, 'codex-home');
2369
- const fakeBinDir = join(cwd, 'fake-bin');
2370
- const tmuxLogPath = join(cwd, 'tmux.log');
2371
- const captureFile = join(cwd, 'capture-output.txt');
2372
- await mkdir(logsDir, { recursive: true });
2373
- await mkdir(stateDir, { recursive: true });
2374
- await mkdir(codexHome, { recursive: true });
2375
- await mkdir(fakeBinDir, { recursive: true });
2376
- await writeJson(join(codexHome, '.rcs-config.json'), {
2377
- autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
2378
- });
2379
- await writeFile(captureFile, 'Here are the results.\nKeep going and finish the implementation.\n› ');
2380
- await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
2381
- await chmod(join(fakeBinDir, 'tmux'), 0o755);
2382
- const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
2383
- 'last-assistant-message': 'clean output with no stall',
2384
- }, {
2385
- TMUX_PANE: '', // No pane available
2386
- TMUX: '',
2387
- RCS_TEST_CAPTURE_FILE: captureFile,
2388
- });
2389
- assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
2390
- if (existsSync(tmuxLogPath)) {
2391
- const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
2392
- assert.match(tmuxLog, defaultAutoNudgePattern('%99'), 'should fall back to the managed session pane when TMUX_PANE is absent');
2393
- }
2394
- });
2395
- });
2396
- });
2397
- //# sourceMappingURL=notify-hook-auto-nudge.test.js.map