@cluesmith/codev 3.2.3 → 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 (445) 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 +173 -0
  7. package/dist/agent-farm/cli.js.map +1 -1
  8. package/dist/agent-farm/commands/attach.js +2 -2
  9. package/dist/agent-farm/commands/attach.js.map +1 -1
  10. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  11. package/dist/agent-farm/commands/cleanup.js +16 -0
  12. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  13. package/dist/agent-farm/commands/inbox.d.ts +42 -0
  14. package/dist/agent-farm/commands/inbox.d.ts.map +1 -0
  15. package/dist/agent-farm/commands/inbox.js +129 -0
  16. package/dist/agent-farm/commands/inbox.js.map +1 -0
  17. package/dist/agent-farm/commands/interrupt.d.ts +20 -0
  18. package/dist/agent-farm/commands/interrupt.d.ts.map +1 -0
  19. package/dist/agent-farm/commands/interrupt.js +65 -0
  20. package/dist/agent-farm/commands/interrupt.js.map +1 -0
  21. package/dist/agent-farm/commands/reset/constants.d.ts +52 -0
  22. package/dist/agent-farm/commands/reset/constants.d.ts.map +1 -0
  23. package/dist/agent-farm/commands/reset/constants.js +52 -0
  24. package/dist/agent-farm/commands/reset/constants.js.map +1 -0
  25. package/dist/agent-farm/commands/reset/context.d.ts +230 -0
  26. package/dist/agent-farm/commands/reset/context.d.ts.map +1 -0
  27. package/dist/agent-farm/commands/reset/context.js +428 -0
  28. package/dist/agent-farm/commands/reset/context.js.map +1 -0
  29. package/dist/agent-farm/commands/reset/index.d.ts +192 -0
  30. package/dist/agent-farm/commands/reset/index.d.ts.map +1 -0
  31. package/dist/agent-farm/commands/reset/index.js +488 -0
  32. package/dist/agent-farm/commands/reset/index.js.map +1 -0
  33. package/dist/agent-farm/commands/reset/receipt.d.ts +97 -0
  34. package/dist/agent-farm/commands/reset/receipt.d.ts.map +1 -0
  35. package/dist/agent-farm/commands/reset/receipt.js +149 -0
  36. package/dist/agent-farm/commands/reset/receipt.js.map +1 -0
  37. package/dist/agent-farm/commands/reset/reorient.d.ts +117 -0
  38. package/dist/agent-farm/commands/reset/reorient.d.ts.map +1 -0
  39. package/dist/agent-farm/commands/reset/reorient.js +313 -0
  40. package/dist/agent-farm/commands/reset/reorient.js.map +1 -0
  41. package/dist/agent-farm/commands/reset.d.ts +19 -0
  42. package/dist/agent-farm/commands/reset.d.ts.map +1 -0
  43. package/dist/agent-farm/commands/reset.js +292 -0
  44. package/dist/agent-farm/commands/reset.js.map +1 -0
  45. package/dist/agent-farm/commands/send.d.ts +2 -2
  46. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  47. package/dist/agent-farm/commands/send.js +52 -11
  48. package/dist/agent-farm/commands/send.js.map +1 -1
  49. package/dist/agent-farm/commands/setup.d.ts +4 -1
  50. package/dist/agent-farm/commands/setup.d.ts.map +1 -1
  51. package/dist/agent-farm/commands/setup.js +8 -4
  52. package/dist/agent-farm/commands/setup.js.map +1 -1
  53. package/dist/agent-farm/commands/spawn-worktree.d.ts +116 -6
  54. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  55. package/dist/agent-farm/commands/spawn-worktree.js +345 -74
  56. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  57. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  58. package/dist/agent-farm/commands/spawn.js +13 -1
  59. package/dist/agent-farm/commands/spawn.js.map +1 -1
  60. package/dist/agent-farm/commands/status.d.ts.map +1 -1
  61. package/dist/agent-farm/commands/status.js +105 -9
  62. package/dist/agent-farm/commands/status.js.map +1 -1
  63. package/dist/agent-farm/commands/tower-sweep-husks.d.ts +6 -0
  64. package/dist/agent-farm/commands/tower-sweep-husks.d.ts.map +1 -0
  65. package/dist/agent-farm/commands/tower-sweep-husks.js +77 -0
  66. package/dist/agent-farm/commands/tower-sweep-husks.js.map +1 -0
  67. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  68. package/dist/agent-farm/commands/tower.js +34 -0
  69. package/dist/agent-farm/commands/tower.js.map +1 -1
  70. package/dist/agent-farm/commands/whoami.d.ts +65 -0
  71. package/dist/agent-farm/commands/whoami.d.ts.map +1 -0
  72. package/dist/agent-farm/commands/whoami.js +196 -0
  73. package/dist/agent-farm/commands/whoami.js.map +1 -0
  74. package/dist/agent-farm/db/index.d.ts +1 -1
  75. package/dist/agent-farm/db/index.d.ts.map +1 -1
  76. package/dist/agent-farm/db/index.js +80 -1
  77. package/dist/agent-farm/db/index.js.map +1 -1
  78. package/dist/agent-farm/db/mailbox.d.ts +222 -0
  79. package/dist/agent-farm/db/mailbox.d.ts.map +1 -0
  80. package/dist/agent-farm/db/mailbox.js +304 -0
  81. package/dist/agent-farm/db/mailbox.js.map +1 -0
  82. package/dist/agent-farm/db/schema.d.ts +1 -1
  83. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  84. package/dist/agent-farm/db/schema.js +35 -0
  85. package/dist/agent-farm/db/schema.js.map +1 -1
  86. package/dist/agent-farm/db/types.d.ts +45 -0
  87. package/dist/agent-farm/db/types.d.ts.map +1 -1
  88. package/dist/agent-farm/db/types.js.map +1 -1
  89. package/dist/agent-farm/lib/builder-lookup.d.ts +1 -1
  90. package/dist/agent-farm/lib/builder-lookup.js +2 -2
  91. package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
  92. package/dist/agent-farm/lib/reconnect-backoff.d.ts +54 -0
  93. package/dist/agent-farm/lib/reconnect-backoff.d.ts.map +1 -0
  94. package/dist/agent-farm/lib/reconnect-backoff.js +47 -0
  95. package/dist/agent-farm/lib/reconnect-backoff.js.map +1 -0
  96. package/dist/agent-farm/lib/tower-client.d.ts +16 -6
  97. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
  98. package/dist/agent-farm/lib/tower-client.js +37 -6
  99. package/dist/agent-farm/lib/tower-client.js.map +1 -1
  100. package/dist/agent-farm/lib/tunnel-client.d.ts +69 -1
  101. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  102. package/dist/agent-farm/lib/tunnel-client.js +218 -27
  103. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  104. package/dist/agent-farm/servers/architect-session-holder.d.ts +133 -0
  105. package/dist/agent-farm/servers/architect-session-holder.d.ts.map +1 -0
  106. package/dist/agent-farm/servers/architect-session-holder.js +268 -0
  107. package/dist/agent-farm/servers/architect-session-holder.js.map +1 -0
  108. package/dist/agent-farm/servers/cron-delivery.d.ts +72 -0
  109. package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -0
  110. package/dist/agent-farm/servers/cron-delivery.js +80 -0
  111. package/dist/agent-farm/servers/cron-delivery.js.map +1 -0
  112. package/dist/agent-farm/servers/delayed-send.d.ts +85 -0
  113. package/dist/agent-farm/servers/delayed-send.d.ts.map +1 -0
  114. package/dist/agent-farm/servers/delayed-send.js +165 -0
  115. package/dist/agent-farm/servers/delayed-send.js.map +1 -0
  116. package/dist/agent-farm/servers/gate-profiles.d.ts +67 -0
  117. package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -0
  118. package/dist/agent-farm/servers/gate-profiles.js +113 -0
  119. package/dist/agent-farm/servers/gate-profiles.js.map +1 -0
  120. package/dist/agent-farm/servers/mailbox-delivery.d.ts +370 -0
  121. package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -0
  122. package/dist/agent-farm/servers/mailbox-delivery.js +617 -0
  123. package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -0
  124. package/dist/agent-farm/servers/mailbox-wiring.d.ts +125 -0
  125. package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -0
  126. package/dist/agent-farm/servers/mailbox-wiring.js +425 -0
  127. package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -0
  128. package/dist/agent-farm/servers/message-write.d.ts +53 -1
  129. package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
  130. package/dist/agent-farm/servers/message-write.js +63 -0
  131. package/dist/agent-farm/servers/message-write.js.map +1 -1
  132. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  133. package/dist/agent-farm/servers/overview.js +23 -4
  134. package/dist/agent-farm/servers/overview.js.map +1 -1
  135. package/dist/agent-farm/servers/process-census.d.ts +41 -0
  136. package/dist/agent-farm/servers/process-census.d.ts.map +1 -0
  137. package/dist/agent-farm/servers/process-census.js +62 -0
  138. package/dist/agent-farm/servers/process-census.js.map +1 -0
  139. package/dist/agent-farm/servers/render-gate.d.ts +141 -0
  140. package/dist/agent-farm/servers/render-gate.d.ts.map +1 -0
  141. package/dist/agent-farm/servers/render-gate.js +251 -0
  142. package/dist/agent-farm/servers/render-gate.js.map +1 -0
  143. package/dist/agent-farm/servers/session-log-sweep.d.ts +93 -0
  144. package/dist/agent-farm/servers/session-log-sweep.d.ts.map +1 -0
  145. package/dist/agent-farm/servers/session-log-sweep.js +165 -0
  146. package/dist/agent-farm/servers/session-log-sweep.js.map +1 -0
  147. package/dist/agent-farm/servers/session-submit.d.ts +90 -0
  148. package/dist/agent-farm/servers/session-submit.d.ts.map +1 -0
  149. package/dist/agent-farm/servers/session-submit.js +127 -0
  150. package/dist/agent-farm/servers/session-submit.js.map +1 -0
  151. package/dist/agent-farm/servers/shellper-husk-sweep.d.ts +87 -0
  152. package/dist/agent-farm/servers/shellper-husk-sweep.d.ts.map +1 -0
  153. package/dist/agent-farm/servers/shellper-husk-sweep.js +129 -0
  154. package/dist/agent-farm/servers/shellper-husk-sweep.js.map +1 -0
  155. package/dist/agent-farm/servers/tower-cron.d.ts +10 -7
  156. package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
  157. package/dist/agent-farm/servers/tower-cron.js +58 -53
  158. package/dist/agent-farm/servers/tower-cron.js.map +1 -1
  159. package/dist/agent-farm/servers/tower-instances.d.ts +14 -2
  160. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  161. package/dist/agent-farm/servers/tower-instances.js +128 -19
  162. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  163. package/dist/agent-farm/servers/tower-messages.d.ts +38 -1
  164. package/dist/agent-farm/servers/tower-messages.d.ts.map +1 -1
  165. package/dist/agent-farm/servers/tower-messages.js +106 -1
  166. package/dist/agent-farm/servers/tower-messages.js.map +1 -1
  167. package/dist/agent-farm/servers/tower-routes.d.ts +16 -4
  168. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  169. package/dist/agent-farm/servers/tower-routes.js +807 -99
  170. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  171. package/dist/agent-farm/servers/tower-server.js +241 -15
  172. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  173. package/dist/agent-farm/servers/tower-terminals.d.ts +17 -2
  174. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  175. package/dist/agent-farm/servers/tower-terminals.js +139 -124
  176. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  177. package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
  178. package/dist/agent-farm/servers/tower-tunnel.js +63 -4
  179. package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
  180. package/dist/agent-farm/servers/tower-types.d.ts +2 -1
  181. package/dist/agent-farm/servers/tower-types.d.ts.map +1 -1
  182. package/dist/agent-farm/servers/tower-utils.d.ts +99 -1
  183. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
  184. package/dist/agent-farm/servers/tower-utils.js +242 -6
  185. package/dist/agent-farm/servers/tower-utils.js.map +1 -1
  186. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
  187. package/dist/agent-farm/servers/tower-websocket.js +6 -21
  188. package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
  189. package/dist/agent-farm/servers/write-queue.d.ts +35 -0
  190. package/dist/agent-farm/servers/write-queue.d.ts.map +1 -0
  191. package/dist/agent-farm/servers/write-queue.js +56 -0
  192. package/dist/agent-farm/servers/write-queue.js.map +1 -0
  193. package/dist/agent-farm/state.d.ts +6 -1
  194. package/dist/agent-farm/state.d.ts.map +1 -1
  195. package/dist/agent-farm/state.js +5 -2
  196. package/dist/agent-farm/state.js.map +1 -1
  197. package/dist/agent-farm/types.d.ts +39 -0
  198. package/dist/agent-farm/types.d.ts.map +1 -1
  199. package/dist/agent-farm/utils/agent-names.d.ts +2 -2
  200. package/dist/agent-farm/utils/agent-names.d.ts.map +1 -1
  201. package/dist/agent-farm/utils/agent-names.js +3 -3
  202. package/dist/agent-farm/utils/agent-names.js.map +1 -1
  203. package/dist/agent-farm/utils/architect-name.d.ts +2 -2
  204. package/dist/agent-farm/utils/architect-name.d.ts.map +1 -1
  205. package/dist/agent-farm/utils/architect-name.js +3 -3
  206. package/dist/agent-farm/utils/architect-name.js.map +1 -1
  207. package/dist/agent-farm/utils/config.d.ts +13 -0
  208. package/dist/agent-farm/utils/config.d.ts.map +1 -1
  209. package/dist/agent-farm/utils/config.js +33 -1
  210. package/dist/agent-farm/utils/config.js.map +1 -1
  211. package/dist/agent-farm/utils/harness.d.ts +103 -7
  212. package/dist/agent-farm/utils/harness.d.ts.map +1 -1
  213. package/dist/agent-farm/utils/harness.js +126 -19
  214. package/dist/agent-farm/utils/harness.js.map +1 -1
  215. package/dist/cli.d.ts.map +1 -1
  216. package/dist/cli.js +6 -32
  217. package/dist/cli.js.map +1 -1
  218. package/dist/commands/adopt.d.ts +3 -2
  219. package/dist/commands/adopt.d.ts.map +1 -1
  220. package/dist/commands/adopt.js +7 -6
  221. package/dist/commands/adopt.js.map +1 -1
  222. package/dist/commands/consult/agy-auth-cache.d.ts +97 -0
  223. package/dist/commands/consult/agy-auth-cache.d.ts.map +1 -0
  224. package/dist/commands/consult/agy-auth-cache.js +320 -0
  225. package/dist/commands/consult/agy-auth-cache.js.map +1 -0
  226. package/dist/commands/consult/cli-options.d.ts +34 -0
  227. package/dist/commands/consult/cli-options.d.ts.map +1 -0
  228. package/dist/commands/consult/cli-options.js +67 -0
  229. package/dist/commands/consult/cli-options.js.map +1 -0
  230. package/dist/commands/consult/index.d.ts +56 -2
  231. package/dist/commands/consult/index.d.ts.map +1 -1
  232. package/dist/commands/consult/index.js +330 -27
  233. package/dist/commands/consult/index.js.map +1 -1
  234. package/dist/commands/consult/metrics.d.ts +42 -0
  235. package/dist/commands/consult/metrics.d.ts.map +1 -1
  236. package/dist/commands/consult/metrics.js +129 -9
  237. package/dist/commands/consult/metrics.js.map +1 -1
  238. package/dist/commands/doctor.d.ts +28 -0
  239. package/dist/commands/doctor.d.ts.map +1 -1
  240. package/dist/commands/doctor.js +258 -22
  241. package/dist/commands/doctor.js.map +1 -1
  242. package/dist/commands/init.d.ts +3 -2
  243. package/dist/commands/init.d.ts.map +1 -1
  244. package/dist/commands/init.js +7 -6
  245. package/dist/commands/init.js.map +1 -1
  246. package/dist/commands/porch/checks.d.ts +23 -0
  247. package/dist/commands/porch/checks.d.ts.map +1 -1
  248. package/dist/commands/porch/checks.js +60 -0
  249. package/dist/commands/porch/checks.js.map +1 -1
  250. package/dist/commands/porch/config.d.ts +20 -0
  251. package/dist/commands/porch/config.d.ts.map +1 -1
  252. package/dist/commands/porch/config.js +20 -0
  253. package/dist/commands/porch/config.js.map +1 -1
  254. package/dist/commands/porch/index.d.ts.map +1 -1
  255. package/dist/commands/porch/index.js +32 -36
  256. package/dist/commands/porch/index.js.map +1 -1
  257. package/dist/commands/porch/next.d.ts.map +1 -1
  258. package/dist/commands/porch/next.js +2 -41
  259. package/dist/commands/porch/next.js.map +1 -1
  260. package/dist/commands/update.d.ts +4 -4
  261. package/dist/commands/update.d.ts.map +1 -1
  262. package/dist/commands/update.js +9 -11
  263. package/dist/commands/update.js.map +1 -1
  264. package/dist/lib/config.d.ts +70 -3
  265. package/dist/lib/config.d.ts.map +1 -1
  266. package/dist/lib/config.js +67 -3
  267. package/dist/lib/config.js.map +1 -1
  268. package/dist/lib/consult-lanes.d.ts +149 -0
  269. package/dist/lib/consult-lanes.d.ts.map +1 -0
  270. package/dist/lib/consult-lanes.js +360 -0
  271. package/dist/lib/consult-lanes.js.map +1 -0
  272. package/dist/lib/default-branch.d.ts +1 -1
  273. package/dist/lib/default-branch.js +1 -1
  274. package/dist/lib/github.js +1 -1
  275. package/dist/lib/github.js.map +1 -1
  276. package/dist/lib/gitignore.d.ts +25 -2
  277. package/dist/lib/gitignore.d.ts.map +1 -1
  278. package/dist/lib/gitignore.js +70 -0
  279. package/dist/lib/gitignore.js.map +1 -1
  280. package/dist/lib/migration-backup-audit.d.ts +64 -0
  281. package/dist/lib/migration-backup-audit.d.ts.map +1 -0
  282. package/dist/lib/migration-backup-audit.js +145 -0
  283. package/dist/lib/migration-backup-audit.js.map +1 -0
  284. package/dist/lib/prompt-behavior-metrics.d.ts +67 -0
  285. package/dist/lib/prompt-behavior-metrics.d.ts.map +1 -0
  286. package/dist/lib/prompt-behavior-metrics.js +290 -0
  287. package/dist/lib/prompt-behavior-metrics.js.map +1 -0
  288. package/dist/lib/protocol-drift-audit.d.ts +118 -0
  289. package/dist/lib/protocol-drift-audit.d.ts.map +1 -0
  290. package/dist/lib/protocol-drift-audit.js +217 -0
  291. package/dist/lib/protocol-drift-audit.js.map +1 -0
  292. package/dist/lib/scaffold.d.ts +10 -3
  293. package/dist/lib/scaffold.d.ts.map +1 -1
  294. package/dist/lib/scaffold.js +29 -26
  295. package/dist/lib/scaffold.js.map +1 -1
  296. package/dist/lib/skeleton.d.ts +22 -1
  297. package/dist/lib/skeleton.d.ts.map +1 -1
  298. package/dist/lib/skeleton.js +120 -0
  299. package/dist/lib/skeleton.js.map +1 -1
  300. package/dist/lib/test-env.d.ts +74 -0
  301. package/dist/lib/test-env.d.ts.map +1 -0
  302. package/dist/lib/test-env.js +92 -0
  303. package/dist/lib/test-env.js.map +1 -0
  304. package/dist/terminal/pty-manager.d.ts +9 -0
  305. package/dist/terminal/pty-manager.d.ts.map +1 -1
  306. package/dist/terminal/pty-manager.js +32 -6
  307. package/dist/terminal/pty-manager.js.map +1 -1
  308. package/dist/terminal/pty-session.d.ts +156 -4
  309. package/dist/terminal/pty-session.d.ts.map +1 -1
  310. package/dist/terminal/pty-session.js +307 -42
  311. package/dist/terminal/pty-session.js.map +1 -1
  312. package/dist/terminal/ring-buffer.d.ts +39 -6
  313. package/dist/terminal/ring-buffer.d.ts.map +1 -1
  314. package/dist/terminal/ring-buffer.js +74 -6
  315. package/dist/terminal/ring-buffer.js.map +1 -1
  316. package/dist/terminal/session-manager.d.ts +129 -0
  317. package/dist/terminal/session-manager.d.ts.map +1 -1
  318. package/dist/terminal/session-manager.js +337 -44
  319. package/dist/terminal/session-manager.js.map +1 -1
  320. package/dist/terminal/session-screen.d.ts +91 -0
  321. package/dist/terminal/session-screen.d.ts.map +1 -0
  322. package/dist/terminal/session-screen.js +135 -0
  323. package/dist/terminal/session-screen.js.map +1 -0
  324. package/dist/terminal/shellper-client.d.ts +19 -4
  325. package/dist/terminal/shellper-client.d.ts.map +1 -1
  326. package/dist/terminal/shellper-client.js +70 -8
  327. package/dist/terminal/shellper-client.js.map +1 -1
  328. package/dist/terminal/shellper-main.js +2 -1
  329. package/dist/terminal/shellper-main.js.map +1 -1
  330. package/dist/terminal/shellper-process.d.ts +1 -1
  331. package/dist/terminal/shellper-process.d.ts.map +1 -1
  332. package/dist/terminal/shellper-process.js +33 -9
  333. package/dist/terminal/shellper-process.js.map +1 -1
  334. package/dist/terminal/shellper-protocol.d.ts +40 -2
  335. package/dist/terminal/shellper-protocol.d.ts.map +1 -1
  336. package/dist/terminal/shellper-protocol.js +72 -5
  337. package/dist/terminal/shellper-protocol.js.map +1 -1
  338. package/dist/terminal/shellper-replay-buffer.d.ts +69 -7
  339. package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -1
  340. package/dist/terminal/shellper-replay-buffer.js +167 -31
  341. package/dist/terminal/shellper-replay-buffer.js.map +1 -1
  342. package/package.json +11 -9
  343. package/skeleton/.claude/skills/afx/SKILL.md +27 -1
  344. package/skeleton/.claude/skills/arch-init/SKILL.md +135 -0
  345. package/skeleton/.claude/skills/arch-save/SKILL.md +183 -0
  346. package/skeleton/.claude/skills/codev/SKILL.md +33 -2
  347. package/skeleton/.claude/skills/runnable-worktrees/SKILL.md +119 -0
  348. package/skeleton/.codex/skills/afx/SKILL.md +170 -0
  349. package/skeleton/.codex/skills/arch-init/SKILL.md +135 -0
  350. package/skeleton/.codex/skills/arch-save/SKILL.md +183 -0
  351. package/skeleton/.codex/skills/codev/SKILL.md +90 -0
  352. package/skeleton/.codex/skills/consult/SKILL.md +96 -0
  353. package/skeleton/.codex/skills/generate-image/SKILL.md +45 -0
  354. package/skeleton/.codex/skills/porch/SKILL.md +60 -0
  355. package/skeleton/.codex/skills/runnable-worktrees/SKILL.md +119 -0
  356. package/skeleton/.codex/skills/update-arch-docs/SKILL.md +132 -0
  357. package/skeleton/protocols/air/builder-prompt.md +28 -47
  358. package/skeleton/protocols/air/consult-types/impl-review.md +17 -34
  359. package/skeleton/protocols/air/consult-types/pr-review.md +14 -37
  360. package/skeleton/protocols/air/prompts/implement.md +20 -73
  361. package/skeleton/protocols/air/prompts/pr.md +22 -54
  362. package/skeleton/protocols/air/protocol.md +40 -71
  363. package/skeleton/protocols/aspir/builder-prompt.md +29 -66
  364. package/skeleton/protocols/aspir/consult-types/impl-review.md +17 -44
  365. package/skeleton/protocols/aspir/consult-types/phase-review.md +17 -44
  366. package/skeleton/protocols/aspir/consult-types/plan-review.md +14 -38
  367. package/skeleton/protocols/aspir/consult-types/pr-review.md +13 -39
  368. package/skeleton/protocols/aspir/consult-types/spec-review.md +13 -33
  369. package/skeleton/protocols/aspir/prompts/implement.md +27 -196
  370. package/skeleton/protocols/aspir/prompts/plan.md +21 -85
  371. package/skeleton/protocols/aspir/prompts/review.md +29 -228
  372. package/skeleton/protocols/aspir/prompts/specify.md +25 -111
  373. package/skeleton/protocols/aspir/protocol.json +10 -0
  374. package/skeleton/protocols/aspir/protocol.md +36 -82
  375. package/skeleton/protocols/bugfix/builder-prompt.md +23 -45
  376. package/skeleton/protocols/bugfix/consult-types/impl-review.md +21 -45
  377. package/skeleton/protocols/bugfix/consult-types/pr-review.md +18 -52
  378. package/skeleton/protocols/bugfix/prompts/fix.md +16 -61
  379. package/skeleton/protocols/bugfix/prompts/investigate.md +18 -62
  380. package/skeleton/protocols/bugfix/prompts/pr.md +22 -57
  381. package/skeleton/protocols/bugfix/protocol.md +44 -50
  382. package/skeleton/protocols/experiment/builder-prompt.md +25 -58
  383. package/skeleton/protocols/experiment/protocol.md +22 -188
  384. package/skeleton/protocols/experiment/templates/notes.md +11 -71
  385. package/skeleton/protocols/maintain/builder-prompt.md +24 -45
  386. package/skeleton/protocols/maintain/consult-types/impl-review.md +17 -44
  387. package/skeleton/protocols/maintain/consult-types/pr-review.md +13 -39
  388. package/skeleton/protocols/maintain/prompts/maintain.md +1 -1
  389. package/skeleton/protocols/maintain/protocol.md +32 -266
  390. package/skeleton/protocols/maintain/templates/maintenance-run.md +11 -0
  391. package/skeleton/protocols/pir/builder-prompt.md +30 -64
  392. package/skeleton/protocols/pir/consult-types/impl-review.md +17 -50
  393. package/skeleton/protocols/pir/consult-types/pr-review.md +11 -40
  394. package/skeleton/protocols/pir/prompts/implement.md +1 -2
  395. package/skeleton/protocols/pir/prompts/plan.md +0 -3
  396. package/skeleton/protocols/pir/prompts/review.md +1 -1
  397. package/skeleton/protocols/pir/protocol.md +54 -177
  398. package/skeleton/protocols/research/builder-prompt.md +27 -58
  399. package/skeleton/protocols/research/protocol.md +28 -153
  400. package/skeleton/protocols/spike/builder-prompt.md +30 -48
  401. package/skeleton/protocols/spike/protocol.md +24 -107
  402. package/skeleton/protocols/spike/templates/findings.md +9 -39
  403. package/skeleton/protocols/spir/builder-prompt.md +33 -62
  404. package/skeleton/protocols/spir/consult-types/impl-review.md +17 -44
  405. package/skeleton/protocols/spir/consult-types/phase-review.md +17 -44
  406. package/skeleton/protocols/spir/consult-types/plan-review.md +14 -38
  407. package/skeleton/protocols/spir/consult-types/pr-review.md +13 -39
  408. package/skeleton/protocols/spir/consult-types/spec-review.md +13 -33
  409. package/skeleton/protocols/spir/prompts/implement.md +26 -195
  410. package/skeleton/protocols/spir/prompts/plan.md +20 -84
  411. package/skeleton/protocols/spir/prompts/review.md +28 -227
  412. package/skeleton/protocols/spir/prompts/specify.md +24 -110
  413. package/skeleton/protocols/spir/protocol.json +10 -0
  414. package/skeleton/protocols/spir/protocol.md +84 -633
  415. package/skeleton/protocols/spir/templates/plan.md +28 -147
  416. package/skeleton/protocols/spir/templates/review.md +21 -80
  417. package/skeleton/protocols/spir/templates/spec.md +24 -118
  418. package/skeleton/resources/commands/agent-farm.md +348 -0
  419. package/skeleton/resources/commands/codev.md +5 -0
  420. package/skeleton/resources/commands/consult.md +262 -8
  421. package/skeleton/resources/commands/overview.md +1 -0
  422. package/skeleton/roles/architect.md +67 -306
  423. package/skeleton/roles/builder.md +77 -191
  424. package/skeleton/templates/AGENTS.md +2 -0
  425. package/skeleton/templates/CLAUDE.md +2 -0
  426. package/templates/tower.html +39 -2
  427. package/dashboard-dist/assets/index-BZ1x7x1X.js.map +0 -1
  428. package/dashboard-dist/assets/index-DB1KBSNE.css +0 -32
  429. package/dist/agent-farm/servers/send-buffer.d.ts +0 -59
  430. package/dist/agent-farm/servers/send-buffer.d.ts.map +0 -1
  431. package/dist/agent-farm/servers/send-buffer.js +0 -103
  432. package/dist/agent-farm/servers/send-buffer.js.map +0 -1
  433. package/skeleton/porch/prompts/defend.md +0 -108
  434. package/skeleton/porch/prompts/diagnose.md +0 -70
  435. package/skeleton/porch/prompts/evaluate.md +0 -132
  436. package/skeleton/porch/prompts/fix.md +0 -59
  437. package/skeleton/porch/prompts/implement.md +0 -88
  438. package/skeleton/porch/prompts/plan.md +0 -74
  439. package/skeleton/porch/prompts/pr.md +0 -84
  440. package/skeleton/porch/prompts/review.md +0 -249
  441. package/skeleton/porch/prompts/specify.md +0 -53
  442. package/skeleton/porch/prompts/test.md +0 -63
  443. package/skeleton/protocols/aspir/templates/plan.md +0 -184
  444. package/skeleton/protocols/aspir/templates/review.md +0 -120
  445. package/skeleton/protocols/aspir/templates/spec.md +0 -154
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Live-Tower wiring for mailbox delivery (Spec 1313, Phase 4).
3
+ *
4
+ * `mailbox-delivery.ts` holds the PURE orchestration (persist → gate → deliver |
5
+ * hold) behind the {@link DeliveryPorts} seam. This module binds those ports to
6
+ * the real Tower — the live terminal registry, the render-gate, paced PTY writes,
7
+ * and the WebSocket message bus — and owns the backstop drainer's lifecycle,
8
+ * which replaces the retired in-memory `SendBuffer`.
9
+ *
10
+ * Keeping the wiring here (not in the pure module) is what lets the orchestration
11
+ * be unit-tested without a live Tower, and lets `handleSend` and the drainer share
12
+ * exactly one delivery path (and one per-agent write serializer).
13
+ */
14
+ import { type PtySession } from '../../terminal/pty-session.js';
15
+ import { type GateProfile, type GateVerdict } from './render-gate.js';
16
+ import { MailboxDrainer, type DeliveryPorts, type DeliverySession } from './mailbox-delivery.js';
17
+ type LogFn = (level: 'INFO' | 'ERROR' | 'WARN', message: string) => void;
18
+ /**
19
+ * The SSE broadcast fn (Tower's `broadcastNotification`), wired once at boot via
20
+ * {@link setMailboxBroadcaster}. Mirrors `codev-config-watcher.ts`'s
21
+ * `setCodevConfigNotifier` pattern: the pure delivery module and the boot-time drainer
22
+ * have no `RouteContext`, so the two held-set SSE events they raise
23
+ * (`overview-changed` on a held-state change, `mailbox-escalation` on an age crossing)
24
+ * are fanned out through this module singleton instead. Undefined until boot wires it,
25
+ * so `makeDeliveryPorts` is safe to call before Tower is up (unit tests never set it,
26
+ * making the ports genuine no-ops).
27
+ */
28
+ type MailboxBroadcastFn = (n: {
29
+ type: string;
30
+ title: string;
31
+ body: string;
32
+ workspace?: string;
33
+ }) => void;
34
+ /** Wire the SSE broadcast fn once at Tower startup (see {@link MailboxBroadcastFn}). */
35
+ export declare function setMailboxBroadcaster(fn: MailboxBroadcastFn): void;
36
+ /**
37
+ * The live, writable {@link PtySession} for an agent in a workspace, or `null`
38
+ * when there is no usable live PTY — unknown agent, an exited session (the
39
+ * PtyManager keeps an exited session for 30 s, so a stale hit is still filtered
40
+ * here), or a session whose shellper connection is down (#1198). A `null` result
41
+ * makes the delivery hold `no-live-pty` rather than write into the void.
42
+ *
43
+ * `toAgent` is the canonical identity stored on the row (a builder id or a
44
+ * specific architect name), so an exact key match against the routing sub-maps is
45
+ * correct — and because rows address the AGENT, a respawned terminal (new id, same
46
+ * builder id) transparently drains its predecessor's held mail.
47
+ */
48
+ export declare function resolveLiveSessionForAgent(workspacePath: string, toAgent: string): PtySession | null;
49
+ /**
50
+ * The inverse of {@link resolveLiveSessionForAgent}: reverse-map a live session id to
51
+ * the agent it serves (`{ workspacePath, toAgent }`), or `null` when the id belongs to
52
+ * no registered agent — a plain shell nobody addresses, or a session already torn
53
+ * down. Drives the Phase 5 fast triggers: a submit/quiescence signal carries only the
54
+ * session id, and delivery is keyed on the canonical agent, so the id must be resolved
55
+ * back before scheduling a drain. Iterates the routing registry (agents per active
56
+ * workspace — small) which is cheap at trigger frequency and coalesced downstream. The
57
+ * agent name it returns is the same canonical identity the row is addressed to, so a
58
+ * respawned terminal's signal still resolves to the right held mail.
59
+ */
60
+ export declare function resolveAgentForSession(sessionId: string): {
61
+ workspacePath: string;
62
+ toAgent: string;
63
+ } | null;
64
+ /**
65
+ * The classifier profile for a session, resolving the wrapped-launch case. A real
66
+ * builder runs through `.builder-start.sh`, so `session.command` is the shell, not
67
+ * the agent, and the pure {@link resolveProfile} returns `null`. We then read the
68
+ * launch script (exactly as `afx reset` does) to recover the underlying harness
69
+ * command and resolve against that. Still `null` → the delivery holds `no-profile`
70
+ * (fail-safe by construction: an unknown agent is held and surfaced, never guessed
71
+ * — this is what correctly trips on wrapper/boot/relaunch screens too).
72
+ *
73
+ * Stale-identity note (Spec 1313): `session.command` is now sourced from the
74
+ * persisted `terminal_sessions.command` on reconnect. If it ever goes stale (a
75
+ * user re-points `shell.architect` at a different harness and the shellper later
76
+ * auto-restarts into it while the row still names the old one), this can resolve
77
+ * the WRONG profile — but it fails CLOSED today, not misdelivered: CLAUDE_PROFILE
78
+ * and CODEX_PROFILE are behaviourally identical (same marker + region patterns),
79
+ * and any cross-family mismatch (e.g. agy's `> ` marker) fails the composer-marker
80
+ * test → not clean → held. That safety is a property of the current profile TABLE,
81
+ * not of this design; the day codex/claude markers diverge, stale identity becomes
82
+ * a live bug and the authoritative fix is WELCOME-frame hydration (see review).
83
+ */
84
+ export declare function resolveProfileForSession(session: DeliverySession): GateProfile | null;
85
+ /**
86
+ * Classify a session's CURRENT screen for the gate (Spec 1313 render-gate round 2). Reads the
87
+ * session's persistent {@link SessionScreen} mirror — a bounded headless Terminal fed the
88
+ * session's output from birth — and runs the shared classifier on its viewport. This replaces
89
+ * the old whole-ring re-render (`classifyScreen(ringBuffer.getAll()…)`), which #1205's 2 MiB
90
+ * partial cap could hand a TORN frame → a permanent false-`busy` hold for the busiest agents.
91
+ *
92
+ * The delivery path only ever calls this with a live session resolved by
93
+ * {@link resolveLiveSessionForAgent} — always a `PtySession`, which carries the mirror — so the
94
+ * cast is sound. A session that has produced NO output yet has no mirror (`gateScreen` is null);
95
+ * that is not a verified-empty prompt, so it classifies not-clean (`no-composer-marker`), exactly
96
+ * as an empty replay always did. `SessionScreen.read()` flushes the parser, so the buffer the
97
+ * shared {@link classifyBuffer} reads reflects every byte counted by the change token the
98
+ * delivery path sampled — the property its gate→write TOCTOU relies on.
99
+ */
100
+ export declare function classifyAgentScreen(session: DeliverySession, profile: GateProfile): Promise<GateVerdict>;
101
+ /**
102
+ * Build the {@link DeliveryPorts} bound to the live Tower. Cheap (closures over
103
+ * module singletons), so `handleSend` may construct one per request and the
104
+ * drainer one at boot; the shared state that matters (the per-agent write
105
+ * serializer) lives in `mailbox-delivery.ts`, not here.
106
+ */
107
+ export declare function makeDeliveryPorts(log: LogFn): DeliveryPorts;
108
+ /**
109
+ * Start the mailbox drainer (replaces `startSendBuffer`). Called once on Tower boot:
110
+ * prunes terminal rows, begins the periodic held-row backstop that redelivers on the
111
+ * first clean gate after a line clears, and subscribes the Phase 5 fast triggers so a
112
+ * held message drains within a microtask of a user submit or output quiescence rather
113
+ * than waiting for the next backstop tick.
114
+ */
115
+ export declare function startMailboxDrainer(log: LogFn): void;
116
+ /**
117
+ * Stop the mailbox drainer (replaces `stopSendBuffer`). Detaches the fast triggers and
118
+ * stops the backstop timer — there is NO shutdown force-flush, because every held row
119
+ * is already persisted in SQLite and will be redelivered after restart on a clean gate.
120
+ */
121
+ export declare function stopMailboxDrainer(): void;
122
+ /** The live drainer (liveness-telemetry streaks; Phase 7 surfaces them). */
123
+ export declare function getMailboxDrainer(): MailboxDrainer;
124
+ export {};
125
+ //# sourceMappingURL=mailbox-wiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-wiring.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/mailbox-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAIzF,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQtF,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EAKrB,MAAM,uBAAuB,CAAC;AAa/B,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzE;;;;;;;;;GASG;AACH,KAAK,kBAAkB,GAAG,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAGzG,wFAAwF;AACxF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI,CAElE;AA2BD;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAChB;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASnD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,eAAe,GAAG,WAAW,GAAG,IAAI,CAMrF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAK9G;AAcD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,GAAG,aAAa,CAe3D;AAwND;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,CAIpD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,IAAI,cAAc,CAElD"}
@@ -0,0 +1,425 @@
1
+ /**
2
+ * Live-Tower wiring for mailbox delivery (Spec 1313, Phase 4).
3
+ *
4
+ * `mailbox-delivery.ts` holds the PURE orchestration (persist → gate → deliver |
5
+ * hold) behind the {@link DeliveryPorts} seam. This module binds those ports to
6
+ * the real Tower — the live terminal registry, the render-gate, paced PTY writes,
7
+ * and the WebSocket message bus — and owns the backstop drainer's lifecycle,
8
+ * which replaces the retired in-memory `SendBuffer`.
9
+ *
10
+ * Keeping the wiring here (not in the pure module) is what lets the orchestration
11
+ * be unit-tested without a live Tower, and lets `handleSend` and the drainer share
12
+ * exactly one delivery path (and one per-agent write serializer).
13
+ */
14
+ import { readFileSync, existsSync, readdirSync } from 'node:fs';
15
+ import { homedir } from 'node:os';
16
+ import { loadConfig } from '../../lib/config.js';
17
+ import { terminalDeliverySignals } from '../../terminal/pty-session.js';
18
+ import { getWorkspaceTerminals, getTerminalManager } from './tower-terminals.js';
19
+ import { broadcastMessage, resolveAgentInRegistry, isResolveError } from './tower-messages.js';
20
+ import { writeMessagePaced } from './message-write.js';
21
+ import { classifyBuffer } from './render-gate.js';
22
+ import { resolveProfile } from './gate-profiles.js';
23
+ import { harnessFromLaunchScript } from '../commands/reset/context.js';
24
+ import { getGlobalDb } from '../db/index.js';
25
+ import { getArchitectByName } from '../state.js';
26
+ import { formatBuilderMessage } from '../utils/message-format.js';
27
+ import { supersede as supersedeMailbox, dismissHeldWithKey, NOTICE_SUPERSEDE_PREFIX } from '../db/mailbox.js';
28
+ import path from 'node:path';
29
+ import { MailboxDrainer, } from './mailbox-delivery.js';
30
+ /**
31
+ * "Recent output" window for the liveness diagnostic (Spec 1313, Phase 7 — spec line
32
+ * 91). A `no-profile` streak only raises the loud log/broadcast when the session emitted
33
+ * output within this window: that distinguishes a genuinely broken/unknown classifier on
34
+ * a LIVE, producing app (worth alarming) from a dormant unknown session (still visible in
35
+ * `afx inbox`, but no loud alarm). Sized well above the streak's own duration
36
+ * (threshold × backstop interval ≈ 15s) so an actively-failing app comfortably qualifies.
37
+ */
38
+ const LIVENESS_RECENT_OUTPUT_MS = 30_000;
39
+ let mailboxBroadcaster;
40
+ /** Wire the SSE broadcast fn once at Tower startup (see {@link MailboxBroadcastFn}). */
41
+ export function setMailboxBroadcaster(fn) {
42
+ mailboxBroadcaster = fn;
43
+ }
44
+ /**
45
+ * A node-fs adapter for {@link harnessFromLaunchScript}. Only `.read` is exercised
46
+ * by that function, but `exists`/`listDirs` are implemented faithfully so the port
47
+ * is honest and reusable rather than a lying stub.
48
+ */
49
+ const NODE_FS_PORT = {
50
+ exists: (p) => existsSync(p),
51
+ read: (p) => {
52
+ try {
53
+ return readFileSync(p, 'utf-8');
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ },
59
+ listDirs: (p) => {
60
+ try {
61
+ return readdirSync(p, { withFileTypes: true })
62
+ .filter((d) => d.isDirectory())
63
+ .map((d) => d.name);
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ },
69
+ };
70
+ /**
71
+ * The live, writable {@link PtySession} for an agent in a workspace, or `null`
72
+ * when there is no usable live PTY — unknown agent, an exited session (the
73
+ * PtyManager keeps an exited session for 30 s, so a stale hit is still filtered
74
+ * here), or a session whose shellper connection is down (#1198). A `null` result
75
+ * makes the delivery hold `no-live-pty` rather than write into the void.
76
+ *
77
+ * `toAgent` is the canonical identity stored on the row (a builder id or a
78
+ * specific architect name), so an exact key match against the routing sub-maps is
79
+ * correct — and because rows address the AGENT, a respawned terminal (new id, same
80
+ * builder id) transparently drains its predecessor's held mail.
81
+ */
82
+ export function resolveLiveSessionForAgent(workspacePath, toAgent) {
83
+ const entry = getWorkspaceTerminals().get(workspacePath);
84
+ if (!entry)
85
+ return null;
86
+ const tid = entry.builders.get(toAgent) ?? entry.architects.get(toAgent) ?? entry.shells.get(toAgent);
87
+ if (!tid)
88
+ return null;
89
+ const session = getTerminalManager().getSession(tid);
90
+ if (!session || !session.writable)
91
+ return null;
92
+ return session;
93
+ }
94
+ /**
95
+ * The inverse of {@link resolveLiveSessionForAgent}: reverse-map a live session id to
96
+ * the agent it serves (`{ workspacePath, toAgent }`), or `null` when the id belongs to
97
+ * no registered agent — a plain shell nobody addresses, or a session already torn
98
+ * down. Drives the Phase 5 fast triggers: a submit/quiescence signal carries only the
99
+ * session id, and delivery is keyed on the canonical agent, so the id must be resolved
100
+ * back before scheduling a drain. Iterates the routing registry (agents per active
101
+ * workspace — small) which is cheap at trigger frequency and coalesced downstream. The
102
+ * agent name it returns is the same canonical identity the row is addressed to, so a
103
+ * respawned terminal's signal still resolves to the right held mail.
104
+ */
105
+ export function resolveAgentForSession(sessionId) {
106
+ for (const [workspacePath, entry] of getWorkspaceTerminals()) {
107
+ for (const registry of [entry.builders, entry.architects, entry.shells]) {
108
+ for (const [agent, tid] of registry) {
109
+ if (tid === sessionId)
110
+ return { workspacePath, toAgent: agent };
111
+ }
112
+ }
113
+ }
114
+ return null;
115
+ }
116
+ /**
117
+ * The classifier profile for a session, resolving the wrapped-launch case. A real
118
+ * builder runs through `.builder-start.sh`, so `session.command` is the shell, not
119
+ * the agent, and the pure {@link resolveProfile} returns `null`. We then read the
120
+ * launch script (exactly as `afx reset` does) to recover the underlying harness
121
+ * command and resolve against that. Still `null` → the delivery holds `no-profile`
122
+ * (fail-safe by construction: an unknown agent is held and surfaced, never guessed
123
+ * — this is what correctly trips on wrapper/boot/relaunch screens too).
124
+ *
125
+ * Stale-identity note (Spec 1313): `session.command` is now sourced from the
126
+ * persisted `terminal_sessions.command` on reconnect. If it ever goes stale (a
127
+ * user re-points `shell.architect` at a different harness and the shellper later
128
+ * auto-restarts into it while the row still names the old one), this can resolve
129
+ * the WRONG profile — but it fails CLOSED today, not misdelivered: CLAUDE_PROFILE
130
+ * and CODEX_PROFILE are behaviourally identical (same marker + region patterns),
131
+ * and any cross-family mismatch (e.g. agy's `> ` marker) fails the composer-marker
132
+ * test → not clean → held. That safety is a property of the current profile TABLE,
133
+ * not of this design; the day codex/claude markers diverge, stale identity becomes
134
+ * a live bug and the authoritative fix is WELCOME-frame hydration (see review).
135
+ */
136
+ export function resolveProfileForSession(session) {
137
+ const direct = resolveProfile({ command: session.command, args: session.launchArgs });
138
+ if (direct)
139
+ return direct;
140
+ const harness = harnessFromLaunchScript(NODE_FS_PORT, session.cwd);
141
+ if (!harness)
142
+ return null;
143
+ return resolveProfile({ command: harness });
144
+ }
145
+ /**
146
+ * Classify a session's CURRENT screen for the gate (Spec 1313 render-gate round 2). Reads the
147
+ * session's persistent {@link SessionScreen} mirror — a bounded headless Terminal fed the
148
+ * session's output from birth — and runs the shared classifier on its viewport. This replaces
149
+ * the old whole-ring re-render (`classifyScreen(ringBuffer.getAll()…)`), which #1205's 2 MiB
150
+ * partial cap could hand a TORN frame → a permanent false-`busy` hold for the busiest agents.
151
+ *
152
+ * The delivery path only ever calls this with a live session resolved by
153
+ * {@link resolveLiveSessionForAgent} — always a `PtySession`, which carries the mirror — so the
154
+ * cast is sound. A session that has produced NO output yet has no mirror (`gateScreen` is null);
155
+ * that is not a verified-empty prompt, so it classifies not-clean (`no-composer-marker`), exactly
156
+ * as an empty replay always did. `SessionScreen.read()` flushes the parser, so the buffer the
157
+ * shared {@link classifyBuffer} reads reflects every byte counted by the change token the
158
+ * delivery path sampled — the property its gate→write TOCTOU relies on.
159
+ */
160
+ export async function classifyAgentScreen(session, profile) {
161
+ const screen = session.gateScreen;
162
+ if (!screen)
163
+ return { clean: false, reason: 'busy', detail: 'no-composer-marker' };
164
+ const { term, cols, rows } = await screen.read();
165
+ return classifyBuffer(term, cols, rows, profile);
166
+ }
167
+ /** Convert a delivered-message frame to the WebSocket bus shape and broadcast it. */
168
+ function broadcastDelivered(frame) {
169
+ broadcastMessage({
170
+ type: 'message',
171
+ from: { project: frame.from.project ?? 'unknown', agent: frame.from.agent ?? 'unknown' },
172
+ to: frame.to,
173
+ content: frame.content,
174
+ metadata: { source: 'mailbox' },
175
+ timestamp: new Date(frame.timestamp).toISOString(),
176
+ });
177
+ }
178
+ /**
179
+ * Build the {@link DeliveryPorts} bound to the live Tower. Cheap (closures over
180
+ * module singletons), so `handleSend` may construct one per request and the
181
+ * drainer one at boot; the shared state that matters (the per-agent write
182
+ * serializer) lives in `mailbox-delivery.ts`, not here.
183
+ */
184
+ export function makeDeliveryPorts(log) {
185
+ return {
186
+ getSessionForAgent: (ws, agent) => resolveLiveSessionForAgent(ws, agent),
187
+ resolveProfile: (session) => resolveProfileForSession(session),
188
+ classify: (session, profile) => classifyAgentScreen(session, profile),
189
+ writeMessage: (session, msg, noEnter) => writeMessagePaced(session, msg, noEnter),
190
+ broadcast: (frame) => broadcastDelivered(frame),
191
+ onHeldStateChange: () => broadcastHeldStateChange(),
192
+ onEscalation: (info) => broadcastEscalation(info),
193
+ onLiveness: (info) => surfaceLiveness(info, log),
194
+ escalateHeldToOwner: (info) => escalateHeldToOwner(info, log),
195
+ clearHeldOwnerNotice: (ws, agent) => clearHeldOwnerNotice(ws, agent),
196
+ log: (m) => log('INFO', m),
197
+ now: () => Date.now(),
198
+ };
199
+ }
200
+ /** Pseudo-sender identity for owner starvation notices (Spec 1313 round 3, change 3). */
201
+ const NOTICE_SENDER = 'af-mailbox';
202
+ /** Supersede key for the single pending owner notice ABOUT a starving `toAgent`. */
203
+ function noticeSupersedeKey(toAgent) {
204
+ return `${NOTICE_SUPERSEDE_PREFIX}${toAgent}`;
205
+ }
206
+ /** Human-readable notice body (metadata only — never the starved messages' contents). */
207
+ function formatOwnerNoticeBody(info) {
208
+ const mins = Math.max(1, Math.round(info.ageMs / 60_000));
209
+ const plural = info.heldCount === 1 ? 'message' : 'messages';
210
+ return (`Mailbox delivery is STUCK for builder '${info.toAgent}' @ ${path.basename(info.workspacePath)}. ` +
211
+ `${info.heldCount} ${plural} held ~${mins}m (reason: ${info.reason ?? 'held'}) — its composer never classifies as a ready prompt, ` +
212
+ `so nothing is being delivered (cron nudges included). ` +
213
+ `Remedy: run 'afx inbox' to inspect; 'afx interrupt ${info.toAgent}' clears a stuck composer.`);
214
+ }
215
+ /**
216
+ * Raise a starvation notice to a starving agent's OWNER architect (Spec 1313 round 3, change
217
+ * 3). Skips agents that are themselves architects — the alarm would land in the same starved
218
+ * mailbox, and `afx status` covers that case. Resolves the recipient EXACTLY as `afx send
219
+ * architect` does — the starving builder's spawning architect (affinity), else the workspace's
220
+ * `main`, else the first-registered architect — via the shared registry resolver. Then enqueues
221
+ * ONE coalesced (supersede-keyed), GATE-delivered mailbox row: visibility only, never a force
222
+ * path. No-op when no architect can be resolved (nowhere to send).
223
+ *
224
+ * RETURNS `true` iff a notice row was enqueued; `false` on every no-op path (recipient is
225
+ * itself an architect / no architect resolvable / would notify the agent about itself). The
226
+ * drainer arms its once-per-episode guard only on `true`, so a no-op retries next tick rather
227
+ * than silently suppressing the alarm for the episode.
228
+ */
229
+ function escalateHeldToOwner(info, log) {
230
+ // An architect-addressed row gets no notice (it would starve in the same mailbox).
231
+ if (getArchitectByName(info.workspacePath, info.toAgent))
232
+ return false;
233
+ // Resolve the owner architect the same way `afx send architect` does (bare `architect` form
234
+ // with the starving builder as sender → spawning affinity, else main, else first).
235
+ const owner = resolveAgentInRegistry('architect', info.workspacePath, info.toAgent);
236
+ if (isResolveError(owner)) {
237
+ log('INFO', `[mailbox] starvation notice for ${info.toAgent} skipped: no architect to notify (${owner.message})`);
238
+ return false;
239
+ }
240
+ if (owner.agent === info.toAgent)
241
+ return false; // defensive: never notify an agent about itself
242
+ const body = formatOwnerNoticeBody(info);
243
+ supersedeMailbox(getGlobalDb(), info.workspacePath, noticeSupersedeKey(info.toAgent), {
244
+ workspacePath: info.workspacePath,
245
+ toAgent: owner.agent,
246
+ body,
247
+ formattedMessage: formatBuilderMessage(NOTICE_SENDER, body),
248
+ fromAgent: NOTICE_SENDER,
249
+ fromWorkspace: info.workspacePath,
250
+ });
251
+ broadcastHeldStateChange();
252
+ // Deliver the notice promptly through the SAME gate (it holds if the architect is busy).
253
+ void ensureDrainer().scheduleDrain(owner.workspacePath, owner.agent);
254
+ log('WARN', `[mailbox] STARVATION notice → ${owner.agent} about ${info.toAgent} @ ${path.basename(info.workspacePath)} ` +
255
+ `(${info.heldCount} held ~${Math.round(info.ageMs / 1000)}s, reason ${info.reason ?? 'held'})`);
256
+ return true;
257
+ }
258
+ /**
259
+ * Clear (dismiss) any still-held owner notice about `toAgent` once its starvation is over
260
+ * (Spec 1313 round 3). A no-op on an already-delivered notice — the architect already saw it.
261
+ */
262
+ function clearHeldOwnerNotice(workspacePath, toAgent) {
263
+ const dismissed = dismissHeldWithKey(getGlobalDb(), workspacePath, noticeSupersedeKey(toAgent));
264
+ if (dismissed > 0)
265
+ broadcastHeldStateChange();
266
+ }
267
+ /**
268
+ * Fire the `overview-changed` SSE event so the held-count indicator refetches its
269
+ * count (Spec 1313, Phase 7). Cheap and idempotent (it only triggers a refetch), so
270
+ * the delivery path fires it freely on any held-set change. No-op until the broadcaster
271
+ * is wired at boot.
272
+ */
273
+ function broadcastHeldStateChange() {
274
+ mailboxBroadcaster?.({
275
+ type: 'overview-changed',
276
+ title: 'Held mail changed',
277
+ body: 'Mailbox held-set changed',
278
+ });
279
+ }
280
+ /**
281
+ * Fire the `mailbox-escalation` SSE event when a held row crosses the escalation age
282
+ * (Spec 1313, Phase 7) — a VISIBILITY signal that moves the dashboard/VSCode indicator
283
+ * into its attention state; it never triggers delivery. Carries metadata only (ids +
284
+ * age + reason), never the message body, per the spec's redaction rule. No-op until the
285
+ * broadcaster is wired at boot.
286
+ */
287
+ function broadcastEscalation(info) {
288
+ const payload = {
289
+ workspacePath: info.workspacePath,
290
+ toAgent: info.toAgent,
291
+ mailboxId: info.mailboxId,
292
+ ageMs: info.ageMs,
293
+ reason: info.reason,
294
+ };
295
+ mailboxBroadcaster?.({
296
+ type: 'mailbox-escalation',
297
+ title: 'Message held past escalation age',
298
+ body: JSON.stringify(payload),
299
+ workspace: info.workspacePath,
300
+ });
301
+ }
302
+ /**
303
+ * Surface the liveness diagnostic (Spec 1313, Phase 7 — spec line 91). Applies the spec's
304
+ * "with recent output" gate: only when the agent's live session emitted output within
305
+ * {@link LIVENESS_RECENT_OUTPUT_MS} — proving a genuinely broken/unknown classifier on a
306
+ * PRODUCING app, not a dormant unknown session — does it raise the loud log AND a broadcast.
307
+ * The broadcast rides the existing generic `notification` SSE channel (human title/body, no
308
+ * body-of-message), so it is immediately visible in the dashboard's notification surface
309
+ * without any new event type or client wiring. An idle unknown session raises nothing here —
310
+ * its held row is still discoverable in `afx inbox`, per the metadata-only visibility model.
311
+ */
312
+ function surfaceLiveness(info, log) {
313
+ const session = resolveLiveSessionForAgent(info.workspacePath, info.toAgent);
314
+ const hasRecentOutput = session != null && Date.now() - session.lastDataAt <= LIVENESS_RECENT_OUTPUT_MS;
315
+ if (!hasRecentOutput)
316
+ return; // dormant unknown session → no loud alarm (still in `afx inbox`)
317
+ const where = `${info.toAgent} @ ${path.basename(info.workspacePath)}`;
318
+ log('WARN', `[mailbox] LIVENESS: ${where} held no-profile for ${info.streak} consecutive checks with recent output — ` +
319
+ `unrecognized app; its mail will not deliver until a classifier profile matches (check for a TUI update)`);
320
+ mailboxBroadcaster?.({
321
+ type: 'notification',
322
+ title: 'Mailbox: delivery blocked (unrecognized app)',
323
+ body: `${where} — its screen never classifies as a ready prompt, so held messages will not deliver. A classifier profile may need updating.`,
324
+ workspace: info.workspacePath,
325
+ });
326
+ }
327
+ // The single backstop drainer instance (replaces the retired SendBuffer). Created
328
+ // lazily so it picks up the configured retention window (below) at first use.
329
+ let drainer;
330
+ /**
331
+ * The terminal-row retention window (days) for the prune. This is a Tower-GLOBAL
332
+ * policy — the drainer prunes rows across every workspace in the user-global
333
+ * `global.db` — so it is read from the user-global `~/.codev/config.json` layer via
334
+ * `loadConfig` (rooted at home), not any single workspace's config. Spec default 30
335
+ * (already `DEFAULT_CONFIG.mailbox.retentionDays`). A malformed config never stops
336
+ * the drainer from booting — it falls back to the default.
337
+ */
338
+ function configuredRetentionDays() {
339
+ try {
340
+ return loadConfig(homedir()).mailbox?.retentionDays ?? 30;
341
+ }
342
+ catch {
343
+ return 30;
344
+ }
345
+ }
346
+ /**
347
+ * The held-row escalation age in ms (Spec 1313, Phase 7). Like the retention window
348
+ * this is a Tower-GLOBAL policy read from the user-global config layer, default 60s
349
+ * (matching today's max-age; `DEFAULT_CONFIG.mailbox.escalationSeconds`). A malformed
350
+ * config never stops the drainer from booting — it falls back to the default.
351
+ */
352
+ function configuredEscalationMs() {
353
+ try {
354
+ return (loadConfig(homedir()).mailbox?.escalationSeconds ?? 60) * 1000;
355
+ }
356
+ catch {
357
+ return 60_000;
358
+ }
359
+ }
360
+ function ensureDrainer() {
361
+ if (!drainer) {
362
+ drainer = new MailboxDrainer({
363
+ pruneRetentionDays: configuredRetentionDays(),
364
+ escalationMs: configuredEscalationMs(),
365
+ });
366
+ }
367
+ return drainer;
368
+ }
369
+ // Phase 5 fast-trigger bus handler. Held at module scope so `stopMailboxDrainer` can
370
+ // detach it: re-subscribing on every start would accumulate duplicate listeners across
371
+ // Tower restarts within one process (and the tests do start/stop/start).
372
+ let deliverySignalHandler;
373
+ /**
374
+ * Subscribe the fast submit/quiescence triggers (Spec 1313 Phase 5) to the drainer.
375
+ * Each signal names only the emitting session; we reverse-map it to its agent and
376
+ * schedule a coalesced, gated drain. Idempotent — a second call while already
377
+ * subscribed is a no-op, so the single-listener invariant (which arms the
378
+ * per-session quiescence timers) holds.
379
+ */
380
+ function subscribeDeliverySignals() {
381
+ if (deliverySignalHandler)
382
+ return;
383
+ const handler = (sessionId) => {
384
+ const target = resolveAgentForSession(sessionId);
385
+ if (target)
386
+ void ensureDrainer().scheduleDrain(target.workspacePath, target.toAgent);
387
+ };
388
+ deliverySignalHandler = handler;
389
+ terminalDeliverySignals.on('submit', handler);
390
+ terminalDeliverySignals.on('quiescence', handler);
391
+ }
392
+ /** Detach the Phase 5 trigger handler so a subsequent start re-subscribes cleanly. */
393
+ function unsubscribeDeliverySignals() {
394
+ if (!deliverySignalHandler)
395
+ return;
396
+ terminalDeliverySignals.off('submit', deliverySignalHandler);
397
+ terminalDeliverySignals.off('quiescence', deliverySignalHandler);
398
+ deliverySignalHandler = undefined;
399
+ }
400
+ /**
401
+ * Start the mailbox drainer (replaces `startSendBuffer`). Called once on Tower boot:
402
+ * prunes terminal rows, begins the periodic held-row backstop that redelivers on the
403
+ * first clean gate after a line clears, and subscribes the Phase 5 fast triggers so a
404
+ * held message drains within a microtask of a user submit or output quiescence rather
405
+ * than waiting for the next backstop tick.
406
+ */
407
+ export function startMailboxDrainer(log) {
408
+ ensureDrainer().start(makeDeliveryPorts(log), getGlobalDb());
409
+ subscribeDeliverySignals();
410
+ log('INFO', '[mailbox] backstop drainer started');
411
+ }
412
+ /**
413
+ * Stop the mailbox drainer (replaces `stopSendBuffer`). Detaches the fast triggers and
414
+ * stops the backstop timer — there is NO shutdown force-flush, because every held row
415
+ * is already persisted in SQLite and will be redelivered after restart on a clean gate.
416
+ */
417
+ export function stopMailboxDrainer() {
418
+ unsubscribeDeliverySignals();
419
+ drainer?.stop();
420
+ }
421
+ /** The live drainer (liveness-telemetry streaks; Phase 7 surfaces them). */
422
+ export function getMailboxDrainer() {
423
+ return ensureDrainer();
424
+ }
425
+ //# sourceMappingURL=mailbox-wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-wiring.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/mailbox-wiring.ts"],"names":[],"mappings":"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"}
@@ -6,8 +6,39 @@
6
6
  */
7
7
  /** Minimal writable session interface — avoids coupling to PtySession. */
8
8
  export interface WritableSession {
9
- write(data: string): void;
9
+ /**
10
+ * Write input to the underlying PTY. Returns `false` when the write was dropped
11
+ * (#1198: a shellper-backed session whose socket has died still reports status
12
+ * 'running', yet its writes silently no-op). {@link writeMessagePaced} threads this
13
+ * boolean so a mailbox delivery whose bytes never reached the terminal is held, not
14
+ * marked delivered (Spec 1313 integration review — the silent-loss finding).
15
+ */
16
+ write(data: string): boolean;
10
17
  }
18
+ /** ESC keystroke — ends the agent's current turn (Spec 1273). */
19
+ export declare const ESC = "\u001B";
20
+ /**
21
+ * Delay between the ESC and the Enter that follows it. Matches the short-message
22
+ * Enter delay: ESC has to be processed by the TUI before Enter is meaningful.
23
+ */
24
+ export declare const ESCAPE_ENTER_DELAY_MS = 50;
25
+ /**
26
+ * Write a bare ESC keystroke to a PTY session (Spec 1273).
27
+ *
28
+ * This is the verified mid-turn recovery for a wedged agent: ESC interrupts the
29
+ * running tool and ends the turn, after which queued messages process. It is the
30
+ * command form of `afx send <builder> --raw "$(printf '\x1b')"`.
31
+ *
32
+ * The trailing Enter is sent by default and is load-bearing, not incidental —
33
+ * it is what lets already-queued input through once ESC has ended the turn. Pass
34
+ * `noEnter` to write ESC alone.
35
+ *
36
+ * Deliberately not routed through `writeMessageToSession`: ESC is a control byte,
37
+ * not text, so line-pacing and paste-detection logic do not apply to it.
38
+ *
39
+ * @returns ms timestamp (from call time) when all writes complete
40
+ */
41
+ export declare function writeEscapeToSession(session: WritableSession, noEnter: boolean): number;
11
42
  /**
12
43
  * Write a message to a PTY session, pacing multi-line output to prevent
13
44
  * the terminal from treating it as a paste (Bugfix #584).
@@ -21,4 +52,25 @@ export interface WritableSession {
21
52
  * @returns ms timestamp (from call time) when all writes complete
22
53
  */
23
54
  export declare function writeMessageToSession(session: WritableSession, message: string, noEnter: boolean, delayOffset?: number): number;
55
+ /**
56
+ * Paced write of a message (text + trailing Enter unless `noEnter`) that reports
57
+ * whether every byte reached the PTY. Resolves `true` when the whole submit landed,
58
+ * `false` when ANY scheduled write was dropped (#1198: a shellper socket that died
59
+ * mid-pace). This is the delivery layer's authoritative success signal — a mailbox
60
+ * delivery holds a row whose bytes never made it instead of marking it delivered
61
+ * (Spec 1313 integration review — the silent-loss finding).
62
+ *
63
+ * `writeMessageToSession` fires the text, any subsequent lines, and the trailing
64
+ * Enter across `setTimeout` gaps (10–130ms+), and a t=0 `writable` precheck cannot
65
+ * see a socket that dies *during* that sequence. So wrap the session and record
66
+ * whether any of those writes returned false. The returned promise resolves at the
67
+ * final scheduled offset (`doneMs`); `writeMessageToSession` registers the Enter's
68
+ * `setTimeout` at that same offset *before* this resolve is scheduled, so the Enter
69
+ * executes first and its result is observed by resolution time.
70
+ *
71
+ * Awaiting the promise is also what makes the per-agent write serializer's
72
+ * completion-chaining real — the next delivery cannot begin until this submit
73
+ * (Enter included) is entirely on the wire.
74
+ */
75
+ export declare function writeMessagePaced(session: WritableSession, message: string, noEnter: boolean): Promise<boolean>;
24
76
  //# sourceMappingURL=message-write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-write.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/message-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAI,GAC3E,MAAM,CAqCR"}
1
+ {"version":3,"file":"message-write.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/message-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AAUD,iEAAiE;AACjE,eAAO,MAAM,GAAG,WAAS,CAAC;AAE1B;;;GAGG;AACH,eAAO,MAAM,qBAAqB,KAAwB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAKvF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAI,GAC3E,MAAM,CAqCR;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAC1D,OAAO,CAAC,OAAO,CAAC,CAWlB"}