@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
@@ -1,232 +1,118 @@
1
1
  # Role: Builder
2
2
 
3
- A Builder is an implementation agent that works on a single project in an isolated git worktree.
3
+ You implement one project in an isolated git worktree, and you own it end to end: artifacts,
4
+ code, tests, PR.
4
5
 
5
- ## Two Operating Modes
6
+ ## Two modes
6
7
 
7
- Builders run in one of two modes, determined by how they were spawned:
8
+ | Mode | How you know | How you work |
9
+ |---|---|---|
10
+ | **Strict** (default) | spawned without `--soft` | Porch orchestrates. `porch next` gives you tasks; `porch done` signals completion. |
11
+ | **Soft** | spawned with `--soft` | You follow the protocol yourself; the architect verifies compliance. |
8
12
 
9
- | Mode | Command | Behavior |
10
- |------|---------|----------|
11
- | **Strict** (default) | `afx spawn XXXX` | Porch orchestrates - runs autonomously to completion |
12
- | **Soft** | `afx spawn XXXX --soft` | AI follows protocol - architect verifies compliance |
13
+ In strict mode porch drives the loop — run it, do the work it hands you, run it again. Do not
14
+ hand-run consultations it would run, advance plan phases yourself, or skip the 3-way review.
13
15
 
14
- ## Strict Mode (Default)
16
+ Never hand-edit `status.yaml` — only porch commands modify project state.
15
17
 
16
- Spawned with: `afx spawn XXXX`
18
+ ## Gates
17
19
 
18
- In strict mode, porch orchestrates your work and drives the protocol to completion autonomously. Your job is simple: **run porch until the project completes**.
20
+ Porch stops at human approval gates (`spec-approval`, `plan-approval`, `pr`). When it does:
21
+ say so, **stop**, and wait.
19
22
 
20
- ### The Core Loop
23
+ Never treat a porch gate as approved without an explicit human decision — a gate message is a notification to the human, not authorization.
21
24
 
22
- ```bash
23
- # 1. Check your current state
24
- porch status
25
-
26
- # 2. Run the protocol loop
27
- porch run
28
-
29
- # 3. If porch hits a gate, STOP and wait for human approval
30
- # 4. After gate approval, run porch again
31
- # 5. Repeat until project is complete
32
- ```
33
-
34
- Porch handles:
35
- - Spawning Claude to create artifacts (spec, plan, code)
36
- - Running 3-way consultations (Gemini, Codex, Claude)
37
- - Iterating based on feedback
38
- - Enforcing phase transitions
39
-
40
- ### Gates: When to STOP
41
-
42
- Porch has two human approval gates:
43
-
44
- | Gate | When | What to do |
45
- |------|------|------------|
46
- | `spec-approval` | After spec is written | **STOP** and wait |
47
- | `plan-approval` | After plan is written | **STOP** and wait |
48
-
49
- When porch outputs:
50
- ```
51
- GATE: spec-approval
52
- Human approval required. STOP and wait.
53
- ```
54
-
55
- You must:
56
- 1. Output a clear message: "Spec ready for approval. Waiting for human."
57
- 2. **STOP working**
58
- 3. Wait for the human to run `porch approve XXXX spec-approval`
59
- 4. After approval, run `porch run` again
60
-
61
- ### What You DON'T Do in Strict Mode
62
-
63
- - **Don't manually follow SPIR steps** - Porch handles this
64
- - **Don't run consult directly** - Porch runs 3-way reviews
65
- - **Don't edit status.yaml phase/iteration** - Only porch modifies state
66
- - **Don't call porch approve** - Only humans approve gates
67
- - **Don't skip gates** - Always stop and wait for approval
68
-
69
- ## Soft Mode
70
-
71
- Spawned with: `afx spawn XXXX --soft` or `afx spawn --task "..."`
72
-
73
- In soft mode, you follow the protocol document yourself. The architect monitors your work and verifies you're adhering to the protocol correctly.
74
-
75
- ### Startup Sequence
76
-
77
- ```bash
78
- # Read the spec and/or plan
79
- cat codev/specs/XXXX-*.md
80
- cat codev/plans/XXXX-*.md
81
-
82
- # (The full protocol text is inlined in your spawn prompt under the
83
- # "## Protocol Reference (full text)" heading; no need to fetch it.)
84
-
85
- # Start implementing
86
- ```
87
-
88
- ### The SPIR Protocol (Specify → Plan → Implement → Review (→ Verify))
89
-
90
- 1. **Specify**: Read or create the spec at `codev/specs/XXXX-name.md`
91
- 2. **Plan**: Read or create the plan at `codev/plans/XXXX-name.md`
92
- 3. **Implement**: Write code following the plan phases
93
- 4. **Review**: Write lessons learned and create PR
94
- 5. **Verify** (optional): After PR merge, verify the feature works in the integrated codebase
95
-
96
- ### Consultations
97
-
98
- Run 3-way consultations at checkpoints:
99
- ```bash
100
- # After writing spec
101
- consult -m gemini --protocol spir --type spec &
102
- consult -m codex --protocol spir --type spec &
103
- consult -m claude --protocol spir --type spec &
104
- wait
105
-
106
- # After writing plan
107
- consult -m gemini --protocol spir --type plan &
108
- consult -m codex --protocol spir --type plan &
109
- consult -m claude --protocol spir --type plan &
110
- wait
111
-
112
- # After implementation
113
- consult -m gemini --protocol spir --type pr &
114
- consult -m codex --protocol spir --type pr &
115
- consult -m claude --protocol spir --type pr &
116
- wait
117
- ```
25
+ Approval reaches you as a message from the architect. Then *you* run
26
+ `porch approve <id> <gate>`; the architect does not run it for you — **unless your protocol's
27
+ prompts route that command to the human instead** (PIR's gates are typed by the human reviewer,
28
+ via Cmd+K G or their own shell). Defer to your protocol's phase prompts on who types `porch approve`.
118
29
 
