@jstn-sdk/rcs 0.1.0 → 0.1.6

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 (1739) hide show
  1. package/README.md +154 -101
  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.d.ts.map +1 -1
  20. package/dist/cli/index.js +20 -15
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/cli/setup.d.ts.map +1 -1
  23. package/dist/cli/setup.js +2 -3
  24. package/dist/cli/setup.js.map +1 -1
  25. package/dist/cli/star-prompt.js +2 -2
  26. package/dist/cli/star-prompt.js.map +1 -1
  27. package/dist/cli/state.js +1 -1
  28. package/dist/cli/team.d.ts.map +1 -1
  29. package/dist/cli/team.js +3 -2
  30. package/dist/cli/team.js.map +1 -1
  31. package/dist/cli/tmux-hook.d.ts.map +1 -1
  32. package/dist/cli/tmux-hook.js +9 -1
  33. package/dist/cli/tmux-hook.js.map +1 -1
  34. package/dist/config/generator.d.ts +1 -1
  35. package/dist/config/generator.d.ts.map +1 -1
  36. package/dist/config/generator.js +1 -1
  37. package/dist/config/generator.js.map +1 -1
  38. package/dist/forge/contract.d.ts +17 -0
  39. package/dist/{ralph → forge}/contract.d.ts.map +1 -1
  40. package/dist/{ralph → forge}/contract.js +16 -16
  41. package/dist/{ralph → forge}/contract.js.map +1 -1
  42. package/dist/{ralph → forge}/persistence.d.ts +5 -5
  43. package/dist/{ralph → forge}/persistence.d.ts.map +1 -1
  44. package/dist/{ralph → forge}/persistence.js +7 -6
  45. package/dist/forge/persistence.js.map +1 -0
  46. package/dist/hooks/agents-overlay.d.ts +1 -1
  47. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  48. package/dist/hooks/agents-overlay.js +37 -31
  49. package/dist/hooks/agents-overlay.js.map +1 -1
  50. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  51. package/dist/hooks/extensibility/dispatcher.js +82 -14
  52. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  53. package/dist/hooks/keyword-detector.d.ts +8 -8
  54. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  55. package/dist/hooks/keyword-detector.js +94 -64
  56. package/dist/hooks/keyword-detector.js.map +1 -1
  57. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  58. package/dist/hooks/keyword-registry.js +9 -11
  59. package/dist/hooks/keyword-registry.js.map +1 -1
  60. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  61. package/dist/hooks/prompt-guidance-contract.js +10 -21
  62. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  63. package/dist/hooks/task-size-detector.js +2 -2
  64. package/dist/hooks/task-size-detector.js.map +1 -1
  65. package/dist/hooks/triage-state.d.ts +1 -1
  66. package/dist/hooks/triage-state.js +1 -1
  67. package/dist/hud/colors.d.ts +2 -2
  68. package/dist/hud/colors.js +2 -2
  69. package/dist/hud/render.js +21 -21
  70. package/dist/hud/render.js.map +1 -1
  71. package/dist/hud/state.d.ts +3 -3
  72. package/dist/hud/state.d.ts.map +1 -1
  73. package/dist/hud/state.js +18 -15
  74. package/dist/hud/state.js.map +1 -1
  75. package/dist/hud/types.d.ts +6 -6
  76. package/dist/hud/types.d.ts.map +1 -1
  77. package/dist/mcp/bootstrap.d.ts.map +1 -1
  78. package/dist/mcp/bootstrap.js +36 -2
  79. package/dist/mcp/bootstrap.js.map +1 -1
  80. package/dist/mcp/state-paths.d.ts +1 -0
  81. package/dist/mcp/state-paths.d.ts.map +1 -1
  82. package/dist/mcp/state-paths.js +4 -1
  83. package/dist/mcp/state-paths.js.map +1 -1
  84. package/dist/mcp/state-server.d.ts +4 -4
  85. package/dist/mcp/state-server.js +2 -2
  86. package/dist/mcp/state-server.js.map +1 -1
  87. package/dist/modes/base.d.ts +2 -2
  88. package/dist/modes/base.d.ts.map +1 -1
  89. package/dist/modes/base.js +29 -26
  90. package/dist/modes/base.js.map +1 -1
  91. package/dist/notifications/reply-listener.d.ts.map +1 -1
  92. package/dist/notifications/reply-listener.js +7 -1
  93. package/dist/notifications/reply-listener.js.map +1 -1
  94. package/dist/notifications/tmux.d.ts.map +1 -1
  95. package/dist/notifications/tmux.js +39 -6
  96. package/dist/notifications/tmux.js.map +1 -1
  97. package/dist/pipeline/index.d.ts +7 -6
  98. package/dist/pipeline/index.d.ts.map +1 -1
  99. package/dist/pipeline/index.js +5 -4
  100. package/dist/pipeline/index.js.map +1 -1
  101. package/dist/pipeline/orchestrator.d.ts +5 -5
  102. package/dist/pipeline/orchestrator.js +25 -25
  103. package/dist/pipeline/orchestrator.js.map +1 -1
  104. package/dist/pipeline/stages/blueprint.d.ts +25 -0
  105. package/dist/pipeline/stages/blueprint.d.ts.map +1 -0
  106. package/dist/pipeline/stages/{ralplan.js → blueprint.js} +16 -16
  107. package/dist/pipeline/stages/blueprint.js.map +1 -0
  108. package/dist/pipeline/stages/code-review.d.ts +2 -2
  109. package/dist/pipeline/stages/code-review.js +6 -6
  110. package/dist/pipeline/stages/code-review.js.map +1 -1
  111. package/dist/pipeline/stages/forge-verify.d.ts +50 -0
  112. package/dist/pipeline/stages/forge-verify.d.ts.map +1 -0
  113. package/dist/pipeline/stages/{ralph-verify.js → forge-verify.js} +21 -24
  114. package/dist/pipeline/stages/forge-verify.js.map +1 -0
  115. package/dist/pipeline/stages/team-exec.d.ts +1 -1
  116. package/dist/pipeline/stages/team-exec.js +19 -19
  117. package/dist/pipeline/stages/team-exec.js.map +1 -1
  118. package/dist/pipeline/types.d.ts +12 -12
  119. package/dist/pipeline/types.d.ts.map +1 -1
  120. package/dist/pipeline/types.js +1 -1
  121. package/dist/planning/artifacts.d.ts +3 -4
  122. package/dist/planning/artifacts.d.ts.map +1 -1
  123. package/dist/planning/artifacts.js +2 -3
  124. package/dist/planning/artifacts.js.map +1 -1
  125. package/dist/question/policy.js +1 -1
  126. package/dist/runtime/bridge.d.ts.map +1 -1
  127. package/dist/runtime/bridge.js +70 -13
  128. package/dist/runtime/bridge.js.map +1 -1
  129. package/dist/scripts/codex-native-hook.js +30 -30
  130. package/dist/scripts/codex-native-hook.js.map +1 -1
  131. package/dist/scripts/eval/eval-cross-server-party-flow.d.ts +3 -0
  132. package/dist/scripts/eval/eval-cross-server-party-flow.d.ts.map +1 -0
  133. package/dist/scripts/eval/eval-cross-server-party-flow.js +12 -0
  134. package/dist/scripts/eval/eval-cross-server-party-flow.js.map +1 -0
  135. package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts +3 -0
  136. package/dist/scripts/eval/eval-gui-onboarding-clarity.d.ts.map +1 -0
  137. package/dist/scripts/eval/eval-gui-onboarding-clarity.js +17 -0
  138. package/dist/scripts/eval/eval-gui-onboarding-clarity.js.map +1 -0
  139. package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts +3 -0
  140. package/dist/scripts/eval/eval-liveops-reward-loop-balance.d.ts.map +1 -0
  141. package/dist/scripts/eval/eval-liveops-reward-loop-balance.js +12 -0
  142. package/dist/scripts/eval/eval-liveops-reward-loop-balance.js.map +1 -0
  143. package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts +3 -0
  144. package/dist/scripts/eval/eval-profile-datastore-recovery.d.ts.map +1 -0
  145. package/dist/scripts/eval/eval-profile-datastore-recovery.js +17 -0
  146. package/dist/scripts/eval/eval-profile-datastore-recovery.js.map +1 -0
  147. package/dist/scripts/eval/eval-remote-contract-hardening.d.ts +3 -0
  148. package/dist/scripts/eval/eval-remote-contract-hardening.d.ts.map +1 -0
  149. package/dist/scripts/eval/eval-remote-contract-hardening.js +17 -0
  150. package/dist/scripts/eval/eval-remote-contract-hardening.js.map +1 -0
  151. package/dist/scripts/notify-fallback-watcher.js +140 -139
  152. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  153. package/dist/scripts/notify-hook/forge-session-resume.d.ts +23 -0
  154. package/dist/scripts/notify-hook/{ralph-session-resume.d.ts.map → forge-session-resume.d.ts.map} +1 -1
  155. package/dist/scripts/notify-hook/{ralph-session-resume.js → forge-session-resume.js} +37 -36
  156. package/dist/scripts/notify-hook/{ralph-session-resume.js.map → forge-session-resume.js.map} +1 -1
  157. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  158. package/dist/scripts/notify-hook/team-dispatch.js +34 -4
  159. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  160. package/dist/scripts/notify-hook/visual-verdict.js +3 -3
  161. package/dist/scripts/notify-hook.js +9 -9
  162. package/dist/scripts/run-test-files.js +1 -1
  163. package/dist/scripts/run-test-files.js.map +1 -1
  164. package/dist/scripts/surface-taxonomy.d.ts +23 -0
  165. package/dist/scripts/surface-taxonomy.d.ts.map +1 -0
  166. package/dist/scripts/surface-taxonomy.js +271 -0
  167. package/dist/scripts/surface-taxonomy.js.map +1 -0
  168. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  169. package/dist/scripts/sync-plugin-mirror.js +5 -4
  170. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  171. package/dist/scripts/tmux-hook-engine.d.ts +1 -1
  172. package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
  173. package/dist/scripts/tmux-hook-engine.js +29 -20
  174. package/dist/scripts/tmux-hook-engine.js.map +1 -1
  175. package/dist/state/operations.d.ts +1 -1
  176. package/dist/state/operations.d.ts.map +1 -1
  177. package/dist/state/operations.js +18 -18
  178. package/dist/state/operations.js.map +1 -1
  179. package/dist/state/skill-active.d.ts +13 -1
  180. package/dist/state/skill-active.d.ts.map +1 -1
  181. package/dist/state/skill-active.js +38 -17
  182. package/dist/state/skill-active.js.map +1 -1
  183. package/dist/state/workflow-transition.d.ts +6 -5
  184. package/dist/state/workflow-transition.d.ts.map +1 -1
  185. package/dist/state/workflow-transition.js +27 -15
  186. package/dist/state/workflow-transition.js.map +1 -1
  187. package/dist/team/contracts.d.ts +1 -1
  188. package/dist/team/contracts.js +2 -2
  189. package/dist/team/followup-planner.d.ts +2 -2
  190. package/dist/team/followup-planner.d.ts.map +1 -1
  191. package/dist/team/followup-planner.js +16 -14
  192. package/dist/team/followup-planner.js.map +1 -1
  193. package/dist/team/idle-nudge.d.ts.map +1 -1
  194. package/dist/team/idle-nudge.js +3 -2
  195. package/dist/team/idle-nudge.js.map +1 -1
  196. package/dist/team/leader-activity.js +1 -1
  197. package/dist/team/model-contract.d.ts.map +1 -1
  198. package/dist/team/model-contract.js +4 -1
  199. package/dist/team/model-contract.js.map +1 -1
  200. package/dist/team/orchestrator.js +4 -4
  201. package/dist/team/orchestrator.js.map +1 -1
  202. package/dist/team/role-router.js +3 -3
  203. package/dist/team/role-router.js.map +1 -1
  204. package/dist/team/state/dispatch.d.ts.map +1 -1
  205. package/dist/team/state/dispatch.js +4 -1
  206. package/dist/team/state/dispatch.js.map +1 -1
  207. package/dist/team/tmux-session.d.ts +4 -0
  208. package/dist/team/tmux-session.d.ts.map +1 -1
  209. package/dist/team/tmux-session.js +42 -9
  210. package/dist/team/tmux-session.js.map +1 -1
  211. package/dist/team/worktree.d.ts +1 -1
  212. package/dist/utils/platform-command.d.ts.map +1 -1
  213. package/dist/utils/platform-command.js +9 -0
  214. package/dist/utils/platform-command.js.map +1 -1
  215. package/dist/verification/verifier.d.ts +1 -1
  216. package/dist/verification/verifier.js +2 -2
  217. package/docs/STATE_MODEL.md +24 -24
  218. package/docs/agents.html +8 -16
  219. package/docs/archive/README.md +15 -0
  220. package/docs/{prompt-migration-changelog.md → archive/prompt-migration-changelog.md} +0 -11
  221. package/docs/{release-body-0.9.0.md → archive/release-body-0.9.0.md} +6 -24
  222. package/docs/{release-body-0.9.1.md → archive/release-body-0.9.1.md} +3 -3
  223. package/docs/codex-native-hooks.md +4 -4
  224. package/docs/contracts/forge-cancel-contract.md +20 -0
  225. package/docs/contracts/forge-state-contract.md +52 -0
  226. package/docs/contracts/multi-state-transition-contract.md +5 -5
  227. package/docs/contracts/multi-state-transition-review.md +3 -3
  228. package/docs/contracts/repo-aware-team-dag-decomposition.md +1 -1
  229. package/docs/contracts/rust-runtime-thin-adapter-contract.md +1 -1
  230. package/docs/contracts/team-startup-dispatch-latency.md +1 -1
  231. package/docs/getting-started.html +11 -1
  232. package/docs/guidance-schema.md +6 -3
  233. package/docs/index.html +55 -4
  234. package/docs/integrations.html +4 -3
  235. package/docs/issues/team-forge-followup-team.md +38 -0
  236. package/docs/openclaw-integration.md +2 -2
  237. package/docs/prompt-guidance-contract.md +11 -11
  238. package/docs/prs/{dev-deprecate-team-ralph.md → dev-deprecate-team-forge.md} +27 -27
  239. package/docs/prs/{dev-fix-ralph-live-pane-invariant.md → dev-fix-forge-live-pane-invariant.md} +7 -7
  240. package/docs/prs/{dev-team-ralph-workflow-positioning.md → dev-team-forge-workflow-positioning.md} +7 -7
  241. package/docs/qa/forge-persistence-gate.md +20 -0
  242. package/docs/qa/rust-runtime-thin-adapter-gate.md +31 -40
  243. package/docs/readme/README.de.md +14 -0
  244. package/docs/readme/README.el.md +14 -0
  245. package/docs/readme/README.es.md +14 -0
  246. package/docs/readme/README.fr.md +14 -0
  247. package/docs/readme/README.it.md +14 -0
  248. package/docs/readme/README.ja.md +14 -0
  249. package/docs/readme/README.ko.md +14 -0
  250. package/docs/readme/README.pl.md +14 -0
  251. package/docs/readme/README.pt.md +14 -0
  252. package/docs/readme/README.ru.md +14 -0
  253. package/docs/readme/README.tr.md +14 -0
  254. package/docs/readme/README.uk.md +14 -0
  255. package/docs/readme/README.vi.md +14 -0
  256. package/docs/readme/README.zh-TW.md +14 -0
  257. package/docs/readme/README.zh.md +14 -0
  258. package/docs/readme/rcs-cover.svg +75 -0
  259. package/docs/reference/canonical-vocabulary.md +106 -0
  260. package/docs/reference/forge-parity-matrix.md +26 -0
  261. package/docs/reference/forge-upstream-baseline.md +32 -0
  262. package/docs/reference/rcs-config-schema-routing.md +5 -5
  263. package/docs/reference/roblox-pre-action-protocol.md +4 -0
  264. package/docs/reference/roblox-taxonomy-migration-plan.md +46 -0
  265. package/docs/reference/roblox-workspace-standard.md +83 -0
  266. package/docs/reference/robloxstudio-mcp-compatibility.md +117 -0
  267. package/docs/reference/semantic-design-system.md +110 -0
  268. package/docs/reference/surface-map.md +131 -0
  269. package/docs/reference/team-allocation-rebalance-policy.md +1 -1
  270. package/docs/release-notes-v0.1.0.md +1 -1
  271. package/docs/release-notes-v0.1.1.md +49 -0
  272. package/docs/release-notes-v0.1.6.md +27 -0
  273. package/docs/reports/open-prs-dev-readiness-2026-04-09.md +2 -2
  274. package/docs/shared/agent-tiers.md +3 -3
  275. package/docs/skills.html +10 -12
  276. package/docs/troubleshooting.md +1 -1
  277. package/package.json +20 -13
  278. package/plugins/roblox-ai-os-creator-skills/.codex-plugin/plugin.json +1 -1
  279. package/plugins/roblox-ai-os-creator-skills/docs/reference/roblox-pre-action-protocol.md +4 -0
  280. package/plugins/roblox-ai-os-creator-skills/skills/ai-slop-cleaner/SKILL.md +14 -7
  281. package/plugins/roblox-ai-os-creator-skills/skills/analyze/SKILL.md +9 -2
  282. package/plugins/roblox-ai-os-creator-skills/skills/ask-claude/SKILL.md +7 -0
  283. package/plugins/roblox-ai-os-creator-skills/skills/ask-gemini/SKILL.md +7 -0
  284. package/plugins/roblox-ai-os-creator-skills/skills/autoforge/SKILL.md +7 -0
  285. package/plugins/roblox-ai-os-creator-skills/skills/autopilot/SKILL.md +48 -41
  286. package/plugins/roblox-ai-os-creator-skills/skills/autoresearch/SKILL.md +8 -1
  287. package/plugins/roblox-ai-os-creator-skills/skills/blueprint/SKILL.md +227 -9
  288. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-loop/SKILL.md +7 -0
  289. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-psych/SKILL.md +7 -0
  290. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-retention/SKILL.md +7 -0
  291. package/plugins/roblox-ai-os-creator-skills/skills/blueprint-social/SKILL.md +7 -0
  292. package/plugins/roblox-ai-os-creator-skills/skills/brief/SKILL.md +7 -0
  293. package/plugins/roblox-ai-os-creator-skills/skills/brief-audience/SKILL.md +7 -0
  294. package/plugins/roblox-ai-os-creator-skills/skills/brief-motivation/SKILL.md +7 -0
  295. package/plugins/roblox-ai-os-creator-skills/skills/cancel/SKILL.md +59 -52
  296. package/plugins/roblox-ai-os-creator-skills/skills/code-review/SKILL.md +30 -24
  297. package/plugins/roblox-ai-os-creator-skills/skills/configure-notifications/SKILL.md +7 -0
  298. package/plugins/roblox-ai-os-creator-skills/skills/crew/SKILL.md +7 -0
  299. package/plugins/roblox-ai-os-creator-skills/skills/deep-interview/SKILL.md +25 -18
  300. package/plugins/roblox-ai-os-creator-skills/skills/doctor/SKILL.md +7 -0
  301. package/plugins/roblox-ai-os-creator-skills/skills/forge/SKILL.md +174 -11
  302. package/plugins/roblox-ai-os-creator-skills/skills/forge-community/SKILL.md +7 -0
  303. package/plugins/roblox-ai-os-creator-skills/skills/forge-daily-loop/SKILL.md +7 -0
  304. package/plugins/roblox-ai-os-creator-skills/skills/forge-event-loop/SKILL.md +7 -0
  305. package/plugins/roblox-ai-os-creator-skills/skills/forge-fomo/SKILL.md +7 -0
  306. package/plugins/roblox-ai-os-creator-skills/skills/forge-mastery/SKILL.md +7 -0
  307. package/plugins/roblox-ai-os-creator-skills/skills/forge-progression/SKILL.md +7 -0
  308. package/plugins/roblox-ai-os-creator-skills/skills/forge-reward-loop/SKILL.md +7 -0
  309. package/plugins/roblox-ai-os-creator-skills/skills/forge-status/SKILL.md +7 -0
  310. package/plugins/roblox-ai-os-creator-skills/skills/help/SKILL.md +8 -1
  311. package/plugins/roblox-ai-os-creator-skills/skills/hud/SKILL.md +16 -9
  312. package/plugins/roblox-ai-os-creator-skills/skills/note/SKILL.md +8 -1
  313. package/plugins/roblox-ai-os-creator-skills/skills/pipeline/SKILL.md +18 -11
  314. package/plugins/roblox-ai-os-creator-skills/skills/plan/SKILL.md +36 -29
  315. package/plugins/roblox-ai-os-creator-skills/skills/rcs-setup/SKILL.md +8 -1
  316. package/plugins/roblox-ai-os-creator-skills/skills/security-review/SKILL.md +120 -236
  317. package/plugins/roblox-ai-os-creator-skills/skills/skill/SKILL.md +20 -13
  318. package/plugins/roblox-ai-os-creator-skills/skills/team/SKILL.md +17 -11
  319. package/plugins/roblox-ai-os-creator-skills/skills/trace/SKILL.md +7 -0
  320. package/plugins/roblox-ai-os-creator-skills/skills/ultraqa/SKILL.md +10 -3
  321. package/plugins/roblox-ai-os-creator-skills/skills/ultrawork/SKILL.md +19 -12
  322. package/plugins/roblox-ai-os-creator-skills/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
  323. package/plugins/roblox-ai-os-creator-skills/skills/visual-verdict/SKILL.md +9 -2
  324. package/plugins/roblox-ai-os-creator-skills/skills/wiki/SKILL.md +10 -3
  325. package/plugins/roblox-ai-os-creator-skills/skills/worker/SKILL.md +16 -7
  326. package/plugins/roblox-ai-os-creator-skills/templates/roblox/pre-action-plan.md +1 -0
  327. package/prompts/analyst.md +7 -0
  328. package/prompts/architect.md +11 -4
  329. package/prompts/build-fixer.md +7 -0
  330. package/prompts/code-reviewer.md +9 -2
  331. package/prompts/code-simplifier.md +4 -0
  332. package/prompts/critic.md +13 -6
  333. package/prompts/debugger.md +8 -1
  334. package/prompts/dependency-expert.md +8 -1
  335. package/prompts/designer.md +20 -10
  336. package/prompts/executor.md +7 -0
  337. package/prompts/explore-harness.md +7 -0
  338. package/prompts/explore.md +7 -0
  339. package/prompts/git-master.md +8 -1
  340. package/prompts/planner.md +10 -3
  341. package/prompts/researcher.md +7 -0
  342. package/prompts/security-reviewer.md +76 -92
  343. package/prompts/sisyphus-lite.md +7 -0
  344. package/prompts/team-executor.md +7 -0
  345. package/prompts/team-orchestrator.md +9 -2
  346. package/prompts/test-engineer.md +11 -3
  347. package/prompts/verifier.md +7 -0
  348. package/prompts/vision.md +9 -2
  349. package/prompts/writer.md +11 -4
  350. package/skills/.agents/skills/roblox-animations/SKILL.md +220 -0
  351. package/skills/.agents/skills/roblox-datastores/SKILL.md +219 -0
  352. package/skills/.agents/skills/roblox-gui/SKILL.md +192 -0
  353. package/skills/.agents/skills/roblox-monetization/SKILL.md +208 -0
  354. package/skills/.agents/skills/roblox-performance/SKILL.md +230 -0
  355. package/skills/.agents/skills/roblox-remote-events/SKILL.md +199 -0
  356. package/skills/.agents/skills/roblox-security/SKILL.md +236 -0
  357. package/skills/ai-slop-cleaner/SKILL.md +14 -7
  358. package/skills/analyze/SKILL.md +9 -2
  359. package/skills/ask-claude/SKILL.md +7 -0
  360. package/skills/ask-gemini/SKILL.md +7 -0
  361. package/skills/autoforge/SKILL.md +7 -0
  362. package/skills/autopilot/SKILL.md +48 -41
  363. package/skills/autoresearch/SKILL.md +8 -1
  364. package/skills/blueprint/SKILL.md +227 -9
  365. package/skills/blueprint-loop/SKILL.md +7 -0
  366. package/skills/blueprint-psych/SKILL.md +7 -0
  367. package/skills/blueprint-retention/SKILL.md +7 -0
  368. package/skills/blueprint-social/SKILL.md +7 -0
  369. package/skills/brief/SKILL.md +7 -0
  370. package/skills/brief-audience/SKILL.md +7 -0
  371. package/skills/brief-motivation/SKILL.md +7 -0
  372. package/skills/build-fix/SKILL.md +9 -2
  373. package/skills/cancel/SKILL.md +59 -52
  374. package/skills/code-review/SKILL.md +30 -24
  375. package/skills/configure-notifications/SKILL.md +7 -0
  376. package/skills/crew/SKILL.md +7 -0
  377. package/skills/deep-interview/SKILL.md +25 -18
  378. package/skills/deepsearch/SKILL.md +7 -0
  379. package/skills/doctor/SKILL.md +7 -0
  380. package/skills/ecomode/SKILL.md +9 -2
  381. package/skills/forge/SKILL.md +174 -11
  382. package/skills/forge-community/SKILL.md +7 -0
  383. package/skills/forge-daily-loop/SKILL.md +7 -0
  384. package/skills/forge-event-loop/SKILL.md +7 -0
  385. package/skills/forge-fomo/SKILL.md +7 -0
  386. package/skills/{ralph-init → forge-init}/SKILL.md +20 -13
  387. package/skills/forge-mastery/SKILL.md +7 -0
  388. package/skills/forge-progression/SKILL.md +7 -0
  389. package/skills/forge-reward-loop/SKILL.md +7 -0
  390. package/skills/forge-status/SKILL.md +7 -0
  391. package/skills/git-master/SKILL.md +7 -0
  392. package/skills/help/SKILL.md +8 -1
  393. package/skills/hud/SKILL.md +16 -9
  394. package/skills/note/SKILL.md +8 -1
  395. package/skills/pipeline/SKILL.md +18 -11
  396. package/skills/plan/SKILL.md +36 -29
  397. package/skills/rcs-setup/SKILL.md +8 -1
  398. package/skills/review/SKILL.md +7 -0
  399. package/skills/security-review/SKILL.md +120 -236
  400. package/skills/skill/SKILL.md +20 -13
  401. package/skills/skills-lock.json +47 -0
  402. package/skills/swarm/SKILL.md +8 -1
  403. package/skills/tdd/SKILL.md +7 -0
  404. package/skills/team/SKILL.md +17 -11
  405. package/skills/trace/SKILL.md +7 -0
  406. package/skills/ultraqa/SKILL.md +10 -3
  407. package/skills/ultrawork/SKILL.md +19 -12
  408. package/skills/{visual-ralph → visual-forge}/SKILL.md +36 -27
  409. package/skills/visual-verdict/SKILL.md +9 -2
  410. package/skills/web-clone/SKILL.md +14 -7
  411. package/skills/wiki/SKILL.md +10 -3
  412. package/skills/worker/SKILL.md +16 -7
  413. package/src/scripts/__tests__/codex-native-hook.test.ts +386 -319
  414. package/src/scripts/__tests__/run-test-files.test.ts +6 -4
  415. package/src/scripts/__tests__/verify-native-agents.test.ts +16 -16
  416. package/src/scripts/codex-native-hook.ts +34 -34
  417. package/src/scripts/eval/eval-cross-server-party-flow.ts +14 -0
  418. package/src/scripts/eval/eval-gui-onboarding-clarity.ts +20 -0
  419. package/src/scripts/eval/eval-liveops-reward-loop-balance.ts +14 -0
  420. package/src/scripts/eval/eval-profile-datastore-recovery.ts +20 -0
  421. package/src/scripts/eval/eval-remote-contract-hardening.ts +20 -0
  422. package/src/scripts/notify-fallback-watcher.ts +147 -146
  423. package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +24 -10
  424. package/src/scripts/notify-hook/{ralph-session-resume.ts → forge-session-resume.ts} +45 -43
  425. package/src/scripts/notify-hook/team-dispatch.ts +31 -4
  426. package/src/scripts/notify-hook/visual-verdict.ts +3 -3
  427. package/src/scripts/notify-hook.ts +10 -10
  428. package/src/scripts/run-test-files.ts +1 -1
  429. package/src/scripts/surface-taxonomy.ts +316 -0
  430. package/src/scripts/sync-plugin-mirror.ts +5 -4
  431. package/src/scripts/tmux-hook-engine.ts +31 -19
  432. package/templates/AGENTS.md +24 -15
  433. package/templates/catalog-manifest.json +5 -88
  434. package/templates/roblox/pre-action-plan.md +1 -0
  435. package/templates/roblox/robloxstudio-mcp.codex.json +18 -0
  436. package/templates/roblox/robloxstudio-mcp.windows.json +22 -0
  437. package/dist/adapt/__tests__/foundation.test.d.ts +0 -2
  438. package/dist/adapt/__tests__/foundation.test.d.ts.map +0 -1
  439. package/dist/adapt/__tests__/foundation.test.js +0 -171
  440. package/dist/adapt/__tests__/foundation.test.js.map +0 -1
  441. package/dist/adapt/__tests__/hermes.test.d.ts +0 -2
  442. package/dist/adapt/__tests__/hermes.test.d.ts.map +0 -1
  443. package/dist/adapt/__tests__/hermes.test.js +0 -137
  444. package/dist/adapt/__tests__/hermes.test.js.map +0 -1
  445. package/dist/agents/__tests__/definitions.test.d.ts +0 -2
  446. package/dist/agents/__tests__/definitions.test.d.ts.map +0 -1
  447. package/dist/agents/__tests__/definitions.test.js +0 -62
  448. package/dist/agents/__tests__/definitions.test.js.map +0 -1
  449. package/dist/agents/__tests__/native-config.test.d.ts +0 -2
  450. package/dist/agents/__tests__/native-config.test.d.ts.map +0 -1
  451. package/dist/agents/__tests__/native-config.test.js +0 -278
  452. package/dist/agents/__tests__/native-config.test.js.map +0 -1
  453. package/dist/autoresearch/__tests__/contracts.test.d.ts +0 -2
  454. package/dist/autoresearch/__tests__/contracts.test.d.ts.map +0 -1
  455. package/dist/autoresearch/__tests__/contracts.test.js +0 -127
  456. package/dist/autoresearch/__tests__/contracts.test.js.map +0 -1
  457. package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts +0 -2
  458. package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts.map +0 -1
  459. package/dist/autoresearch/__tests__/runtime-parity-extra.test.js +0 -356
  460. package/dist/autoresearch/__tests__/runtime-parity-extra.test.js.map +0 -1
  461. package/dist/autoresearch/__tests__/runtime.test.d.ts +0 -2
  462. package/dist/autoresearch/__tests__/runtime.test.d.ts.map +0 -1
  463. package/dist/autoresearch/__tests__/runtime.test.js +0 -218
  464. package/dist/autoresearch/__tests__/runtime.test.js.map +0 -1
  465. package/dist/autoresearch/__tests__/skill-validation.test.d.ts +0 -2
  466. package/dist/autoresearch/__tests__/skill-validation.test.d.ts.map +0 -1
  467. package/dist/autoresearch/__tests__/skill-validation.test.js +0 -91
  468. package/dist/autoresearch/__tests__/skill-validation.test.js.map +0 -1
  469. package/dist/catalog/__tests__/generator.test.d.ts +0 -2
  470. package/dist/catalog/__tests__/generator.test.d.ts.map +0 -1
  471. package/dist/catalog/__tests__/generator.test.js +0 -49
  472. package/dist/catalog/__tests__/generator.test.js.map +0 -1
  473. package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts +0 -2
  474. package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts.map +0 -1
  475. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +0 -83
  476. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +0 -1
  477. package/dist/catalog/__tests__/schema.test.d.ts +0 -2
  478. package/dist/catalog/__tests__/schema.test.d.ts.map +0 -1
  479. package/dist/catalog/__tests__/schema.test.js +0 -91
  480. package/dist/catalog/__tests__/schema.test.js.map +0 -1
  481. package/dist/cli/__tests__/adapt-help.test.d.ts +0 -2
  482. package/dist/cli/__tests__/adapt-help.test.d.ts.map +0 -1
  483. package/dist/cli/__tests__/adapt-help.test.js +0 -37
  484. package/dist/cli/__tests__/adapt-help.test.js.map +0 -1
  485. package/dist/cli/__tests__/adapt.test.d.ts +0 -2
  486. package/dist/cli/__tests__/adapt.test.d.ts.map +0 -1
  487. package/dist/cli/__tests__/adapt.test.js +0 -62
  488. package/dist/cli/__tests__/adapt.test.js.map +0 -1
  489. package/dist/cli/__tests__/agents-init.test.d.ts +0 -2
  490. package/dist/cli/__tests__/agents-init.test.d.ts.map +0 -1
  491. package/dist/cli/__tests__/agents-init.test.js +0 -184
  492. package/dist/cli/__tests__/agents-init.test.js.map +0 -1
  493. package/dist/cli/__tests__/agents.test.d.ts +0 -2
  494. package/dist/cli/__tests__/agents.test.d.ts.map +0 -1
  495. package/dist/cli/__tests__/agents.test.js +0 -137
  496. package/dist/cli/__tests__/agents.test.js.map +0 -1
  497. package/dist/cli/__tests__/ask.test.d.ts +0 -2
  498. package/dist/cli/__tests__/ask.test.d.ts.map +0 -1
  499. package/dist/cli/__tests__/ask.test.js +0 -265
  500. package/dist/cli/__tests__/ask.test.js.map +0 -1
  501. package/dist/cli/__tests__/autoresearch-guided.test.d.ts +0 -2
  502. package/dist/cli/__tests__/autoresearch-guided.test.d.ts.map +0 -1
  503. package/dist/cli/__tests__/autoresearch-guided.test.js +0 -365
  504. package/dist/cli/__tests__/autoresearch-guided.test.js.map +0 -1
  505. package/dist/cli/__tests__/autoresearch.test.d.ts +0 -2
  506. package/dist/cli/__tests__/autoresearch.test.d.ts.map +0 -1
  507. package/dist/cli/__tests__/autoresearch.test.js +0 -203
  508. package/dist/cli/__tests__/autoresearch.test.js.map +0 -1
  509. package/dist/cli/__tests__/catalog-contract.test.d.ts +0 -2
  510. package/dist/cli/__tests__/catalog-contract.test.d.ts.map +0 -1
  511. package/dist/cli/__tests__/catalog-contract.test.js +0 -18
  512. package/dist/cli/__tests__/catalog-contract.test.js.map +0 -1
  513. package/dist/cli/__tests__/cleanup.test.d.ts +0 -2
  514. package/dist/cli/__tests__/cleanup.test.d.ts.map +0 -1
  515. package/dist/cli/__tests__/cleanup.test.js +0 -419
  516. package/dist/cli/__tests__/cleanup.test.js.map +0 -1
  517. package/dist/cli/__tests__/codex-plugin-layout.test.d.ts +0 -2
  518. package/dist/cli/__tests__/codex-plugin-layout.test.d.ts.map +0 -1
  519. package/dist/cli/__tests__/codex-plugin-layout.test.js +0 -210
  520. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +0 -1
  521. package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts +0 -2
  522. package/dist/cli/__tests__/doctor-context-window-warning.test.d.ts.map +0 -1
  523. package/dist/cli/__tests__/doctor-context-window-warning.test.js +0 -122
  524. package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +0 -1
  525. package/dist/cli/__tests__/doctor-invalid-config.test.d.ts +0 -2
  526. package/dist/cli/__tests__/doctor-invalid-config.test.d.ts.map +0 -1
  527. package/dist/cli/__tests__/doctor-invalid-config.test.js +0 -52
  528. package/dist/cli/__tests__/doctor-invalid-config.test.js.map +0 -1
  529. package/dist/cli/__tests__/doctor-team.test.d.ts +0 -2
  530. package/dist/cli/__tests__/doctor-team.test.d.ts.map +0 -1
  531. package/dist/cli/__tests__/doctor-team.test.js +0 -299
  532. package/dist/cli/__tests__/doctor-team.test.js.map +0 -1
  533. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts +0 -2
  534. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts.map +0 -1
  535. package/dist/cli/__tests__/doctor-warning-copy.test.js +0 -438
  536. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +0 -1
  537. package/dist/cli/__tests__/error-handling-warnings.test.d.ts +0 -2
  538. package/dist/cli/__tests__/error-handling-warnings.test.d.ts.map +0 -1
  539. package/dist/cli/__tests__/error-handling-warnings.test.js +0 -52
  540. package/dist/cli/__tests__/error-handling-warnings.test.js.map +0 -1
  541. package/dist/cli/__tests__/exec.test.d.ts +0 -2
  542. package/dist/cli/__tests__/exec.test.d.ts.map +0 -1
  543. package/dist/cli/__tests__/exec.test.js +0 -213
  544. package/dist/cli/__tests__/exec.test.js.map +0 -1
  545. package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts +0 -2
  546. package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts.map +0 -1
  547. package/dist/cli/__tests__/explore-windows-diagnostics.test.js +0 -17
  548. package/dist/cli/__tests__/explore-windows-diagnostics.test.js.map +0 -1
  549. package/dist/cli/__tests__/explore.test.d.ts +0 -2
  550. package/dist/cli/__tests__/explore.test.d.ts.map +0 -1
  551. package/dist/cli/__tests__/explore.test.js +0 -1090
  552. package/dist/cli/__tests__/explore.test.js.map +0 -1
  553. package/dist/cli/__tests__/hooks.test.d.ts +0 -2
  554. package/dist/cli/__tests__/hooks.test.d.ts.map +0 -1
  555. package/dist/cli/__tests__/hooks.test.js +0 -55
  556. package/dist/cli/__tests__/hooks.test.js.map +0 -1
  557. package/dist/cli/__tests__/index.test.d.ts +0 -2
  558. package/dist/cli/__tests__/index.test.d.ts.map +0 -1
  559. package/dist/cli/__tests__/index.test.js +0 -2259
  560. package/dist/cli/__tests__/index.test.js.map +0 -1
  561. package/dist/cli/__tests__/launch-fallback.test.d.ts +0 -2
  562. package/dist/cli/__tests__/launch-fallback.test.d.ts.map +0 -1
  563. package/dist/cli/__tests__/launch-fallback.test.js +0 -661
  564. package/dist/cli/__tests__/launch-fallback.test.js.map +0 -1
  565. package/dist/cli/__tests__/lifecycle-notifications.test.d.ts +0 -2
  566. package/dist/cli/__tests__/lifecycle-notifications.test.d.ts.map +0 -1
  567. package/dist/cli/__tests__/lifecycle-notifications.test.js +0 -48
  568. package/dist/cli/__tests__/lifecycle-notifications.test.js.map +0 -1
  569. package/dist/cli/__tests__/list.test.d.ts +0 -2
  570. package/dist/cli/__tests__/list.test.d.ts.map +0 -1
  571. package/dist/cli/__tests__/list.test.js +0 -38
  572. package/dist/cli/__tests__/list.test.js.map +0 -1
  573. package/dist/cli/__tests__/mcp-parity.test.d.ts +0 -2
  574. package/dist/cli/__tests__/mcp-parity.test.d.ts.map +0 -1
  575. package/dist/cli/__tests__/mcp-parity.test.js +0 -228
  576. package/dist/cli/__tests__/mcp-parity.test.js.map +0 -1
  577. package/dist/cli/__tests__/mcp-serve.test.d.ts +0 -2
  578. package/dist/cli/__tests__/mcp-serve.test.d.ts.map +0 -1
  579. package/dist/cli/__tests__/mcp-serve.test.js +0 -64
  580. package/dist/cli/__tests__/mcp-serve.test.js.map +0 -1
  581. package/dist/cli/__tests__/native-assets.test.d.ts +0 -2
  582. package/dist/cli/__tests__/native-assets.test.d.ts.map +0 -1
  583. package/dist/cli/__tests__/native-assets.test.js +0 -308
  584. package/dist/cli/__tests__/native-assets.test.js.map +0 -1
  585. package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts +0 -2
  586. package/dist/cli/__tests__/native-hook-dispatch-contract.test.d.ts.map +0 -1
  587. package/dist/cli/__tests__/native-hook-dispatch-contract.test.js +0 -11
  588. package/dist/cli/__tests__/native-hook-dispatch-contract.test.js.map +0 -1
  589. package/dist/cli/__tests__/nested-help-routing.test.d.ts +0 -2
  590. package/dist/cli/__tests__/nested-help-routing.test.d.ts.map +0 -1
  591. package/dist/cli/__tests__/nested-help-routing.test.js +0 -96
  592. package/dist/cli/__tests__/nested-help-routing.test.js.map +0 -1
  593. package/dist/cli/__tests__/package-bin-contract.test.d.ts +0 -2
  594. package/dist/cli/__tests__/package-bin-contract.test.d.ts.map +0 -1
  595. package/dist/cli/__tests__/package-bin-contract.test.js +0 -177
  596. package/dist/cli/__tests__/package-bin-contract.test.js.map +0 -1
  597. package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts +0 -3
  598. package/dist/cli/__tests__/packaged-explore-harness-lock.d.ts.map +0 -1
  599. package/dist/cli/__tests__/packaged-explore-harness-lock.js +0 -67
  600. package/dist/cli/__tests__/packaged-explore-harness-lock.js.map +0 -1
  601. package/dist/cli/__tests__/packaged-script-resolution.test.d.ts +0 -2
  602. package/dist/cli/__tests__/packaged-script-resolution.test.d.ts.map +0 -1
  603. package/dist/cli/__tests__/packaged-script-resolution.test.js +0 -19
  604. package/dist/cli/__tests__/packaged-script-resolution.test.js.map +0 -1
  605. package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts +0 -2
  606. package/dist/cli/__tests__/prompt-skill-sanitization.test.d.ts.map +0 -1
  607. package/dist/cli/__tests__/prompt-skill-sanitization.test.js +0 -48
  608. package/dist/cli/__tests__/prompt-skill-sanitization.test.js.map +0 -1
  609. package/dist/cli/__tests__/question.test.d.ts +0 -2
  610. package/dist/cli/__tests__/question.test.d.ts.map +0 -1
  611. package/dist/cli/__tests__/question.test.js +0 -633
  612. package/dist/cli/__tests__/question.test.js.map +0 -1
  613. package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts +0 -2
  614. package/dist/cli/__tests__/ralph-deslop-contract.test.d.ts.map +0 -1
  615. package/dist/cli/__tests__/ralph-deslop-contract.test.js +0 -28
  616. package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +0 -1
  617. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts +0 -2
  618. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts.map +0 -1
  619. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +0 -24
  620. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +0 -1
  621. package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts +0 -2
  622. package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts.map +0 -1
  623. package/dist/cli/__tests__/ralph-prd-smoke.test.js +0 -167
  624. package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +0 -1
  625. package/dist/cli/__tests__/ralph.test.d.ts +0 -2
  626. package/dist/cli/__tests__/ralph.test.d.ts.map +0 -1
  627. package/dist/cli/__tests__/ralph.test.js +0 -256
  628. package/dist/cli/__tests__/ralph.test.js.map +0 -1
  629. package/dist/cli/__tests__/resume.test.d.ts +0 -2
  630. package/dist/cli/__tests__/resume.test.d.ts.map +0 -1
  631. package/dist/cli/__tests__/resume.test.js +0 -84
  632. package/dist/cli/__tests__/resume.test.js.map +0 -1
  633. package/dist/cli/__tests__/session-scoped-runtime.test.d.ts +0 -2
  634. package/dist/cli/__tests__/session-scoped-runtime.test.d.ts.map +0 -1
  635. package/dist/cli/__tests__/session-scoped-runtime.test.js +0 -146
  636. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +0 -1
  637. package/dist/cli/__tests__/session-search-help.test.d.ts +0 -2
  638. package/dist/cli/__tests__/session-search-help.test.d.ts.map +0 -1
  639. package/dist/cli/__tests__/session-search-help.test.js +0 -76
  640. package/dist/cli/__tests__/session-search-help.test.js.map +0 -1
  641. package/dist/cli/__tests__/session-search.test.d.ts +0 -2
  642. package/dist/cli/__tests__/session-search.test.d.ts.map +0 -1
  643. package/dist/cli/__tests__/session-search.test.js +0 -77
  644. package/dist/cli/__tests__/session-search.test.js.map +0 -1
  645. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts +0 -2
  646. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts.map +0 -1
  647. package/dist/cli/__tests__/setup-agents-overwrite.test.js +0 -457
  648. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +0 -1
  649. package/dist/cli/__tests__/setup-gh-star.test.d.ts +0 -2
  650. package/dist/cli/__tests__/setup-gh-star.test.d.ts.map +0 -1
  651. package/dist/cli/__tests__/setup-gh-star.test.js +0 -67
  652. package/dist/cli/__tests__/setup-gh-star.test.js.map +0 -1
  653. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts +0 -2
  654. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.d.ts.map +0 -1
  655. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +0 -189
  656. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +0 -1
  657. package/dist/cli/__tests__/setup-install-mode.test.d.ts +0 -2
  658. package/dist/cli/__tests__/setup-install-mode.test.d.ts.map +0 -1
  659. package/dist/cli/__tests__/setup-install-mode.test.js +0 -873
  660. package/dist/cli/__tests__/setup-install-mode.test.js.map +0 -1
  661. package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts +0 -2
  662. package/dist/cli/__tests__/setup-prompts-overwrite.test.d.ts.map +0 -1
  663. package/dist/cli/__tests__/setup-prompts-overwrite.test.js +0 -191
  664. package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +0 -1
  665. package/dist/cli/__tests__/setup-refresh.test.d.ts +0 -2
  666. package/dist/cli/__tests__/setup-refresh.test.d.ts.map +0 -1
  667. package/dist/cli/__tests__/setup-refresh.test.js +0 -591
  668. package/dist/cli/__tests__/setup-refresh.test.js.map +0 -1
  669. package/dist/cli/__tests__/setup-scope.test.d.ts +0 -2
  670. package/dist/cli/__tests__/setup-scope.test.d.ts.map +0 -1
  671. package/dist/cli/__tests__/setup-scope.test.js +0 -340
  672. package/dist/cli/__tests__/setup-scope.test.js.map +0 -1
  673. package/dist/cli/__tests__/setup-skill-validation.test.d.ts +0 -2
  674. package/dist/cli/__tests__/setup-skill-validation.test.d.ts.map +0 -1
  675. package/dist/cli/__tests__/setup-skill-validation.test.js +0 -44
  676. package/dist/cli/__tests__/setup-skill-validation.test.js.map +0 -1
  677. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts +0 -2
  678. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts.map +0 -1
  679. package/dist/cli/__tests__/setup-skills-overwrite.test.js +0 -295
  680. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +0 -1
  681. package/dist/cli/__tests__/sidecar.test.d.ts +0 -2
  682. package/dist/cli/__tests__/sidecar.test.d.ts.map +0 -1
  683. package/dist/cli/__tests__/sidecar.test.js +0 -24
  684. package/dist/cli/__tests__/sidecar.test.js.map +0 -1
  685. package/dist/cli/__tests__/sparkshell-cli.test.d.ts +0 -2
  686. package/dist/cli/__tests__/sparkshell-cli.test.d.ts.map +0 -1
  687. package/dist/cli/__tests__/sparkshell-cli.test.js +0 -400
  688. package/dist/cli/__tests__/sparkshell-cli.test.js.map +0 -1
  689. package/dist/cli/__tests__/sparkshell-packaging.test.d.ts +0 -2
  690. package/dist/cli/__tests__/sparkshell-packaging.test.d.ts.map +0 -1
  691. package/dist/cli/__tests__/sparkshell-packaging.test.js +0 -74
  692. package/dist/cli/__tests__/sparkshell-packaging.test.js.map +0 -1
  693. package/dist/cli/__tests__/star-prompt.test.d.ts +0 -2
  694. package/dist/cli/__tests__/star-prompt.test.d.ts.map +0 -1
  695. package/dist/cli/__tests__/star-prompt.test.js +0 -172
  696. package/dist/cli/__tests__/star-prompt.test.js.map +0 -1
  697. package/dist/cli/__tests__/state.test.d.ts +0 -2
  698. package/dist/cli/__tests__/state.test.d.ts.map +0 -1
  699. package/dist/cli/__tests__/state.test.js +0 -46
  700. package/dist/cli/__tests__/state.test.js.map +0 -1
  701. package/dist/cli/__tests__/team-decompose.test.d.ts +0 -2
  702. package/dist/cli/__tests__/team-decompose.test.d.ts.map +0 -1
  703. package/dist/cli/__tests__/team-decompose.test.js +0 -133
  704. package/dist/cli/__tests__/team-decompose.test.js.map +0 -1
  705. package/dist/cli/__tests__/team.test.d.ts +0 -2
  706. package/dist/cli/__tests__/team.test.d.ts.map +0 -1
  707. package/dist/cli/__tests__/team.test.js +0 -1820
  708. package/dist/cli/__tests__/team.test.js.map +0 -1
  709. package/dist/cli/__tests__/uninstall.test.d.ts +0 -2
  710. package/dist/cli/__tests__/uninstall.test.d.ts.map +0 -1
  711. package/dist/cli/__tests__/uninstall.test.js +0 -766
  712. package/dist/cli/__tests__/uninstall.test.js.map +0 -1
  713. package/dist/cli/__tests__/update.test.d.ts +0 -2
  714. package/dist/cli/__tests__/update.test.d.ts.map +0 -1
  715. package/dist/cli/__tests__/update.test.js +0 -589
  716. package/dist/cli/__tests__/update.test.js.map +0 -1
  717. package/dist/cli/__tests__/version-sync-contract.test.d.ts +0 -2
  718. package/dist/cli/__tests__/version-sync-contract.test.d.ts.map +0 -1
  719. package/dist/cli/__tests__/version-sync-contract.test.js +0 -41
  720. package/dist/cli/__tests__/version-sync-contract.test.js.map +0 -1
  721. package/dist/cli/__tests__/version.test.d.ts +0 -2
  722. package/dist/cli/__tests__/version.test.d.ts.map +0 -1
  723. package/dist/cli/__tests__/version.test.js +0 -21
  724. package/dist/cli/__tests__/version.test.js.map +0 -1
  725. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +0 -2
  726. package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +0 -1
  727. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +0 -31
  728. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +0 -1
  729. package/dist/cli/ralph.d.ts +0 -17
  730. package/dist/compat/__tests__/doctor-contract.test.d.ts +0 -2
  731. package/dist/compat/__tests__/doctor-contract.test.d.ts.map +0 -1
  732. package/dist/compat/__tests__/doctor-contract.test.js +0 -108
  733. package/dist/compat/__tests__/doctor-contract.test.js.map +0 -1
  734. package/dist/compat/__tests__/rust-runtime-compat.test.d.ts +0 -2
  735. package/dist/compat/__tests__/rust-runtime-compat.test.d.ts.map +0 -1
  736. package/dist/compat/__tests__/rust-runtime-compat.test.js +0 -218
  737. package/dist/compat/__tests__/rust-runtime-compat.test.js.map +0 -1
  738. package/dist/config/__tests__/codex-hooks.test.d.ts +0 -2
  739. package/dist/config/__tests__/codex-hooks.test.d.ts.map +0 -1
  740. package/dist/config/__tests__/codex-hooks.test.js +0 -77
  741. package/dist/config/__tests__/codex-hooks.test.js.map +0 -1
  742. package/dist/config/__tests__/generator-idempotent.test.d.ts +0 -2
  743. package/dist/config/__tests__/generator-idempotent.test.d.ts.map +0 -1
  744. package/dist/config/__tests__/generator-idempotent.test.js +0 -882
  745. package/dist/config/__tests__/generator-idempotent.test.js.map +0 -1
  746. package/dist/config/__tests__/generator-notify.test.d.ts +0 -2
  747. package/dist/config/__tests__/generator-notify.test.d.ts.map +0 -1
  748. package/dist/config/__tests__/generator-notify.test.js +0 -343
  749. package/dist/config/__tests__/generator-notify.test.js.map +0 -1
  750. package/dist/config/__tests__/generator-status-line-presets.test.d.ts +0 -2
  751. package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +0 -1
  752. package/dist/config/__tests__/generator-status-line-presets.test.js +0 -203
  753. package/dist/config/__tests__/generator-status-line-presets.test.js.map +0 -1
  754. package/dist/config/__tests__/mcp-registry.test.d.ts +0 -2
  755. package/dist/config/__tests__/mcp-registry.test.d.ts.map +0 -1
  756. package/dist/config/__tests__/mcp-registry.test.js +0 -190
  757. package/dist/config/__tests__/mcp-registry.test.js.map +0 -1
  758. package/dist/config/__tests__/models.test.d.ts +0 -2
  759. package/dist/config/__tests__/models.test.d.ts.map +0 -1
  760. package/dist/config/__tests__/models.test.js +0 -224
  761. package/dist/config/__tests__/models.test.js.map +0 -1
  762. package/dist/config/__tests__/wiki-config-contract.test.d.ts +0 -2
  763. package/dist/config/__tests__/wiki-config-contract.test.d.ts.map +0 -1
  764. package/dist/config/__tests__/wiki-config-contract.test.js +0 -19
  765. package/dist/config/__tests__/wiki-config-contract.test.js.map +0 -1
  766. package/dist/document-refresh/__tests__/enforcer.test.d.ts +0 -2
  767. package/dist/document-refresh/__tests__/enforcer.test.d.ts.map +0 -1
  768. package/dist/document-refresh/__tests__/enforcer.test.js +0 -128
  769. package/dist/document-refresh/__tests__/enforcer.test.js.map +0 -1
  770. package/dist/hooks/__tests__/agents-overlay.test.d.ts +0 -8
  771. package/dist/hooks/__tests__/agents-overlay.test.d.ts.map +0 -1
  772. package/dist/hooks/__tests__/agents-overlay.test.js +0 -644
  773. package/dist/hooks/__tests__/agents-overlay.test.js.map +0 -1
  774. package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts +0 -2
  775. package/dist/hooks/__tests__/analyze-routing-contract.test.d.ts.map +0 -1
  776. package/dist/hooks/__tests__/analyze-routing-contract.test.js +0 -45
  777. package/dist/hooks/__tests__/analyze-routing-contract.test.js.map +0 -1
  778. package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts +0 -2
  779. package/dist/hooks/__tests__/analyze-skill-contract.test.d.ts.map +0 -1
  780. package/dist/hooks/__tests__/analyze-skill-contract.test.js +0 -48
  781. package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +0 -1
  782. package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts +0 -2
  783. package/dist/hooks/__tests__/anti-slop-workflow.test.d.ts.map +0 -1
  784. package/dist/hooks/__tests__/anti-slop-workflow.test.js +0 -146
  785. package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +0 -1
  786. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts +0 -2
  787. package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts.map +0 -1
  788. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +0 -37
  789. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +0 -1
  790. package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts +0 -2
  791. package/dist/hooks/__tests__/clawhip-event-contract.test.d.ts.map +0 -1
  792. package/dist/hooks/__tests__/clawhip-event-contract.test.js +0 -37
  793. package/dist/hooks/__tests__/clawhip-event-contract.test.js.map +0 -1
  794. package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts +0 -2
  795. package/dist/hooks/__tests__/code-review-skill-contract.test.d.ts.map +0 -1
  796. package/dist/hooks/__tests__/code-review-skill-contract.test.js +0 -56
  797. package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +0 -1
  798. package/dist/hooks/__tests__/codebase-map.test.d.ts +0 -8
  799. package/dist/hooks/__tests__/codebase-map.test.d.ts.map +0 -1
  800. package/dist/hooks/__tests__/codebase-map.test.js +0 -218
  801. package/dist/hooks/__tests__/codebase-map.test.js.map +0 -1
  802. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +0 -18
  803. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +0 -1
  804. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +0 -234
  805. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +0 -1
  806. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +0 -2
  807. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +0 -1
  808. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +0 -20
  809. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +0 -1
  810. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts +0 -2
  811. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts.map +0 -1
  812. package/dist/hooks/__tests__/deep-interview-contract.test.js +0 -213
  813. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +0 -1
  814. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts +0 -2
  815. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.d.ts.map +0 -1
  816. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js +0 -43
  817. package/dist/hooks/__tests__/explicit-terminal-stop-docs-contract.test.js.map +0 -1
  818. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts +0 -2
  819. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.d.ts.map +0 -1
  820. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js +0 -38
  821. package/dist/hooks/__tests__/explicit-terminal-stop-model-docs-contract.test.js.map +0 -1
  822. package/dist/hooks/__tests__/explore-routing.test.d.ts +0 -2
  823. package/dist/hooks/__tests__/explore-routing.test.d.ts.map +0 -1
  824. package/dist/hooks/__tests__/explore-routing.test.js +0 -43
  825. package/dist/hooks/__tests__/explore-routing.test.js.map +0 -1
  826. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts +0 -2
  827. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.d.ts.map +0 -1
  828. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +0 -69
  829. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +0 -1
  830. package/dist/hooks/__tests__/keyword-detector.test.d.ts +0 -2
  831. package/dist/hooks/__tests__/keyword-detector.test.d.ts.map +0 -1
  832. package/dist/hooks/__tests__/keyword-detector.test.js +0 -1716
  833. package/dist/hooks/__tests__/keyword-detector.test.js.map +0 -1
  834. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts +0 -2
  835. package/dist/hooks/__tests__/notify-fallback-watcher.test.d.ts.map +0 -1
  836. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +0 -3898
  837. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +0 -1
  838. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts +0 -2
  839. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.d.ts.map +0 -1
  840. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +0 -786
  841. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +0 -1
  842. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts +0 -2
  843. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.d.ts.map +0 -1
  844. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +0 -2397
  845. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +0 -1
  846. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts +0 -2
  847. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.d.ts.map +0 -1
  848. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +0 -160
  849. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +0 -1
  850. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +0 -2
  851. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +0 -1
  852. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +0 -1178
  853. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +0 -1
  854. package/dist/hooks/__tests__/notify-hook-modules.test.d.ts +0 -9
  855. package/dist/hooks/__tests__/notify-hook-modules.test.d.ts.map +0 -1
  856. package/dist/hooks/__tests__/notify-hook-modules.test.js +0 -529
  857. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +0 -1
  858. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts +0 -2
  859. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.d.ts.map +0 -1
  860. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js +0 -14
  861. package/dist/hooks/__tests__/notify-hook-native-dispatch-contract.test.js.map +0 -1
  862. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +0 -2
  863. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +0 -1
  864. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +0 -682
  865. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +0 -1
  866. package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts +0 -9
  867. package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts.map +0 -1
  868. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +0 -255
  869. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +0 -1
  870. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +0 -2
  871. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +0 -1
  872. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +0 -162
  873. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +0 -1
  874. package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts +0 -2
  875. package/dist/hooks/__tests__/notify-hook-session-scope.test.d.ts.map +0 -1
  876. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +0 -301
  877. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +0 -1
  878. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts +0 -2
  879. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.d.ts.map +0 -1
  880. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +0 -1510
  881. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +0 -1
  882. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts +0 -2
  883. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.d.ts.map +0 -1
  884. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +0 -2879
  885. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +0 -1
  886. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts +0 -2
  887. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.d.ts.map +0 -1
  888. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +0 -228
  889. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +0 -1
  890. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts +0 -2
  891. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +0 -1
  892. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +0 -35
  893. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +0 -1
  894. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts +0 -2
  895. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.d.ts.map +0 -1
  896. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +0 -1589
  897. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +0 -1
  898. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts +0 -10
  899. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.d.ts.map +0 -1
  900. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
  901. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +0 -1
  902. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts +0 -11
  903. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts.map +0 -1
  904. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js +0 -266
  905. package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +0 -1
  906. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts +0 -2
  907. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts.map +0 -1
  908. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +0 -895
  909. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +0 -1
  910. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts +0 -2
  911. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts.map +0 -1
  912. package/dist/hooks/__tests__/openclaw-setup-contract.test.js +0 -61
  913. package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +0 -1
  914. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts +0 -2
  915. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts.map +0 -1
  916. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +0 -40
  917. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +0 -1
  918. package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts +0 -2
  919. package/dist/hooks/__tests__/prompt-guidance-catalog.test.d.ts.map +0 -1
  920. package/dist/hooks/__tests__/prompt-guidance-catalog.test.js +0 -11
  921. package/dist/hooks/__tests__/prompt-guidance-catalog.test.js.map +0 -1
  922. package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts +0 -2
  923. package/dist/hooks/__tests__/prompt-guidance-contract.test.d.ts.map +0 -1
  924. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +0 -38
  925. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +0 -1
  926. package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts +0 -2
  927. package/dist/hooks/__tests__/prompt-guidance-fragments.test.d.ts.map +0 -1
  928. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +0 -48
  929. package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +0 -1
  930. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts +0 -2
  931. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.d.ts.map +0 -1
  932. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js +0 -11
  933. package/dist/hooks/__tests__/prompt-guidance-scenarios.test.js.map +0 -1
  934. package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts +0 -5
  935. package/dist/hooks/__tests__/prompt-guidance-test-helpers.d.ts.map +0 -1
  936. package/dist/hooks/__tests__/prompt-guidance-test-helpers.js +0 -34
  937. package/dist/hooks/__tests__/prompt-guidance-test-helpers.js.map +0 -1
  938. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts +0 -2
  939. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.d.ts.map +0 -1
  940. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +0 -65
  941. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +0 -1
  942. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts +0 -2
  943. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.d.ts.map +0 -1
  944. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js +0 -38
  945. package/dist/hooks/__tests__/prompt-orchestration-boundary.test.js.map +0 -1
  946. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +0 -2
  947. package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +0 -1
  948. package/dist/hooks/__tests__/prompt-refactor-contract.test.js +0 -22
  949. package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +0 -1
  950. package/dist/hooks/__tests__/prompt-team-routing.test.d.ts +0 -2
  951. package/dist/hooks/__tests__/prompt-team-routing.test.d.ts.map +0 -1
  952. package/dist/hooks/__tests__/prompt-team-routing.test.js +0 -49
  953. package/dist/hooks/__tests__/prompt-team-routing.test.js.map +0 -1
  954. package/dist/hooks/__tests__/session.test.d.ts +0 -2
  955. package/dist/hooks/__tests__/session.test.d.ts.map +0 -1
  956. package/dist/hooks/__tests__/session.test.js +0 -322
  957. package/dist/hooks/__tests__/session.test.js.map +0 -1
  958. package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts +0 -2
  959. package/dist/hooks/__tests__/skill-guidance-contract.test.d.ts.map +0 -1
  960. package/dist/hooks/__tests__/skill-guidance-contract.test.js +0 -29
  961. package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +0 -1
  962. package/dist/hooks/__tests__/task-size-detector.test.d.ts +0 -2
  963. package/dist/hooks/__tests__/task-size-detector.test.d.ts.map +0 -1
  964. package/dist/hooks/__tests__/task-size-detector.test.js +0 -330
  965. package/dist/hooks/__tests__/task-size-detector.test.js.map +0 -1
  966. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts +0 -2
  967. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts.map +0 -1
  968. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +0 -28
  969. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +0 -1
  970. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts +0 -2
  971. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts.map +0 -1
  972. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js +0 -24
  973. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js.map +0 -1
  974. package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts +0 -2
  975. package/dist/hooks/__tests__/tmux-hook-engine.test.d.ts.map +0 -1
  976. package/dist/hooks/__tests__/tmux-hook-engine.test.js +0 -403
  977. package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +0 -1
  978. package/dist/hooks/__tests__/triage-config.test.d.ts +0 -2
  979. package/dist/hooks/__tests__/triage-config.test.d.ts.map +0 -1
  980. package/dist/hooks/__tests__/triage-config.test.js +0 -211
  981. package/dist/hooks/__tests__/triage-config.test.js.map +0 -1
  982. package/dist/hooks/__tests__/triage-heuristic.test.d.ts +0 -2
  983. package/dist/hooks/__tests__/triage-heuristic.test.d.ts.map +0 -1
  984. package/dist/hooks/__tests__/triage-heuristic.test.js +0 -285
  985. package/dist/hooks/__tests__/triage-heuristic.test.js.map +0 -1
  986. package/dist/hooks/__tests__/triage-state.test.d.ts +0 -2
  987. package/dist/hooks/__tests__/triage-state.test.d.ts.map +0 -1
  988. package/dist/hooks/__tests__/triage-state.test.js +0 -426
  989. package/dist/hooks/__tests__/triage-state.test.js.map +0 -1
  990. package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts +0 -2
  991. package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts.map +0 -1
  992. package/dist/hooks/__tests__/visual-ralph-skill.test.js +0 -44
  993. package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +0 -1
  994. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts +0 -2
  995. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts.map +0 -1
  996. package/dist/hooks/__tests__/visual-verdict-loop.test.js +0 -35
  997. package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +0 -1
  998. package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts +0 -2
  999. package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts.map +0 -1
  1000. package/dist/hooks/__tests__/wiki-docs-contract.test.js +0 -34
  1001. package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +0 -1
  1002. package/dist/hooks/code-simplifier/__tests__/index.test.d.ts +0 -2
  1003. package/dist/hooks/code-simplifier/__tests__/index.test.d.ts.map +0 -1
  1004. package/dist/hooks/code-simplifier/__tests__/index.test.js +0 -187
  1005. package/dist/hooks/code-simplifier/__tests__/index.test.js.map +0 -1
  1006. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts +0 -2
  1007. package/dist/hooks/extensibility/__tests__/dispatcher.test.d.ts.map +0 -1
  1008. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +0 -242
  1009. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +0 -1
  1010. package/dist/hooks/extensibility/__tests__/events.test.d.ts +0 -2
  1011. package/dist/hooks/extensibility/__tests__/events.test.d.ts.map +0 -1
  1012. package/dist/hooks/extensibility/__tests__/events.test.js +0 -125
  1013. package/dist/hooks/extensibility/__tests__/events.test.js.map +0 -1
  1014. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts +0 -2
  1015. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.d.ts.map +0 -1
  1016. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js +0 -153
  1017. package/dist/hooks/extensibility/__tests__/example-hook-plugins.test.js.map +0 -1
  1018. package/dist/hooks/extensibility/__tests__/loader.test.d.ts +0 -2
  1019. package/dist/hooks/extensibility/__tests__/loader.test.d.ts.map +0 -1
  1020. package/dist/hooks/extensibility/__tests__/loader.test.js +0 -254
  1021. package/dist/hooks/extensibility/__tests__/loader.test.js.map +0 -1
  1022. package/dist/hooks/extensibility/__tests__/logging.test.d.ts +0 -2
  1023. package/dist/hooks/extensibility/__tests__/logging.test.d.ts.map +0 -1
  1024. package/dist/hooks/extensibility/__tests__/logging.test.js +0 -74
  1025. package/dist/hooks/extensibility/__tests__/logging.test.js.map +0 -1
  1026. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts +0 -2
  1027. package/dist/hooks/extensibility/__tests__/plugin-runner.test.d.ts.map +0 -1
  1028. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +0 -202
  1029. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +0 -1
  1030. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts +0 -2
  1031. package/dist/hooks/extensibility/__tests__/runtime.test.d.ts.map +0 -1
  1032. package/dist/hooks/extensibility/__tests__/runtime.test.js +0 -198
  1033. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +0 -1
  1034. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts +0 -2
  1035. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.d.ts.map +0 -1
  1036. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js +0 -32
  1037. package/dist/hooks/extensibility/__tests__/sdk-public-surface.test.js.map +0 -1
  1038. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts +0 -2
  1039. package/dist/hooks/extensibility/__tests__/sdk.test.d.ts.map +0 -1
  1040. package/dist/hooks/extensibility/__tests__/sdk.test.js +0 -479
  1041. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +0 -1
  1042. package/dist/hud/__tests__/authority.test.d.ts +0 -2
  1043. package/dist/hud/__tests__/authority.test.d.ts.map +0 -1
  1044. package/dist/hud/__tests__/authority.test.js +0 -56
  1045. package/dist/hud/__tests__/authority.test.js.map +0 -1
  1046. package/dist/hud/__tests__/colors.test.d.ts +0 -2
  1047. package/dist/hud/__tests__/colors.test.d.ts.map +0 -1
  1048. package/dist/hud/__tests__/colors.test.js +0 -92
  1049. package/dist/hud/__tests__/colors.test.js.map +0 -1
  1050. package/dist/hud/__tests__/hud-tmux-injection.test.d.ts +0 -10
  1051. package/dist/hud/__tests__/hud-tmux-injection.test.d.ts.map +0 -1
  1052. package/dist/hud/__tests__/hud-tmux-injection.test.js +0 -150
  1053. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +0 -1
  1054. package/dist/hud/__tests__/index.test.d.ts +0 -2
  1055. package/dist/hud/__tests__/index.test.d.ts.map +0 -1
  1056. package/dist/hud/__tests__/index.test.js +0 -180
  1057. package/dist/hud/__tests__/index.test.js.map +0 -1
  1058. package/dist/hud/__tests__/reconcile.test.d.ts +0 -2
  1059. package/dist/hud/__tests__/reconcile.test.d.ts.map +0 -1
  1060. package/dist/hud/__tests__/reconcile.test.js +0 -125
  1061. package/dist/hud/__tests__/reconcile.test.js.map +0 -1
  1062. package/dist/hud/__tests__/render.test.d.ts +0 -2
  1063. package/dist/hud/__tests__/render.test.d.ts.map +0 -1
  1064. package/dist/hud/__tests__/render.test.js +0 -573
  1065. package/dist/hud/__tests__/render.test.js.map +0 -1
  1066. package/dist/hud/__tests__/state.test.d.ts +0 -2
  1067. package/dist/hud/__tests__/state.test.d.ts.map +0 -1
  1068. package/dist/hud/__tests__/state.test.js +0 -618
  1069. package/dist/hud/__tests__/state.test.js.map +0 -1
  1070. package/dist/hud/__tests__/types.test.d.ts +0 -2
  1071. package/dist/hud/__tests__/types.test.d.ts.map +0 -1
  1072. package/dist/hud/__tests__/types.test.js +0 -79
  1073. package/dist/hud/__tests__/types.test.js.map +0 -1
  1074. package/dist/hud/__tests__/watch.test.d.ts +0 -2
  1075. package/dist/hud/__tests__/watch.test.d.ts.map +0 -1
  1076. package/dist/hud/__tests__/watch.test.js +0 -63
  1077. package/dist/hud/__tests__/watch.test.js.map +0 -1
  1078. package/dist/mcp/__tests__/bootstrap.test.d.ts +0 -2
  1079. package/dist/mcp/__tests__/bootstrap.test.d.ts.map +0 -1
  1080. package/dist/mcp/__tests__/bootstrap.test.js +0 -207
  1081. package/dist/mcp/__tests__/bootstrap.test.js.map +0 -1
  1082. package/dist/mcp/__tests__/code-intel-server.test.d.ts +0 -2
  1083. package/dist/mcp/__tests__/code-intel-server.test.d.ts.map +0 -1
  1084. package/dist/mcp/__tests__/code-intel-server.test.js +0 -70
  1085. package/dist/mcp/__tests__/code-intel-server.test.js.map +0 -1
  1086. package/dist/mcp/__tests__/memory-server.test.d.ts +0 -2
  1087. package/dist/mcp/__tests__/memory-server.test.d.ts.map +0 -1
  1088. package/dist/mcp/__tests__/memory-server.test.js +0 -36
  1089. package/dist/mcp/__tests__/memory-server.test.js.map +0 -1
  1090. package/dist/mcp/__tests__/memory-validation.test.d.ts +0 -2
  1091. package/dist/mcp/__tests__/memory-validation.test.d.ts.map +0 -1
  1092. package/dist/mcp/__tests__/memory-validation.test.js +0 -29
  1093. package/dist/mcp/__tests__/memory-validation.test.js.map +0 -1
  1094. package/dist/mcp/__tests__/path-traversal.test.d.ts +0 -2
  1095. package/dist/mcp/__tests__/path-traversal.test.d.ts.map +0 -1
  1096. package/dist/mcp/__tests__/path-traversal.test.js +0 -83
  1097. package/dist/mcp/__tests__/path-traversal.test.js.map +0 -1
  1098. package/dist/mcp/__tests__/server-lifecycle.test.d.ts +0 -2
  1099. package/dist/mcp/__tests__/server-lifecycle.test.d.ts.map +0 -1
  1100. package/dist/mcp/__tests__/server-lifecycle.test.js +0 -260
  1101. package/dist/mcp/__tests__/server-lifecycle.test.js.map +0 -1
  1102. package/dist/mcp/__tests__/state-paths.test.d.ts +0 -2
  1103. package/dist/mcp/__tests__/state-paths.test.d.ts.map +0 -1
  1104. package/dist/mcp/__tests__/state-paths.test.js +0 -209
  1105. package/dist/mcp/__tests__/state-paths.test.js.map +0 -1
  1106. package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts +0 -2
  1107. package/dist/mcp/__tests__/state-server-ralph-phase.test.d.ts.map +0 -1
  1108. package/dist/mcp/__tests__/state-server-ralph-phase.test.js +0 -109
  1109. package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +0 -1
  1110. package/dist/mcp/__tests__/state-server-schema.test.d.ts +0 -2
  1111. package/dist/mcp/__tests__/state-server-schema.test.d.ts.map +0 -1
  1112. package/dist/mcp/__tests__/state-server-schema.test.js +0 -29
  1113. package/dist/mcp/__tests__/state-server-schema.test.js.map +0 -1
  1114. package/dist/mcp/__tests__/state-server-team-tools.test.d.ts +0 -2
  1115. package/dist/mcp/__tests__/state-server-team-tools.test.d.ts.map +0 -1
  1116. package/dist/mcp/__tests__/state-server-team-tools.test.js +0 -35
  1117. package/dist/mcp/__tests__/state-server-team-tools.test.js.map +0 -1
  1118. package/dist/mcp/__tests__/state-server.test.d.ts +0 -2
  1119. package/dist/mcp/__tests__/state-server.test.d.ts.map +0 -1
  1120. package/dist/mcp/__tests__/state-server.test.js +0 -965
  1121. package/dist/mcp/__tests__/state-server.test.js.map +0 -1
  1122. package/dist/mcp/__tests__/trace-server.test.d.ts +0 -2
  1123. package/dist/mcp/__tests__/trace-server.test.d.ts.map +0 -1
  1124. package/dist/mcp/__tests__/trace-server.test.js +0 -119
  1125. package/dist/mcp/__tests__/trace-server.test.js.map +0 -1
  1126. package/dist/mcp/__tests__/wiki-server.test.d.ts +0 -2
  1127. package/dist/mcp/__tests__/wiki-server.test.d.ts.map +0 -1
  1128. package/dist/mcp/__tests__/wiki-server.test.js +0 -30
  1129. package/dist/mcp/__tests__/wiki-server.test.js.map +0 -1
  1130. package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts +0 -2
  1131. package/dist/modes/__tests__/base-autoresearch-contract.test.d.ts.map +0 -1
  1132. package/dist/modes/__tests__/base-autoresearch-contract.test.js +0 -123
  1133. package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +0 -1
  1134. package/dist/modes/__tests__/base-multi-state-compat.test.d.ts +0 -2
  1135. package/dist/modes/__tests__/base-multi-state-compat.test.d.ts.map +0 -1
  1136. package/dist/modes/__tests__/base-multi-state-compat.test.js +0 -38
  1137. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +0 -1
  1138. package/dist/modes/__tests__/base-ralph-contract.test.d.ts +0 -2
  1139. package/dist/modes/__tests__/base-ralph-contract.test.d.ts.map +0 -1
  1140. package/dist/modes/__tests__/base-ralph-contract.test.js +0 -64
  1141. package/dist/modes/__tests__/base-ralph-contract.test.js.map +0 -1
  1142. package/dist/modes/__tests__/base-session-scope.test.d.ts +0 -2
  1143. package/dist/modes/__tests__/base-session-scope.test.d.ts.map +0 -1
  1144. package/dist/modes/__tests__/base-session-scope.test.js +0 -98
  1145. package/dist/modes/__tests__/base-session-scope.test.js.map +0 -1
  1146. package/dist/modes/__tests__/base-tmux-pane.test.d.ts +0 -2
  1147. package/dist/modes/__tests__/base-tmux-pane.test.d.ts.map +0 -1
  1148. package/dist/modes/__tests__/base-tmux-pane.test.js +0 -39
  1149. package/dist/modes/__tests__/base-tmux-pane.test.js.map +0 -1
  1150. package/dist/notifications/__tests__/config.test.d.ts +0 -2
  1151. package/dist/notifications/__tests__/config.test.d.ts.map +0 -1
  1152. package/dist/notifications/__tests__/config.test.js +0 -269
  1153. package/dist/notifications/__tests__/config.test.js.map +0 -1
  1154. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +0 -2
  1155. package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +0 -1
  1156. package/dist/notifications/__tests__/custom-alias-enablement.test.js +0 -84
  1157. package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +0 -1
  1158. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +0 -5
  1159. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +0 -1
  1160. package/dist/notifications/__tests__/dispatch-cooldown.test.js +0 -100
  1161. package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +0 -1
  1162. package/dist/notifications/__tests__/dispatcher.test.d.ts +0 -2
  1163. package/dist/notifications/__tests__/dispatcher.test.d.ts.map +0 -1
  1164. package/dist/notifications/__tests__/dispatcher.test.js +0 -202
  1165. package/dist/notifications/__tests__/dispatcher.test.js.map +0 -1
  1166. package/dist/notifications/__tests__/formatter.test.d.ts +0 -2
  1167. package/dist/notifications/__tests__/formatter.test.d.ts.map +0 -1
  1168. package/dist/notifications/__tests__/formatter.test.js +0 -270
  1169. package/dist/notifications/__tests__/formatter.test.js.map +0 -1
  1170. package/dist/notifications/__tests__/hook-config.test.d.ts +0 -5
  1171. package/dist/notifications/__tests__/hook-config.test.d.ts.map +0 -1
  1172. package/dist/notifications/__tests__/hook-config.test.js +0 -139
  1173. package/dist/notifications/__tests__/hook-config.test.js.map +0 -1
  1174. package/dist/notifications/__tests__/idle-cooldown.test.d.ts +0 -5
  1175. package/dist/notifications/__tests__/idle-cooldown.test.d.ts.map +0 -1
  1176. package/dist/notifications/__tests__/idle-cooldown.test.js +0 -209
  1177. package/dist/notifications/__tests__/idle-cooldown.test.js.map +0 -1
  1178. package/dist/notifications/__tests__/index.test.d.ts +0 -2
  1179. package/dist/notifications/__tests__/index.test.d.ts.map +0 -1
  1180. package/dist/notifications/__tests__/index.test.js +0 -188
  1181. package/dist/notifications/__tests__/index.test.js.map +0 -1
  1182. package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts +0 -2
  1183. package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts.map +0 -1
  1184. package/dist/notifications/__tests__/lifecycle-dedupe.test.js +0 -86
  1185. package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +0 -1
  1186. package/dist/notifications/__tests__/notifier.test.d.ts +0 -2
  1187. package/dist/notifications/__tests__/notifier.test.d.ts.map +0 -1
  1188. package/dist/notifications/__tests__/notifier.test.js +0 -239
  1189. package/dist/notifications/__tests__/notifier.test.js.map +0 -1
  1190. package/dist/notifications/__tests__/profiles.test.d.ts +0 -2
  1191. package/dist/notifications/__tests__/profiles.test.d.ts.map +0 -1
  1192. package/dist/notifications/__tests__/profiles.test.js +0 -404
  1193. package/dist/notifications/__tests__/profiles.test.js.map +0 -1
  1194. package/dist/notifications/__tests__/reply-config.test.d.ts +0 -2
  1195. package/dist/notifications/__tests__/reply-config.test.d.ts.map +0 -1
  1196. package/dist/notifications/__tests__/reply-config.test.js +0 -79
  1197. package/dist/notifications/__tests__/reply-config.test.js.map +0 -1
  1198. package/dist/notifications/__tests__/reply-listener.test.d.ts +0 -2
  1199. package/dist/notifications/__tests__/reply-listener.test.d.ts.map +0 -1
  1200. package/dist/notifications/__tests__/reply-listener.test.js +0 -723
  1201. package/dist/notifications/__tests__/reply-listener.test.js.map +0 -1
  1202. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts +0 -2
  1203. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts.map +0 -1
  1204. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +0 -93
  1205. package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +0 -1
  1206. package/dist/notifications/__tests__/session-registry.test.d.ts +0 -2
  1207. package/dist/notifications/__tests__/session-registry.test.d.ts.map +0 -1
  1208. package/dist/notifications/__tests__/session-registry.test.js +0 -234
  1209. package/dist/notifications/__tests__/session-registry.test.js.map +0 -1
  1210. package/dist/notifications/__tests__/session-status.test.d.ts +0 -2
  1211. package/dist/notifications/__tests__/session-status.test.d.ts.map +0 -1
  1212. package/dist/notifications/__tests__/session-status.test.js +0 -249
  1213. package/dist/notifications/__tests__/session-status.test.js.map +0 -1
  1214. package/dist/notifications/__tests__/temp-mode.test.d.ts +0 -2
  1215. package/dist/notifications/__tests__/temp-mode.test.d.ts.map +0 -1
  1216. package/dist/notifications/__tests__/temp-mode.test.js +0 -172
  1217. package/dist/notifications/__tests__/temp-mode.test.js.map +0 -1
  1218. package/dist/notifications/__tests__/template-engine.test.d.ts +0 -5
  1219. package/dist/notifications/__tests__/template-engine.test.d.ts.map +0 -1
  1220. package/dist/notifications/__tests__/template-engine.test.js +0 -158
  1221. package/dist/notifications/__tests__/template-engine.test.js.map +0 -1
  1222. package/dist/notifications/__tests__/tmux-detector.test.d.ts +0 -2
  1223. package/dist/notifications/__tests__/tmux-detector.test.d.ts.map +0 -1
  1224. package/dist/notifications/__tests__/tmux-detector.test.js +0 -208
  1225. package/dist/notifications/__tests__/tmux-detector.test.js.map +0 -1
  1226. package/dist/notifications/__tests__/tmux.test.d.ts +0 -2
  1227. package/dist/notifications/__tests__/tmux.test.d.ts.map +0 -1
  1228. package/dist/notifications/__tests__/tmux.test.js +0 -285
  1229. package/dist/notifications/__tests__/tmux.test.js.map +0 -1
  1230. package/dist/notifications/__tests__/verbosity.test.d.ts +0 -2
  1231. package/dist/notifications/__tests__/verbosity.test.d.ts.map +0 -1
  1232. package/dist/notifications/__tests__/verbosity.test.js +0 -237
  1233. package/dist/notifications/__tests__/verbosity.test.js.map +0 -1
  1234. package/dist/openclaw/__tests__/config.test.d.ts +0 -6
  1235. package/dist/openclaw/__tests__/config.test.d.ts.map +0 -1
  1236. package/dist/openclaw/__tests__/config.test.js +0 -344
  1237. package/dist/openclaw/__tests__/config.test.js.map +0 -1
  1238. package/dist/openclaw/__tests__/dispatcher.test.d.ts +0 -5
  1239. package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +0 -1
  1240. package/dist/openclaw/__tests__/dispatcher.test.js +0 -169
  1241. package/dist/openclaw/__tests__/dispatcher.test.js.map +0 -1
  1242. package/dist/openclaw/__tests__/index.test.d.ts +0 -6
  1243. package/dist/openclaw/__tests__/index.test.d.ts.map +0 -1
  1244. package/dist/openclaw/__tests__/index.test.js +0 -382
  1245. package/dist/openclaw/__tests__/index.test.js.map +0 -1
  1246. package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
  1247. package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
  1248. package/dist/pipeline/__tests__/orchestrator.test.js +0 -505
  1249. package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
  1250. package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
  1251. package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
  1252. package/dist/pipeline/__tests__/stages.test.js +0 -754
  1253. package/dist/pipeline/__tests__/stages.test.js.map +0 -1
  1254. package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
  1255. package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
  1256. package/dist/pipeline/stages/ralph-verify.js.map +0 -1
  1257. package/dist/pipeline/stages/ralplan.d.ts +0 -25
  1258. package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
  1259. package/dist/pipeline/stages/ralplan.js.map +0 -1
  1260. package/dist/planning/__tests__/artifacts.test.d.ts +0 -2
  1261. package/dist/planning/__tests__/artifacts.test.d.ts.map +0 -1
  1262. package/dist/planning/__tests__/artifacts.test.js +0 -544
  1263. package/dist/planning/__tests__/artifacts.test.js.map +0 -1
  1264. package/dist/question/__tests__/client.test.d.ts +0 -2
  1265. package/dist/question/__tests__/client.test.d.ts.map +0 -1
  1266. package/dist/question/__tests__/client.test.js +0 -90
  1267. package/dist/question/__tests__/client.test.js.map +0 -1
  1268. package/dist/question/__tests__/deep-interview.test.d.ts +0 -2
  1269. package/dist/question/__tests__/deep-interview.test.d.ts.map +0 -1
  1270. package/dist/question/__tests__/deep-interview.test.js +0 -209
  1271. package/dist/question/__tests__/deep-interview.test.js.map +0 -1
  1272. package/dist/question/__tests__/policy.test.d.ts +0 -2
  1273. package/dist/question/__tests__/policy.test.d.ts.map +0 -1
  1274. package/dist/question/__tests__/policy.test.js +0 -107
  1275. package/dist/question/__tests__/policy.test.js.map +0 -1
  1276. package/dist/question/__tests__/renderer.test.d.ts +0 -2
  1277. package/dist/question/__tests__/renderer.test.d.ts.map +0 -1
  1278. package/dist/question/__tests__/renderer.test.js +0 -707
  1279. package/dist/question/__tests__/renderer.test.js.map +0 -1
  1280. package/dist/question/__tests__/state.test.d.ts +0 -2
  1281. package/dist/question/__tests__/state.test.d.ts.map +0 -1
  1282. package/dist/question/__tests__/state.test.js +0 -102
  1283. package/dist/question/__tests__/state.test.js.map +0 -1
  1284. package/dist/question/__tests__/types.test.d.ts +0 -2
  1285. package/dist/question/__tests__/types.test.d.ts.map +0 -1
  1286. package/dist/question/__tests__/types.test.js +0 -65
  1287. package/dist/question/__tests__/types.test.js.map +0 -1
  1288. package/dist/question/__tests__/ui.test.d.ts +0 -2
  1289. package/dist/question/__tests__/ui.test.d.ts.map +0 -1
  1290. package/dist/question/__tests__/ui.test.js +0 -446
  1291. package/dist/question/__tests__/ui.test.js.map +0 -1
  1292. package/dist/ralph/__tests__/persistence.test.d.ts +0 -2
  1293. package/dist/ralph/__tests__/persistence.test.d.ts.map +0 -1
  1294. package/dist/ralph/__tests__/persistence.test.js +0 -116
  1295. package/dist/ralph/__tests__/persistence.test.js.map +0 -1
  1296. package/dist/ralph/contract.d.ts +0 -17
  1297. package/dist/ralph/persistence.js.map +0 -1
  1298. package/dist/ralplan/__tests__/runtime.test.d.ts +0 -2
  1299. package/dist/ralplan/__tests__/runtime.test.d.ts.map +0 -1
  1300. package/dist/ralplan/__tests__/runtime.test.js +0 -165
  1301. package/dist/ralplan/__tests__/runtime.test.js.map +0 -1
  1302. package/dist/ralplan/runtime.d.ts +0 -52
  1303. package/dist/ralplan/runtime.d.ts.map +0 -1
  1304. package/dist/ralplan/runtime.js.map +0 -1
  1305. package/dist/runtime/__tests__/bridge.test.d.ts +0 -2
  1306. package/dist/runtime/__tests__/bridge.test.d.ts.map +0 -1
  1307. package/dist/runtime/__tests__/bridge.test.js +0 -194
  1308. package/dist/runtime/__tests__/bridge.test.js.map +0 -1
  1309. package/dist/runtime/__tests__/run-loop.test.d.ts +0 -2
  1310. package/dist/runtime/__tests__/run-loop.test.d.ts.map +0 -1
  1311. package/dist/runtime/__tests__/run-loop.test.js +0 -35
  1312. package/dist/runtime/__tests__/run-loop.test.js.map +0 -1
  1313. package/dist/runtime/__tests__/run-outcome.test.d.ts +0 -2
  1314. package/dist/runtime/__tests__/run-outcome.test.d.ts.map +0 -1
  1315. package/dist/runtime/__tests__/run-outcome.test.js +0 -102
  1316. package/dist/runtime/__tests__/run-outcome.test.js.map +0 -1
  1317. package/dist/runtime/__tests__/run-state.test.d.ts +0 -2
  1318. package/dist/runtime/__tests__/run-state.test.d.ts.map +0 -1
  1319. package/dist/runtime/__tests__/run-state.test.js +0 -37
  1320. package/dist/runtime/__tests__/run-state.test.js.map +0 -1
  1321. package/dist/scripts/__tests__/codex-native-hook.test.d.ts +0 -2
  1322. package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +0 -1
  1323. package/dist/scripts/__tests__/codex-native-hook.test.js +0 -6788
  1324. package/dist/scripts/__tests__/codex-native-hook.test.js.map +0 -1
  1325. package/dist/scripts/__tests__/generate-release-body.test.d.ts +0 -2
  1326. package/dist/scripts/__tests__/generate-release-body.test.d.ts.map +0 -1
  1327. package/dist/scripts/__tests__/generate-release-body.test.js +0 -233
  1328. package/dist/scripts/__tests__/generate-release-body.test.js.map +0 -1
  1329. package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts +0 -2
  1330. package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts.map +0 -1
  1331. package/dist/scripts/__tests__/hook-derived-watcher.test.js +0 -195
  1332. package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +0 -1
  1333. package/dist/scripts/__tests__/postinstall.test.d.ts +0 -2
  1334. package/dist/scripts/__tests__/postinstall.test.d.ts.map +0 -1
  1335. package/dist/scripts/__tests__/postinstall.test.js +0 -92
  1336. package/dist/scripts/__tests__/postinstall.test.js.map +0 -1
  1337. package/dist/scripts/__tests__/prompt-inventory.test.d.ts +0 -2
  1338. package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +0 -1
  1339. package/dist/scripts/__tests__/prompt-inventory.test.js +0 -56
  1340. package/dist/scripts/__tests__/prompt-inventory.test.js.map +0 -1
  1341. package/dist/scripts/__tests__/run-test-files.test.d.ts +0 -2
  1342. package/dist/scripts/__tests__/run-test-files.test.d.ts.map +0 -1
  1343. package/dist/scripts/__tests__/run-test-files.test.js +0 -62
  1344. package/dist/scripts/__tests__/run-test-files.test.js.map +0 -1
  1345. package/dist/scripts/__tests__/smoke-packed-install.test.d.ts +0 -2
  1346. package/dist/scripts/__tests__/smoke-packed-install.test.d.ts.map +0 -1
  1347. package/dist/scripts/__tests__/smoke-packed-install.test.js +0 -135
  1348. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +0 -1
  1349. package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts +0 -2
  1350. package/dist/scripts/__tests__/test-reply-listener-live.test.d.ts.map +0 -1
  1351. package/dist/scripts/__tests__/test-reply-listener-live.test.js +0 -82
  1352. package/dist/scripts/__tests__/test-reply-listener-live.test.js.map +0 -1
  1353. package/dist/scripts/__tests__/verify-native-agents.test.d.ts +0 -2
  1354. package/dist/scripts/__tests__/verify-native-agents.test.d.ts.map +0 -1
  1355. package/dist/scripts/__tests__/verify-native-agents.test.js +0 -166
  1356. package/dist/scripts/__tests__/verify-native-agents.test.js.map +0 -1
  1357. package/dist/scripts/eval/eval-candidate-handoff.d.ts +0 -2
  1358. package/dist/scripts/eval/eval-candidate-handoff.d.ts.map +0 -1
  1359. package/dist/scripts/eval/eval-candidate-handoff.js +0 -11
  1360. package/dist/scripts/eval/eval-candidate-handoff.js.map +0 -1
  1361. package/dist/scripts/eval/eval-cli-discoverability.d.ts +0 -3
  1362. package/dist/scripts/eval/eval-cli-discoverability.d.ts.map +0 -1
  1363. package/dist/scripts/eval/eval-cli-discoverability.js +0 -37
  1364. package/dist/scripts/eval/eval-cli-discoverability.js.map +0 -1
  1365. package/dist/scripts/eval/eval-fresh-run-tagging.d.ts +0 -2
  1366. package/dist/scripts/eval/eval-fresh-run-tagging.d.ts.map +0 -1
  1367. package/dist/scripts/eval/eval-fresh-run-tagging.js +0 -11
  1368. package/dist/scripts/eval/eval-fresh-run-tagging.js.map +0 -1
  1369. package/dist/scripts/eval/eval-help-consistency.d.ts +0 -2
  1370. package/dist/scripts/eval/eval-help-consistency.d.ts.map +0 -1
  1371. package/dist/scripts/eval/eval-help-consistency.js +0 -12
  1372. package/dist/scripts/eval/eval-help-consistency.js.map +0 -1
  1373. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts +0 -2
  1374. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.d.ts.map +0 -1
  1375. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js +0 -31
  1376. package/dist/scripts/eval/eval-in-action-cat-shellout-demo.js.map +0 -1
  1377. package/dist/scripts/eval/eval-parity-smoke.d.ts +0 -2
  1378. package/dist/scripts/eval/eval-parity-smoke.d.ts.map +0 -1
  1379. package/dist/scripts/eval/eval-parity-smoke.js +0 -23
  1380. package/dist/scripts/eval/eval-parity-smoke.js.map +0 -1
  1381. package/dist/scripts/eval/eval-parity-sweep.d.ts +0 -2
  1382. package/dist/scripts/eval/eval-parity-sweep.d.ts.map +0 -1
  1383. package/dist/scripts/eval/eval-parity-sweep.js +0 -29
  1384. package/dist/scripts/eval/eval-parity-sweep.js.map +0 -1
  1385. package/dist/scripts/eval/eval-resume-dirty-guard.d.ts +0 -2
  1386. package/dist/scripts/eval/eval-resume-dirty-guard.d.ts.map +0 -1
  1387. package/dist/scripts/eval/eval-resume-dirty-guard.js +0 -11
  1388. package/dist/scripts/eval/eval-resume-dirty-guard.js.map +0 -1
  1389. package/dist/scripts/eval/eval-security-path-traversal.d.ts +0 -3
  1390. package/dist/scripts/eval/eval-security-path-traversal.d.ts.map +0 -1
  1391. package/dist/scripts/eval/eval-security-path-traversal.js +0 -35
  1392. package/dist/scripts/eval/eval-security-path-traversal.js.map +0 -1
  1393. package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts +0 -2
  1394. package/dist/scripts/notify-hook/__tests__/operational-events.test.d.ts.map +0 -1
  1395. package/dist/scripts/notify-hook/__tests__/operational-events.test.js +0 -24
  1396. package/dist/scripts/notify-hook/__tests__/operational-events.test.js.map +0 -1
  1397. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +0 -2
  1398. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +0 -1
  1399. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +0 -153
  1400. package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +0 -1
  1401. package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -22
  1402. package/dist/session-history/__tests__/search.test.d.ts +0 -2
  1403. package/dist/session-history/__tests__/search.test.d.ts.map +0 -1
  1404. package/dist/session-history/__tests__/search.test.js +0 -150
  1405. package/dist/session-history/__tests__/search.test.js.map +0 -1
  1406. package/dist/sidecar/__tests__/boundary.test.d.ts +0 -2
  1407. package/dist/sidecar/__tests__/boundary.test.d.ts.map +0 -1
  1408. package/dist/sidecar/__tests__/boundary.test.js +0 -48
  1409. package/dist/sidecar/__tests__/boundary.test.js.map +0 -1
  1410. package/dist/sidecar/__tests__/collector.test.d.ts +0 -2
  1411. package/dist/sidecar/__tests__/collector.test.d.ts.map +0 -1
  1412. package/dist/sidecar/__tests__/collector.test.js +0 -162
  1413. package/dist/sidecar/__tests__/collector.test.js.map +0 -1
  1414. package/dist/sidecar/__tests__/render.test.d.ts +0 -2
  1415. package/dist/sidecar/__tests__/render.test.d.ts.map +0 -1
  1416. package/dist/sidecar/__tests__/render.test.js +0 -67
  1417. package/dist/sidecar/__tests__/render.test.js.map +0 -1
  1418. package/dist/sidecar/__tests__/tmux.test.d.ts +0 -2
  1419. package/dist/sidecar/__tests__/tmux.test.d.ts.map +0 -1
  1420. package/dist/sidecar/__tests__/tmux.test.js +0 -30
  1421. package/dist/sidecar/__tests__/tmux.test.js.map +0 -1
  1422. package/dist/sidecar/__tests__/watch.test.d.ts +0 -2
  1423. package/dist/sidecar/__tests__/watch.test.d.ts.map +0 -1
  1424. package/dist/sidecar/__tests__/watch.test.js +0 -42
  1425. package/dist/sidecar/__tests__/watch.test.js.map +0 -1
  1426. package/dist/state/__tests__/mode-state-context.test.d.ts +0 -2
  1427. package/dist/state/__tests__/mode-state-context.test.d.ts.map +0 -1
  1428. package/dist/state/__tests__/mode-state-context.test.js +0 -35
  1429. package/dist/state/__tests__/mode-state-context.test.js.map +0 -1
  1430. package/dist/state/__tests__/operations-ralph-phase.test.d.ts +0 -2
  1431. package/dist/state/__tests__/operations-ralph-phase.test.d.ts.map +0 -1
  1432. package/dist/state/__tests__/operations-ralph-phase.test.js +0 -103
  1433. package/dist/state/__tests__/operations-ralph-phase.test.js.map +0 -1
  1434. package/dist/state/__tests__/operations.test.d.ts +0 -2
  1435. package/dist/state/__tests__/operations.test.d.ts.map +0 -1
  1436. package/dist/state/__tests__/operations.test.js +0 -439
  1437. package/dist/state/__tests__/operations.test.js.map +0 -1
  1438. package/dist/state/__tests__/path-traversal.test.d.ts +0 -2
  1439. package/dist/state/__tests__/path-traversal.test.d.ts.map +0 -1
  1440. package/dist/state/__tests__/path-traversal.test.js +0 -49
  1441. package/dist/state/__tests__/path-traversal.test.js.map +0 -1
  1442. package/dist/state/__tests__/skill-active.test.d.ts +0 -2
  1443. package/dist/state/__tests__/skill-active.test.d.ts.map +0 -1
  1444. package/dist/state/__tests__/skill-active.test.js +0 -160
  1445. package/dist/state/__tests__/skill-active.test.js.map +0 -1
  1446. package/dist/state/__tests__/workflow-transition.test.d.ts +0 -2
  1447. package/dist/state/__tests__/workflow-transition.test.d.ts.map +0 -1
  1448. package/dist/state/__tests__/workflow-transition.test.js +0 -77
  1449. package/dist/state/__tests__/workflow-transition.test.js.map +0 -1
  1450. package/dist/subagents/__tests__/tracker.test.d.ts +0 -2
  1451. package/dist/subagents/__tests__/tracker.test.d.ts.map +0 -1
  1452. package/dist/subagents/__tests__/tracker.test.js +0 -47
  1453. package/dist/subagents/__tests__/tracker.test.js.map +0 -1
  1454. package/dist/team/__tests__/allocation-policy.test.d.ts +0 -2
  1455. package/dist/team/__tests__/allocation-policy.test.d.ts.map +0 -1
  1456. package/dist/team/__tests__/allocation-policy.test.js +0 -111
  1457. package/dist/team/__tests__/allocation-policy.test.js.map +0 -1
  1458. package/dist/team/__tests__/api-interop.test.d.ts +0 -2
  1459. package/dist/team/__tests__/api-interop.test.d.ts.map +0 -1
  1460. package/dist/team/__tests__/api-interop.test.js +0 -2262
  1461. package/dist/team/__tests__/api-interop.test.js.map +0 -1
  1462. package/dist/team/__tests__/commit-hygiene.test.d.ts +0 -2
  1463. package/dist/team/__tests__/commit-hygiene.test.d.ts.map +0 -1
  1464. package/dist/team/__tests__/commit-hygiene.test.js +0 -93
  1465. package/dist/team/__tests__/commit-hygiene.test.js.map +0 -1
  1466. package/dist/team/__tests__/cross-rebase-smoke.test.d.ts +0 -2
  1467. package/dist/team/__tests__/cross-rebase-smoke.test.d.ts.map +0 -1
  1468. package/dist/team/__tests__/cross-rebase-smoke.test.js +0 -161
  1469. package/dist/team/__tests__/cross-rebase-smoke.test.js.map +0 -1
  1470. package/dist/team/__tests__/current-task-baseline.test.d.ts +0 -2
  1471. package/dist/team/__tests__/current-task-baseline.test.d.ts.map +0 -1
  1472. package/dist/team/__tests__/current-task-baseline.test.js +0 -87
  1473. package/dist/team/__tests__/current-task-baseline.test.js.map +0 -1
  1474. package/dist/team/__tests__/delegation-policy.test.d.ts +0 -2
  1475. package/dist/team/__tests__/delegation-policy.test.d.ts.map +0 -1
  1476. package/dist/team/__tests__/delegation-policy.test.js +0 -69
  1477. package/dist/team/__tests__/delegation-policy.test.js.map +0 -1
  1478. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +0 -2
  1479. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +0 -1
  1480. package/dist/team/__tests__/delivery-e2e-smoke.test.js +0 -679
  1481. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +0 -1
  1482. package/dist/team/__tests__/events.test.d.ts +0 -2
  1483. package/dist/team/__tests__/events.test.d.ts.map +0 -1
  1484. package/dist/team/__tests__/events.test.js +0 -313
  1485. package/dist/team/__tests__/events.test.js.map +0 -1
  1486. package/dist/team/__tests__/followup-planner.test.d.ts +0 -2
  1487. package/dist/team/__tests__/followup-planner.test.d.ts.map +0 -1
  1488. package/dist/team/__tests__/followup-planner.test.js +0 -84
  1489. package/dist/team/__tests__/followup-planner.test.js.map +0 -1
  1490. package/dist/team/__tests__/hardening-e2e.test.d.ts +0 -2
  1491. package/dist/team/__tests__/hardening-e2e.test.d.ts.map +0 -1
  1492. package/dist/team/__tests__/hardening-e2e.test.js +0 -98
  1493. package/dist/team/__tests__/hardening-e2e.test.js.map +0 -1
  1494. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +0 -2
  1495. package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +0 -1
  1496. package/dist/team/__tests__/hook-primary-e2e-contract.test.js +0 -78
  1497. package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +0 -1
  1498. package/dist/team/__tests__/idle-nudge.test.d.ts +0 -2
  1499. package/dist/team/__tests__/idle-nudge.test.d.ts.map +0 -1
  1500. package/dist/team/__tests__/idle-nudge.test.js +0 -230
  1501. package/dist/team/__tests__/idle-nudge.test.js.map +0 -1
  1502. package/dist/team/__tests__/leader-activity.test.d.ts +0 -2
  1503. package/dist/team/__tests__/leader-activity.test.d.ts.map +0 -1
  1504. package/dist/team/__tests__/leader-activity.test.js +0 -261
  1505. package/dist/team/__tests__/leader-activity.test.js.map +0 -1
  1506. package/dist/team/__tests__/mcp-comm.test.d.ts +0 -2
  1507. package/dist/team/__tests__/mcp-comm.test.d.ts.map +0 -1
  1508. package/dist/team/__tests__/mcp-comm.test.js +0 -289
  1509. package/dist/team/__tests__/mcp-comm.test.js.map +0 -1
  1510. package/dist/team/__tests__/model-contract.test.d.ts +0 -2
  1511. package/dist/team/__tests__/model-contract.test.d.ts.map +0 -1
  1512. package/dist/team/__tests__/model-contract.test.js +0 -171
  1513. package/dist/team/__tests__/model-contract.test.js.map +0 -1
  1514. package/dist/team/__tests__/orchestrator.test.d.ts +0 -2
  1515. package/dist/team/__tests__/orchestrator.test.d.ts.map +0 -1
  1516. package/dist/team/__tests__/orchestrator.test.js +0 -111
  1517. package/dist/team/__tests__/orchestrator.test.js.map +0 -1
  1518. package/dist/team/__tests__/phase-controller.test.d.ts +0 -2
  1519. package/dist/team/__tests__/phase-controller.test.d.ts.map +0 -1
  1520. package/dist/team/__tests__/phase-controller.test.js +0 -50
  1521. package/dist/team/__tests__/phase-controller.test.js.map +0 -1
  1522. package/dist/team/__tests__/rebalance-policy.test.d.ts +0 -2
  1523. package/dist/team/__tests__/rebalance-policy.test.d.ts.map +0 -1
  1524. package/dist/team/__tests__/rebalance-policy.test.js +0 -168
  1525. package/dist/team/__tests__/rebalance-policy.test.js.map +0 -1
  1526. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +0 -2
  1527. package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +0 -1
  1528. package/dist/team/__tests__/repo-aware-decomposition.test.js +0 -136
  1529. package/dist/team/__tests__/repo-aware-decomposition.test.js.map +0 -1
  1530. package/dist/team/__tests__/role-router.test.d.ts +0 -2
  1531. package/dist/team/__tests__/role-router.test.d.ts.map +0 -1
  1532. package/dist/team/__tests__/role-router.test.js +0 -263
  1533. package/dist/team/__tests__/role-router.test.js.map +0 -1
  1534. package/dist/team/__tests__/runtime-cli.test.d.ts +0 -2
  1535. package/dist/team/__tests__/runtime-cli.test.d.ts.map +0 -1
  1536. package/dist/team/__tests__/runtime-cli.test.js +0 -304
  1537. package/dist/team/__tests__/runtime-cli.test.js.map +0 -1
  1538. package/dist/team/__tests__/runtime.test.d.ts +0 -2
  1539. package/dist/team/__tests__/runtime.test.d.ts.map +0 -1
  1540. package/dist/team/__tests__/runtime.test.js +0 -5734
  1541. package/dist/team/__tests__/runtime.test.js.map +0 -1
  1542. package/dist/team/__tests__/scaling.test.d.ts +0 -2
  1543. package/dist/team/__tests__/scaling.test.d.ts.map +0 -1
  1544. package/dist/team/__tests__/scaling.test.js +0 -1005
  1545. package/dist/team/__tests__/scaling.test.js.map +0 -1
  1546. package/dist/team/__tests__/shutdown-fallback.test.d.ts +0 -2
  1547. package/dist/team/__tests__/shutdown-fallback.test.d.ts.map +0 -1
  1548. package/dist/team/__tests__/shutdown-fallback.test.js +0 -125
  1549. package/dist/team/__tests__/shutdown-fallback.test.js.map +0 -1
  1550. package/dist/team/__tests__/state-root.test.d.ts +0 -2
  1551. package/dist/team/__tests__/state-root.test.d.ts.map +0 -1
  1552. package/dist/team/__tests__/state-root.test.js +0 -195
  1553. package/dist/team/__tests__/state-root.test.js.map +0 -1
  1554. package/dist/team/__tests__/state.test.d.ts +0 -2
  1555. package/dist/team/__tests__/state.test.d.ts.map +0 -1
  1556. package/dist/team/__tests__/state.test.js +0 -1859
  1557. package/dist/team/__tests__/state.test.js.map +0 -1
  1558. package/dist/team/__tests__/team-identity.test.d.ts +0 -2
  1559. package/dist/team/__tests__/team-identity.test.d.ts.map +0 -1
  1560. package/dist/team/__tests__/team-identity.test.js +0 -166
  1561. package/dist/team/__tests__/team-identity.test.js.map +0 -1
  1562. package/dist/team/__tests__/team-ops-contract.test.d.ts +0 -2
  1563. package/dist/team/__tests__/team-ops-contract.test.d.ts.map +0 -1
  1564. package/dist/team/__tests__/team-ops-contract.test.js +0 -96
  1565. package/dist/team/__tests__/team-ops-contract.test.js.map +0 -1
  1566. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +0 -2
  1567. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +0 -1
  1568. package/dist/team/__tests__/tmux-claude-workers-demo.test.js +0 -191
  1569. package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +0 -1
  1570. package/dist/team/__tests__/tmux-session.test.d.ts +0 -2
  1571. package/dist/team/__tests__/tmux-session.test.d.ts.map +0 -1
  1572. package/dist/team/__tests__/tmux-session.test.js +0 -3785
  1573. package/dist/team/__tests__/tmux-session.test.js.map +0 -1
  1574. package/dist/team/__tests__/tmux-test-fixture.d.ts +0 -20
  1575. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +0 -1
  1576. package/dist/team/__tests__/tmux-test-fixture.js +0 -152
  1577. package/dist/team/__tests__/tmux-test-fixture.js.map +0 -1
  1578. package/dist/team/__tests__/tmux-test-fixture.test.d.ts +0 -2
  1579. package/dist/team/__tests__/tmux-test-fixture.test.d.ts.map +0 -1
  1580. package/dist/team/__tests__/tmux-test-fixture.test.js +0 -113
  1581. package/dist/team/__tests__/tmux-test-fixture.test.js.map +0 -1
  1582. package/dist/team/__tests__/worker-bootstrap.test.d.ts +0 -2
  1583. package/dist/team/__tests__/worker-bootstrap.test.d.ts.map +0 -1
  1584. package/dist/team/__tests__/worker-bootstrap.test.js +0 -685
  1585. package/dist/team/__tests__/worker-bootstrap.test.js.map +0 -1
  1586. package/dist/team/__tests__/worker-runtime-identity.test.d.ts +0 -2
  1587. package/dist/team/__tests__/worker-runtime-identity.test.d.ts.map +0 -1
  1588. package/dist/team/__tests__/worker-runtime-identity.test.js +0 -250
  1589. package/dist/team/__tests__/worker-runtime-identity.test.js.map +0 -1
  1590. package/dist/team/__tests__/worktree.test.d.ts +0 -2
  1591. package/dist/team/__tests__/worktree.test.d.ts.map +0 -1
  1592. package/dist/team/__tests__/worktree.test.js +0 -317
  1593. package/dist/team/__tests__/worktree.test.js.map +0 -1
  1594. package/dist/utils/__tests__/agents-md.test.d.ts +0 -2
  1595. package/dist/utils/__tests__/agents-md.test.d.ts.map +0 -1
  1596. package/dist/utils/__tests__/agents-md.test.js +0 -52
  1597. package/dist/utils/__tests__/agents-md.test.js.map +0 -1
  1598. package/dist/utils/__tests__/agents-model-table.test.d.ts +0 -2
  1599. package/dist/utils/__tests__/agents-model-table.test.d.ts.map +0 -1
  1600. package/dist/utils/__tests__/agents-model-table.test.js +0 -104
  1601. package/dist/utils/__tests__/agents-model-table.test.js.map +0 -1
  1602. package/dist/utils/__tests__/dep-versions.test.d.ts +0 -2
  1603. package/dist/utils/__tests__/dep-versions.test.d.ts.map +0 -1
  1604. package/dist/utils/__tests__/dep-versions.test.js +0 -46
  1605. package/dist/utils/__tests__/dep-versions.test.js.map +0 -1
  1606. package/dist/utils/__tests__/package.test.d.ts +0 -2
  1607. package/dist/utils/__tests__/package.test.d.ts.map +0 -1
  1608. package/dist/utils/__tests__/package.test.js +0 -21
  1609. package/dist/utils/__tests__/package.test.js.map +0 -1
  1610. package/dist/utils/__tests__/paths.test.d.ts +0 -2
  1611. package/dist/utils/__tests__/paths.test.d.ts.map +0 -1
  1612. package/dist/utils/__tests__/paths.test.js +0 -541
  1613. package/dist/utils/__tests__/paths.test.js.map +0 -1
  1614. package/dist/utils/__tests__/platform-command.test.d.ts +0 -2
  1615. package/dist/utils/__tests__/platform-command.test.d.ts.map +0 -1
  1616. package/dist/utils/__tests__/platform-command.test.js +0 -410
  1617. package/dist/utils/__tests__/platform-command.test.js.map +0 -1
  1618. package/dist/utils/__tests__/repo-deps.test.d.ts +0 -2
  1619. package/dist/utils/__tests__/repo-deps.test.d.ts.map +0 -1
  1620. package/dist/utils/__tests__/repo-deps.test.js +0 -71
  1621. package/dist/utils/__tests__/repo-deps.test.js.map +0 -1
  1622. package/dist/verification/__tests__/ci-rust-gates.test.d.ts +0 -2
  1623. package/dist/verification/__tests__/ci-rust-gates.test.d.ts.map +0 -1
  1624. package/dist/verification/__tests__/ci-rust-gates.test.js +0 -89
  1625. package/dist/verification/__tests__/ci-rust-gates.test.js.map +0 -1
  1626. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts +0 -2
  1627. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts.map +0 -1
  1628. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +0 -54
  1629. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +0 -1
  1630. package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts +0 -2
  1631. package/dist/verification/__tests__/explore-harness-release-workflow.test.d.ts.map +0 -1
  1632. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +0 -73
  1633. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +0 -1
  1634. package/dist/verification/__tests__/native-release-manifest.test.d.ts +0 -2
  1635. package/dist/verification/__tests__/native-release-manifest.test.d.ts.map +0 -1
  1636. package/dist/verification/__tests__/native-release-manifest.test.js +0 -80
  1637. package/dist/verification/__tests__/native-release-manifest.test.js.map +0 -1
  1638. package/dist/verification/__tests__/pr-check-workflow.test.d.ts +0 -2
  1639. package/dist/verification/__tests__/pr-check-workflow.test.d.ts.map +0 -1
  1640. package/dist/verification/__tests__/pr-check-workflow.test.js +0 -27
  1641. package/dist/verification/__tests__/pr-check-workflow.test.js.map +0 -1
  1642. package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts +0 -2
  1643. package/dist/verification/__tests__/ralph-persistence-gate.test.d.ts.map +0 -1
  1644. package/dist/verification/__tests__/ralph-persistence-gate.test.js +0 -55
  1645. package/dist/verification/__tests__/ralph-persistence-gate.test.js.map +0 -1
  1646. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts +0 -2
  1647. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.d.ts.map +0 -1
  1648. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js +0 -32
  1649. package/dist/verification/__tests__/rust-runtime-thin-adapter-gate.test.js.map +0 -1
  1650. package/dist/verification/__tests__/verifier.test.d.ts +0 -2
  1651. package/dist/verification/__tests__/verifier.test.d.ts.map +0 -1
  1652. package/dist/verification/__tests__/verifier.test.js +0 -113
  1653. package/dist/verification/__tests__/verifier.test.js.map +0 -1
  1654. package/dist/visual/__tests__/verdict.test.d.ts +0 -2
  1655. package/dist/visual/__tests__/verdict.test.d.ts.map +0 -1
  1656. package/dist/visual/__tests__/verdict.test.js +0 -81
  1657. package/dist/visual/__tests__/verdict.test.js.map +0 -1
  1658. package/dist/wiki/__tests__/cjk-tokenize.test.d.ts +0 -12
  1659. package/dist/wiki/__tests__/cjk-tokenize.test.d.ts.map +0 -1
  1660. package/dist/wiki/__tests__/cjk-tokenize.test.js +0 -139
  1661. package/dist/wiki/__tests__/cjk-tokenize.test.js.map +0 -1
  1662. package/dist/wiki/__tests__/crlf-parse.test.d.ts +0 -2
  1663. package/dist/wiki/__tests__/crlf-parse.test.d.ts.map +0 -1
  1664. package/dist/wiki/__tests__/crlf-parse.test.js +0 -24
  1665. package/dist/wiki/__tests__/crlf-parse.test.js.map +0 -1
  1666. package/dist/wiki/__tests__/escape-newline.test.d.ts +0 -2
  1667. package/dist/wiki/__tests__/escape-newline.test.d.ts.map +0 -1
  1668. package/dist/wiki/__tests__/escape-newline.test.js +0 -45
  1669. package/dist/wiki/__tests__/escape-newline.test.js.map +0 -1
  1670. package/dist/wiki/__tests__/ingest.test.d.ts +0 -5
  1671. package/dist/wiki/__tests__/ingest.test.d.ts.map +0 -1
  1672. package/dist/wiki/__tests__/ingest.test.js +0 -181
  1673. package/dist/wiki/__tests__/ingest.test.js.map +0 -1
  1674. package/dist/wiki/__tests__/lint.test.d.ts +0 -5
  1675. package/dist/wiki/__tests__/lint.test.d.ts.map +0 -1
  1676. package/dist/wiki/__tests__/lint.test.js +0 -163
  1677. package/dist/wiki/__tests__/lint.test.js.map +0 -1
  1678. package/dist/wiki/__tests__/query.test.d.ts +0 -5
  1679. package/dist/wiki/__tests__/query.test.d.ts.map +0 -1
  1680. package/dist/wiki/__tests__/query.test.js +0 -141
  1681. package/dist/wiki/__tests__/query.test.js.map +0 -1
  1682. package/dist/wiki/__tests__/reserved-file-guard.test.d.ts +0 -2
  1683. package/dist/wiki/__tests__/reserved-file-guard.test.d.ts.map +0 -1
  1684. package/dist/wiki/__tests__/reserved-file-guard.test.js +0 -44
  1685. package/dist/wiki/__tests__/reserved-file-guard.test.js.map +0 -1
  1686. package/dist/wiki/__tests__/session-hooks.test.d.ts +0 -5
  1687. package/dist/wiki/__tests__/session-hooks.test.d.ts.map +0 -1
  1688. package/dist/wiki/__tests__/session-hooks.test.js +0 -36
  1689. package/dist/wiki/__tests__/session-hooks.test.js.map +0 -1
  1690. package/dist/wiki/__tests__/slug-nonascii.test.d.ts +0 -2
  1691. package/dist/wiki/__tests__/slug-nonascii.test.d.ts.map +0 -1
  1692. package/dist/wiki/__tests__/slug-nonascii.test.js +0 -30
  1693. package/dist/wiki/__tests__/slug-nonascii.test.js.map +0 -1
  1694. package/dist/wiki/__tests__/storage.test.d.ts +0 -5
  1695. package/dist/wiki/__tests__/storage.test.d.ts.map +0 -1
  1696. package/dist/wiki/__tests__/storage.test.js +0 -278
  1697. package/dist/wiki/__tests__/storage.test.js.map +0 -1
  1698. package/dist/wiki/__tests__/test-helpers.d.ts +0 -31
  1699. package/dist/wiki/__tests__/test-helpers.d.ts.map +0 -1
  1700. package/dist/wiki/__tests__/test-helpers.js +0 -108
  1701. package/dist/wiki/__tests__/test-helpers.js.map +0 -1
  1702. package/docs/contracts/ralph-cancel-contract.md +0 -23
  1703. package/docs/contracts/ralph-state-contract.md +0 -95
  1704. package/docs/issues/team-ralph-followup-team.md +0 -38
  1705. package/docs/qa/ralph-persistence-gate.md +0 -59
  1706. package/docs/reference/ralph-parity-matrix.md +0 -25
  1707. package/docs/reference/ralph-upstream-baseline.md +0 -34
  1708. package/plugins/roblox-ai-os-creator-skills/skills/ralph/SKILL.md +0 -269
  1709. package/plugins/roblox-ai-os-creator-skills/skills/ralplan/SKILL.md +0 -162
  1710. package/prompts/api-reviewer.md +0 -113
  1711. package/prompts/information-architect.md +0 -226
  1712. package/prompts/performance-reviewer.md +0 -109
  1713. package/prompts/product-analyst.md +0 -304
  1714. package/prompts/product-manager.md +0 -245
  1715. package/prompts/qa-tester.md +0 -124
  1716. package/prompts/quality-reviewer.md +0 -123
  1717. package/prompts/quality-strategist.md +0 -274
  1718. package/prompts/style-reviewer.md +0 -102
  1719. package/prompts/ux-researcher.md +0 -327
  1720. package/skills/frontend-ui-ux/SKILL.md +0 -34
  1721. package/skills/ralph/SKILL.md +0 -269
  1722. package/skills/ralplan/SKILL.md +0 -162
  1723. package/src/scripts/eval/eval-adaptive-sort-optimization.py +0 -24
  1724. package/src/scripts/eval/eval-candidate-handoff.ts +0 -8
  1725. package/src/scripts/eval/eval-cli-discoverability.ts +0 -40
  1726. package/src/scripts/eval/eval-fresh-run-tagging.ts +0 -8
  1727. package/src/scripts/eval/eval-help-consistency.ts +0 -11
  1728. package/src/scripts/eval/eval-in-action-cat-shellout-demo.ts +0 -31
  1729. package/src/scripts/eval/eval-ml-kaggle-model-optimization.py +0 -29
  1730. package/src/scripts/eval/eval-noisy-bayesopt-highdim.py +0 -44
  1731. package/src/scripts/eval/eval-noisy-latent-subspace-discovery.py +0 -44
  1732. package/src/scripts/eval/eval-parity-smoke.ts +0 -20
  1733. package/src/scripts/eval/eval-parity-sweep.ts +0 -26
  1734. package/src/scripts/eval/eval-resume-dirty-guard.ts +0 -8
  1735. package/src/scripts/eval/eval-security-path-traversal.ts +0 -38
  1736. package/src/scripts/run-autoresearch-showcase.sh +0 -75
  1737. /package/docs/{migration-mainline-post-v0.4.4.md → archive/migration-mainline-post-v0.4.4.md} +0 -0
  1738. /package/docs/{qa-plan-0.4.2.md → archive/qa-plan-0.4.2.md} +0 -0
  1739. /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