@cluesmith/codev 2.0.0-rc.7 → 2.0.0-rc.70

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 (456) hide show
  1. package/bin/af.js +2 -2
  2. package/bin/consult.js +1 -1
  3. package/bin/porch.js +6 -35
  4. package/dashboard/dist/assets/index-C7FtNK6Y.css +32 -0
  5. package/dashboard/dist/assets/index-CDAINZKT.js +131 -0
  6. package/dashboard/dist/assets/index-CDAINZKT.js.map +1 -0
  7. package/dashboard/dist/index.html +14 -0
  8. package/dist/agent-farm/cli.d.ts.map +1 -1
  9. package/dist/agent-farm/cli.js +173 -118
  10. package/dist/agent-farm/cli.js.map +1 -1
  11. package/dist/agent-farm/commands/architect.d.ts +3 -3
  12. package/dist/agent-farm/commands/architect.d.ts.map +1 -1
  13. package/dist/agent-farm/commands/architect.js +20 -147
  14. package/dist/agent-farm/commands/architect.js.map +1 -1
  15. package/dist/agent-farm/commands/attach.d.ts +13 -0
  16. package/dist/agent-farm/commands/attach.d.ts.map +1 -0
  17. package/dist/agent-farm/commands/attach.js +144 -0
  18. package/dist/agent-farm/commands/attach.js.map +1 -0
  19. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  20. package/dist/agent-farm/commands/cleanup.js +35 -19
  21. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  22. package/dist/agent-farm/commands/consult.d.ts +3 -4
  23. package/dist/agent-farm/commands/consult.d.ts.map +1 -1
  24. package/dist/agent-farm/commands/consult.js +27 -37
  25. package/dist/agent-farm/commands/consult.js.map +1 -1
  26. package/dist/agent-farm/commands/index.d.ts +2 -2
  27. package/dist/agent-farm/commands/index.d.ts.map +1 -1
  28. package/dist/agent-farm/commands/index.js +2 -2
  29. package/dist/agent-farm/commands/index.js.map +1 -1
  30. package/dist/agent-farm/commands/open.d.ts +4 -2
  31. package/dist/agent-farm/commands/open.d.ts.map +1 -1
  32. package/dist/agent-farm/commands/open.js +33 -83
  33. package/dist/agent-farm/commands/open.js.map +1 -1
  34. package/dist/agent-farm/commands/send.d.ts +1 -1
  35. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  36. package/dist/agent-farm/commands/send.js +60 -79
  37. package/dist/agent-farm/commands/send.js.map +1 -1
  38. package/dist/agent-farm/commands/shell.d.ts +15 -0
  39. package/dist/agent-farm/commands/shell.d.ts.map +1 -0
  40. package/dist/agent-farm/commands/shell.js +50 -0
  41. package/dist/agent-farm/commands/shell.js.map +1 -0
  42. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  43. package/dist/agent-farm/commands/spawn.js +597 -281
  44. package/dist/agent-farm/commands/spawn.js.map +1 -1
  45. package/dist/agent-farm/commands/start.d.ts +10 -20
  46. package/dist/agent-farm/commands/start.d.ts.map +1 -1
  47. package/dist/agent-farm/commands/start.js +45 -491
  48. package/dist/agent-farm/commands/start.js.map +1 -1
  49. package/dist/agent-farm/commands/status.d.ts +2 -0
  50. package/dist/agent-farm/commands/status.d.ts.map +1 -1
  51. package/dist/agent-farm/commands/status.js +75 -24
  52. package/dist/agent-farm/commands/status.js.map +1 -1
  53. package/dist/agent-farm/commands/stop.d.ts +6 -0
  54. package/dist/agent-farm/commands/stop.d.ts.map +1 -1
  55. package/dist/agent-farm/commands/stop.js +49 -109
  56. package/dist/agent-farm/commands/stop.js.map +1 -1
  57. package/dist/agent-farm/commands/tower-cloud.d.ts +48 -0
  58. package/dist/agent-farm/commands/tower-cloud.d.ts.map +1 -0
  59. package/dist/agent-farm/commands/tower-cloud.js +334 -0
  60. package/dist/agent-farm/commands/tower-cloud.js.map +1 -0
  61. package/dist/agent-farm/commands/tower.d.ts +9 -0
  62. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  63. package/dist/agent-farm/commands/tower.js +59 -19
  64. package/dist/agent-farm/commands/tower.js.map +1 -1
  65. package/dist/agent-farm/db/index.d.ts +6 -2
  66. package/dist/agent-farm/db/index.d.ts.map +1 -1
  67. package/dist/agent-farm/db/index.js +246 -18
  68. package/dist/agent-farm/db/index.js.map +1 -1
  69. package/dist/agent-farm/db/migrate.d.ts +0 -4
  70. package/dist/agent-farm/db/migrate.d.ts.map +1 -1
  71. package/dist/agent-farm/db/migrate.js +6 -55
  72. package/dist/agent-farm/db/migrate.js.map +1 -1
  73. package/dist/agent-farm/db/schema.d.ts +3 -3
  74. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  75. package/dist/agent-farm/db/schema.js +25 -19
  76. package/dist/agent-farm/db/schema.js.map +1 -1
  77. package/dist/agent-farm/db/types.d.ts +3 -13
  78. package/dist/agent-farm/db/types.d.ts.map +1 -1
  79. package/dist/agent-farm/db/types.js +3 -11
  80. package/dist/agent-farm/db/types.js.map +1 -1
  81. package/dist/agent-farm/hq-connector.d.ts +2 -6
  82. package/dist/agent-farm/hq-connector.d.ts.map +1 -1
  83. package/dist/agent-farm/hq-connector.js +2 -17
  84. package/dist/agent-farm/hq-connector.js.map +1 -1
  85. package/dist/agent-farm/lib/cloud-config.d.ts +59 -0
  86. package/dist/agent-farm/lib/cloud-config.d.ts.map +1 -0
  87. package/dist/agent-farm/lib/cloud-config.js +143 -0
  88. package/dist/agent-farm/lib/cloud-config.js.map +1 -0
  89. package/dist/agent-farm/lib/tower-client.d.ts +163 -0
  90. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -0
  91. package/dist/agent-farm/lib/tower-client.js +233 -0
  92. package/dist/agent-farm/lib/tower-client.js.map +1 -0
  93. package/dist/agent-farm/lib/tunnel-client.d.ts +117 -0
  94. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -0
  95. package/dist/agent-farm/lib/tunnel-client.js +504 -0
  96. package/dist/agent-farm/lib/tunnel-client.js.map +1 -0
  97. package/dist/agent-farm/servers/tower-server.js +2650 -185
  98. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  99. package/dist/agent-farm/state.d.ts +6 -12
  100. package/dist/agent-farm/state.d.ts.map +1 -1
  101. package/dist/agent-farm/state.js +34 -49
  102. package/dist/agent-farm/state.js.map +1 -1
  103. package/dist/agent-farm/types.d.ts +49 -26
  104. package/dist/agent-farm/types.d.ts.map +1 -1
  105. package/dist/agent-farm/utils/config.d.ts +0 -5
  106. package/dist/agent-farm/utils/config.d.ts.map +1 -1
  107. package/dist/agent-farm/utils/config.js +12 -44
  108. package/dist/agent-farm/utils/config.js.map +1 -1
  109. package/dist/agent-farm/utils/deps.d.ts.map +1 -1
  110. package/dist/agent-farm/utils/deps.js +0 -32
  111. package/dist/agent-farm/utils/deps.js.map +1 -1
  112. package/dist/agent-farm/utils/file-tabs.d.ts +27 -0
  113. package/dist/agent-farm/utils/file-tabs.d.ts.map +1 -0
  114. package/dist/agent-farm/utils/file-tabs.js +46 -0
  115. package/dist/agent-farm/utils/file-tabs.js.map +1 -0
  116. package/dist/agent-farm/utils/gate-status.d.ts +16 -0
  117. package/dist/agent-farm/utils/gate-status.d.ts.map +1 -0
  118. package/dist/agent-farm/utils/gate-status.js +79 -0
  119. package/dist/agent-farm/utils/gate-status.js.map +1 -0
  120. package/dist/agent-farm/utils/gate-watcher.d.ts +38 -0
  121. package/dist/agent-farm/utils/gate-watcher.d.ts.map +1 -0
  122. package/dist/agent-farm/utils/gate-watcher.js +122 -0
  123. package/dist/agent-farm/utils/gate-watcher.js.map +1 -0
  124. package/dist/agent-farm/utils/index.d.ts +0 -1
  125. package/dist/agent-farm/utils/index.d.ts.map +1 -1
  126. package/dist/agent-farm/utils/index.js +0 -1
  127. package/dist/agent-farm/utils/index.js.map +1 -1
  128. package/dist/agent-farm/utils/notifications.d.ts +30 -0
  129. package/dist/agent-farm/utils/notifications.d.ts.map +1 -0
  130. package/dist/agent-farm/utils/notifications.js +121 -0
  131. package/dist/agent-farm/utils/notifications.js.map +1 -0
  132. package/dist/agent-farm/utils/server-utils.d.ts +5 -5
  133. package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
  134. package/dist/agent-farm/utils/server-utils.js +5 -16
  135. package/dist/agent-farm/utils/server-utils.js.map +1 -1
  136. package/dist/agent-farm/utils/session.d.ts +32 -0
  137. package/dist/agent-farm/utils/session.d.ts.map +1 -0
  138. package/dist/agent-farm/utils/session.js +57 -0
  139. package/dist/agent-farm/utils/session.js.map +1 -0
  140. package/dist/agent-farm/utils/shell.d.ts +9 -22
  141. package/dist/agent-farm/utils/shell.d.ts.map +1 -1
  142. package/dist/agent-farm/utils/shell.js +34 -34
  143. package/dist/agent-farm/utils/shell.js.map +1 -1
  144. package/dist/cli.d.ts.map +1 -1
  145. package/dist/cli.js +11 -54
  146. package/dist/cli.js.map +1 -1
  147. package/dist/commands/adopt.d.ts.map +1 -1
  148. package/dist/commands/adopt.js +49 -4
  149. package/dist/commands/adopt.js.map +1 -1
  150. package/dist/commands/consult/index.d.ts +13 -2
  151. package/dist/commands/consult/index.d.ts.map +1 -1
  152. package/dist/commands/consult/index.js +245 -29
  153. package/dist/commands/consult/index.js.map +1 -1
  154. package/dist/commands/doctor.d.ts.map +1 -1
  155. package/dist/commands/doctor.js +96 -79
  156. package/dist/commands/doctor.js.map +1 -1
  157. package/dist/commands/init.d.ts.map +1 -1
  158. package/dist/commands/init.js +41 -2
  159. package/dist/commands/init.js.map +1 -1
  160. package/dist/commands/porch/build-counter.d.ts +5 -0
  161. package/dist/commands/porch/build-counter.d.ts.map +1 -0
  162. package/dist/commands/porch/build-counter.js +5 -0
  163. package/dist/commands/porch/build-counter.js.map +1 -0
  164. package/dist/commands/porch/checks.d.ts +17 -29
  165. package/dist/commands/porch/checks.d.ts.map +1 -1
  166. package/dist/commands/porch/checks.js +96 -144
  167. package/dist/commands/porch/checks.js.map +1 -1
  168. package/dist/commands/porch/index.d.ts +25 -43
  169. package/dist/commands/porch/index.d.ts.map +1 -1
  170. package/dist/commands/porch/index.js +463 -1116
  171. package/dist/commands/porch/index.js.map +1 -1
  172. package/dist/commands/porch/next.d.ts +22 -0
  173. package/dist/commands/porch/next.d.ts.map +1 -0
  174. package/dist/commands/porch/next.js +571 -0
  175. package/dist/commands/porch/next.js.map +1 -0
  176. package/dist/commands/porch/plan.d.ts +70 -0
  177. package/dist/commands/porch/plan.d.ts.map +1 -0
  178. package/dist/commands/porch/plan.js +190 -0
  179. package/dist/commands/porch/plan.js.map +1 -0
  180. package/dist/commands/porch/prompts.d.ts +19 -0
  181. package/dist/commands/porch/prompts.d.ts.map +1 -0
  182. package/dist/commands/porch/prompts.js +277 -0
  183. package/dist/commands/porch/prompts.js.map +1 -0
  184. package/dist/commands/porch/protocol.d.ts +59 -0
  185. package/dist/commands/porch/protocol.d.ts.map +1 -0
  186. package/dist/commands/porch/protocol.js +294 -0
  187. package/dist/commands/porch/protocol.js.map +1 -0
  188. package/dist/commands/porch/state.d.ts +36 -107
  189. package/dist/commands/porch/state.d.ts.map +1 -1
  190. package/dist/commands/porch/state.js +120 -699
  191. package/dist/commands/porch/state.js.map +1 -1
  192. package/dist/commands/porch/types.d.ts +99 -164
  193. package/dist/commands/porch/types.d.ts.map +1 -1
  194. package/dist/commands/porch/types.js +2 -1
  195. package/dist/commands/porch/types.js.map +1 -1
  196. package/dist/commands/porch/verdict.d.ts +31 -0
  197. package/dist/commands/porch/verdict.d.ts.map +1 -0
  198. package/dist/commands/porch/verdict.js +59 -0
  199. package/dist/commands/porch/verdict.js.map +1 -0
  200. package/dist/commands/update.d.ts.map +1 -1
  201. package/dist/commands/update.js +31 -0
  202. package/dist/commands/update.js.map +1 -1
  203. package/dist/lib/scaffold.d.ts +37 -0
  204. package/dist/lib/scaffold.d.ts.map +1 -1
  205. package/dist/lib/scaffold.js +114 -0
  206. package/dist/lib/scaffold.js.map +1 -1
  207. package/dist/terminal/index.d.ts +8 -0
  208. package/dist/terminal/index.d.ts.map +1 -0
  209. package/dist/terminal/index.js +5 -0
  210. package/dist/terminal/index.js.map +1 -0
  211. package/dist/terminal/pty-manager.d.ts +69 -0
  212. package/dist/terminal/pty-manager.d.ts.map +1 -0
  213. package/dist/terminal/pty-manager.js +377 -0
  214. package/dist/terminal/pty-manager.js.map +1 -0
  215. package/dist/terminal/pty-session.d.ts +104 -0
  216. package/dist/terminal/pty-session.d.ts.map +1 -0
  217. package/dist/terminal/pty-session.js +327 -0
  218. package/dist/terminal/pty-session.js.map +1 -0
  219. package/dist/terminal/ring-buffer.d.ts +34 -0
  220. package/dist/terminal/ring-buffer.d.ts.map +1 -0
  221. package/dist/terminal/ring-buffer.js +94 -0
  222. package/dist/terminal/ring-buffer.js.map +1 -0
  223. package/dist/terminal/session-manager.d.ts +115 -0
  224. package/dist/terminal/session-manager.d.ts.map +1 -0
  225. package/dist/terminal/session-manager.js +582 -0
  226. package/dist/terminal/session-manager.js.map +1 -0
  227. package/dist/terminal/shepherd-client.d.ts +58 -0
  228. package/dist/terminal/shepherd-client.d.ts.map +1 -0
  229. package/dist/terminal/shepherd-client.js +212 -0
  230. package/dist/terminal/shepherd-client.js.map +1 -0
  231. package/dist/terminal/shepherd-main.d.ts +19 -0
  232. package/dist/terminal/shepherd-main.d.ts.map +1 -0
  233. package/dist/terminal/shepherd-main.js +153 -0
  234. package/dist/terminal/shepherd-main.js.map +1 -0
  235. package/dist/terminal/shepherd-process.d.ts +75 -0
  236. package/dist/terminal/shepherd-process.d.ts.map +1 -0
  237. package/dist/terminal/shepherd-process.js +279 -0
  238. package/dist/terminal/shepherd-process.js.map +1 -0
  239. package/dist/terminal/shepherd-protocol.d.ts +115 -0
  240. package/dist/terminal/shepherd-protocol.d.ts.map +1 -0
  241. package/dist/terminal/shepherd-protocol.js +214 -0
  242. package/dist/terminal/shepherd-protocol.js.map +1 -0
  243. package/dist/terminal/shepherd-replay-buffer.d.ts +38 -0
  244. package/dist/terminal/shepherd-replay-buffer.d.ts.map +1 -0
  245. package/dist/terminal/shepherd-replay-buffer.js +94 -0
  246. package/dist/terminal/shepherd-replay-buffer.js.map +1 -0
  247. package/dist/terminal/ws-protocol.d.ts +27 -0
  248. package/dist/terminal/ws-protocol.d.ts.map +1 -0
  249. package/dist/terminal/ws-protocol.js +44 -0
  250. package/dist/terminal/ws-protocol.js.map +1 -0
  251. package/package.json +19 -5
  252. package/skeleton/.claude/skills/af/SKILL.md +89 -0
  253. package/skeleton/.claude/skills/codev/SKILL.md +41 -0
  254. package/skeleton/.claude/skills/consult/SKILL.md +81 -0
  255. package/skeleton/.claude/skills/generate-image/SKILL.md +56 -0
  256. package/skeleton/DEPENDENCIES.md +4 -62
  257. package/skeleton/builders.md +1 -1
  258. package/skeleton/consult-types/impl-review.md +18 -9
  259. package/skeleton/consult-types/integration-review.md +1 -1
  260. package/skeleton/consult-types/plan-review.md +1 -1
  261. package/skeleton/consult-types/pr-ready.md +1 -1
  262. package/skeleton/consult-types/spec-review.md +1 -1
  263. package/skeleton/porch/prompts/defend.md +1 -1
  264. package/skeleton/porch/prompts/evaluate.md +2 -2
  265. package/skeleton/porch/prompts/implement.md +1 -1
  266. package/skeleton/porch/prompts/plan.md +1 -1
  267. package/skeleton/porch/prompts/review.md +4 -4
  268. package/skeleton/porch/prompts/specify.md +1 -1
  269. package/skeleton/porch/prompts/understand.md +2 -2
  270. package/skeleton/protocol-schema.json +282 -0
  271. package/skeleton/protocols/bugfix/builder-prompt.md +54 -0
  272. package/skeleton/protocols/bugfix/prompts/fix.md +77 -0
  273. package/skeleton/protocols/bugfix/prompts/investigate.md +77 -0
  274. package/skeleton/protocols/bugfix/prompts/pr.md +84 -0
  275. package/skeleton/protocols/bugfix/protocol.json +20 -33
  276. package/skeleton/protocols/experiment/builder-prompt.md +52 -0
  277. package/skeleton/protocols/experiment/protocol.json +101 -0
  278. package/skeleton/protocols/experiment/protocol.md +3 -3
  279. package/skeleton/protocols/experiment/templates/notes.md +1 -1
  280. package/skeleton/protocols/maintain/builder-prompt.md +46 -0
  281. package/skeleton/protocols/maintain/prompts/audit.md +111 -0
  282. package/skeleton/protocols/maintain/prompts/clean.md +91 -0
  283. package/skeleton/protocols/maintain/prompts/sync.md +113 -0
  284. package/skeleton/protocols/maintain/prompts/verify.md +110 -0
  285. package/skeleton/protocols/maintain/protocol.json +141 -0
  286. package/skeleton/protocols/maintain/protocol.md +17 -11
  287. package/skeleton/protocols/protocol-schema.json +54 -1
  288. package/skeleton/protocols/spir/builder-prompt.md +59 -0
  289. package/skeleton/protocols/spir/prompts/implement.md +208 -0
  290. package/skeleton/protocols/{spider → spir}/prompts/plan.md +6 -70
  291. package/skeleton/protocols/{spider → spir}/prompts/review.md +20 -39
  292. package/skeleton/protocols/{spider → spir}/prompts/specify.md +33 -61
  293. package/skeleton/protocols/spir/protocol.json +156 -0
  294. package/skeleton/protocols/{spider → spir}/protocol.md +35 -21
  295. package/skeleton/protocols/{spider → spir}/templates/plan.md +14 -0
  296. package/skeleton/protocols/spir/templates/review.md +89 -0
  297. package/skeleton/protocols/tick/builder-prompt.md +56 -0
  298. package/skeleton/protocols/tick/protocol.json +7 -2
  299. package/skeleton/protocols/tick/protocol.md +18 -18
  300. package/skeleton/protocols/tick/templates/review.md +1 -1
  301. package/skeleton/resources/commands/agent-farm.md +63 -46
  302. package/skeleton/resources/commands/codev.md +0 -2
  303. package/skeleton/resources/commands/overview.md +7 -17
  304. package/skeleton/resources/workflow-reference.md +4 -4
  305. package/skeleton/roles/architect.md +152 -315
  306. package/skeleton/roles/builder.md +110 -218
  307. package/skeleton/roles/consultant.md +6 -6
  308. package/skeleton/templates/AGENTS.md +2 -2
  309. package/skeleton/templates/CLAUDE.md +2 -2
  310. package/skeleton/templates/cheatsheet.md +7 -5
  311. package/skeleton/templates/projectlist.md +1 -1
  312. package/templates/dashboard/index.html +17 -43
  313. package/templates/dashboard/js/dialogs.js +7 -7
  314. package/templates/dashboard/js/files.js +2 -2
  315. package/templates/dashboard/js/main.js +4 -4
  316. package/templates/dashboard/js/projects.js +3 -3
  317. package/templates/dashboard/js/tabs.js +1 -1
  318. package/templates/dashboard/js/utils.js +22 -87
  319. package/templates/open.html +26 -0
  320. package/templates/tower.html +642 -36
  321. package/dist/agent-farm/commands/kickoff.d.ts +0 -20
  322. package/dist/agent-farm/commands/kickoff.d.ts.map +0 -1
  323. package/dist/agent-farm/commands/kickoff.js +0 -337
  324. package/dist/agent-farm/commands/kickoff.js.map +0 -1
  325. package/dist/agent-farm/commands/rename.d.ts +0 -13
  326. package/dist/agent-farm/commands/rename.d.ts.map +0 -1
  327. package/dist/agent-farm/commands/rename.js +0 -33
  328. package/dist/agent-farm/commands/rename.js.map +0 -1
  329. package/dist/agent-farm/commands/tutorial.d.ts +0 -10
  330. package/dist/agent-farm/commands/tutorial.d.ts.map +0 -1
  331. package/dist/agent-farm/commands/tutorial.js +0 -49
  332. package/dist/agent-farm/commands/tutorial.js.map +0 -1
  333. package/dist/agent-farm/commands/util.d.ts +0 -15
  334. package/dist/agent-farm/commands/util.d.ts.map +0 -1
  335. package/dist/agent-farm/commands/util.js +0 -108
  336. package/dist/agent-farm/commands/util.js.map +0 -1
  337. package/dist/agent-farm/servers/dashboard-server.d.ts +0 -7
  338. package/dist/agent-farm/servers/dashboard-server.d.ts.map +0 -1
  339. package/dist/agent-farm/servers/dashboard-server.js +0 -1872
  340. package/dist/agent-farm/servers/dashboard-server.js.map +0 -1
  341. package/dist/agent-farm/servers/open-server.d.ts +0 -7
  342. package/dist/agent-farm/servers/open-server.d.ts.map +0 -1
  343. package/dist/agent-farm/servers/open-server.js +0 -315
  344. package/dist/agent-farm/servers/open-server.js.map +0 -1
  345. package/dist/agent-farm/tutorial/index.d.ts +0 -8
  346. package/dist/agent-farm/tutorial/index.d.ts.map +0 -1
  347. package/dist/agent-farm/tutorial/index.js +0 -8
  348. package/dist/agent-farm/tutorial/index.js.map +0 -1
  349. package/dist/agent-farm/tutorial/prompts.d.ts +0 -57
  350. package/dist/agent-farm/tutorial/prompts.d.ts.map +0 -1
  351. package/dist/agent-farm/tutorial/prompts.js +0 -147
  352. package/dist/agent-farm/tutorial/prompts.js.map +0 -1
  353. package/dist/agent-farm/tutorial/runner.d.ts +0 -52
  354. package/dist/agent-farm/tutorial/runner.d.ts.map +0 -1
  355. package/dist/agent-farm/tutorial/runner.js +0 -204
  356. package/dist/agent-farm/tutorial/runner.js.map +0 -1
  357. package/dist/agent-farm/tutorial/state.d.ts +0 -26
  358. package/dist/agent-farm/tutorial/state.d.ts.map +0 -1
  359. package/dist/agent-farm/tutorial/state.js +0 -89
  360. package/dist/agent-farm/tutorial/state.js.map +0 -1
  361. package/dist/agent-farm/tutorial/steps/first-spec.d.ts +0 -7
  362. package/dist/agent-farm/tutorial/steps/first-spec.d.ts.map +0 -1
  363. package/dist/agent-farm/tutorial/steps/first-spec.js +0 -136
  364. package/dist/agent-farm/tutorial/steps/first-spec.js.map +0 -1
  365. package/dist/agent-farm/tutorial/steps/implementation.d.ts +0 -7
  366. package/dist/agent-farm/tutorial/steps/implementation.d.ts.map +0 -1
  367. package/dist/agent-farm/tutorial/steps/implementation.js +0 -76
  368. package/dist/agent-farm/tutorial/steps/implementation.js.map +0 -1
  369. package/dist/agent-farm/tutorial/steps/index.d.ts +0 -10
  370. package/dist/agent-farm/tutorial/steps/index.d.ts.map +0 -1
  371. package/dist/agent-farm/tutorial/steps/index.js +0 -10
  372. package/dist/agent-farm/tutorial/steps/index.js.map +0 -1
  373. package/dist/agent-farm/tutorial/steps/planning.d.ts +0 -7
  374. package/dist/agent-farm/tutorial/steps/planning.d.ts.map +0 -1
  375. package/dist/agent-farm/tutorial/steps/planning.js +0 -143
  376. package/dist/agent-farm/tutorial/steps/planning.js.map +0 -1
  377. package/dist/agent-farm/tutorial/steps/review.d.ts +0 -7
  378. package/dist/agent-farm/tutorial/steps/review.d.ts.map +0 -1
  379. package/dist/agent-farm/tutorial/steps/review.js +0 -78
  380. package/dist/agent-farm/tutorial/steps/review.js.map +0 -1
  381. package/dist/agent-farm/tutorial/steps/setup.d.ts +0 -7
  382. package/dist/agent-farm/tutorial/steps/setup.d.ts.map +0 -1
  383. package/dist/agent-farm/tutorial/steps/setup.js +0 -126
  384. package/dist/agent-farm/tutorial/steps/setup.js.map +0 -1
  385. package/dist/agent-farm/tutorial/steps/welcome.d.ts +0 -7
  386. package/dist/agent-farm/tutorial/steps/welcome.d.ts.map +0 -1
  387. package/dist/agent-farm/tutorial/steps/welcome.js +0 -50
  388. package/dist/agent-farm/tutorial/steps/welcome.js.map +0 -1
  389. package/dist/agent-farm/utils/orphan-handler.d.ts +0 -27
  390. package/dist/agent-farm/utils/orphan-handler.d.ts.map +0 -1
  391. package/dist/agent-farm/utils/orphan-handler.js +0 -149
  392. package/dist/agent-farm/utils/orphan-handler.js.map +0 -1
  393. package/dist/agent-farm/utils/port-registry.d.ts +0 -58
  394. package/dist/agent-farm/utils/port-registry.d.ts.map +0 -1
  395. package/dist/agent-farm/utils/port-registry.js +0 -166
  396. package/dist/agent-farm/utils/port-registry.js.map +0 -1
  397. package/dist/agent-farm/utils/terminal-ports.d.ts +0 -18
  398. package/dist/agent-farm/utils/terminal-ports.d.ts.map +0 -1
  399. package/dist/agent-farm/utils/terminal-ports.js +0 -35
  400. package/dist/agent-farm/utils/terminal-ports.js.map +0 -1
  401. package/dist/commands/pcheck/cache.d.ts +0 -48
  402. package/dist/commands/pcheck/cache.d.ts.map +0 -1
  403. package/dist/commands/pcheck/cache.js +0 -170
  404. package/dist/commands/pcheck/cache.js.map +0 -1
  405. package/dist/commands/pcheck/evaluator.d.ts +0 -15
  406. package/dist/commands/pcheck/evaluator.d.ts.map +0 -1
  407. package/dist/commands/pcheck/evaluator.js +0 -246
  408. package/dist/commands/pcheck/evaluator.js.map +0 -1
  409. package/dist/commands/pcheck/index.d.ts +0 -12
  410. package/dist/commands/pcheck/index.d.ts.map +0 -1
  411. package/dist/commands/pcheck/index.js +0 -249
  412. package/dist/commands/pcheck/index.js.map +0 -1
  413. package/dist/commands/pcheck/parser.d.ts +0 -39
  414. package/dist/commands/pcheck/parser.d.ts.map +0 -1
  415. package/dist/commands/pcheck/parser.js +0 -155
  416. package/dist/commands/pcheck/parser.js.map +0 -1
  417. package/dist/commands/pcheck/types.d.ts +0 -82
  418. package/dist/commands/pcheck/types.d.ts.map +0 -1
  419. package/dist/commands/pcheck/types.js +0 -5
  420. package/dist/commands/pcheck/types.js.map +0 -1
  421. package/dist/commands/porch/consultation.d.ts +0 -56
  422. package/dist/commands/porch/consultation.d.ts.map +0 -1
  423. package/dist/commands/porch/consultation.js +0 -330
  424. package/dist/commands/porch/consultation.js.map +0 -1
  425. package/dist/commands/porch/notifications.d.ts +0 -99
  426. package/dist/commands/porch/notifications.d.ts.map +0 -1
  427. package/dist/commands/porch/notifications.js +0 -223
  428. package/dist/commands/porch/notifications.js.map +0 -1
  429. package/dist/commands/porch/plan-parser.d.ts +0 -38
  430. package/dist/commands/porch/plan-parser.d.ts.map +0 -1
  431. package/dist/commands/porch/plan-parser.js +0 -166
  432. package/dist/commands/porch/plan-parser.js.map +0 -1
  433. package/dist/commands/porch/protocol-loader.d.ts +0 -46
  434. package/dist/commands/porch/protocol-loader.d.ts.map +0 -1
  435. package/dist/commands/porch/protocol-loader.js +0 -253
  436. package/dist/commands/porch/protocol-loader.js.map +0 -1
  437. package/dist/commands/porch/signal-parser.d.ts +0 -88
  438. package/dist/commands/porch/signal-parser.d.ts.map +0 -1
  439. package/dist/commands/porch/signal-parser.js +0 -148
  440. package/dist/commands/porch/signal-parser.js.map +0 -1
  441. package/dist/commands/tower.d.ts +0 -16
  442. package/dist/commands/tower.d.ts.map +0 -1
  443. package/dist/commands/tower.js +0 -21
  444. package/dist/commands/tower.js.map +0 -1
  445. package/skeleton/config.json +0 -7
  446. package/skeleton/porch/protocols/bugfix.json +0 -85
  447. package/skeleton/porch/protocols/spider.json +0 -135
  448. package/skeleton/porch/protocols/tick.json +0 -76
  449. package/skeleton/protocols/spider/prompts/defend.md +0 -215
  450. package/skeleton/protocols/spider/prompts/evaluate.md +0 -241
  451. package/skeleton/protocols/spider/prompts/implement.md +0 -149
  452. package/skeleton/protocols/spider/protocol.json +0 -210
  453. package/skeleton/protocols/spider/templates/review.md +0 -207
  454. package/templates/dashboard/css/activity.css +0 -151
  455. package/templates/dashboard/js/activity.js +0 -112
  456. /package/skeleton/protocols/{spider → spir}/templates/spec.md +0 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Single PTY session: wraps node-pty with ring buffer, disk logging,
