@cluesmith/codev 3.2.4 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (394) hide show
  1. package/dashboard-dist/assets/index-BZRTEMtH.css +32 -0
  2. package/dashboard-dist/assets/{index-BZ1x7x1X.js → index-D3XaKpZW.js} +46 -44
  3. package/dashboard-dist/assets/index-D3XaKpZW.js.map +1 -0
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agent-farm/cli.d.ts.map +1 -1
  6. package/dist/agent-farm/cli.js +154 -0
  7. package/dist/agent-farm/cli.js.map +1 -1
  8. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  9. package/dist/agent-farm/commands/cleanup.js +16 -0
  10. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  11. package/dist/agent-farm/commands/inbox.d.ts +42 -0
  12. package/dist/agent-farm/commands/inbox.d.ts.map +1 -0
  13. package/dist/agent-farm/commands/inbox.js +129 -0
  14. package/dist/agent-farm/commands/inbox.js.map +1 -0
  15. package/dist/agent-farm/commands/interrupt.d.ts +20 -0
  16. package/dist/agent-farm/commands/interrupt.d.ts.map +1 -0
  17. package/dist/agent-farm/commands/interrupt.js +65 -0
  18. package/dist/agent-farm/commands/interrupt.js.map +1 -0
  19. package/dist/agent-farm/commands/reset/constants.d.ts +52 -0
  20. package/dist/agent-farm/commands/reset/constants.d.ts.map +1 -0
  21. package/dist/agent-farm/commands/reset/constants.js +52 -0
  22. package/dist/agent-farm/commands/reset/constants.js.map +1 -0
  23. package/dist/agent-farm/commands/reset/context.d.ts +230 -0
  24. package/dist/agent-farm/commands/reset/context.d.ts.map +1 -0
  25. package/dist/agent-farm/commands/reset/context.js +428 -0
  26. package/dist/agent-farm/commands/reset/context.js.map +1 -0
  27. package/dist/agent-farm/commands/reset/index.d.ts +192 -0
  28. package/dist/agent-farm/commands/reset/index.d.ts.map +1 -0
  29. package/dist/agent-farm/commands/reset/index.js +488 -0
  30. package/dist/agent-farm/commands/reset/index.js.map +1 -0
  31. package/dist/agent-farm/commands/reset/receipt.d.ts +97 -0
  32. package/dist/agent-farm/commands/reset/receipt.d.ts.map +1 -0
  33. package/dist/agent-farm/commands/reset/receipt.js +149 -0
  34. package/dist/agent-farm/commands/reset/receipt.js.map +1 -0
  35. package/dist/agent-farm/commands/reset/reorient.d.ts +117 -0
  36. package/dist/agent-farm/commands/reset/reorient.d.ts.map +1 -0
  37. package/dist/agent-farm/commands/reset/reorient.js +313 -0
  38. package/dist/agent-farm/commands/reset/reorient.js.map +1 -0
  39. package/dist/agent-farm/commands/reset.d.ts +34 -0
  40. package/dist/agent-farm/commands/reset.d.ts.map +1 -0
  41. package/dist/agent-farm/commands/reset.js +309 -0
  42. package/dist/agent-farm/commands/reset.js.map +1 -0
  43. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  44. package/dist/agent-farm/commands/send.js +49 -8
  45. package/dist/agent-farm/commands/send.js.map +1 -1
  46. package/dist/agent-farm/commands/spawn-worktree.d.ts +105 -6
  47. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  48. package/dist/agent-farm/commands/spawn-worktree.js +289 -66
  49. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  50. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  51. package/dist/agent-farm/commands/spawn.js +13 -1
  52. package/dist/agent-farm/commands/spawn.js.map +1 -1
  53. package/dist/agent-farm/commands/status.d.ts.map +1 -1
  54. package/dist/agent-farm/commands/status.js +80 -8
  55. package/dist/agent-farm/commands/status.js.map +1 -1
  56. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  57. package/dist/agent-farm/commands/tower.js +13 -0
  58. package/dist/agent-farm/commands/tower.js.map +1 -1
  59. package/dist/agent-farm/db/index.d.ts +1 -1
  60. package/dist/agent-farm/db/index.d.ts.map +1 -1
  61. package/dist/agent-farm/db/index.js +80 -1
  62. package/dist/agent-farm/db/index.js.map +1 -1
  63. package/dist/agent-farm/db/mailbox.d.ts +222 -0
  64. package/dist/agent-farm/db/mailbox.d.ts.map +1 -0
  65. package/dist/agent-farm/db/mailbox.js +304 -0
  66. package/dist/agent-farm/db/mailbox.js.map +1 -0
  67. package/dist/agent-farm/db/schema.d.ts +1 -1
  68. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  69. package/dist/agent-farm/db/schema.js +35 -0
  70. package/dist/agent-farm/db/schema.js.map +1 -1
  71. package/dist/agent-farm/db/types.d.ts +45 -0
  72. package/dist/agent-farm/db/types.d.ts.map +1 -1
  73. package/dist/agent-farm/db/types.js.map +1 -1
  74. package/dist/agent-farm/lib/builder-lookup.d.ts +1 -1
  75. package/dist/agent-farm/lib/builder-lookup.js +2 -2
  76. package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
  77. package/dist/agent-farm/lib/reconnect-backoff.d.ts +64 -0
  78. package/dist/agent-farm/lib/reconnect-backoff.d.ts.map +1 -0
  79. package/dist/agent-farm/lib/reconnect-backoff.js +57 -0
  80. package/dist/agent-farm/lib/reconnect-backoff.js.map +1 -0
  81. package/dist/agent-farm/lib/tower-client.d.ts +16 -6
  82. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
  83. package/dist/agent-farm/lib/tower-client.js +37 -6
  84. package/dist/agent-farm/lib/tower-client.js.map +1 -1
  85. package/dist/agent-farm/lib/tunnel-client.d.ts +69 -1
  86. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  87. package/dist/agent-farm/lib/tunnel-client.js +225 -30
  88. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  89. package/dist/agent-farm/servers/canvas-relay.d.ts +60 -0
  90. package/dist/agent-farm/servers/canvas-relay.d.ts.map +1 -0
  91. package/dist/agent-farm/servers/canvas-relay.js +376 -0
  92. package/dist/agent-farm/servers/canvas-relay.js.map +1 -0
  93. package/dist/agent-farm/servers/cron-delivery.d.ts +72 -0
  94. package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -0
  95. package/dist/agent-farm/servers/cron-delivery.js +80 -0
  96. package/dist/agent-farm/servers/cron-delivery.js.map +1 -0
  97. package/dist/agent-farm/servers/delayed-send.d.ts +85 -0
  98. package/dist/agent-farm/servers/delayed-send.d.ts.map +1 -0
  99. package/dist/agent-farm/servers/delayed-send.js +165 -0
  100. package/dist/agent-farm/servers/delayed-send.js.map +1 -0
  101. package/dist/agent-farm/servers/gate-profiles.d.ts +67 -0
  102. package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -0
  103. package/dist/agent-farm/servers/gate-profiles.js +113 -0
  104. package/dist/agent-farm/servers/gate-profiles.js.map +1 -0
  105. package/dist/agent-farm/servers/mailbox-delivery.d.ts +370 -0
  106. package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -0
  107. package/dist/agent-farm/servers/mailbox-delivery.js +617 -0
  108. package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -0
  109. package/dist/agent-farm/servers/mailbox-wiring.d.ts +125 -0
  110. package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -0
  111. package/dist/agent-farm/servers/mailbox-wiring.js +425 -0
  112. package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -0
  113. package/dist/agent-farm/servers/message-write.d.ts +53 -1
  114. package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
  115. package/dist/agent-farm/servers/message-write.js +63 -0
  116. package/dist/agent-farm/servers/message-write.js.map +1 -1
  117. package/dist/agent-farm/servers/overview.d.ts +19 -0
  118. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  119. package/dist/agent-farm/servers/overview.js +100 -4
  120. package/dist/agent-farm/servers/overview.js.map +1 -1
  121. package/dist/agent-farm/servers/render-gate.d.ts +141 -0
  122. package/dist/agent-farm/servers/render-gate.d.ts.map +1 -0
  123. package/dist/agent-farm/servers/render-gate.js +251 -0
  124. package/dist/agent-farm/servers/render-gate.js.map +1 -0
  125. package/dist/agent-farm/servers/session-submit.d.ts +90 -0
  126. package/dist/agent-farm/servers/session-submit.d.ts.map +1 -0
  127. package/dist/agent-farm/servers/session-submit.js +127 -0
  128. package/dist/agent-farm/servers/session-submit.js.map +1 -0
  129. package/dist/agent-farm/servers/tower-cron.d.ts +10 -7
  130. package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
  131. package/dist/agent-farm/servers/tower-cron.js +58 -53
  132. package/dist/agent-farm/servers/tower-cron.js.map +1 -1
  133. package/dist/agent-farm/servers/tower-instances.d.ts +14 -2
  134. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  135. package/dist/agent-farm/servers/tower-instances.js +78 -16
  136. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  137. package/dist/agent-farm/servers/tower-messages.d.ts +38 -1
  138. package/dist/agent-farm/servers/tower-messages.d.ts.map +1 -1
  139. package/dist/agent-farm/servers/tower-messages.js +106 -1
  140. package/dist/agent-farm/servers/tower-messages.js.map +1 -1
  141. package/dist/agent-farm/servers/tower-routes.d.ts +16 -4
  142. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  143. package/dist/agent-farm/servers/tower-routes.js +826 -145
  144. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  145. package/dist/agent-farm/servers/tower-server.js +188 -34
  146. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  147. package/dist/agent-farm/servers/tower-terminals.d.ts +23 -2
  148. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  149. package/dist/agent-farm/servers/tower-terminals.js +134 -127
  150. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  151. package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
  152. package/dist/agent-farm/servers/tower-tunnel.js +63 -4
  153. package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
  154. package/dist/agent-farm/servers/tower-types.d.ts +2 -1
  155. package/dist/agent-farm/servers/tower-types.d.ts.map +1 -1
  156. package/dist/agent-farm/servers/tower-utils.d.ts +64 -1
  157. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
  158. package/dist/agent-farm/servers/tower-utils.js +168 -1
  159. package/dist/agent-farm/servers/tower-utils.js.map +1 -1
  160. package/dist/agent-farm/servers/tower-websocket.d.ts +6 -1
  161. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
  162. package/dist/agent-farm/servers/tower-websocket.js +95 -57
  163. package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
  164. package/dist/agent-farm/servers/write-queue.d.ts +35 -0
  165. package/dist/agent-farm/servers/write-queue.d.ts.map +1 -0
  166. package/dist/agent-farm/servers/write-queue.js +56 -0
  167. package/dist/agent-farm/servers/write-queue.js.map +1 -0
  168. package/dist/agent-farm/types.d.ts +39 -0
  169. package/dist/agent-farm/types.d.ts.map +1 -1
  170. package/dist/agent-farm/utils/agent-names.d.ts +2 -2
  171. package/dist/agent-farm/utils/agent-names.d.ts.map +1 -1
  172. package/dist/agent-farm/utils/agent-names.js +3 -3
  173. package/dist/agent-farm/utils/agent-names.js.map +1 -1
  174. package/dist/agent-farm/utils/architect-name.d.ts +2 -2
  175. package/dist/agent-farm/utils/architect-name.d.ts.map +1 -1
  176. package/dist/agent-farm/utils/architect-name.js +3 -3
  177. package/dist/agent-farm/utils/architect-name.js.map +1 -1
  178. package/dist/agent-farm/utils/config.d.ts +13 -0
  179. package/dist/agent-farm/utils/config.d.ts.map +1 -1
  180. package/dist/agent-farm/utils/config.js +33 -1
  181. package/dist/agent-farm/utils/config.js.map +1 -1
  182. package/dist/agent-farm/utils/harness.d.ts +103 -7
  183. package/dist/agent-farm/utils/harness.d.ts.map +1 -1
  184. package/dist/agent-farm/utils/harness.js +126 -19
  185. package/dist/agent-farm/utils/harness.js.map +1 -1
  186. package/dist/agent-farm/utils/message-format.d.ts +8 -0
  187. package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
  188. package/dist/agent-farm/utils/message-format.js +20 -0
  189. package/dist/agent-farm/utils/message-format.js.map +1 -1
  190. package/dist/agent-farm/utils/server-utils.d.ts +80 -4
  191. package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
  192. package/dist/agent-farm/utils/server-utils.js +286 -5
  193. package/dist/agent-farm/utils/server-utils.js.map +1 -1
  194. package/dist/cli.d.ts.map +1 -1
  195. package/dist/cli.js +6 -32
  196. package/dist/cli.js.map +1 -1
  197. package/dist/commands/consult/cli-options.d.ts +34 -0
  198. package/dist/commands/consult/cli-options.d.ts.map +1 -0
  199. package/dist/commands/consult/cli-options.js +67 -0
  200. package/dist/commands/consult/cli-options.js.map +1 -0
  201. package/dist/commands/consult/index.d.ts +56 -2
  202. package/dist/commands/consult/index.d.ts.map +1 -1
  203. package/dist/commands/consult/index.js +272 -28
  204. package/dist/commands/consult/index.js.map +1 -1
  205. package/dist/commands/consult/metrics.d.ts +42 -0
  206. package/dist/commands/consult/metrics.d.ts.map +1 -1
  207. package/dist/commands/consult/metrics.js +129 -9
  208. package/dist/commands/consult/metrics.js.map +1 -1
  209. package/dist/commands/doctor.d.ts.map +1 -1
  210. package/dist/commands/doctor.js +71 -19
  211. package/dist/commands/doctor.js.map +1 -1
  212. package/dist/commands/porch/checks.d.ts +23 -0
  213. package/dist/commands/porch/checks.d.ts.map +1 -1
  214. package/dist/commands/porch/checks.js +60 -0
  215. package/dist/commands/porch/checks.js.map +1 -1
  216. package/dist/commands/porch/config.d.ts +20 -0
  217. package/dist/commands/porch/config.d.ts.map +1 -1
  218. package/dist/commands/porch/config.js +20 -0
  219. package/dist/commands/porch/config.js.map +1 -1
  220. package/dist/commands/porch/index.js +21 -28
  221. package/dist/commands/porch/index.js.map +1 -1
  222. package/dist/commands/porch/next.d.ts.map +1 -1
  223. package/dist/commands/porch/next.js +2 -41
  224. package/dist/commands/porch/next.js.map +1 -1
  225. package/dist/lib/config.d.ts +69 -3
  226. package/dist/lib/config.d.ts.map +1 -1
  227. package/dist/lib/config.js +67 -3
  228. package/dist/lib/config.js.map +1 -1
  229. package/dist/lib/consult-lanes.d.ts +149 -0
  230. package/dist/lib/consult-lanes.d.ts.map +1 -0
  231. package/dist/lib/consult-lanes.js +360 -0
  232. package/dist/lib/consult-lanes.js.map +1 -0
  233. package/dist/lib/forge-contracts.d.ts +9 -0
  234. package/dist/lib/forge-contracts.d.ts.map +1 -1
  235. package/dist/lib/forge-contracts.js.map +1 -1
  236. package/dist/lib/github.d.ts +15 -1
  237. package/dist/lib/github.d.ts.map +1 -1
  238. package/dist/lib/github.js +18 -1
  239. package/dist/lib/github.js.map +1 -1
  240. package/dist/lib/prompt-behavior-metrics.d.ts +67 -0
  241. package/dist/lib/prompt-behavior-metrics.d.ts.map +1 -0
  242. package/dist/lib/prompt-behavior-metrics.js +290 -0
  243. package/dist/lib/prompt-behavior-metrics.js.map +1 -0
  244. package/dist/lib/skeleton.d.ts +22 -1
  245. package/dist/lib/skeleton.d.ts.map +1 -1
  246. package/dist/lib/skeleton.js +120 -0
  247. package/dist/lib/skeleton.js.map +1 -1
  248. package/dist/lib/test-env.d.ts +74 -0
  249. package/dist/lib/test-env.d.ts.map +1 -0
  250. package/dist/lib/test-env.js +92 -0
  251. package/dist/lib/test-env.js.map +1 -0
  252. package/dist/terminal/attach-replay.d.ts +39 -0
  253. package/dist/terminal/attach-replay.d.ts.map +1 -0
  254. package/dist/terminal/attach-replay.js +76 -0
  255. package/dist/terminal/attach-replay.js.map +1 -0
  256. package/dist/terminal/pty-manager.d.ts +2 -0
  257. package/dist/terminal/pty-manager.d.ts.map +1 -1
  258. package/dist/terminal/pty-manager.js +51 -23
  259. package/dist/terminal/pty-manager.js.map +1 -1
  260. package/dist/terminal/pty-session.d.ts +201 -1
  261. package/dist/terminal/pty-session.d.ts.map +1 -1
  262. package/dist/terminal/pty-session.js +327 -46
  263. package/dist/terminal/pty-session.js.map +1 -1
  264. package/dist/terminal/ring-buffer.d.ts +39 -6
  265. package/dist/terminal/ring-buffer.d.ts.map +1 -1
  266. package/dist/terminal/ring-buffer.js +74 -6
  267. package/dist/terminal/ring-buffer.js.map +1 -1
  268. package/dist/terminal/session-manager.d.ts +53 -0
  269. package/dist/terminal/session-manager.d.ts.map +1 -1
  270. package/dist/terminal/session-manager.js +94 -9
  271. package/dist/terminal/session-manager.js.map +1 -1
  272. package/dist/terminal/session-screen.d.ts +116 -0
  273. package/dist/terminal/session-screen.d.ts.map +1 -0
  274. package/dist/terminal/session-screen.js +180 -0
  275. package/dist/terminal/session-screen.js.map +1 -0
  276. package/dist/terminal/shellper-main.js +2 -1
  277. package/dist/terminal/shellper-main.js.map +1 -1
  278. package/dist/terminal/shellper-process.d.ts +1 -1
  279. package/dist/terminal/shellper-process.d.ts.map +1 -1
  280. package/dist/terminal/shellper-process.js +17 -8
  281. package/dist/terminal/shellper-process.js.map +1 -1
  282. package/dist/terminal/shellper-replay-buffer.d.ts +69 -7
  283. package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -1
  284. package/dist/terminal/shellper-replay-buffer.js +167 -31
  285. package/dist/terminal/shellper-replay-buffer.js.map +1 -1
  286. package/package.json +13 -8
  287. package/scripts/forge/gitea/pr-view.sh +4 -1
  288. package/scripts/forge/github/pr-view.sh +1 -1
  289. package/scripts/forge/gitlab/pr-view.sh +4 -1
  290. package/skeleton/.claude/skills/afx/SKILL.md +68 -1
  291. package/skeleton/.claude/skills/arch-init/SKILL.md +22 -9
  292. package/skeleton/.claude/skills/arch-save/SKILL.md +183 -0
  293. package/skeleton/.claude/skills/codev/SKILL.md +31 -0
  294. package/skeleton/.claude/skills/runnable-worktrees/SKILL.md +119 -0
  295. package/skeleton/.codex/skills/afx/SKILL.md +68 -1
  296. package/skeleton/.codex/skills/arch-init/SKILL.md +22 -9
  297. package/skeleton/.codex/skills/arch-save/SKILL.md +183 -0
  298. package/skeleton/.codex/skills/codev/SKILL.md +31 -0
  299. package/skeleton/.codex/skills/runnable-worktrees/SKILL.md +119 -0
  300. package/skeleton/protocols/air/builder-prompt.md +28 -47
  301. package/skeleton/protocols/air/consult-types/impl-review.md +17 -34
  302. package/skeleton/protocols/air/consult-types/pr-review.md +14 -37
  303. package/skeleton/protocols/air/prompts/implement.md +20 -73
  304. package/skeleton/protocols/air/prompts/pr.md +22 -54
  305. package/skeleton/protocols/air/protocol.md +40 -71
  306. package/skeleton/protocols/aspir/builder-prompt.md +29 -66
  307. package/skeleton/protocols/aspir/consult-types/impl-review.md +17 -44
  308. package/skeleton/protocols/aspir/consult-types/phase-review.md +17 -44
  309. package/skeleton/protocols/aspir/consult-types/plan-review.md +14 -38
  310. package/skeleton/protocols/aspir/consult-types/pr-review.md +13 -39
  311. package/skeleton/protocols/aspir/consult-types/spec-review.md +13 -33
  312. package/skeleton/protocols/aspir/prompts/implement.md +27 -196
  313. package/skeleton/protocols/aspir/prompts/plan.md +21 -85
  314. package/skeleton/protocols/aspir/prompts/review.md +29 -228
  315. package/skeleton/protocols/aspir/prompts/specify.md +25 -111
  316. package/skeleton/protocols/aspir/protocol.json +10 -0
  317. package/skeleton/protocols/aspir/protocol.md +36 -82
  318. package/skeleton/protocols/bugfix/builder-prompt.md +23 -45
  319. package/skeleton/protocols/bugfix/consult-types/impl-review.md +21 -45
  320. package/skeleton/protocols/bugfix/consult-types/pr-review.md +18 -52
  321. package/skeleton/protocols/bugfix/prompts/fix.md +16 -61
  322. package/skeleton/protocols/bugfix/prompts/investigate.md +18 -62
  323. package/skeleton/protocols/bugfix/prompts/pr.md +22 -57
  324. package/skeleton/protocols/bugfix/protocol.md +44 -50
  325. package/skeleton/protocols/experiment/builder-prompt.md +25 -58
  326. package/skeleton/protocols/experiment/protocol.md +22 -188
  327. package/skeleton/protocols/experiment/templates/notes.md +11 -71
  328. package/skeleton/protocols/maintain/builder-prompt.md +24 -45
  329. package/skeleton/protocols/maintain/consult-types/impl-review.md +17 -44
  330. package/skeleton/protocols/maintain/consult-types/pr-review.md +13 -39
  331. package/skeleton/protocols/maintain/prompts/maintain.md +1 -1
  332. package/skeleton/protocols/maintain/protocol.md +32 -266
  333. package/skeleton/protocols/maintain/templates/maintenance-run.md +11 -0
  334. package/skeleton/protocols/pir/builder-prompt.md +31 -64
  335. package/skeleton/protocols/pir/consult-types/impl-review.md +17 -50
  336. package/skeleton/protocols/pir/consult-types/pr-review.md +11 -40
  337. package/skeleton/protocols/pir/prompts/implement.md +2 -3
  338. package/skeleton/protocols/pir/prompts/plan.md +1 -4
  339. package/skeleton/protocols/pir/prompts/review.md +2 -2
  340. package/skeleton/protocols/pir/protocol.md +54 -177
  341. package/skeleton/protocols/research/builder-prompt.md +27 -58
  342. package/skeleton/protocols/research/protocol.md +28 -153
  343. package/skeleton/protocols/spike/builder-prompt.md +30 -48
  344. package/skeleton/protocols/spike/protocol.md +24 -107
  345. package/skeleton/protocols/spike/templates/findings.md +9 -39
  346. package/skeleton/protocols/spir/builder-prompt.md +33 -62
  347. package/skeleton/protocols/spir/consult-types/impl-review.md +17 -44
  348. package/skeleton/protocols/spir/consult-types/phase-review.md +17 -44
  349. package/skeleton/protocols/spir/consult-types/plan-review.md +14 -38
  350. package/skeleton/protocols/spir/consult-types/pr-review.md +13 -39
  351. package/skeleton/protocols/spir/consult-types/spec-review.md +13 -33
  352. package/skeleton/protocols/spir/prompts/implement.md +26 -195
  353. package/skeleton/protocols/spir/prompts/plan.md +20 -84
  354. package/skeleton/protocols/spir/prompts/review.md +28 -227
  355. package/skeleton/protocols/spir/prompts/specify.md +24 -110
  356. package/skeleton/protocols/spir/protocol.json +10 -0
  357. package/skeleton/protocols/spir/protocol.md +84 -633
  358. package/skeleton/protocols/spir/templates/plan.md +28 -147
  359. package/skeleton/protocols/spir/templates/review.md +21 -80
  360. package/skeleton/protocols/spir/templates/spec.md +24 -118
  361. package/skeleton/resources/commands/agent-farm.md +262 -0
  362. package/skeleton/resources/commands/consult.md +236 -8
  363. package/skeleton/resources/commands/overview.md +1 -0
  364. package/skeleton/roles/architect.md +67 -317
  365. package/skeleton/roles/builder.md +76 -191
  366. package/skeleton/templates/AGENTS.md +2 -0
  367. package/skeleton/templates/CLAUDE.md +2 -0
  368. package/templates/3d-viewer.html +32 -4
  369. package/templates/open.html +58 -12
  370. package/templates/tower.html +65 -9
  371. package/templates/vendor/three-3MFLoader.js +1478 -0
  372. package/templates/vendor/three-STLLoader.js +410 -0
  373. package/templates/vendor/three-TrackballControls.js +828 -0
  374. package/templates/vendor/three-fflate.module.js +2474 -0
  375. package/templates/vendor/three.module.js +53044 -0
  376. package/dashboard-dist/assets/index-BZ1x7x1X.js.map +0 -1
  377. package/dashboard-dist/assets/index-DB1KBSNE.css +0 -32
  378. package/dist/agent-farm/servers/send-buffer.d.ts +0 -59
  379. package/dist/agent-farm/servers/send-buffer.d.ts.map +0 -1
  380. package/dist/agent-farm/servers/send-buffer.js +0 -116
  381. package/dist/agent-farm/servers/send-buffer.js.map +0 -1
  382. package/skeleton/porch/prompts/defend.md +0 -108
  383. package/skeleton/porch/prompts/diagnose.md +0 -70
  384. package/skeleton/porch/prompts/evaluate.md +0 -132
  385. package/skeleton/porch/prompts/fix.md +0 -59
  386. package/skeleton/porch/prompts/implement.md +0 -88
  387. package/skeleton/porch/prompts/plan.md +0 -74
  388. package/skeleton/porch/prompts/pr.md +0 -84
  389. package/skeleton/porch/prompts/review.md +0 -249
  390. package/skeleton/porch/prompts/specify.md +0 -53
  391. package/skeleton/porch/prompts/test.md +0 -63
  392. package/skeleton/protocols/aspir/templates/plan.md +0 -184
  393. package/skeleton/protocols/aspir/templates/review.md +0 -120
  394. package/skeleton/protocols/aspir/templates/spec.md +0 -154
