@cluesmith/codev 3.2.4 → 3.3.0

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 (358) hide show
  1. package/dashboard-dist/assets/index-BZRTEMtH.css +32 -0
  2. package/dashboard-dist/assets/{index-BZ1x7x1X.js → index-JCbkpAcV.js} +33 -33
  3. package/dashboard-dist/assets/index-JCbkpAcV.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 +142 -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 +19 -0
  40. package/dist/agent-farm/commands/reset.d.ts.map +1 -0
  41. package/dist/agent-farm/commands/reset.js +292 -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/db/index.d.ts +1 -1
  57. package/dist/agent-farm/db/index.d.ts.map +1 -1
  58. package/dist/agent-farm/db/index.js +80 -1
  59. package/dist/agent-farm/db/index.js.map +1 -1
  60. package/dist/agent-farm/db/mailbox.d.ts +222 -0
  61. package/dist/agent-farm/db/mailbox.d.ts.map +1 -0
  62. package/dist/agent-farm/db/mailbox.js +304 -0
  63. package/dist/agent-farm/db/mailbox.js.map +1 -0
  64. package/dist/agent-farm/db/schema.d.ts +1 -1
  65. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  66. package/dist/agent-farm/db/schema.js +35 -0
  67. package/dist/agent-farm/db/schema.js.map +1 -1
  68. package/dist/agent-farm/db/types.d.ts +45 -0
  69. package/dist/agent-farm/db/types.d.ts.map +1 -1
  70. package/dist/agent-farm/db/types.js.map +1 -1
  71. package/dist/agent-farm/lib/builder-lookup.d.ts +1 -1
  72. package/dist/agent-farm/lib/builder-lookup.js +2 -2
  73. package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
  74. package/dist/agent-farm/lib/reconnect-backoff.d.ts +54 -0
  75. package/dist/agent-farm/lib/reconnect-backoff.d.ts.map +1 -0
  76. package/dist/agent-farm/lib/reconnect-backoff.js +47 -0
  77. package/dist/agent-farm/lib/reconnect-backoff.js.map +1 -0
  78. package/dist/agent-farm/lib/tower-client.d.ts +16 -6
  79. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
  80. package/dist/agent-farm/lib/tower-client.js +37 -6
  81. package/dist/agent-farm/lib/tower-client.js.map +1 -1
  82. package/dist/agent-farm/lib/tunnel-client.d.ts +69 -1
  83. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  84. package/dist/agent-farm/lib/tunnel-client.js +218 -27
  85. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  86. package/dist/agent-farm/servers/cron-delivery.d.ts +72 -0
  87. package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -0
  88. package/dist/agent-farm/servers/cron-delivery.js +80 -0
  89. package/dist/agent-farm/servers/cron-delivery.js.map +1 -0
  90. package/dist/agent-farm/servers/delayed-send.d.ts +85 -0
  91. package/dist/agent-farm/servers/delayed-send.d.ts.map +1 -0
  92. package/dist/agent-farm/servers/delayed-send.js +165 -0
  93. package/dist/agent-farm/servers/delayed-send.js.map +1 -0
  94. package/dist/agent-farm/servers/gate-profiles.d.ts +67 -0
  95. package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -0
  96. package/dist/agent-farm/servers/gate-profiles.js +113 -0
  97. package/dist/agent-farm/servers/gate-profiles.js.map +1 -0
  98. package/dist/agent-farm/servers/mailbox-delivery.d.ts +370 -0
  99. package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -0
  100. package/dist/agent-farm/servers/mailbox-delivery.js +617 -0
  101. package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -0
  102. package/dist/agent-farm/servers/mailbox-wiring.d.ts +125 -0
  103. package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -0
  104. package/dist/agent-farm/servers/mailbox-wiring.js +425 -0
  105. package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -0
  106. package/dist/agent-farm/servers/message-write.d.ts +53 -1
  107. package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
  108. package/dist/agent-farm/servers/message-write.js +63 -0
  109. package/dist/agent-farm/servers/message-write.js.map +1 -1
  110. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  111. package/dist/agent-farm/servers/overview.js +23 -4
  112. package/dist/agent-farm/servers/overview.js.map +1 -1
  113. package/dist/agent-farm/servers/render-gate.d.ts +141 -0
  114. package/dist/agent-farm/servers/render-gate.d.ts.map +1 -0
  115. package/dist/agent-farm/servers/render-gate.js +251 -0
  116. package/dist/agent-farm/servers/render-gate.js.map +1 -0
  117. package/dist/agent-farm/servers/session-submit.d.ts +90 -0
  118. package/dist/agent-farm/servers/session-submit.d.ts.map +1 -0
  119. package/dist/agent-farm/servers/session-submit.js +127 -0
  120. package/dist/agent-farm/servers/session-submit.js.map +1 -0
  121. package/dist/agent-farm/servers/tower-cron.d.ts +10 -7
  122. package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
  123. package/dist/agent-farm/servers/tower-cron.js +58 -53
  124. package/dist/agent-farm/servers/tower-cron.js.map +1 -1
  125. package/dist/agent-farm/servers/tower-instances.d.ts +14 -2
  126. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  127. package/dist/agent-farm/servers/tower-instances.js +78 -16
  128. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  129. package/dist/agent-farm/servers/tower-messages.d.ts +38 -1
  130. package/dist/agent-farm/servers/tower-messages.d.ts.map +1 -1
  131. package/dist/agent-farm/servers/tower-messages.js +106 -1
  132. package/dist/agent-farm/servers/tower-messages.js.map +1 -1
  133. package/dist/agent-farm/servers/tower-routes.d.ts +16 -4
  134. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  135. package/dist/agent-farm/servers/tower-routes.js +670 -105
  136. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  137. package/dist/agent-farm/servers/tower-server.js +163 -31
  138. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  139. package/dist/agent-farm/servers/tower-terminals.d.ts +17 -2
  140. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  141. package/dist/agent-farm/servers/tower-terminals.js +104 -122
  142. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  143. package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
  144. package/dist/agent-farm/servers/tower-tunnel.js +63 -4
  145. package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
  146. package/dist/agent-farm/servers/tower-types.d.ts +2 -1
  147. package/dist/agent-farm/servers/tower-types.d.ts.map +1 -1
  148. package/dist/agent-farm/servers/tower-utils.d.ts +64 -1
  149. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
  150. package/dist/agent-farm/servers/tower-utils.js +168 -1
  151. package/dist/agent-farm/servers/tower-utils.js.map +1 -1
  152. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
  153. package/dist/agent-farm/servers/tower-websocket.js +6 -21
  154. package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
  155. package/dist/agent-farm/servers/write-queue.d.ts +35 -0
  156. package/dist/agent-farm/servers/write-queue.d.ts.map +1 -0
  157. package/dist/agent-farm/servers/write-queue.js +56 -0
  158. package/dist/agent-farm/servers/write-queue.js.map +1 -0
  159. package/dist/agent-farm/types.d.ts +39 -0
  160. package/dist/agent-farm/types.d.ts.map +1 -1
  161. package/dist/agent-farm/utils/agent-names.d.ts +2 -2
  162. package/dist/agent-farm/utils/agent-names.d.ts.map +1 -1
  163. package/dist/agent-farm/utils/agent-names.js +3 -3
  164. package/dist/agent-farm/utils/agent-names.js.map +1 -1
  165. package/dist/agent-farm/utils/architect-name.d.ts +2 -2
  166. package/dist/agent-farm/utils/architect-name.d.ts.map +1 -1
  167. package/dist/agent-farm/utils/architect-name.js +3 -3
  168. package/dist/agent-farm/utils/architect-name.js.map +1 -1
  169. package/dist/agent-farm/utils/config.d.ts +13 -0
  170. package/dist/agent-farm/utils/config.d.ts.map +1 -1
  171. package/dist/agent-farm/utils/config.js +33 -1
  172. package/dist/agent-farm/utils/config.js.map +1 -1
  173. package/dist/agent-farm/utils/harness.d.ts +103 -7
  174. package/dist/agent-farm/utils/harness.d.ts.map +1 -1
  175. package/dist/agent-farm/utils/harness.js +126 -19
  176. package/dist/agent-farm/utils/harness.js.map +1 -1
  177. package/dist/cli.d.ts.map +1 -1
  178. package/dist/cli.js +6 -32
  179. package/dist/cli.js.map +1 -1
  180. package/dist/commands/consult/cli-options.d.ts +34 -0
  181. package/dist/commands/consult/cli-options.d.ts.map +1 -0
  182. package/dist/commands/consult/cli-options.js +67 -0
  183. package/dist/commands/consult/cli-options.js.map +1 -0
  184. package/dist/commands/consult/index.d.ts +56 -2
  185. package/dist/commands/consult/index.d.ts.map +1 -1
  186. package/dist/commands/consult/index.js +272 -28
  187. package/dist/commands/consult/index.js.map +1 -1
  188. package/dist/commands/consult/metrics.d.ts +42 -0
  189. package/dist/commands/consult/metrics.d.ts.map +1 -1
  190. package/dist/commands/consult/metrics.js +129 -9
  191. package/dist/commands/consult/metrics.js.map +1 -1
  192. package/dist/commands/doctor.d.ts.map +1 -1
  193. package/dist/commands/doctor.js +71 -19
  194. package/dist/commands/doctor.js.map +1 -1
  195. package/dist/commands/porch/checks.d.ts +23 -0
  196. package/dist/commands/porch/checks.d.ts.map +1 -1
  197. package/dist/commands/porch/checks.js +60 -0
  198. package/dist/commands/porch/checks.js.map +1 -1
  199. package/dist/commands/porch/config.d.ts +20 -0
  200. package/dist/commands/porch/config.d.ts.map +1 -1
  201. package/dist/commands/porch/config.js +20 -0
  202. package/dist/commands/porch/config.js.map +1 -1
  203. package/dist/commands/porch/index.js +21 -28
  204. package/dist/commands/porch/index.js.map +1 -1
  205. package/dist/commands/porch/next.d.ts.map +1 -1
  206. package/dist/commands/porch/next.js +2 -41
  207. package/dist/commands/porch/next.js.map +1 -1
  208. package/dist/lib/config.d.ts +69 -3
  209. package/dist/lib/config.d.ts.map +1 -1
  210. package/dist/lib/config.js +67 -3
  211. package/dist/lib/config.js.map +1 -1
  212. package/dist/lib/consult-lanes.d.ts +149 -0
  213. package/dist/lib/consult-lanes.d.ts.map +1 -0
  214. package/dist/lib/consult-lanes.js +360 -0
  215. package/dist/lib/consult-lanes.js.map +1 -0
  216. package/dist/lib/github.js +1 -1
  217. package/dist/lib/github.js.map +1 -1
  218. package/dist/lib/prompt-behavior-metrics.d.ts +67 -0
  219. package/dist/lib/prompt-behavior-metrics.d.ts.map +1 -0
  220. package/dist/lib/prompt-behavior-metrics.js +290 -0
  221. package/dist/lib/prompt-behavior-metrics.js.map +1 -0
  222. package/dist/lib/skeleton.d.ts +22 -1
  223. package/dist/lib/skeleton.d.ts.map +1 -1
  224. package/dist/lib/skeleton.js +120 -0
  225. package/dist/lib/skeleton.js.map +1 -1
  226. package/dist/lib/test-env.d.ts +74 -0
  227. package/dist/lib/test-env.d.ts.map +1 -0
  228. package/dist/lib/test-env.js +92 -0
  229. package/dist/lib/test-env.js.map +1 -0
  230. package/dist/terminal/pty-manager.d.ts +2 -0
  231. package/dist/terminal/pty-manager.d.ts.map +1 -1
  232. package/dist/terminal/pty-manager.js +16 -6
  233. package/dist/terminal/pty-manager.js.map +1 -1
  234. package/dist/terminal/pty-session.d.ts +131 -0
  235. package/dist/terminal/pty-session.d.ts.map +1 -1
  236. package/dist/terminal/pty-session.js +232 -39
  237. package/dist/terminal/pty-session.js.map +1 -1
  238. package/dist/terminal/ring-buffer.d.ts +39 -6
  239. package/dist/terminal/ring-buffer.d.ts.map +1 -1
  240. package/dist/terminal/ring-buffer.js +74 -6
  241. package/dist/terminal/ring-buffer.js.map +1 -1
  242. package/dist/terminal/session-manager.d.ts +53 -0
  243. package/dist/terminal/session-manager.d.ts.map +1 -1
  244. package/dist/terminal/session-manager.js +94 -9
  245. package/dist/terminal/session-manager.js.map +1 -1
  246. package/dist/terminal/session-screen.d.ts +91 -0
  247. package/dist/terminal/session-screen.d.ts.map +1 -0
  248. package/dist/terminal/session-screen.js +135 -0
  249. package/dist/terminal/session-screen.js.map +1 -0
  250. package/dist/terminal/shellper-main.js +2 -1
  251. package/dist/terminal/shellper-main.js.map +1 -1
  252. package/dist/terminal/shellper-process.d.ts +1 -1
  253. package/dist/terminal/shellper-process.d.ts.map +1 -1
  254. package/dist/terminal/shellper-process.js +17 -8
  255. package/dist/terminal/shellper-process.js.map +1 -1
  256. package/dist/terminal/shellper-replay-buffer.d.ts +69 -7
  257. package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -1
  258. package/dist/terminal/shellper-replay-buffer.js +167 -31
  259. package/dist/terminal/shellper-replay-buffer.js.map +1 -1
  260. package/package.json +8 -6
  261. package/skeleton/.claude/skills/afx/SKILL.md +14 -1
  262. package/skeleton/.claude/skills/arch-init/SKILL.md +22 -9
  263. package/skeleton/.claude/skills/arch-save/SKILL.md +183 -0
  264. package/skeleton/.claude/skills/codev/SKILL.md +31 -0
  265. package/skeleton/.claude/skills/runnable-worktrees/SKILL.md +119 -0
  266. package/skeleton/.codex/skills/afx/SKILL.md +14 -1
  267. package/skeleton/.codex/skills/arch-init/SKILL.md +22 -9
  268. package/skeleton/.codex/skills/arch-save/SKILL.md +183 -0
  269. package/skeleton/.codex/skills/codev/SKILL.md +31 -0
  270. package/skeleton/.codex/skills/runnable-worktrees/SKILL.md +119 -0
  271. package/skeleton/protocols/air/builder-prompt.md +28 -47
  272. package/skeleton/protocols/air/consult-types/impl-review.md +17 -34
  273. package/skeleton/protocols/air/consult-types/pr-review.md +14 -37
  274. package/skeleton/protocols/air/prompts/implement.md +20 -73
  275. package/skeleton/protocols/air/prompts/pr.md +22 -54
  276. package/skeleton/protocols/air/protocol.md +40 -71
  277. package/skeleton/protocols/aspir/builder-prompt.md +29 -66
  278. package/skeleton/protocols/aspir/consult-types/impl-review.md +17 -44
  279. package/skeleton/protocols/aspir/consult-types/phase-review.md +17 -44
  280. package/skeleton/protocols/aspir/consult-types/plan-review.md +14 -38
  281. package/skeleton/protocols/aspir/consult-types/pr-review.md +13 -39
  282. package/skeleton/protocols/aspir/consult-types/spec-review.md +13 -33
  283. package/skeleton/protocols/aspir/prompts/implement.md +27 -196
  284. package/skeleton/protocols/aspir/prompts/plan.md +21 -85
  285. package/skeleton/protocols/aspir/prompts/review.md +29 -228
  286. package/skeleton/protocols/aspir/prompts/specify.md +25 -111
  287. package/skeleton/protocols/aspir/protocol.json +10 -0
  288. package/skeleton/protocols/aspir/protocol.md +36 -82
  289. package/skeleton/protocols/bugfix/builder-prompt.md +23 -45
  290. package/skeleton/protocols/bugfix/consult-types/impl-review.md +21 -45
  291. package/skeleton/protocols/bugfix/consult-types/pr-review.md +18 -52
  292. package/skeleton/protocols/bugfix/prompts/fix.md +16 -61
  293. package/skeleton/protocols/bugfix/prompts/investigate.md +18 -62
  294. package/skeleton/protocols/bugfix/prompts/pr.md +22 -57
  295. package/skeleton/protocols/bugfix/protocol.md +44 -50
  296. package/skeleton/protocols/experiment/builder-prompt.md +25 -58
  297. package/skeleton/protocols/experiment/protocol.md +22 -188
  298. package/skeleton/protocols/experiment/templates/notes.md +11 -71
  299. package/skeleton/protocols/maintain/builder-prompt.md +24 -45
  300. package/skeleton/protocols/maintain/consult-types/impl-review.md +17 -44
  301. package/skeleton/protocols/maintain/consult-types/pr-review.md +13 -39
  302. package/skeleton/protocols/maintain/prompts/maintain.md +1 -1
  303. package/skeleton/protocols/maintain/protocol.md +32 -266
  304. package/skeleton/protocols/maintain/templates/maintenance-run.md +11 -0
  305. package/skeleton/protocols/pir/builder-prompt.md +30 -64
  306. package/skeleton/protocols/pir/consult-types/impl-review.md +17 -50
  307. package/skeleton/protocols/pir/consult-types/pr-review.md +11 -40
  308. package/skeleton/protocols/pir/prompts/implement.md +1 -2
  309. package/skeleton/protocols/pir/prompts/plan.md +0 -3
  310. package/skeleton/protocols/pir/prompts/review.md +1 -1
  311. package/skeleton/protocols/pir/protocol.md +54 -177
  312. package/skeleton/protocols/research/builder-prompt.md +27 -58
  313. package/skeleton/protocols/research/protocol.md +28 -153
  314. package/skeleton/protocols/spike/builder-prompt.md +30 -48
  315. package/skeleton/protocols/spike/protocol.md +24 -107
  316. package/skeleton/protocols/spike/templates/findings.md +9 -39
  317. package/skeleton/protocols/spir/builder-prompt.md +33 -62
  318. package/skeleton/protocols/spir/consult-types/impl-review.md +17 -44
  319. package/skeleton/protocols/spir/consult-types/phase-review.md +17 -44
  320. package/skeleton/protocols/spir/consult-types/plan-review.md +14 -38
  321. package/skeleton/protocols/spir/consult-types/pr-review.md +13 -39
  322. package/skeleton/protocols/spir/consult-types/spec-review.md +13 -33
  323. package/skeleton/protocols/spir/prompts/implement.md +26 -195
  324. package/skeleton/protocols/spir/prompts/plan.md +20 -84
  325. package/skeleton/protocols/spir/prompts/review.md +28 -227
  326. package/skeleton/protocols/spir/prompts/specify.md +24 -110
  327. package/skeleton/protocols/spir/protocol.json +10 -0
  328. package/skeleton/protocols/spir/protocol.md +84 -633
  329. package/skeleton/protocols/spir/templates/plan.md +28 -147
  330. package/skeleton/protocols/spir/templates/review.md +21 -80
  331. package/skeleton/protocols/spir/templates/spec.md +24 -118
  332. package/skeleton/resources/commands/agent-farm.md +259 -0
  333. package/skeleton/resources/commands/consult.md +236 -8
  334. package/skeleton/resources/commands/overview.md +1 -0
  335. package/skeleton/roles/architect.md +67 -317
  336. package/skeleton/roles/builder.md +77 -191
  337. package/skeleton/templates/AGENTS.md +2 -0
  338. package/skeleton/templates/CLAUDE.md +2 -0
  339. package/templates/tower.html +39 -2
  340. package/dashboard-dist/assets/index-BZ1x7x1X.js.map +0 -1
  341. package/dashboard-dist/assets/index-DB1KBSNE.css +0 -32
  342. package/dist/agent-farm/servers/send-buffer.d.ts +0 -59
  343. package/dist/agent-farm/servers/send-buffer.d.ts.map +0 -1
  344. package/dist/agent-farm/servers/send-buffer.js +0 -116
  345. package/dist/agent-farm/servers/send-buffer.js.map +0 -1
  346. package/skeleton/porch/prompts/defend.md +0 -108
  347. package/skeleton/porch/prompts/diagnose.md +0 -70
  348. package/skeleton/porch/prompts/evaluate.md +0 -132
  349. package/skeleton/porch/prompts/fix.md +0 -59
  350. package/skeleton/porch/prompts/implement.md +0 -88
  351. package/skeleton/porch/prompts/plan.md +0 -74
  352. package/skeleton/porch/prompts/pr.md +0 -84
  353. package/skeleton/porch/prompts/review.md +0 -249
  354. package/skeleton/porch/prompts/specify.md +0 -53
  355. package/skeleton/porch/prompts/test.md +0 -63
  356. package/skeleton/protocols/aspir/templates/plan.md +0 -184
  357. package/skeleton/protocols/aspir/templates/review.md +0 -120
  358. package/skeleton/protocols/aspir/templates/spec.md +0 -154
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Cron message delivery through the mailbox + gate (Spec 1313, Phase 6).
3
+ *
4
+ * Cron is today the most unguarded message writer: it wrote straight to the PTY with
5
+ * no idle check and logged "delivered" unconditionally. This phase makes it an
6
+ * ordinary mailbox sender — every cron notification is persisted and then delivered
7
+ * through the SAME single gated path (`deliverAgentMailSerialized`) that `handleSend`
8
+ * and the backstop drainer use, so a cron message can never land mid-draft or fuse
9
+ * with a human's half-typed line. There is no force path: a busy/menu/wrapper screen
10
+ * holds the message for the backstop, exactly like any other send.
11
+ *
12
+ * Two cron-specific twists on top of the shared path:
13
+ * - **Supersede key = task name** (Baked Decision 6): a newer run of a task replaces
14
+ * its own older *held* row instead of queueing a backlog. Supersede keys are
15
+ * cron-only in this project — no non-cron send ever supplies one.
16
+ * - **Honest run outcome**: the caller logs the real fate (`delivered` / `held` /
17
+ * `superseded`) rather than an unconditional "delivered".
18
+ *
19
+ * This module holds the registry-free orchestration core behind the Phase-4
20
+ * {@link DeliveryPorts} seam, so it is unit-testable against a real mailbox DB with
21
+ * fake edges (no live Tower). The identity resolution that needs the live routing
22
+ * registry (`resolveTarget` + the architect reverse-map + the dead-session registry
23
+ * fallback) lives in `tower-routes.ts`'s `deliverCronMessage`, which calls this.
24
+ */
25
+ import { supersede, getById, countHeldWithKey } from '../db/mailbox.js';
26
+ import { deliverAgentMailSerialized } from './mailbox-delivery.js';
27
+ /** The pseudo-agent identity every cron notification is sent as. */
28
+ export const CRON_SENDER = 'af-cron';
29
+ /**
30
+ * Persist a cron notification (superseding any still-held row from an earlier run of
31
+ * the same task) and attempt one gated delivery, returning the run's real outcome.
32
+ *
33
+ * The corruption-safety is entirely inherited from {@link deliverAgentMailSerialized}:
34
+ * the body is only ever written to a render-verified empty prompt, and the per-agent
35
+ * serializer means a concurrent send can never interleave with this write. A busy or
36
+ * unclassifiable screen simply leaves the row held for the backstop — there is no
37
+ * force path here, by construction.
38
+ */
39
+ export async function deliverCronMail(ports, db, target) {
40
+ const { workspacePath, toAgent, supersedeKey } = target;
41
+ // Did an earlier run of this task leave a row still held? Read it BEFORE the
42
+ // supersede, with no await between, so the pair is atomic on the synchronous DB
43
+ // handle (see countHeldWithKey). This only informs the log word — the "no backlog"
44
+ // correctness comes from supersede() being atomic regardless.
45
+ const replacedPrior = countHeldWithKey(db, workspacePath, supersedeKey) > 0;
46
+ const row = supersede(db, workspacePath, supersedeKey, {
47
+ workspacePath,
48
+ toAgent,
49
+ terminalId: target.terminalId,
50
+ body: target.body,
51
+ formattedMessage: target.formattedMessage,
52
+ fromAgent: CRON_SENDER,
53
+ fromWorkspace: workspacePath,
54
+ }, ports.now());
55
+ // The held set changed (a new row enqueued, possibly replacing a prior held one) →
56
+ // refresh the indicator count (Spec 1313, Phase 7). A clean delivery below fires it
57
+ // again when the row leaves the set; both are cheap, idempotent refetch triggers.
58
+ ports.onHeldStateChange();
59
+ try {
60
+ await deliverAgentMailSerialized(ports, db, workspacePath, toAgent);
61
+ }
62
+ catch (err) {
63
+ // A gate/write error leaves the row HELD (markDelivered only runs on a completed
64
+ // write); the backstop drainer retries. Mirrors handleSend — never throws upward.
65
+ ports.log(`[cron] delivery attempt errored for ${toAgent} (row ${row.id.slice(0, 8)}… stays held): ${String(err)}`);
66
+ }
67
+ const stored = getById(db, row.id);
68
+ if (stored?.status === 'delivered') {
69
+ return { outcome: 'delivered', reason: null, mailboxId: row.id };
70
+ }
71
+ // Held. `reason` is set by the delivery pass when it holds; default to `busy` for
72
+ // the rare case where an older row for the same agent delivered first and left ours
73
+ // queued behind it (its Enter makes the line busy for the next pass anyway).
74
+ return {
75
+ outcome: replacedPrior ? 'superseded' : 'held',
76
+ reason: stored?.reason ?? 'busy',
77
+ mailboxId: row.id,
78
+ };
79
+ }
80
+ //# sourceMappingURL=cron-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-delivery.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/cron-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAExE,OAAO,EAAE,0BAA0B,EAAsB,MAAM,uBAAuB,CAAC;AAEvF,oEAAoE;AACpE,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAoCrC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAoB,EACpB,EAAqB,EACrB,MAAkB;IAElB,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAExD,6EAA6E;IAC7E,gFAAgF;IAChF,mFAAmF;IACnF,8DAA8D;IAC9D,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,aAAa,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;IAC5E,MAAM,GAAG,GAAG,SAAS,CACnB,EAAE,EACF,aAAa,EACb,YAAY,EACZ;QACE,aAAa;QACb,OAAO;QACP,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,SAAS,EAAE,WAAW;QACtB,aAAa,EAAE,aAAa;KAC7B,EACD,KAAK,CAAC,GAAG,EAAE,CACZ,CAAC;IACF,mFAAmF;IACnF,oFAAoF;IACpF,kFAAkF;IAClF,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,0BAA0B,CAAC,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iFAAiF;QACjF,kFAAkF;QAClF,KAAK,CAAC,GAAG,CAAC,uCAAuC,OAAO,SAAS,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACtH,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,MAAM,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,kFAAkF;IAClF,oFAAoF;IACpF,6EAA6E;IAC7E,OAAO;QACL,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM;QAC9C,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,MAAM;QAChC,SAAS,EAAE,GAAG,CAAC,EAAE;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Due-time timer for the delayed `afx send --delay --interrupt` path (Spec 1307,
3
+ * reshaped by Spec 1313 round 3).
4
+ *
5
+ * ## What this module does NOW (and no longer does)
6
+ *
7
+ * The message *body* of every `--delay` send is persisted to the durable mailbox
8
+ * at REQUEST time, with a `not_before` due time, by `handleDelayedSend` in
9
+ * tower-routes.ts — NOT here, and NOT at fire time. The gated backstop drainer
10
+ * delivers that row once `not_before` passes, so a plain `--delay` keeps no timer
11
+ * at all and survives a Tower restart by construction.
12
+ *
13
+ * This module holds a due-time timer used by ONE caller: the delayed-`--interrupt`
14
+ * path. When it fires it writes only the Ctrl+C that ends the current turn — no
15
+ * message body, and it marks nothing `delivered`. The body then lands through the
16
+ * same render gate every send uses, after the ^C ends the turn.
17
+ *
18
+ * ## Why the registry exists at all
19
+ *
20
+ * A bare `setTimeout` would work until Tower shuts down, at which point the
21
+ * process would either hang on a pending timer or exit with a ^C half-scheduled
22
+ * and no record of it. The registry makes shutdown explicit.
23
+ *
24
+ * ## Shutdown drops the ^C nudge, never the message
25
+ *
26
+ * A pre-due `--delay` message is a persisted mailbox row: it survives a restart
27
+ * and delivers when the target's prompt is next clean. Only the in-memory ^C
28
+ * nudge is dropped on shutdown — recoverable (a human re-interrupts if it matters),
29
+ * and matching the documented "only the interrupt semantics gracefully degrade"
30
+ * boundary. This is the CONSCIOUS reversal of Spec 1307's original body-drop-on-
31
+ * restart trade (see review 1313): the render gate now supplies the protection that
32
+ * trade wanted — a post-restart delivery still only lands on a render-verified empty
33
+ * prompt, and a stale pending row is visible and cancellable in `afx inbox`.
34
+ */
35
+ /**
36
+ * Upper bound on `--delay`, in seconds.
37
+ *
38
+ * One hour. Not a meaningful workflow limit — it exists so a typo (`--delay
39
+ * 1500` when 15 was meant) cannot park a message far in the future unnoticed.
40
+ * Under Spec 1313 round 3 a parked send IS listable and cancellable via
41
+ * `afx inbox` / `afx inbox dismiss` (it is a durable mailbox row), but the
42
+ * ceiling stays as a cheap guard against the typo case.
43
+ */
44
+ export declare const MAX_DELAY_SECONDS = 3600;
45
+ /**
46
+ * Validate a delay in seconds, returning null when acceptable or an error
47
+ * string naming the problem.
48
+ *
49
+ * `Number.isInteger` rather than a bare comparison chain: `NaN > 0` and
50
+ * `NaN <= 0` are both false, so a NaN slips through any single comparison
51
+ * written the obvious way and yields a `setTimeout` that fires immediately —
52
+ * silently converting a delayed send into an immediate one. Infinity is
53
+ * rejected for the same class of reason.
54
+ */
55
+ export declare function validateDelaySeconds(value: unknown): string | null;
56
+ /**
57
+ * Schedule `deliver` to run after `delaySeconds`.
58
+ *
59
+ * The callback is responsible for re-resolving the session and re-deciding how
60
+ * to deliver; this module guarantees only *when* it is invoked, and that it is
61
+ * invoked at most once.
62
+ */
63
+ export declare function scheduleDelayedSend(delaySeconds: number, terminalId: string,
64
+ /**
65
+ * Invoked when the send comes due. Receives `isStillLive`, which it must
66
+ * re-check at the moment it actually writes (inside the submission lock): a
67
+ * delivery can acquire the lock only AFTER a shutdown that fired while it
68
+ * queued, and the generation check below only guards the moment BEFORE it
69
+ * enters the lock. Return value is ignored.
70
+ */
71
+ deliver: (isStillLive: () => boolean) => unknown): void;
72
+ /**
73
+ * Cancel every pending delayed send without delivering. Returns the count of
74
+ * still-timing sends dropped, so shutdown can log it rather than losing
75
+ * messages silently.
76
+ *
77
+ * Covers two states: sends still on their timer (cleared here) and sends whose
78
+ * timer has fired but whose delivery has not started — invalidated by bumping
79
+ * `generation`, which the delivery callback re-checks. A delivery already
80
+ * writing when this runs is NOT interrupted; see `generation`'s note.
81
+ */
82
+ export declare function shutdownDelayedSends(): number;
83
+ /** Number of pending delayed sends. Diagnostics and tests. */
84
+ export declare function pendingDelayedSendCount(): number;
85
+ //# sourceMappingURL=delayed-send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delayed-send.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/delayed-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAwCH;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWlE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM;AAClB;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,OAAO,KAAK,OAAO,GAC/C,IAAI,CAmCN;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAQ7C;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Due-time timer for the delayed `afx send --delay --interrupt` path (Spec 1307,
3
+ * reshaped by Spec 1313 round 3).
4
+ *
5
+ * ## What this module does NOW (and no longer does)
6
+ *
7
+ * The message *body* of every `--delay` send is persisted to the durable mailbox
8
+ * at REQUEST time, with a `not_before` due time, by `handleDelayedSend` in
9
+ * tower-routes.ts — NOT here, and NOT at fire time. The gated backstop drainer
10
+ * delivers that row once `not_before` passes, so a plain `--delay` keeps no timer
11
+ * at all and survives a Tower restart by construction.
12
+ *
13
+ * This module holds a due-time timer used by ONE caller: the delayed-`--interrupt`
14
+ * path. When it fires it writes only the Ctrl+C that ends the current turn — no
15
+ * message body, and it marks nothing `delivered`. The body then lands through the
16
+ * same render gate every send uses, after the ^C ends the turn.
17
+ *
18
+ * ## Why the registry exists at all
19
+ *
20
+ * A bare `setTimeout` would work until Tower shuts down, at which point the
21
+ * process would either hang on a pending timer or exit with a ^C half-scheduled
22
+ * and no record of it. The registry makes shutdown explicit.
23
+ *
24
+ * ## Shutdown drops the ^C nudge, never the message
25
+ *
26
+ * A pre-due `--delay` message is a persisted mailbox row: it survives a restart
27
+ * and delivers when the target's prompt is next clean. Only the in-memory ^C
28
+ * nudge is dropped on shutdown — recoverable (a human re-interrupts if it matters),
29
+ * and matching the documented "only the interrupt semantics gracefully degrade"
30
+ * boundary. This is the CONSCIOUS reversal of Spec 1307's original body-drop-on-
31
+ * restart trade (see review 1313): the render gate now supplies the protection that
32
+ * trade wanted — a post-restart delivery still only lands on a render-verified empty
33
+ * prompt, and a stale pending row is visible and cancellable in `afx inbox`.
34
+ */
35
+ const pending = new Set();
36
+ /*
37
+ * NOTE: this module no longer serialises deliveries. It used to hold a
38
+ * per-terminal promise chain; Spec 1273's `submitToSession` now owns that, and
39
+ * every due message re-enters the mailbox delivery path, which submits under the
40
+ * lock. One mechanism, not two — per the architect's ruling that this project
41
+ * adopts the primitive rather than keeping a rival.
42
+ */
43
+ /**
44
+ * Incremented by every shutdown. Each scheduled send captures the value current
45
+ * when it was scheduled and re-checks it at delivery.
46
+ *
47
+ * Clearing the pending timers is not sufficient on its own. A message whose
48
+ * timer has already fired is out of `pending` but its delivery may not have
49
+ * started yet — it can be waiting on the session's `submitToSession` lock
50
+ * behind an in-flight write. That queued delivery would otherwise run AFTER
51
+ * shutdown, which is exactly what "shutdown drops pending delayed sends"
52
+ * promises it will not. The generation check re-read at delivery time makes
53
+ * such an already-scheduled delivery a no-op.
54
+ *
55
+ * Honest bound: a delivery that has ALREADY begun its write when shutdown fires
56
+ * still completes — the lock does not interrupt a write in progress. "Drops on
57
+ * shutdown" therefore means "does not START anything new," not "aborts what is
58
+ * mid-flight." See the shutdown function.
59
+ */
60
+ let generation = 0;
61
+ /**
62
+ * Upper bound on `--delay`, in seconds.
63
+ *
64
+ * One hour. Not a meaningful workflow limit — it exists so a typo (`--delay
65
+ * 1500` when 15 was meant) cannot park a message far in the future unnoticed.
66
+ * Under Spec 1313 round 3 a parked send IS listable and cancellable via
67
+ * `afx inbox` / `afx inbox dismiss` (it is a durable mailbox row), but the
68
+ * ceiling stays as a cheap guard against the typo case.
69
+ */
70
+ export const MAX_DELAY_SECONDS = 3600;
71
+ /**
72
+ * Validate a delay in seconds, returning null when acceptable or an error
73
+ * string naming the problem.
74
+ *
75
+ * `Number.isInteger` rather than a bare comparison chain: `NaN > 0` and
76
+ * `NaN <= 0` are both false, so a NaN slips through any single comparison
77
+ * written the obvious way and yields a `setTimeout` that fires immediately —
78
+ * silently converting a delayed send into an immediate one. Infinity is
79
+ * rejected for the same class of reason.
80
+ */
81
+ export function validateDelaySeconds(value) {
82
+ if (typeof value !== 'number' || !Number.isInteger(value)) {
83
+ return `delay must be a whole number of seconds, got '${String(value)}'`;
84
+ }
85
+ if (value <= 0) {
86
+ return `delay must be greater than zero, got ${value}`;
87
+ }
88
+ if (value > MAX_DELAY_SECONDS) {
89
+ return `delay must be at most ${MAX_DELAY_SECONDS} seconds (1 hour), got ${value}`;
90
+ }
91
+ return null;
92
+ }
93
+ /**
94
+ * Schedule `deliver` to run after `delaySeconds`.
95
+ *
96
+ * The callback is responsible for re-resolving the session and re-deciding how
97
+ * to deliver; this module guarantees only *when* it is invoked, and that it is
98
+ * invoked at most once.
99
+ */
100
+ export function scheduleDelayedSend(delaySeconds, terminalId,
101
+ /**
102
+ * Invoked when the send comes due. Receives `isStillLive`, which it must
103
+ * re-check at the moment it actually writes (inside the submission lock): a
104
+ * delivery can acquire the lock only AFTER a shutdown that fired while it
105
+ * queued, and the generation check below only guards the moment BEFORE it
106
+ * enters the lock. Return value is ignored.
107
+ */
108
+ deliver) {
109
+ const entry = {
110
+ terminalId,
111
+ dueAt: Date.now() + delaySeconds * 1000,
112
+ // Assigned below; the object must exist first so the callback can
113
+ // deregister itself by identity.
114
+ timer: undefined,
115
+ };
116
+ const scheduledGeneration = generation;
117
+ entry.timer = setTimeout(() => {
118
+ // Deregister BEFORE delivering. If delivery throws, the entry must not be
119
+ // left behind as a phantom pending send that shutdown would then report.
120
+ pending.delete(entry);
121
+ void (async () => {
122
+ // Generation re-checked at DELIVERY time, not timer time: delivery now
123
+ // queues behind the session's submission lock, so the wait to actually
124
+ // write can outlast a shutdown.
125
+ if (generation !== scheduledGeneration)
126
+ return;
127
+ try {
128
+ // Passed through to the write site, where it is re-checked while the
129
+ // lock is held — closing the shutdown-during-lock-wait window.
130
+ await deliver(() => generation === scheduledGeneration);
131
+ }
132
+ catch {
133
+ // The mailbox delivery path logs a write failure at its own site with
134
+ // terminal context; this catch is a last-resort guard so an unexpected
135
+ // throw cannot become an unhandled rejection that takes Tower down over
136
+ // one undeliverable message.
137
+ }
138
+ })();
139
+ }, delaySeconds * 1000);
140
+ pending.add(entry);
141
+ }
142
+ /**
143
+ * Cancel every pending delayed send without delivering. Returns the count of
144
+ * still-timing sends dropped, so shutdown can log it rather than losing
145
+ * messages silently.
146
+ *
147
+ * Covers two states: sends still on their timer (cleared here) and sends whose
148
+ * timer has fired but whose delivery has not started — invalidated by bumping
149
+ * `generation`, which the delivery callback re-checks. A delivery already
150
+ * writing when this runs is NOT interrupted; see `generation`'s note.
151
+ */
152
+ export function shutdownDelayedSends() {
153
+ const count = pending.size;
154
+ for (const entry of pending) {
155
+ clearTimeout(entry.timer);
156
+ }
157
+ pending.clear();
158
+ generation++;
159
+ return count;
160
+ }
161
+ /** Number of pending delayed sends. Diagnostics and tests. */
162
+ export function pendingDelayedSendCount() {
163
+ return pending.size;
164
+ }
165
+ //# sourceMappingURL=delayed-send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delayed-send.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/delayed-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAWH,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE9C;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,iDAAiD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;IAC3E,CAAC;IACD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,OAAO,wCAAwC,KAAK,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAC9B,OAAO,yBAAyB,iBAAiB,0BAA0B,KAAK,EAAE,CAAC;IACrF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAoB,EACpB,UAAkB;AAClB;;;;;;GAMG;AACH,OAAgD;IAEhD,MAAM,KAAK,GAAuB;QAChC,UAAU;QACV,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,IAAI;QACvC,kEAAkE;QAClE,iCAAiC;QACjC,KAAK,EAAE,SAAqD;KAC7D,CAAC;IAEF,MAAM,mBAAmB,GAAG,UAAU,CAAC;IAEvC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,0EAA0E;QAC1E,yEAAyE;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEtB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,uEAAuE;YACvE,uEAAuE;YACvE,gCAAgC;YAChC,IAAI,UAAU,KAAK,mBAAmB;gBAAE,OAAO;YAC/C,IAAI,CAAC;gBACH,qEAAqE;gBACrE,+DAA+D;gBAC/D,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,KAAK,mBAAmB,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,sEAAsE;gBACtE,uEAAuE;gBACvE,wEAAwE;gBACxE,6BAA6B;YAC/B,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC,CAAC;IAExB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,uBAAuB;IACrC,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Render-gate classifier profiles (Spec 1313, Phase 2).
3
+ *
4
+ * A profile tells {@link classifyScreen} how to find and bound a given app's
5
+ * composer. Profiles are per-app *data* by design (spike constraint 9): a TUI
6
+ * layout change is a profile drift the smoke suite catches, never a silent
7
+ * misdelivery — an unmatched marker classifies NOT clean.
8
+ *
9
+ * Measured apps have a profile: claude, codex (spike g2), and agy (Spec 1313
10
+ * Phase 3 measurement — its own marker `> ` and a color-keyed placeholder rule,
11
+ * because agy renders its idle hint in palette-8 gray, not SGR-dim). Everything
12
+ * else — gemini, opencode, an unknown binary, or a launch we can't identify —
13
+ * resolves to `null`, and the caller holds the message with reason `no-profile`.
14
+ * This is the strict app-identity table the spike mandates (constraint 10): we
15
+ * deliberately do NOT reuse `resolveHarness`, whose claude fallback would make an
16
+ * agy terminal masquerade as claude and receive claude's (wrong) profile — a
17
+ * correctness bug, since agy's screens classify by an entirely different rule.
18
+ */
19
+ import type { GateProfile } from './render-gate.js';
20
+ /** claude composer profile (marker ❯, dim placeholder — measured, spike g2). */
21
+ export declare const CLAUDE_PROFILE: GateProfile;
22
+ /** codex composer profile (marker ›, dim placeholder — measured, spike g2). */
23
+ export declare const CODEX_PROFILE: GateProfile;
24
+ /**
25
+ * agy composer profile (Spec 1313 Phase 3 — net-new measurement). agy breaks the
26
+ * dim-placeholder assumption: its idle mode-hint (`Accept-edits mode: …`) renders
27
+ * at NORMAL intensity but in **palette-8 (gray)**, while user-typed text is
28
+ * default-fg — so the placeholder signal is a foreground COLOR, not SGR-dim
29
+ * (`placeholderFgPalette: 8`). Consequences, all measured: idle → clean (the
30
+ * gray hint is ignored), draft → busy (default-fg text counted), and the
31
+ * per-folder trust dialog → busy (its selected `> Yes, I trust this folder`
32
+ * option is palette-12, counted) — so a blind Enter never confirms filesystem
33
+ * trust. Region bounds reuse the shared rule-line/status patterns (agy brackets
34
+ * its composer with `─────` rules, like claude).
35
+ */
36
+ export declare const AGY_PROFILE: GateProfile;
37
+ /**
38
+ * The identity signals a caller extracts from a live session. A `PtySession`
39
+ * satisfies this structurally via its `command` / `launchArgs` getters (the
40
+ * Spec 1313 identity seam); tests pass a plain object.
41
+ *
42
+ * `label` is intentionally not used for matching: for a builder it is the
43
+ * builder id (e.g. `spir-1313`), for an architect the architect name — neither
44
+ * names the agent. The authoritative signal is the launch `command`.
45
+ */
46
+ export interface AppIdentity {
47
+ command: string;
48
+ args?: string[];
49
+ label?: string;
50
+ }
51
+ /**
52
+ * Map a session's identity to its classifier profile, or `null` when the app is
53
+ * unknown/unmeasured (→ caller holds with `no-profile`).
54
+ *
55
+ * Resolution is strict: the launch `command`'s basename must match a measured
56
+ * agent. agy is matched directly (its binary is `agy`/`antigravity`), because the
57
+ * shared {@link detectHarnessFromCommand} does not recognize it and we will not
58
+ * extend that resolver — its claude fallback is exactly the misidentification the
59
+ * gate must avoid (constraint 10). claude/codex resolve via that helper. Wrapped
60
+ * launches — a builder run through `.builder-start.sh` whose `command` is the
61
+ * shell, not the agent — resolve to `null` here; the delivery wiring (Phase 4)
62
+ * supplies the resolved agent command for those (it already reads the launch
63
+ * script to identify the harness, as `afx reset` does). Fail-safe by
64
+ * construction: an unresolved identity is held and surfaced, never guessed.
65
+ */
66
+ export declare function resolveProfile(identity: AppIdentity): GateProfile | null;
67
+ //# sourceMappingURL=gate-profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-profiles.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/gate-profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA+BpD,gFAAgF;AAChF,eAAO,MAAM,cAAc,EAAE,WAI5B,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,aAAa,EAAE,WAI3B,CAAC;AASF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,WAKzB,CAAC;AAQF;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAMxE"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Render-gate classifier profiles (Spec 1313, Phase 2).
3
+ *
4
+ * A profile tells {@link classifyScreen} how to find and bound a given app's
5
+ * composer. Profiles are per-app *data* by design (spike constraint 9): a TUI
6
+ * layout change is a profile drift the smoke suite catches, never a silent
7
+ * misdelivery — an unmatched marker classifies NOT clean.
8
+ *
9
+ * Measured apps have a profile: claude, codex (spike g2), and agy (Spec 1313
10
+ * Phase 3 measurement — its own marker `> ` and a color-keyed placeholder rule,
11
+ * because agy renders its idle hint in palette-8 gray, not SGR-dim). Everything
12
+ * else — gemini, opencode, an unknown binary, or a launch we can't identify —
13
+ * resolves to `null`, and the caller holds the message with reason `no-profile`.
14
+ * This is the strict app-identity table the spike mandates (constraint 10): we
15
+ * deliberately do NOT reuse `resolveHarness`, whose claude fallback would make an
16
+ * agy terminal masquerade as claude and receive claude's (wrong) profile — a
17
+ * correctness bug, since agy's screens classify by an entirely different rule.
18
+ */
19
+ import { basename } from 'node:path';
20
+ import { detectHarnessFromCommand } from '../utils/harness.js';
21
+ /**
22
+ * Marker family shared by the measured TUIs: both render a `❯`/`›` prompt glyph
23
+ * at the start of the composer input row. Kept in one place but referenced
24
+ * per-profile so a future app whose marker diverges gets its own pattern without
25
+ * disturbing the others.
26
+ */
27
+ const COMPOSER_MARKER = /^[❯›]/;
28
+ /**
29
+ * Lines that END the composer region — the rule line claude draws beneath its
30
+ * input (`─────`) and the status line codex draws (model / reasoning / cwd, e.g.
31
+ * ` gpt-5.6-sol high: … ~/repo`). Scanning stops at the first such line so
32
+ * status chrome below the composer is never miscounted as user text. Both
33
+ * patterns are carried by both profiles (harmless: a claude screen has no
34
+ * `gpt|high:|~/` status line, a codex screen has no long rule line under input),
35
+ * exactly as the validated spike classifier applied them.
36
+ *
37
+ * Load-bearing since the Spec 1313 render-gate hardening: when NONE of these matches
38
+ * below the marker, the gate now HOLDS (`no-region-end`) rather than scanning to the
39
+ * screen bottom — so this list is the sole lower-bound signal, and it is FAIL-SAFE but
40
+ * DRIFT-FRAGILE. The rule pattern requires the line to *start* with `─/━/╌/┄`; a claude
41
+ * reversion to a rounded box (`╰────╯`, note `╰`/`└` are ignorable glyphs but NOT in
42
+ * this class) or an indented rule would stop matching and hold every send to that app.
43
+ * That is the safe direction (never a false-clean), and a sustained hold now escalates
44
+ * to liveness telemetry (mailbox-delivery `recordStreak`), but broaden this list ONLY
45
+ * from a real capture — a too-loose pattern that matches draft content is a false-clean.
46
+ */
47
+ const REGION_END_PATTERNS = [/^[─━╌┄]{5,}/, /^\s{2,}(gpt|high:|~\/)/];
48
+ /** claude composer profile (marker ❯, dim placeholder — measured, spike g2). */
49
+ export const CLAUDE_PROFILE = {
50
+ app: 'claude',
51
+ markerPattern: COMPOSER_MARKER,
52
+ regionEndPatterns: REGION_END_PATTERNS,
53
+ };
54
+ /** codex composer profile (marker ›, dim placeholder — measured, spike g2). */
55
+ export const CODEX_PROFILE = {
56
+ app: 'codex',
57
+ markerPattern: COMPOSER_MARKER,
58
+ regionEndPatterns: REGION_END_PATTERNS,
59
+ };
60
+ /**
61
+ * agy (Antigravity CLI 1.1.8) composer marker: a `> ` prompt glyph at the input
62
+ * row start — a different glyph from claude/codex's `❯`/`›`, so its own pattern.
63
+ * (Measured, Spec 1313 Phase 3; the marker cell renders palette-12 bright-blue.)
64
+ */
65
+ const AGY_MARKER = /^> /;
66
+ /**
67
+ * agy composer profile (Spec 1313 Phase 3 — net-new measurement). agy breaks the
68
+ * dim-placeholder assumption: its idle mode-hint (`Accept-edits mode: …`) renders
69
+ * at NORMAL intensity but in **palette-8 (gray)**, while user-typed text is
70
+ * default-fg — so the placeholder signal is a foreground COLOR, not SGR-dim
71
+ * (`placeholderFgPalette: 8`). Consequences, all measured: idle → clean (the
72
+ * gray hint is ignored), draft → busy (default-fg text counted), and the
73
+ * per-folder trust dialog → busy (its selected `> Yes, I trust this folder`
74
+ * option is palette-12, counted) — so a blind Enter never confirms filesystem
75
+ * trust. Region bounds reuse the shared rule-line/status patterns (agy brackets
76
+ * its composer with `─────` rules, like claude).
77
+ */
78
+ export const AGY_PROFILE = {
79
+ app: 'agy',
80
+ markerPattern: AGY_MARKER,
81
+ regionEndPatterns: REGION_END_PATTERNS,
82
+ placeholderFgPalette: 8,
83
+ };
84
+ /** Registry keyed by the harness name `detectHarnessFromCommand` returns. */
85
+ const PROFILES_BY_HARNESS = {
86
+ claude: CLAUDE_PROFILE,
87
+ codex: CODEX_PROFILE,
88
+ };
89
+ /**
90
+ * Map a session's identity to its classifier profile, or `null` when the app is
91
+ * unknown/unmeasured (→ caller holds with `no-profile`).
92
+ *
93
+ * Resolution is strict: the launch `command`'s basename must match a measured
94
+ * agent. agy is matched directly (its binary is `agy`/`antigravity`), because the
95
+ * shared {@link detectHarnessFromCommand} does not recognize it and we will not
96
+ * extend that resolver — its claude fallback is exactly the misidentification the
97
+ * gate must avoid (constraint 10). claude/codex resolve via that helper. Wrapped
98
+ * launches — a builder run through `.builder-start.sh` whose `command` is the
99
+ * shell, not the agent — resolve to `null` here; the delivery wiring (Phase 4)
100
+ * supplies the resolved agent command for those (it already reads the launch
101
+ * script to identify the harness, as `afx reset` does). Fail-safe by
102
+ * construction: an unresolved identity is held and surfaced, never guessed.
103
+ */
104
+ export function resolveProfile(identity) {
105
+ const base = basename(identity.command).toLowerCase();
106
+ if (base.includes('agy') || base.includes('antigravity'))
107
+ return AGY_PROFILE;
108
+ const harness = detectHarnessFromCommand(identity.command);
109
+ if (harness && harness in PROFILES_BY_HARNESS)
110
+ return PROFILES_BY_HARNESS[harness];
111
+ return null;
112
+ }
113
+ //# sourceMappingURL=gate-profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-profiles.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/gate-profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAG/D;;;;;GAKG;AACH,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC;AAEtE,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,GAAG,EAAE,QAAQ;IACb,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;CACvC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,GAAG,EAAE,OAAO;IACZ,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;CACvC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,GAAG,EAAE,KAAK;IACV,aAAa,EAAE,UAAU;IACzB,iBAAiB,EAAE,mBAAmB;IACtC,oBAAoB,EAAE,CAAC;CACxB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,mBAAmB,GAAgC;IACvD,MAAM,EAAE,cAAc;IACtB,KAAK,EAAE,aAAa;CACrB,CAAC;AAiBF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,QAAqB;IAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IACtD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,WAAW,CAAC;IAC7E,MAAM,OAAO,GAAG,wBAAwB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,OAAO,IAAI,OAAO,IAAI,mBAAmB;QAAE,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACnF,OAAO,IAAI,CAAC;AACd,CAAC"}