3
+ * WebSocket broadcast, and reconnection support.
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { EventEmitter } from 'node:events';
8
+ import { RingBuffer } from './ring-buffer.js';
9
+ export class PtySession extends EventEmitter {
10
+ config;
11
+ id;
12
+ label;
13
+ createdAt;
14
+ ringBuffer;
15
+ pty = null;
16
+ shepherdClient = null;
17
+ _shepherdBacked = false;
18
+ _shepherdSessionId = null;
19
+ shepherdPid = -1;
20
+ cols;
21
+ rows;
22
+ exitCode;
23
+ logFd = null;
24
+ logBytes = 0;
25
+ logPath;
26
+ diskLogEnabled;
27
+ diskLogMaxBytes;
28
+ reconnectTimeoutMs;
29
+ disconnectTimer = null;
30
+ clients = new Set();
31
+ constructor(config) {
32
+ super();
33
+ this.config = config;
34
+ this.id = config.id;
35
+ this.label = config.label;
36
+ this.cols = config.cols;
37
+ this.rows = config.rows;
38
+ this.createdAt = new Date().toISOString();
39
+ this.ringBuffer = new RingBuffer(config.ringBufferLines ?? 1000);
40
+ this.diskLogEnabled = config.diskLogEnabled ?? true;
41
+ this.diskLogMaxBytes = config.diskLogMaxBytes ?? 50 * 1024 * 1024;
42
+ this.reconnectTimeoutMs = config.reconnectTimeoutMs ?? 300_000;
43
+ this.logPath = path.join(config.logDir, `${config.id}.log`);
44
+ }
45
+ /** Spawn the PTY process. Must be called after construction. */
46
+ async spawn() {
47
+ // Dynamic import to avoid hard dependency at module level
48
+ const nodePty = await import('node-pty');
49
+ // Ensure log directory exists
50
+ if (this.diskLogEnabled) {
51
+ fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
52
+ this.logFd = fs.openSync(this.logPath, 'a');
53
+ }
54
+ this.pty = nodePty.spawn(this.config.command, this.config.args, {
55
+ name: 'xterm-256color',
56
+ cols: this.cols,
57
+ rows: this.rows,
58
+ cwd: this.config.cwd,
59
+ env: this.config.env,
60
+ });
61
+ this.pty.onData((data) => {
62
+ this.onPtyData(data);
63
+ });
64
+ this.pty.onExit(({ exitCode }) => {
65
+ this.exitCode = exitCode;
66
+ this.emit('exit', exitCode);
67
+ this.cleanup();
68
+ });
69
+ }
70
+ /**
71
+ * Attach a shepherd client as the I/O backend instead of node-pty.
72
+ * Data flows: shepherd → ring buffer → WebSocket clients.
73
+ * User input flows: WebSocket → write() → shepherd.
74
+ */
75
+ attachShepherd(client, replayData, shepherdPid, shepherdSessionId) {
76
+ this._shepherdBacked = true;
77
+ this.shepherdClient = client;
78
+ this.shepherdPid = shepherdPid;
79
+ this._shepherdSessionId = shepherdSessionId ?? null;
80
+ // Ensure log directory exists
81
+ if (this.diskLogEnabled) {
82
+ fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
83
+ this.logFd = fs.openSync(this.logPath, 'a');
84
+ }
85
+ // Populate ring buffer with replay data from shepherd
86
+ if (replayData.length > 0) {
87
+ this.ringBuffer.pushData(replayData.toString('utf-8'));
88
+ }
89
+ // Forward shepherd data to ring buffer + WebSocket clients
90
+ client.on('data', (buf) => {
91
+ this.onPtyData(buf.toString('utf-8'));
92
+ });
93
+ // Handle shepherd exit (process inside shepherd exited)
94
+ client.on('exit', (exitInfo) => {
95
+ this.exitCode = exitInfo.code;
96
+ this.emit('exit', exitInfo.code);
97
+ // For shepherd-backed sessions, cleanup closes disk log and clients
98
+ // but doesn't clear the ring buffer (shepherd may still have replay data)
99
+ this.cleanupShepherd();
100
+ });
101
+ // Handle shepherd disconnect (socket closed without EXIT)
102
+ client.on('close', () => {
103
+ if (this.exitCode === undefined) {
104
+ // Unexpected disconnect — shepherd may have crashed
105
+ this.exitCode = -1;
106
+ this.emit('exit', -1);
107
+ this.cleanupShepherd();
108
+ }
109
+ });
110
+ }
111
+ /** Whether this session is backed by a shepherd process. */
112
+ get shepherdBacked() {
113
+ return this._shepherdBacked;
114
+ }
115
+ /** The SessionManager session ID for this shepherd-backed session, or null. */
116
+ get shepherdSessionId() {
117
+ return this._shepherdSessionId;
118
+ }
119
+ /**
120
+ * Detach from shepherd client during Tower shutdown.
121
+ * Removes all event listeners so that SessionManager.shutdown() disconnecting
122
+ * the client doesn't cascade into exit events and SQLite row deletion.
123
+ */
124
+ detachShepherd() {
125
+ if (this.shepherdClient) {
126
+ this.shepherdClient.removeAllListeners();
127
+ this.shepherdClient = null;
128
+ }
129
+ this.cleanupShepherd();
130
+ }
131
+ cleanupShepherd() {
132
+ if (this.disconnectTimer) {
133
+ clearTimeout(this.disconnectTimer);
134
+ this.disconnectTimer = null;
135
+ }
136
+ this.clients.clear();
137
+ // Close disk log handle
138
+ if (this.logFd !== null) {
139
+ try {
140
+ fs.closeSync(this.logFd);
141
+ }
142
+ catch { /* ignore */ }
143
+ this.logFd = null;
144
+ }
145
+ // Note: ring buffer is NOT cleared — shepherd handles replay
146
+ // Note: shepherd client is NOT disconnected — SessionManager owns that lifecycle
147
+ }
148
+ onPtyData(data) {
149
+ // Store in ring buffer
150
+ this.ringBuffer.pushData(data);
151
+ // Write to disk log
152
+ if (this.diskLogEnabled && this.logFd !== null) {
153
+ const buf = Buffer.from(data, 'utf-8');
154
+ if (this.logBytes + buf.length <= this.diskLogMaxBytes) {
155
+ fs.writeSync(this.logFd, buf);
156
+ this.logBytes += buf.length;
157
+ }
158
+ else {
159
+ this.rotateDiskLog();
160
+ fs.writeSync(this.logFd, buf);
161
+ this.logBytes = buf.length;
162
+ }
163
+ }
164
+ // Broadcast to all connected WebSocket clients
165
+ for (const client of this.clients) {
166
+ try {
167
+ client.send(data);
168
+ }
169
+ catch {
170
+ this.clients.delete(client);
171
+ }
172
+ }
173
+ this.emit('data', data);
174
+ }
175
+ rotateDiskLog() {
176
+ if (this.logFd !== null) {
177
+ fs.closeSync(this.logFd);
178
+ }
179
+ const rotatedPath = this.logPath + '.1';
180
+ // Remove old rotation if exists
181
+ try {
182
+ fs.unlinkSync(rotatedPath + '.1');
183
+ }
184
+ catch { /* ignore */ }
185
+ try {
186
+ fs.renameSync(rotatedPath, rotatedPath + '.1');
187
+ }
188
+ catch { /* ignore */ }
189
+ try {
190
+ fs.renameSync(this.logPath, rotatedPath);
191
+ }
192
+ catch { /* ignore */ }
193
+ this.logFd = fs.openSync(this.logPath, 'a');
194
+ this.logBytes = 0;
195
+ }
196
+ /** Write user input to the PTY or shepherd. */
197
+ write(data) {
198
+ if (this._shepherdBacked) {
199
+ if (this.shepherdClient && this.status === 'running') {
200
+ this.shepherdClient.write(data);
201
+ }
202
+ return;
203
+ }
204
+ if (this.pty && this.status === 'running') {
205
+ this.pty.write(data);
206
+ }
207
+ }
208
+ /** Resize the PTY or shepherd. */
209
+ resize(cols, rows) {
210
+ this.cols = cols;
211
+ this.rows = rows;
212
+ if (this._shepherdBacked) {
213
+ if (this.shepherdClient && this.status === 'running') {
214
+ this.shepherdClient.resize(cols, rows);
215
+ }
216
+ return;
217
+ }
218
+ if (this.pty && this.status === 'running') {
219
+ this.pty.resize(cols, rows);
220
+ }
221
+ }
222
+ /** Kill the PTY process or send signal to shepherd. */
223
+ kill() {
224
+ if (this._shepherdBacked) {
225
+ if (this.shepherdClient && this.status === 'running') {
226
+ this.shepherdClient.signal(15); // SIGTERM
227
+ }
228
+ this.cleanupShepherd();
229
+ return;
230
+ }
231
+ if (this.pty && this.status === 'running') {
232
+ try {
233
+ // Kill process group to prevent orphans
234
+ process.kill(-this.pty.pid, 'SIGTERM');
235
+ setTimeout(() => {
236
+ try {
237
+ process.kill(-this.pty.pid, 'SIGKILL');
238
+ }
239
+ catch { /* already dead */ }
240
+ }, 5000);
241
+ }
242
+ catch {
243
+ // Process already exited
244
+ }
245
+ }
246
+ this.cleanup();
247
+ }
248
+ /** Attach a WebSocket client. Returns ring buffer contents for replay. */
249
+ attach(client) {
250
+ this.clients.add(client);
251
+ if (this.disconnectTimer) {
252
+ clearTimeout(this.disconnectTimer);
253
+ this.disconnectTimer = null;
254
+ }
255
+ return this.ringBuffer.getAll();
256
+ }
257
+ /** Attach with resume from a specific sequence number. */
258
+ attachResume(client, sinceSeq) {
259
+ this.clients.add(client);
260
+ if (this.disconnectTimer) {
261
+ clearTimeout(this.disconnectTimer);
262
+ this.disconnectTimer = null;
263
+ }
264
+ return this.ringBuffer.getSince(sinceSeq);
265
+ }
266
+ /** Detach a WebSocket client. Starts disconnect timer if no clients remain (non-shepherd only). */
267
+ detach(client) {
268
+ this.clients.delete(client);
269
+ // Shepherd-backed sessions don't need a disconnect timer — the shepherd
270
+ // keeps the process alive independently of WebSocket connections.
271
+ if (this._shepherdBacked)
272
+ return;
273
+ if (this.clients.size === 0 && this.status === 'running') {
274
+ this.disconnectTimer = setTimeout(() => {
275
+ this.emit('timeout');
276
+ this.kill();
277
+ }, this.reconnectTimeoutMs);
278
+ }
279
+ }
280
+ /** Working directory of the PTY session. */
281
+ get cwd() {
282
+ return this.config.cwd;
283
+ }
284
+ get status() {
285
+ return this.exitCode === undefined ? 'running' : 'exited';
286
+ }
287
+ get pid() {
288
+ if (this._shepherdBacked)
289
+ return this.shepherdPid;
290
+ return this.pty?.pid ?? -1;
291
+ }
292
+ get info() {
293
+ return {
294
+ id: this.id,
295
+ pid: this.pid,
296
+ cols: this.cols,
297
+ rows: this.rows,
298
+ label: this.label,
299
+ status: this.status,
300
+ createdAt: this.createdAt,
301
+ exitCode: this.exitCode,
302
+ persistent: this._shepherdBacked,
303
+ };
304
+ }
305
+ get clientCount() {
306
+ return this.clients.size;
307
+ }
308
+ cleanup() {
309
+ if (this.disconnectTimer) {
310
+ clearTimeout(this.disconnectTimer);
311
+ this.disconnectTimer = null;
312
+ }
313
+ // Release all WebSocket clients
314
+ this.clients.clear();
315
+ // Release ring buffer memory
316
+ this.ringBuffer.clear();
317
+ // Close disk log handle
318
+ if (this.logFd !== null) {
319
+ try {
320
+ fs.closeSync(this.logFd);
321
+ }
322
+ catch { /* ignore */ }
323
+ this.logFd = null;
324
+ }
325
+ }
326
+ }
327
+ //# sourceMappingURL=pty-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-session.js","sourceRoot":"","sources":["../../src/terminal/pty-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Fixed-size circular buffer for storing terminal output lines.
3
+ * Used for reconnection replay — stores last N lines in memory.
4
+ */
5
+ export declare class RingBuffer {
6
+ private readonly capacity;
7
+ private buffer;
8
+ private head;
9
+ private count;
10
+ private seq;
11
+ private partial;
12
+ constructor(capacity?: number);
13
+ /** Push a complete line into the buffer. Returns the assigned sequence number. */
14
+ push(line: string): number;
15
+ /**
16
+ * Push raw data, splitting on newlines. Handles partial lines across
17
+ * chunk boundaries: if data doesn't end with \n, the trailing fragment
18
+ * is held and prepended to the next pushData call.
19
+ *
20
+ * Returns last sequence number.
21
+ */
22
+ pushData(data: string): number;
23
+ /** Get all stored lines in order, including any incomplete trailing line. */
24
+ getAll(): string[];
25
+ /** Get lines starting from a given sequence number (for resume). */
26
+ getSince(sinceSeq: number): string[];
27
+ /** Current sequence number (last written). */
28
+ get currentSeq(): number;
29
+ /** Number of lines currently stored. */
30
+ get size(): number;
31
+ /** Clear the buffer and release memory. */
32
+ clear(): void;
33
+ }
34
+ //# sourceMappingURL=ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,UAAU;IAOT,OAAO,CAAC,QAAQ,CAAC,QAAQ;IANrC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,OAAO,CAAc;gBAEA,QAAQ,GAAE,MAAa;IAIpD,kFAAkF;IAClF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAW1B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAiB9B,6EAA6E;IAC7E,MAAM,IAAI,MAAM,EAAE;IAWlB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAiBpC,8CAA8C;IAC9C,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,2CAA2C;IAC3C,KAAK,IAAI,IAAI;CAOd"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Fixed-size circular buffer for storing terminal output lines.
3
+ * Used for reconnection replay — stores last N lines in memory.
4
+ */
5
+ export class RingBuffer {
6
+ capacity;
7
+ buffer;
8
+ head = 0;
9
+ count = 0;
10
+ seq = 0; // monotonically increasing sequence number
11
+ partial = ''; // incomplete line from previous pushData call
12
+ constructor(capacity = 1000) {
13
+ this.capacity = capacity;
14
+ this.buffer = new Array(capacity);
15
+ }
16
+ /** Push a complete line into the buffer. Returns the assigned sequence number. */
17
+ push(line) {
18
+ const index = (this.head + this.count) % this.capacity;
19
+ this.buffer[index] = line;
20
+ if (this.count < this.capacity) {
21
+ this.count++;
22
+ }
23
+ else {
24
+ this.head = (this.head + 1) % this.capacity;
25
+ }
26
+ return ++this.seq;
27
+ }
28
+ /**
29
+ * Push raw data, splitting on newlines. Handles partial lines across
30
+ * chunk boundaries: if data doesn't end with \n, the trailing fragment
31
+ * is held and prepended to the next pushData call.
32
+ *
33
+ * Returns last sequence number.
34
+ */
35
+ pushData(data) {
36
+ const combined = this.partial + data;
37
+ const parts = combined.split('\n');
38
+ // Last element is either:
39
+ // - "" if data ended with \n (all lines complete)
40
+ // - non-empty if data ended mid-line (incomplete line)
41
+ // Either way, save it as the new partial.
42
+ this.partial = parts.pop();
43
+ let lastSeq = this.seq;
44
+ for (const line of parts) {
45
+ lastSeq = this.push(line);
46
+ }
47
+ return lastSeq;
48
+ }
49
+ /** Get all stored lines in order, including any incomplete trailing line. */
50
+ getAll() {
51
+ const result = [];
52
+ for (let i = 0; i < this.count; i++) {
53
+ result.push(this.buffer[(this.head + i) % this.capacity]);
54
+ }
55
+ if (this.partial) {
56
+ result.push(this.partial);
57
+ }
58
+ return result;
59
+ }
60
+ /** Get lines starting from a given sequence number (for resume). */
61
+ getSince(sinceSeq) {
62
+ const linesAvailable = this.count;
63
+ const oldestSeq = this.seq - linesAvailable + 1;
64
+ const startSeq = Math.max(sinceSeq + 1, oldestSeq);
65
+ if (startSeq > this.seq)
66
+ return [];
67
+ const skip = startSeq - oldestSeq;
68
+ const result = [];
69
+ for (let i = skip; i < this.count; i++) {
70
+ result.push(this.buffer[(this.head + i) % this.capacity]);
71
+ }
72
+ if (this.partial) {
73
+ result.push(this.partial);
74
+ }
75
+ return result;
76
+ }
77
+ /** Current sequence number (last written). */
78
+ get currentSeq() {
79
+ return this.seq;
80
+ }
81
+ /** Number of lines currently stored. */
82
+ get size() {
83
+ return this.count;
84
+ }
85
+ /** Clear the buffer and release memory. */
86
+ clear() {
87
+ this.buffer = [];
88
+ this.head = 0;
89
+ this.count = 0;
90
+ this.partial = '';
91
+ // Don't reset seq — it should be monotonic
92
+ }
93
+ }
94
+ //# sourceMappingURL=ring-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * SessionManager: orchestrates shepherd process lifecycle.
3
+ *
4
+ * Responsibilities:
5
+ * - Spawn shepherd processes as detached children
6
+ * - Connect ShepherdClient to each shepherd
7
+ * - Kill sessions (SIGTERM → wait → SIGKILL)
8
+ * - Detect and clean up stale sockets
9
+ * - Auto-restart on exit (configurable per session)
10
+ * - Reconnect to existing shepherds after Tower restart
11
+ *
12
+ * Process start time validation prevents PID reuse reconnection.
13
+ */
14
+ import { EventEmitter } from 'node:events';
15
+ import { type IShepherdClient } from './shepherd-client.js';
16
+ export interface SessionManagerConfig {
17
+ socketDir: string;
18
+ shepherdScript: string;
19
+ nodeExecutable: string;
20
+ }
21
+ export interface CreateSessionOptions {
22
+ sessionId: string;
23
+ command: string;
24
+ args: string[];
25
+ cwd: string;
26
+ env: Record<string, string>;
27
+ cols: number;
28
+ rows: number;
29
+ restartOnExit?: boolean;
30
+ restartDelay?: number;
31
+ maxRestarts?: number;
32
+ restartResetAfter?: number;
33
+ }
34
+ export interface ReconnectRestartOptions {
35
+ command: string;
36
+ args: string[];
37
+ cwd: string;
38
+ env: Record<string, string>;
39
+ restartDelay?: number;
40
+ maxRestarts?: number;
41
+ restartResetAfter?: number;
42
+ }
43
+ export declare class SessionManager extends EventEmitter {
44
+ private readonly config;
45
+ private sessions;
46
+ constructor(config: SessionManagerConfig);
47
+ /**
48
+ * Spawn a new shepherd process and connect to it.
49
+ * Returns the connected client.
50
+ */
51
+ createSession(opts: CreateSessionOptions): Promise<IShepherdClient>;
52
+ /**
53
+ * Reconnect to an existing shepherd process after Tower restart.
54
+ * Validates PID is alive and start time matches.
55
+ * Returns connected client, or null if shepherd is stale/dead.
56
+ */
57
+ reconnectSession(sessionId: string, socketPath: string, pid: number, startTime: number, restartOptions?: ReconnectRestartOptions): Promise<IShepherdClient | null>;
58
+ /**
59
+ * Kill a session: SIGTERM, wait 5s, SIGKILL if needed.
60
+ * Cleans up socket file and removes from session map.
61
+ */
62
+ killSession(sessionId: string): Promise<void>;
63
+ /**
64
+ * List all active sessions.
65
+ */
66
+ listSessions(): Map<string, IShepherdClient>;
67
+ /**
68
+ * Get session metadata (pid, startTime, socketPath) for a session.
69
+ */
70
+ getSessionInfo(sessionId: string): {
71
+ pid: number;
72
+ startTime: number;
73
+ socketPath: string;
74
+ } | null;
75
+ /**
76
+ * Scan socket directory for stale sockets (no live process).
77
+ * A socket is stale if nothing is listening on it (connection refused).
78
+ * Returns the number of sockets cleaned up.
79
+ */
80
+ cleanupStaleSockets(): Promise<number>;
81
+ /**
82
+ * Test if a Unix socket has a listener by attempting a brief connection.
83
+ * Returns true if connection succeeds, false if refused/timed out.
84
+ */
85
+ private probeSocket;
86
+ /**
87
+ * Disconnect from all sessions without killing shepherd processes.
88
+ * Per spec: "When Tower intentionally stops, Tower closes its socket
89
+ * connections to shepherds. Shepherds continue running."
90
+ */
91
+ shutdown(): void;
92
+ /**
93
+ * Remove a dead session from the map, clear its timers, and clean up socket.
94
+ * Called when a session exits naturally (no restart) or exhausts maxRestarts.
95
+ */
96
+ private removeDeadSession;
97
+ private getSocketPath;
98
+ private unlinkSocketIfExists;
99
+ private readShepherdInfo;
100
+ private waitForSocket;
101
+ private isProcessAlive;
102
+ private waitForProcessExit;
103
+ private setupAutoRestart;
104
+ private startRestartResetTimer;
105
+ }
106
+ /**
107
+ * Get the start time of a process by PID.
108
+ * Returns epoch milliseconds, or null if the process doesn't exist or can't be queried.
109
+ *
110
+ * Platform-specific:
111
+ * - macOS: parse `ps -p {pid} -o lstart=`
112
+ * - Linux: read `/proc/{pid}/stat` field 22 (starttime in clock ticks)
113
+ */
114
+ export declare function getProcessStartTime(pid: number): Promise<number | null>;
115
+ //# sourceMappingURL=session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/terminal/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAYD,qBAAa,cAAe,SAAQ,YAAY;IAGlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAqC;gBAExB,MAAM,EAAE,oBAAoB;IAIzD;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IAiGzE;;;;OAIG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,uBAAuB,GACvC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAwFlC;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCnD;;OAEG;IACH,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAQ5C;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAUhG;;;;OAIG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IA+C5C;;;OAGG;IACH,OAAO,CAAC,WAAW;IAsBnB;;;;OAIG;IACH,QAAQ,IAAI,IAAI;IAahB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,gBAAgB;IA8CxB,OAAO,CAAC,sBAAsB;CAc/B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2DvE"}