@@ -2,56 +2,126 @@
2
2
  * Standalone replay buffer for the shellper process.
3
3
  *
4
4
  * Unlike RingBuffer (which stores lines), this stores raw byte chunks
5
- * to preserve exact terminal output including escape sequences. It tracks
6
- * the total bytes stored and evicts oldest chunks when the limit is exceeded.
5
+ * to preserve exact terminal output including escape sequences. It evicts
6
+ * the oldest chunks when either the line or the byte ceiling is exceeded;
7
+ * both ceilings are needed, because a full-screen TUI emits almost no
8
+ * newlines and so is bounded only by the byte one (#1205).
7
9
  *
8
10
  * This module has NO dependencies beyond Node.js built-ins so the shellper
9
11
  * process doesn't need to pull in the full package dependency tree.
12
+ * (shellper-protocol.ts is a sibling module under the same constraint.)
10
13
  */
14
+ import { REPLAY_PAYLOAD_MAX } from './shellper-protocol.js';
15
+ /**
16
+ * Byte ceiling on what this buffer retains (#1205). Until it existed the buffer
17
+ * was bounded only by line count, and a full-screen TUI (which redraws in place
18
+ * and emits almost no newlines) grew it without limit for the life of the
19
+ * session — multi-GB in the field.
20
+ *
21
+ * Derived from REPLAY_PAYLOAD_MAX rather than written as its own literal, and
22
+ * that derivation is the point: every send is capped at REPLAY_PAYLOAD_MAX and
23
+ * ShellperProcess.getReplayData() has no production callers, so it is provably
24
+ * the most that can ever leave the process. Bytes retained above it are
25
+ * unreadable by any consumer and are pure resident cost. Tying the two together
26
+ * keeps that true if the send cap ever moves — retaining more than can be sent
27
+ * would be waste, retaining less would make the send cap unreachable.
28
+ *
29
+ * This is a retention policy, not a wire constraint, which is why it lives here
30
+ * next to the buffer rather than in shellper-protocol.ts.
31
+ */
32
+ export const REPLAY_BUFFER_MAX_BYTES = REPLAY_PAYLOAD_MAX;
33
+ const ESC = 0x1b;
34
+ /**
35
+ * How far past a byte-driven trim point we scan looking for an ESC to align to.
36
+ * Bounded so alignment can never turn into a long scan over ESC-free data.
37
+ */
38
+ const ESC_ALIGN_SCAN_LIMIT = 4096;
39
+ /**
40
+ * Nudge a trim offset forward to the next ESC byte, so a cut doesn't land in
41
+ * the middle of an escape sequence and leave the client rendering its tail as
42
+ * literal garbage. Returns `offset` unchanged when no ESC is within the scan
43
+ * window, which is the correct fallback: a raw cut is what we'd have done
44
+ * anyway, and the post-connect repaint nudge covers the rest.
45
+ *
46
+ * Only byte-driven cuts need this. A newline-driven cut lands just past a
47
+ * `\n`, which can never appear inside an escape sequence, so it is already
48
+ * safe and aligning it would discard content for nothing.
49
+ */
50
+ function alignToEscape(buf, offset) {
51
+ const limit = Math.min(buf.length, offset + ESC_ALIGN_SCAN_LIMIT);
52
+ for (let i = offset; i < limit; i++) {
53
+ if (buf[i] === ESC)
54
+ return i;
55
+ }
56
+ return offset;
57
+ }
58
+ function countNewlines(buf) {
59
+ let count = 0;
60
+ for (let i = 0; i < buf.length; i++) {
61
+ if (buf[i] === 0x0a)
62
+ count++;
63
+ }
64
+ return count;
65
+ }
11
66
  export class ShellperReplayBuffer {
12
67
  chunks = [];
13
68
  totalBytes = 0;
14
69
  maxLines;
70
+ maxBytes;
15
71
  lineCount = 0;
16
72
  /**
17
73
  * @param maxLines Maximum number of lines to retain. Lines are delimited
18
74
  * by newline characters in the raw data stream.
75
+ * @param maxBytes Maximum bytes to retain. Required because `maxLines` alone
76
+ * does not bound anything for a full-screen TUI: such an app redraws in
77
+ * place via cursor addressing and emits almost no newlines, so the line
78
+ * ceiling never fires and the buffer grows for the life of the session
79
+ * (#1205). Defaults to REPLAY_BUFFER_MAX_BYTES.
19
80
  */
20
- constructor(maxLines = 10_000) {
81
+ constructor(maxLines = 10_000, maxBytes = REPLAY_BUFFER_MAX_BYTES) {
21
82
  this.maxLines = maxLines;
83
+ this.maxBytes = maxBytes;
22
84
  }
23
85
  /**
24
86
  * Append raw PTY output data to the buffer.
25
- * Evicts oldest chunks if the line count exceeds maxLines.
87
+ * Evicts oldest chunks if either the line or the byte ceiling is exceeded.
26
88
  */
27
89
  append(data) {
28
90
  const buf = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;
29
91
  if (buf.length === 0)
30
92
  return;
31
- // Count newlines in this chunk
32
- let newLines = 0;
33
- for (let i = 0; i < buf.length; i++) {
34
- if (buf[i] === 0x0a)
35
- newLines++;
36
- }
37
93
  this.chunks.push(buf);
38
94
  this.totalBytes += buf.length;
39
- this.lineCount += newLines;
40
- // Evict oldest chunks if we've exceeded the line limit
41
- while (this.lineCount > this.maxLines && this.chunks.length > 1) {
95
+ this.lineCount += countNewlines(buf);
96
+ this.evict();
97
+ }
98
+ /**
99
+ * Drop the oldest data until both ceilings are satisfied.
100
+ *
101
+ * Trimming from the front can cut mid-escape-sequence or discard an
102
+ * alt-screen-enter, which is why it was rejected in #1047. It is accepted
103
+ * here because every layer above already does exactly this (the send cap,
104
+ * the ring seed, the frame-skip path) and relies on the client's
105
+ * post-connect repaint nudge; an unbounded buffer, by contrast, killed
106
+ * sessions. Byte-driven cuts are ESC-aligned to narrow the window in which
107
+ * a client renders a truncated sequence as literal text.
108
+ */
109
+ evict() {
110
+ while ((this.lineCount > this.maxLines || this.totalBytes > this.maxBytes) &&
111
+ this.chunks.length > 1) {
42
112
  const oldest = this.chunks[0];
43
- let removedLines = 0;
44
- for (let i = 0; i < oldest.length; i++) {
45
- if (oldest[i] === 0x0a)
46
- removedLines++;
47
- }
48
113
  this.chunks.shift();
49
114
  this.totalBytes -= oldest.length;
50
- this.lineCount -= removedLines;
115
+ this.lineCount -= countNewlines(oldest);
51
116
  }
52
- // Handle edge case: single chunk exceeds line limit.
53
- // Trim from the front to keep only the last maxLines lines.
54
- if (this.lineCount > this.maxLines && this.chunks.length === 1) {
117
+ // A single remaining chunk can still exceed either ceiling on its own.
118
+ if (this.chunks.length !== 1)
119
+ return;
120
+ // Line ceiling: cut just past the newline that leaves maxLines behind.
121
+ // A newline never appears inside an escape sequence, so this cut is
122
+ // inherently safe and must not be ESC-aligned (that would discard content
123
+ // for no benefit).
124
+ if (this.lineCount > this.maxLines) {
55
125
  const chunk = this.chunks[0];
56
126
  let linesToSkip = this.lineCount - this.maxLines;
57
127
  let offset = 0;
@@ -60,21 +130,87 @@ export class ShellperReplayBuffer {
60
130
  linesToSkip--;
61
131
  offset++;
62
132
  }
63
- this.chunks[0] = chunk.subarray(offset);
64
- this.totalBytes = this.chunks[0].length;
65
- this.lineCount = this.maxLines;
133
+ this.replaceSoleChunk(chunk.subarray(offset));
134
+ }
135
+ // Byte ceiling: keep the tail. This cut can land anywhere, so align it.
136
+ const chunk = this.chunks[0];
137
+ if (chunk.length > this.maxBytes) {
138
+ this.replaceSoleChunk(chunk.subarray(alignToEscape(chunk, chunk.length - this.maxBytes)));
66
139
  }
67
140
  }
68
141
  /**
69
- * Get all buffered data as a single concatenated Buffer.
70
- * Used for the REPLAY frame on reconnection.
142
+ * Replace the only chunk with a trimmed version of itself.
143
+ *
144
+ * Copies rather than retaining the `subarray` view: a view keeps the entire
145
+ * original allocation alive, so trimming an oversized chunk down to the
146
+ * ceiling would free none of the memory this class exists to bound. The copy
147
+ * is at most `maxBytes` and only happens on the rare path where a single
148
+ * append exceeded a ceiling by itself.
71
149
  */
72
- getReplayData() {
150
+ replaceSoleChunk(next) {
151
+ const owned = Buffer.from(next);
152
+ this.chunks[0] = owned;
153
+ this.totalBytes = owned.length;
154
+ this.lineCount = countNewlines(owned);
155
+ }
156
+ /**
157
+ * Get buffered data as a single Buffer, for the REPLAY frame on reconnection.
158
+ *
159
+ * @param maxBytes When given, return at most this many bytes (the most recent
160
+ * ones). The tail is collected by walking `chunks` backwards and slicing
161
+ * only the boundary chunk, so the allocation is O(maxBytes) rather than
162
+ * O(history).
163
+ *
164
+ * That distinction is the whole point (#1205). This runs on *every* client
165
+ * connect, and the caller's cap used to be applied to the result — meaning a
166
+ * multi-GB buffer allocated a multi-GB copy on top of itself at exactly the
167
+ * moment a user opened the terminal, then threw almost all of it away. Peak
168
+ * footprint doubled, and sessions were killed for it. Capping here bounds the
169
+ * spike regardless of how large the buffer has already grown, which also
170
+ * makes this correct for a buffer that accumulated before any byte ceiling
171
+ * existed.
172
+ */
173
+ getReplayData(maxBytes) {
73
174
  if (this.chunks.length === 0)
74
175
  return Buffer.alloc(0);
75
- if (this.chunks.length === 1)
76
- return this.chunks[0];
77
- return Buffer.concat(this.chunks);
176
+ if (maxBytes === undefined || this.totalBytes <= maxBytes) {
177
+ // Single-chunk fast path returns the internal Buffer *by reference*
178
+ // rather than copying. Safe because nothing mutates chunks in place and
179
+ // callers only read, but it is an aliasing property the old
180
+ // always-concat version did not have: a caller that mutated the result
181
+ // would corrupt the buffer. Copy here if that ever stops being true.
182
+ if (this.chunks.length === 1)
183
+ return this.chunks[0];
184
+ return Buffer.concat(this.chunks, this.totalBytes);
185
+ }
186
+ if (maxBytes <= 0)
187
+ return Buffer.alloc(0);
188
+ const tail = [];
189
+ let collected = 0;
190
+ for (let i = this.chunks.length - 1; i >= 0 && collected < maxBytes; i--) {
191
+ const chunk = this.chunks[i];
192
+ const remaining = maxBytes - collected;
193
+ if (chunk.length <= remaining) {
194
+ tail.push(chunk);
195
+ collected += chunk.length;
196
+ continue;
197
+ }
198
+ // Boundary chunk: take only its tail, aligned off a mid-sequence cut.
199
+ //
200
+ // `break` is load-bearing. ESC alignment moves the cut *forward*, so the
201
+ // piece is usually shorter than `remaining` — without breaking, the loop
202
+ // would see spare capacity and keep taking bytes from still-older chunks,
203
+ // stitching fragments across a gap into what must be one contiguous
204
+ // suffix. That also re-admits the unaligned mid-sequence prefix this
205
+ // alignment exists to prevent. Returning fewer than `maxBytes` is the
206
+ // accepted contract; returning a spliced stream is not.
207
+ const piece = chunk.subarray(alignToEscape(chunk, chunk.length - remaining));
208
+ tail.push(piece);
209
+ collected += piece.length;
210
+ break;
211
+ }
212
+ tail.reverse();
213
+ return Buffer.concat(tail, collected);
78
214
  }
79
215
  /** Current number of bytes stored. */
80
216
  get size() {
@@ -1 +1 @@
1
- {"version":3,"file":"shellper-replay-buffer.js","sourceRoot":"","sources":["../../src/terminal/shellper-replay-buffer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shellper-replay-buffer.js","sourceRoot":"","sources":["../../src/terminal/shellper-replay-buffer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cluesmith/codev",
3
- "version": "3.2.4",
3
+ "version": "3.3.1",
4
4
  "description": "Codev CLI - AI-assisted software development framework",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,9 @@
23
23
  "dependencies": {
24
24
  "@anthropic-ai/claude-agent-sdk": "^0.2.41",
25
25
  "@google/genai": "^1.0.0",
26
- "@openai/codex-sdk": "^0.142.5",
26
+ "@openai/codex-sdk": "^0.146.0",
27
+ "@xterm/addon-serialize": "^0.14.0",
28
+ "@xterm/headless": "^6.0.0",
27
29
  "better-sqlite3": "^12.10.0",
28
30
  "chalk": "^5.3.0",
29
31
  "commander": "^12.1.0",
@@ -33,23 +35,25 @@
33
35
  "open": "^10.1.0",
34
36
  "tree-kill": "^1.2.2",
35
37
  "ws": "^8.18.0",
36
- "@cluesmith/codev-core": "3.2.4"
38
+ "@cluesmith/codev-core": "3.3.1",
39
+ "@cluesmith/codev-sdk": "3.3.1",
40
+ "@cluesmith/codev-types": "3.3.1"
37
41
  },
38
42
  "devDependencies": {
39
43
  "@playwright/test": "^1.58.0",
40
- "@xterm/xterm": "^5.5.0",
41
44
  "@types/better-sqlite3": "^7.6.13",
42
45
  "@types/js-yaml": "^4.0.9",
43
46
  "@types/node": "^22.10.1",
44
47
  "@types/ws": "^8.18.1",
45
48
  "@vitest/coverage-v8": "^4.0.18",
49
+ "@xterm/xterm": "^5.5.0",
46
50
  "jsdom": "^28.1.0",
47
51
  "playwright": "^1.58.0",
52
+ "three": "0.160.0",
48
53
  "tsx": "^4.19.2",
49
54
  "typescript": "^6.0.3",
50
55
  "vitest": "^4.0.15",
51
- "@cluesmith/codev-web": "0.0.0",
52
- "@cluesmith/codev-types": "3.2.4"
56
+ "@cluesmith/codev-web": "0.0.0"
53
57
  },
54
58
  "engines": {
55
59
  "node": ">=20.0.0"
@@ -71,8 +75,9 @@
71
75
  },
72
76
  "scripts": {
73
77
  "clean": "rm -rf dist",
74
- "build": "pnpm clean && tsc && pnpm build:dashboard && pnpm copy-skeleton",
75
- "build:dashboard": "cd ../../apps/web && pnpm build && rm -rf ../../packages/codev/dashboard-dist && cp -r dist ../../packages/codev/dashboard-dist",
78
+ "build": "pnpm --filter \"@cluesmith/codev^...\" build && pnpm clean && tsc && pnpm bundle-assets",
79
+ "bundle-assets": "pnpm copy-dashboard && pnpm copy-skeleton && node ./scripts/copy-three.mjs",
80
+ "copy-dashboard": "rm -rf dashboard-dist && cp -r ../../apps/web/dist dashboard-dist",
76
81
  "dev:dashboard": "cd ../../apps/web && pnpm dev",
77
82
  "copy-skeleton": "rm -rf skeleton && cp -r ../../codev-skeleton skeleton",
78
83
  "dev": "tsx src/cli.ts",
@@ -1,3 +1,6 @@
1
1
  #!/bin/sh
2
2
  # Forge concept: pr-view (Gitea via tea CLI)
3
- exec tea pulls view "$CODEV_PR_NUMBER" --output json
3
+ # Sets `url` to the PR's browser page (`html_url`). Gitea's own `url` field is
4
+ # the API endpoint (would render raw JSON in a browser), so we prefer `html_url`
5
+ # and fall back to the existing `url` only if `html_url` is absent.
6
+ tea pulls view "$CODEV_PR_NUMBER" --output json | jq '.url = (.html_url // .url)'
@@ -7,5 +7,5 @@ if [ "$CODEV_INCLUDE_COMMENTS" = "1" ]; then
7
7
  exec gh pr view "$CODEV_PR_NUMBER" --comments
8
8
  else
9
9
  exec gh pr view "$CODEV_PR_NUMBER" \
10
- --json title,body,state,author,baseRefName,headRefName,additions,deletions
10
+ --json title,body,state,url,author,baseRefName,headRefName,additions,deletions
11
11
  fi
@@ -1,3 +1,6 @@
1
1
  #!/bin/sh
2
2
  # Forge concept: pr-view (GitLab via glab CLI)
3
- exec glab mr view "$CODEV_PR_NUMBER" --output json
3
+ # Adds a `url` field mapped from GitLab's `web_url` (the MR's browser page);
4
+ # all other fields glab emits are passed through unchanged. `. + {url: …}` is
5
+ # non-destructive — if `web_url` is absent, `url` is null (optional by contract).
6
+ glab mr view "$CODEV_PR_NUMBER" --output json | jq '. + {url: .web_url}'
@@ -69,6 +69,60 @@ afx send 0042 "PR approved, please merge"
69
69
  afx send 0585 "check the test output" --file /tmp/test-results.txt
70
70
  ```
71
71
 
72
+ ## afx interrupt
73
+
74
+ Sends an ESC keystroke to a builder's PTY — the only thing that reaches it **mid-turn**.
75
+
76
+ ```
77
+ afx interrupt <builder>
78
+ ```
79
+
80
+ | Flag | Description |
81
+ |------|-------------|
82
+ | `--no-enter` | Send ESC alone, without the trailing Enter |
83
+
84
+ A builder chaining foreground waits inside one turn queues every `afx send` unread — including your order
85
+ to stop. ESC ends the turn so the queue processes. Distinct from `afx send --interrupt` (Ctrl+C).
86
+
87
+ ```bash
88
+ afx interrupt 0042
89
+ afx send 0042 "That producer died — stop waiting and report."
90
+ ```
91
+
92
+ ## afx refresh
93
+
94
+ Refreshes a builder's context: save working state → `/clear` → re-orient. Use when a builder's context window
95
+ is exhausted; `afx spawn --resume` reattaches the *same* conversation and does **not** give it a fresh one.
96
+
97
+ ```
98
+ afx refresh <builder>
99
+ ```
100
+
101
+ | Flag | Description |
102
+ |------|-------------|
103
+ | `--dry-run` | Print what would be sent; write nothing to the builder |
104
+ | `--note <text>` | Extra context appended to the re-orientation |
105
+ | `--file <path>` | Append file content (48KB max, read from *your* filesystem) |
106
+ | `--interrupt-first` | ESC before the save request, for a builder already wedged |
107
+ | `--mode <strict\|soft>` | Override mode if it cannot be detected |
108
+ | `--timeout <seconds>` | Wait for the save-state receipt (default 300) |
109
+ | `--min-bytes <n>` | Minimum state-file size to accept (default 1000) |
110
+ | `--quiet-window <ms>` | Terminal silence counting as turn-ended (default 1500) |
111
+
112
+ Every gate fails safe: if the state file never arrives, carries a stale nonce, is a stub, is still being
113
+ written, or the builder will not go quiet, the command **aborts without clearing** and exits non-zero,
114
+ naming the gate. Requires a harness with in-session context clearing (Claude Code); others abort loudly.
115
+
116
+ `afx reset` is a deprecated alias: it still works, prints a one-line notice to stderr, and will be removed
117
+ in a future release.
118
+
119
+ ```bash
120
+ afx refresh 0042 --dry-run # inspect first — touches nothing
121
+ afx refresh 0042
122
+ afx refresh 0042 --note "PR #90 merged while you were mid-phase. Rebase first."
123
+ afx refresh 0042 --interrupt-first # builder is wedged mid-turn
124
+ ```
125
+
72
126
  ## afx cleanup
73
127
 
74
128
  Removes a builder's worktree and branch after work is done.
@@ -144,7 +198,20 @@ afx cron enable <name> # Enable
144
198
  afx cron disable <name> # Disable
145
199
  ```
146
200
 
147
- There is NO `afx cron add` — create YAML files in `.af-cron/` directly.
201
+ There is NO `afx cron add` — create YAML files in `.af-cron/` directly:
202
+
203
+ ```yaml
204
+ name: Service Health Check # required, unique per workspace
205
+ schedule: "*/15 * * * *" # required, cron expression (or @hourly/@daily/@startup)
206
+ command: ./health-check.sh # required, run via shell
207
+ message: "Health alert: ${output}" # required, ${output} = trimmed command output
208
+ condition: "exitCode != 0" # optional JS expression, see below
209
+ target: architect # optional, default architect
210
+ timeout: 30 # optional, seconds, default 30
211
+ enabled: true # optional, default true
212
+ ```
213
+
214
+ `condition` is a JavaScript expression with two variables in scope: `output` (string — the command's trimmed output) and `exitCode` (number — 0 on success, the command's exit code on non-zero exit, 124 on timeout, -1 on spawn failure). With a `condition`, the message is delivered exactly when it evaluates truthy — including on failed runs (e.g. `exitCode != 0` alerts when the command fails). Without a `condition`, the message is delivered only when the command exits 0.
148
215
 
149
216
  ## Other commands
150
217
 
@@ -63,7 +63,11 @@ not choose; a state save happens at a boundary **you** pick, with a summary
63
63
  **you** curate. That is strictly better, so use it:
64
64
 
65
65
  ```
66
- /arch-init (recover) → work → save at a checkpoint → suggest /clear → human /clears → /arch-init → …
66
+ /arch-init (recover) → work → save at a checkpoint → refresh → /arch-init (recover) → …
67
+ │
68
+ packaged: /arch-save ─────────────────┤ stops monitors, saves, clears,
69
+ │ schedules /arch-init
70
+ manual: suggest /clear → human clears ┘ then human runs /arch-init
67
71
  ```
68
72
 
69
73
  **When to save.** Save at a *resumable boundary* — a point a fresh session
@@ -99,17 +103,26 @@ plus the most recent dated section*, so a save must leave exactly that behind:
99
103
  dumps or raw tool output. Include only: current focus, open loops, and the
100
104
  instructions a fresh session needs to resume.
101
105
 
102
- **Then — and only then — suggest `/clear`.** Save first, *then* tell the human
103
- it is a good time to clear. You cannot clear your own context and must never
104
- decide unilaterally to lose it; keeping the irreversible step behind a human
105
- keystroke means accepting the suggestion can never lose anything, because the
106
- save already happened. Make the suggestion **advisory, never nagging**, and
107
- only right after a save — e.g.:
106
+ **Then — and only then — suggest the refresh.** Save first, *then* tell the
107
+ human it is a good time to clear. You must never decide unilaterally to lose
108
+ your context; keeping the irreversible step behind a human decision means
109
+ accepting the suggestion can never lose anything, because the save already
110
+ happened. Make the suggestion **advisory, never nagging**, and only right
111
+ after a save — e.g.:
108
112
 
109
- > State saved to `codev/state/<name>.md` — good time to `/clear` if this
113
+ > State saved to `codev/state/<name>.md` — good time to refresh if this
110
114
  > session is feeling heavy.
111
115
 
112
- Do not repeat it, and do not prompt to `/clear` at any other time.
116
+ Do not repeat it, and do not prompt for it at any other time.
117
+
118
+ **`/arch-save` packages this whole loop**, and is the preferred path when the
119
+ owner directs a refresh: it stops your monitors, writes the pruned state file,
120
+ clears, and schedules `/arch-init` to bring you back — in that order, which is
121
+ the part that matters. The save discipline above is what it performs at its
122
+ step 3, so this section remains the source of truth for *how to write the
123
+ file*; `/arch-save` is the source of truth for *the sequence*. The manual path
124
+ (save → human clears → `/arch-init`) stays valid and is the fallback when
125
+ Tower is unavailable.
113
126
 
114
127
  ## Guardrails (architect-wide; the state file may add more)
115
128