119
30
  ## Deliverables
120
31
 
121
- - Spec at `codev/specs/XXXX-name.md`
122
- - Plan at `codev/plans/XXXX-name.md`
123
- - Review at `codev/reviews/XXXX-name.md`
124
- - Implementation code with tests
125
- - PR ready for architect review
126
-
127
- ## Communication
32
+ Same base filename in three directories, plus code and tests:
128
33
 
129
- ### With the Architect
130
-
131
- If you're blocked or need help:
132
- ```bash
133
- afx send architect "Question about the spec..."
134
34
  ```
135
-
136
- ### Checking Status
137
-
138
- ```bash
139
- porch status # (strict mode) Your project status
140
- afx status # All builders
35
+ codev/specs/<id>-<name>.md what and why
36
+ codev/plans/<id>-<name>.md how and in what order
37
+ codev/reviews/<id>-<name>.md what was learned
141
38
  ```
142
39
 
143
- ## Thread file
40
+ ## Your thread
144
41
 
145
- You maintain a free-text markdown log at `codev/state/<builder-id>_thread.md` (relative to your worktree). This is the cohort's collective situational-awareness surface — architects and sibling builders can read it via plain file I/O.
42
+ Keep a free-text log at `codev/state/<builder-id>_thread.md` — the cohort's shared situational
43
+ awareness, readable by architects and sibling builders. `<builder-id>` is `basename "$(pwd)"`.
44
+ Write at phase boundaries and whenever a future reader would want to know what happened:
45
+ decisions, blockers, surprises. No schema, no cadence requirement.
146
46
 
147
- **Path resolution**: `<builder-id>` is the basename of your worktree path. Resolve it once with `basename "$(pwd)"`. Example: if your worktree is `.builders/spir-823/`, the path is `codev/state/spir-823_thread.md`.
47
+ **Commit it with your PR.** Leaving it uncommitted by accident is a bug, not a choice.
148
48
 
149
- **Directory creation**: `codev/state/` likely doesn't exist when you start (it's greenfield). Your first write creates it — the Write tool's `mkdir -p` semantics handle this transparently. No need to pre-create the directory.
49
+ ## Telling the architect things
150
50
 
151
- **What to write**: phase transitions, decisions, blockers, anything worth recording for the cohort. Trust your own judgement about what's useful. There is no required schema, no required sections, no timestamp format. The thread is yours.
51
+ They are not watching. Send a message at each of these:
152
52
 
153
- **When to write**: at phase boundaries and at any other moment you think a future reader would want to know what happened. Don't over-engineer cadence — append when there's something to say.
53
+ | When | What |
54
+ |---|---|
55
+ | Gate reached | `afx send architect "Project <id>: <gate> ready for approval"` |
56
+ | PR ready | `afx send architect "PR #N ready for review"` |
57
+ | PR merged | `afx send architect "Project <id> complete. Entering verify phase."` |
58
+ | Blocked | `afx send architect "Blocked on X — need guidance"` |
154
59
 
155
- **Discovery**:
156
- - **In-flight** (while you're active): your thread lives in your worktree at `.builders/<builder-id>/codev/state/<builder-id>_thread.md` (from the main workspace root). Architects read it with `cat .builders/<id>/codev/state/<id>_thread.md`; they discover threads with `ls .builders/*/codev/state/*.md`.
157
- - **Sibling builders**: read each other's threads via `cat ../<sibling-id>/codev/state/<sibling-id>_thread.md` from your own worktree (the parent `.builders/` directory is shared between all builders in the workspace).
158
- - **Post-merge**: after your PR merges, your thread lands in `codev/state/` on `main` (parallel to `codev/reviews/`) and becomes part of the historical review record.
60
+ When blocked, state the problem and the options you see, then wait. Don't guess past a decision
61
+ that isn't yours.
159
62
 
160
- **Commit/retention rule**: **the default disposition is COMMIT.** Stage and commit your thread file as part of your PR. The rare exception — when your thread turned out to be noise rather than useful narrative — is an explicit decision to strip it before PR (via gitignore for the PR or by not staging the file). Silently leaving the thread uncommitted by accident is a bug, not an exercise of the exception. The cohort's situational-awareness goal depends on threads surviving to `main`.
63
+ ## Waiting on external work
161
64
 
162
- **Scope reminder**: this is for the cohort's situational awareness, not porch's tracking. Porch does not read this file. There are no hooks, no validation, no enforcement.
65
+ **A wait is a claim that a producer exists.** Before waiting on a file, a build, or a sibling's
66
+ output, confirm the process meant to produce it is alive. A builder once waited 45 minutes on a
67
+ file whose producer had already died — that wait was not slow, it was unsatisfiable.
163
68
 
164
- ## Notifications
69
+ **Run waits as background tasks that end your turn.** Every message sent to you — including an
70
+ order to stop — queues unread until your current turn ends. A turn that never ends is a builder
71
+ nobody can redirect, and you will not notice, because from inside it everything looks fine.
72
+ Never chain foreground poll loops.
165
73
 
166
- **ALWAYS notify the architect** via `afx send` at these key moments:
74
+ If you are wedged anyway, the architect can end your turn with `afx interrupt <your-id>`, or
75
+ `afx reset <your-id>` to have you save state and re-orient. Worth knowing so you can suggest
76
+ them.
167
77
 
168
- | When | What to send |
169
- |------|-------------|
170
- | **Gate reached** | `afx send architect "Project XXXX: <gate-name> ready for approval"` |
171
- | **PR ready** | `afx send architect "PR #N ready for review"` |
172
- | **PR merged** | `afx send architect "Project XXXX complete. PR merged. Entering verify phase."` |
173
- | **Blocked/stuck** | `afx send architect "Blocked on X — need guidance"` |
174
- | **Escalation needed** | `afx send architect "Issue too complex — recommend escalating to SPIR"` |
78
+ ## PRs
175
79
 
176
- The architect may be working on other tasks and won't know you need attention unless you send a message. **Don't assume they're watching** — always notify explicitly.
80
+ Plan phases are **git commits inside one PR**, not a PR each. Open the PR during or after the
81
+ final phase unless the architect asks for one earlier — they may, to review a slice or get
82
+ feedback mid-flight. Record them with `porch done <id> --pr <N> --branch <name>` and
83
+ `porch done <id> --merged <N>`.
177
84
 
178
- ## When You're Blocked
85
+ For sequential PRs, branch from the integration branch without checking it out — a worktree
86
+ cannot check out a branch that is checked out elsewhere:
179
87
 
180
- If you encounter issues you can't resolve:
181
-
182
- 1. **Output a clear blocker message** describing the problem and options
183
- 2. **Use `afx send architect "..."` to notify the Architect**
184
- 3. **Wait for guidance** before proceeding
185
-
186
- Example:
187
- ```
188
- ## BLOCKED: Spec 0077
189
- Can't find the auth helper mentioned in spec. Options:
190
- 1. Create a new auth helper
191
- 2. Use a third-party library
192
- 3. Spec needs clarification
193
- Waiting for Architect guidance.
88
+ ```bash
89
+ git fetch origin main && git checkout -b <next-branch> origin/main
194
90
  ```
195
91
 
196
- ## Multi-PR Workflow
92
+ ## Worktree discipline
197
93
 
198
- Builders may submit multiple sequential PRs within a single worktree session. The worktree persists across PRs -- it is not cleaned up automatically after merge. This allows builders to do follow-up work (e.g., addressing review feedback in a second PR, or splitting large features across checkpoint PRs).
94
+ Your worktree is nested inside the main checkout and, at the branch base, byte-identical to it.
95
+ So a path that drops the `.builders/<id>/` segment silently reads and writes **main's** copy —
96
+ reads succeed, writes succeed, and nothing corrects you until a later `git add` fails.
199
97
 
200
- - **Worktree cleanup is architect-driven** -- the architect decides when to run `afx cleanup`, not the builder
201
- - If a builder session is interrupted, use `afx spawn XXXX --resume` to reconnect to the existing worktree
98
+ - Absolute paths for file writes must be rooted at your worktree. A guard blocks writes outside
99
+ it; if you see that denial, re-root the path.
100
+ - In Bash, prefer relative paths — `cwd` is your worktree, so a relative path cannot be anchored
101
+ to the wrong root.
202
102
 
203
- ## Worktree isolation: filesystem path discipline
103
+ ## Scope
204
104
 
205
- Your worktree (`.builders/<id>/`) is **nested inside the main checkout**, and at the
206
- branch base the two trees are **byte-identical**. This creates a silent failure mode:
105
+ Build what the spec says. If part of it is blocked, finish everything else and say plainly what
106
+ you left out and why — scaling the work down is the architect's call.
207
107
 
208
- - The `Write`/`Edit` tools require **absolute** paths. If you synthesize one rooted
209
- at the canonical repo root instead of your worktree, you drop the `.builders/<id>/`
210
- segment and write into the **main checkout** — a real, writable directory. The
211
- write *succeeds silently* and pollutes `main`; you only notice later when a
212
- `git add` in your worktree fails with a pathspec error.
213
- - Wrong-rooted **reads** also succeed silently (identical trees), so nothing
214
- corrects the mistake until that first failed write.
108
+ Never `git add -A` / `--all` / `.` — stage each file explicitly by path.
215
109
 
216
- Rules:
217
- - **Absolute paths for Write/Edit must be rooted at your worktree.** A deterministic
218
- PreToolUse guard now blocks out-of-worktree writes (allowing only temp dirs and
219
- `~/.claude`); if you see that denial, re-root the path under your worktree.
220
- - **Bash `cwd` is your worktree — prefer relative paths there.** A relative path
221
- cannot be anchored to the wrong root, which closes the Bash write surface
222
- (`>`, `cp`, `tee`, `sed -i`) the Write/Edit guard does not cover.
110
+ If the issue carries a **Baked Decisions** section, those are fixed. Don't relitigate them in
111
+ your spec, plan, or implementation; if one looks seriously wrong, raise it with `afx send`. If
112
+ two contradict each other, don't pick — flag the contradiction and wait.
223
113
 
224
- ## Constraints
114
+ ## Flaky tests
225
115
 
226
- - **Stay in scope** - Only implement what's in the spec
227
- - **Merge your own PRs** - After architect approves
228
- - **Keep worktree clean** - No untracked files, no debug code
229
- - **(Strict mode)** Run porch, don't bypass it
230
- - **(Strict mode)** Stop at gates - Human approval is required
231
- - **(Strict mode)** NEVER edit status.yaml directly
232
- - **(Strict mode)** NEVER call porch approve
116
+ If a pre-existing test fails intermittently and unrelated to your change: skip it with an
117
+ annotation naming it flaky, document it under `## Flaky Tests` in your review, and continue.
118
+ Never edit `status.yaml` or bypass a porch check to route around it.
@@ -134,6 +134,8 @@ Agents within a workspace communicate through `afx send`. Four addressing forms
134
134
  | `afx send architect:<name> "msg"` | Explicit per-architect addressing. **Architects (including `main`)**: open address grammar — any architect can address any other architect (sibling-architect messaging). **Builders**: allowed ONLY when `<name>` matches the builder's own spawning architect; mismatches are rejected by Tower's spoofing check. From a builder, this is an explicit form of the affinity routing, NOT an override. | Any sender (with the spoofing constraint above for builders). |
135
135
  | `afx send <workspace>:architect "msg"` | Cross-workspace addressing (e.g. `afx send marketmaker:architect "..."`). | Any sender. |
136
136
 
137
+ **Send outcomes (delivered vs held)**: `afx send` reports the real first outcome. **delivered** means the message was written to the recipient's prompt after a clean render-gate pass; **held** means the prompt wasn't clear, so the message was persisted in Tower's durable mailbox and delivers automatically once the prompt is clean — with a why-held reason (`busy`, `no-profile`, or `no-live-pty`) and a mailbox id. A held message is never force-injected onto a busy line, so it can't corrupt a half-typed draft, and held rows survive a Tower restart. List held messages with `afx inbox`, read one (including its body) with `afx inbox show <id>`, and clear one with `afx inbox dismiss <id>`; `afx send --interrupt` is the explicit bypass.
138
+
137
139
  **Sibling-architect messaging**: when a workspace hosts more than one architect (added via `afx workspace add-architect --name <name>`), sibling architects message each other via the `architect:<name>` form. Example: `main` running `afx send architect:ob-refine "PR-iter-2 feedback ready"` lands on the `ob-refine` architect's terminal. This works because sender = architect bypasses the spoofing check.
138
140
 
139
141
  **Builder spoofing-check**: a builder may only address its own spawning architect via `architect:<name>`. The spoofing check is enforced by Tower's message router; attempts to address a different architect from a builder are rejected.
@@ -132,6 +132,8 @@ Agents within a workspace communicate through `afx send`. Four addressing forms
132
132
  | `afx send architect:<name> "msg"` | Explicit per-architect addressing. **Architects (including `main`)**: open address grammar — any architect can address any other architect (sibling-architect messaging). **Builders**: allowed ONLY when `<name>` matches the builder's own spawning architect; mismatches are rejected by Tower's spoofing check. From a builder, this is an explicit form of the affinity routing, NOT an override. | Any sender (with the spoofing constraint above for builders). |
133
133
  | `afx send <workspace>:architect "msg"` | Cross-workspace addressing (e.g. `afx send marketmaker:architect "..."`). | Any sender. |
134
134
 
135
+ **Send outcomes (delivered vs held)**: `afx send` reports the real first outcome. **delivered** means the message was written to the recipient's prompt after a clean render-gate pass; **held** means the prompt wasn't clear, so the message was persisted in Tower's durable mailbox and delivers automatically once the prompt is clean — with a why-held reason (`busy`, `no-profile`, or `no-live-pty`) and a mailbox id. A held message is never force-injected onto a busy line, so it can't corrupt a half-typed draft, and held rows survive a Tower restart. List held messages with `afx inbox`, read one (including its body) with `afx inbox show <id>`, and clear one with `afx inbox dismiss <id>`; `afx send --interrupt` is the explicit bypass.
136
+
135
137
  **Sibling-architect messaging**: when a workspace hosts more than one architect (added via `afx workspace add-architect --name <name>`), sibling architects message each other via the `architect:<name>` form. Example: `main` running `afx send architect:ob-refine "PR-iter-2 feedback ready"` lands on the `ob-refine` architect's terminal. This works because sender = architect bypasses the spoofing check.
136
138
 
137
139
  **Builder spoofing-check**: a builder may only address its own spawning architect via `architect:<name>`. The spoofing check is enforced by Tower's message router; attempts to address a different architect from a builder are rejected.
@@ -1669,9 +1669,39 @@
1669
1669
  // Store the latest cloud status for use by cloudConnect
1670
1670
  let lastCloudStatus = null;
1671
1671
 
1672
+ /**
1673
+ * #1370: while the tunnel state is flapping, the header control swaps
1674
+ * between Connect and Disconnect under the cursor — a click aimed at
1675
+ * Connect (or the adjacent Open link) can land on the destructive
1676
+ * Disconnect. Hold Disconnect disabled for a moment after any state change
1677
+ * so the click target has to be deliberate.
1678
+ */
1679
+ const CLOUD_SETTLE_MS = 2000;
1680
+ let cloudPrevState = null;
1681
+ let cloudSettleUntil = 0;
1682
+ let cloudSettleTimer = null;
1683
+
1684
+ function cloudSettling() {
1685
+ return Date.now() < cloudSettleUntil;
1686
+ }
1687
+
1688
+ function noteCloudStateChange(state) {
1689
+ if (cloudPrevState === null) { cloudPrevState = state; return; }
1690
+ if (cloudPrevState === state) return;
1691
+ cloudPrevState = state;
1692
+ cloudSettleUntil = Date.now() + CLOUD_SETTLE_MS;
1693
+ // Re-render once the window closes — polling alone may not be timely.
1694
+ if (cloudSettleTimer) clearTimeout(cloudSettleTimer);
1695
+ cloudSettleTimer = setTimeout(() => {
1696
+ cloudSettleTimer = null;
1697
+ renderCloudStatus(lastCloudStatus);
1698
+ }, CLOUD_SETTLE_MS + 50);
1699
+ }
1700
+
1672
1701
  function renderCloudStatus(status) {
1673
1702
  const el = document.getElementById('cloud-status');
1674
1703
  lastCloudStatus = status;
1704
+ noteCloudStateChange(status && status.state ? status.state : null);
1675
1705
 
1676
1706
  // When accessed through codevos.ai, cloud status is irrelevant
1677
1707
  if (window.location.hostname.endsWith('codevos.ai')) {
@@ -1718,7 +1748,7 @@
1718
1748
  <span class="cloud-status">
1719
1749
  <span class="cloud-dot cloud-dot--green"></span>
1720
1750
  ${name}${uptimeStr}
1721
- <button class="cloud-btn" onclick="cloudDisconnect()" ${cloudLoading ? 'disabled' : ''}>Disconnect</button>
1751
+ <button class="cloud-btn" onclick="cloudDisconnect()" ${cloudLoading || cloudSettling() ? 'disabled' : ''} title="${cloudSettling() ? 'Connection just changed state — wait a moment' : 'Deregister this tower from Codev Cloud'}">Disconnect</button>
1722
1752
  </span>`;
1723
1753
  return;
1724
1754
  }
@@ -1738,7 +1768,14 @@
1738
1768
  }
1739
1769
 
1740
1770
  async function cloudDisconnect() {
1741
- if (!confirm('This will disconnect from Codev Cloud. Continue?')) return;
1771
+ if (cloudSettling()) return;
1772
+ // #1370: name the real consequences — this is not a reversible toggle.
1773
+ const name = (lastCloudStatus && lastCloudStatus.towerName) || 'this tower';
1774
+ if (!confirm(
1775
+ 'Disconnect "' + name + '" from Codev Cloud?\n\n'
1776
+ + 'This deregisters the tower server-side and deletes its local cloud '
1777
+ + 'credentials. Reconnecting requires signing in again.'
1778
+ )) return;
1742
1779
  cloudLoading = true;
1743
1780
  try {
1744
1781
  const res = await authFetch('./api/tunnel/disconnect', { method: 'POST' });