@cluesmith/codev 2.0.0-rc.8 → 2.0.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 (507) 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-4n9zpWLY.css +32 -0
  5. package/dashboard/dist/assets/index-b38SaXk5.js +136 -0
  6. package/dashboard/dist/assets/index-b38SaXk5.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 +179 -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 +70 -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-roles.d.ts +80 -0
  43. package/dist/agent-farm/commands/spawn-roles.d.ts.map +1 -0
  44. package/dist/agent-farm/commands/spawn-roles.js +278 -0
  45. package/dist/agent-farm/commands/spawn-roles.js.map +1 -0
  46. package/dist/agent-farm/commands/spawn-worktree.d.ts +96 -0
  47. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -0
  48. package/dist/agent-farm/commands/spawn-worktree.js +305 -0
  49. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -0
  50. package/dist/agent-farm/commands/spawn.d.ts +5 -1
  51. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  52. package/dist/agent-farm/commands/spawn.js +242 -586
  53. package/dist/agent-farm/commands/spawn.js.map +1 -1
  54. package/dist/agent-farm/commands/start.d.ts +10 -20
  55. package/dist/agent-farm/commands/start.d.ts.map +1 -1
  56. package/dist/agent-farm/commands/start.js +45 -491
  57. package/dist/agent-farm/commands/start.js.map +1 -1
  58. package/dist/agent-farm/commands/status.d.ts +2 -0
  59. package/dist/agent-farm/commands/status.d.ts.map +1 -1
  60. package/dist/agent-farm/commands/status.js +75 -24
  61. package/dist/agent-farm/commands/status.js.map +1 -1
  62. package/dist/agent-farm/commands/stop.d.ts +6 -0
  63. package/dist/agent-farm/commands/stop.d.ts.map +1 -1
  64. package/dist/agent-farm/commands/stop.js +49 -109
  65. package/dist/agent-farm/commands/stop.js.map +1 -1
  66. package/dist/agent-farm/commands/tower-cloud.d.ts +48 -0
  67. package/dist/agent-farm/commands/tower-cloud.d.ts.map +1 -0
  68. package/dist/agent-farm/commands/tower-cloud.js +293 -0
  69. package/dist/agent-farm/commands/tower-cloud.js.map +1 -0
  70. package/dist/agent-farm/commands/tower.d.ts +9 -0
  71. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  72. package/dist/agent-farm/commands/tower.js +59 -19
  73. package/dist/agent-farm/commands/tower.js.map +1 -1
  74. package/dist/agent-farm/db/index.d.ts +6 -2
  75. package/dist/agent-farm/db/index.d.ts.map +1 -1
  76. package/dist/agent-farm/db/index.js +301 -19
  77. package/dist/agent-farm/db/index.js.map +1 -1
  78. package/dist/agent-farm/db/migrate.d.ts +0 -4
  79. package/dist/agent-farm/db/migrate.d.ts.map +1 -1
  80. package/dist/agent-farm/db/migrate.js +6 -55
  81. package/dist/agent-farm/db/migrate.js.map +1 -1
  82. package/dist/agent-farm/db/schema.d.ts +3 -3
  83. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  84. package/dist/agent-farm/db/schema.js +25 -19
  85. package/dist/agent-farm/db/schema.js.map +1 -1
  86. package/dist/agent-farm/db/types.d.ts +3 -13
  87. package/dist/agent-farm/db/types.d.ts.map +1 -1
  88. package/dist/agent-farm/db/types.js +3 -11
  89. package/dist/agent-farm/db/types.js.map +1 -1
  90. package/dist/agent-farm/hq-connector.d.ts +2 -6
  91. package/dist/agent-farm/hq-connector.d.ts.map +1 -1
  92. package/dist/agent-farm/hq-connector.js +2 -17
  93. package/dist/agent-farm/hq-connector.js.map +1 -1
  94. package/dist/agent-farm/lib/cloud-config.d.ts +59 -0
  95. package/dist/agent-farm/lib/cloud-config.d.ts.map +1 -0
  96. package/dist/agent-farm/lib/cloud-config.js +143 -0
  97. package/dist/agent-farm/lib/cloud-config.js.map +1 -0
  98. package/dist/agent-farm/lib/device-name.d.ts +25 -0
  99. package/dist/agent-farm/lib/device-name.d.ts.map +1 -0
  100. package/dist/agent-farm/lib/device-name.js +46 -0
  101. package/dist/agent-farm/lib/device-name.js.map +1 -0
  102. package/dist/agent-farm/lib/nonce-store.d.ts +28 -0
  103. package/dist/agent-farm/lib/nonce-store.d.ts.map +1 -0
  104. package/dist/agent-farm/lib/nonce-store.js +60 -0
  105. package/dist/agent-farm/lib/nonce-store.js.map +1 -0
  106. package/dist/agent-farm/lib/token-exchange.d.ts +18 -0
  107. package/dist/agent-farm/lib/token-exchange.d.ts.map +1 -0
  108. package/dist/agent-farm/lib/token-exchange.js +48 -0
  109. package/dist/agent-farm/lib/token-exchange.js.map +1 -0
  110. package/dist/agent-farm/lib/tower-client.d.ts +163 -0
  111. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -0
  112. package/dist/agent-farm/lib/tower-client.js +233 -0
  113. package/dist/agent-farm/lib/tower-client.js.map +1 -0
  114. package/dist/agent-farm/lib/tunnel-client.d.ts +117 -0
  115. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -0
  116. package/dist/agent-farm/lib/tunnel-client.js +504 -0
  117. package/dist/agent-farm/lib/tunnel-client.js.map +1 -0
  118. package/dist/agent-farm/servers/tower-instances.d.ts +82 -0
  119. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -0
  120. package/dist/agent-farm/servers/tower-instances.js +454 -0
  121. package/dist/agent-farm/servers/tower-instances.js.map +1 -0
  122. package/dist/agent-farm/servers/tower-routes.d.ts +34 -0
  123. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -0
  124. package/dist/agent-farm/servers/tower-routes.js +1445 -0
  125. package/dist/agent-farm/servers/tower-routes.js.map +1 -0
  126. package/dist/agent-farm/servers/tower-server.d.ts +5 -2
  127. package/dist/agent-farm/servers/tower-server.d.ts.map +1 -1
  128. package/dist/agent-farm/servers/tower-server.js +157 -475
  129. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  130. package/dist/agent-farm/servers/tower-terminals.d.ts +119 -0
  131. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -0
  132. package/dist/agent-farm/servers/tower-terminals.js +629 -0
  133. package/dist/agent-farm/servers/tower-terminals.js.map +1 -0
  134. package/dist/agent-farm/servers/tower-tunnel.d.ts +34 -0
  135. package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -0
  136. package/dist/agent-farm/servers/tower-tunnel.js +473 -0
  137. package/dist/agent-farm/servers/tower-tunnel.js.map +1 -0
  138. package/dist/agent-farm/servers/tower-types.d.ts +86 -0
  139. package/dist/agent-farm/servers/tower-types.d.ts.map +1 -0
  140. package/dist/agent-farm/servers/tower-types.js +6 -0
  141. package/dist/agent-farm/servers/tower-types.js.map +1 -0
  142. package/dist/agent-farm/servers/tower-utils.d.ts +58 -0
  143. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -0
  144. package/dist/agent-farm/servers/tower-utils.js +182 -0
  145. package/dist/agent-farm/servers/tower-utils.js.map +1 -0
  146. package/dist/agent-farm/servers/tower-websocket.d.ts +25 -0
  147. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -0
  148. package/dist/agent-farm/servers/tower-websocket.js +171 -0
  149. package/dist/agent-farm/servers/tower-websocket.js.map +1 -0
  150. package/dist/agent-farm/state.d.ts +6 -12
  151. package/dist/agent-farm/state.d.ts.map +1 -1
  152. package/dist/agent-farm/state.js +34 -49
  153. package/dist/agent-farm/state.js.map +1 -1
  154. package/dist/agent-farm/types.d.ts +49 -26
  155. package/dist/agent-farm/types.d.ts.map +1 -1
  156. package/dist/agent-farm/utils/config.d.ts +0 -5
  157. package/dist/agent-farm/utils/config.d.ts.map +1 -1
  158. package/dist/agent-farm/utils/config.js +12 -44
  159. package/dist/agent-farm/utils/config.js.map +1 -1
  160. package/dist/agent-farm/utils/deps.d.ts.map +1 -1
  161. package/dist/agent-farm/utils/deps.js +0 -32
  162. package/dist/agent-farm/utils/deps.js.map +1 -1
  163. package/dist/agent-farm/utils/file-tabs.d.ts +27 -0
  164. package/dist/agent-farm/utils/file-tabs.d.ts.map +1 -0
  165. package/dist/agent-farm/utils/file-tabs.js +46 -0
  166. package/dist/agent-farm/utils/file-tabs.js.map +1 -0
  167. package/dist/agent-farm/utils/gate-status.d.ts +16 -0
  168. package/dist/agent-farm/utils/gate-status.d.ts.map +1 -0
  169. package/dist/agent-farm/utils/gate-status.js +79 -0
  170. package/dist/agent-farm/utils/gate-status.js.map +1 -0
  171. package/dist/agent-farm/utils/gate-watcher.d.ts +38 -0
  172. package/dist/agent-farm/utils/gate-watcher.d.ts.map +1 -0
  173. package/dist/agent-farm/utils/gate-watcher.js +122 -0
  174. package/dist/agent-farm/utils/gate-watcher.js.map +1 -0
  175. package/dist/agent-farm/utils/index.d.ts +0 -1
  176. package/dist/agent-farm/utils/index.d.ts.map +1 -1
  177. package/dist/agent-farm/utils/index.js +0 -1
  178. package/dist/agent-farm/utils/index.js.map +1 -1
  179. package/dist/agent-farm/utils/notifications.d.ts +30 -0
  180. package/dist/agent-farm/utils/notifications.d.ts.map +1 -0
  181. package/dist/agent-farm/utils/notifications.js +121 -0
  182. package/dist/agent-farm/utils/notifications.js.map +1 -0
  183. package/dist/agent-farm/utils/server-utils.d.ts +5 -5
  184. package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
  185. package/dist/agent-farm/utils/server-utils.js +5 -16
  186. package/dist/agent-farm/utils/server-utils.js.map +1 -1
  187. package/dist/agent-farm/utils/session.d.ts +32 -0
  188. package/dist/agent-farm/utils/session.d.ts.map +1 -0
  189. package/dist/agent-farm/utils/session.js +57 -0
  190. package/dist/agent-farm/utils/session.js.map +1 -0
  191. package/dist/agent-farm/utils/shell.d.ts +9 -22
  192. package/dist/agent-farm/utils/shell.d.ts.map +1 -1
  193. package/dist/agent-farm/utils/shell.js +34 -34
  194. package/dist/agent-farm/utils/shell.js.map +1 -1
  195. package/dist/cli.d.ts.map +1 -1
  196. package/dist/cli.js +11 -54
  197. package/dist/cli.js.map +1 -1
  198. package/dist/commands/adopt.d.ts.map +1 -1
  199. package/dist/commands/adopt.js +49 -4
  200. package/dist/commands/adopt.js.map +1 -1
  201. package/dist/commands/consult/index.d.ts +13 -2
  202. package/dist/commands/consult/index.d.ts.map +1 -1
  203. package/dist/commands/consult/index.js +245 -29
  204. package/dist/commands/consult/index.js.map +1 -1
  205. package/dist/commands/doctor.d.ts.map +1 -1
  206. package/dist/commands/doctor.js +96 -79
  207. package/dist/commands/doctor.js.map +1 -1
  208. package/dist/commands/init.d.ts.map +1 -1
  209. package/dist/commands/init.js +52 -3
  210. package/dist/commands/init.js.map +1 -1
  211. package/dist/commands/porch/build-counter.d.ts +5 -0
  212. package/dist/commands/porch/build-counter.d.ts.map +1 -0
  213. package/dist/commands/porch/build-counter.js +5 -0
  214. package/dist/commands/porch/build-counter.js.map +1 -0
  215. package/dist/commands/porch/checks.d.ts +17 -29
  216. package/dist/commands/porch/checks.d.ts.map +1 -1
  217. package/dist/commands/porch/checks.js +96 -144
  218. package/dist/commands/porch/checks.js.map +1 -1
  219. package/dist/commands/porch/index.d.ts +25 -43
  220. package/dist/commands/porch/index.d.ts.map +1 -1
  221. package/dist/commands/porch/index.js +466 -1238
  222. package/dist/commands/porch/index.js.map +1 -1
  223. package/dist/commands/porch/next.d.ts +22 -0
  224. package/dist/commands/porch/next.d.ts.map +1 -0
  225. package/dist/commands/porch/next.js +571 -0
  226. package/dist/commands/porch/next.js.map +1 -0
  227. package/dist/commands/porch/plan.d.ts +70 -0
  228. package/dist/commands/porch/plan.d.ts.map +1 -0
  229. package/dist/commands/porch/plan.js +190 -0
  230. package/dist/commands/porch/plan.js.map +1 -0
  231. package/dist/commands/porch/prompts.d.ts +19 -0
  232. package/dist/commands/porch/prompts.d.ts.map +1 -0
  233. package/dist/commands/porch/prompts.js +277 -0
  234. package/dist/commands/porch/prompts.js.map +1 -0
  235. package/dist/commands/porch/protocol.d.ts +59 -0
  236. package/dist/commands/porch/protocol.d.ts.map +1 -0
  237. package/dist/commands/porch/protocol.js +294 -0
  238. package/dist/commands/porch/protocol.js.map +1 -0
  239. package/dist/commands/porch/state.d.ts +36 -107
  240. package/dist/commands/porch/state.d.ts.map +1 -1
  241. package/dist/commands/porch/state.js +120 -699
  242. package/dist/commands/porch/state.js.map +1 -1
  243. package/dist/commands/porch/types.d.ts +99 -164
  244. package/dist/commands/porch/types.d.ts.map +1 -1
  245. package/dist/commands/porch/types.js +2 -1
  246. package/dist/commands/porch/types.js.map +1 -1
  247. package/dist/commands/porch/verdict.d.ts +31 -0
  248. package/dist/commands/porch/verdict.d.ts.map +1 -0
  249. package/dist/commands/porch/verdict.js +59 -0
  250. package/dist/commands/porch/verdict.js.map +1 -0
  251. package/dist/commands/update.d.ts.map +1 -1
  252. package/dist/commands/update.js +31 -0
  253. package/dist/commands/update.js.map +1 -1
  254. package/dist/lib/scaffold.d.ts +37 -0
  255. package/dist/lib/scaffold.d.ts.map +1 -1
  256. package/dist/lib/scaffold.js +114 -0
  257. package/dist/lib/scaffold.js.map +1 -1
  258. package/dist/terminal/index.d.ts +8 -0
  259. package/dist/terminal/index.d.ts.map +1 -0
  260. package/dist/terminal/index.js +5 -0
  261. package/dist/terminal/index.js.map +1 -0
  262. package/dist/terminal/pty-manager.d.ts +69 -0
  263. package/dist/terminal/pty-manager.d.ts.map +1 -0
  264. package/dist/terminal/pty-manager.js +377 -0
  265. package/dist/terminal/pty-manager.js.map +1 -0
  266. package/dist/terminal/pty-session.d.ts +104 -0
  267. package/dist/terminal/pty-session.d.ts.map +1 -0
  268. package/dist/terminal/pty-session.js +327 -0
  269. package/dist/terminal/pty-session.js.map +1 -0
  270. package/dist/terminal/ring-buffer.d.ts +34 -0
  271. package/dist/terminal/ring-buffer.d.ts.map +1 -0
  272. package/dist/terminal/ring-buffer.js +94 -0
  273. package/dist/terminal/ring-buffer.js.map +1 -0
  274. package/dist/terminal/session-manager.d.ts +115 -0
  275. package/dist/terminal/session-manager.d.ts.map +1 -0
  276. package/dist/terminal/session-manager.js +582 -0
  277. package/dist/terminal/session-manager.js.map +1 -0
  278. package/dist/terminal/shellper-client.d.ts +66 -0
  279. package/dist/terminal/shellper-client.d.ts.map +1 -0
  280. package/dist/terminal/shellper-client.js +234 -0
  281. package/dist/terminal/shellper-client.js.map +1 -0
  282. package/dist/terminal/shellper-main.d.ts +19 -0
  283. package/dist/terminal/shellper-main.d.ts.map +1 -0
  284. package/dist/terminal/shellper-main.js +153 -0
  285. package/dist/terminal/shellper-main.js.map +1 -0
  286. package/dist/terminal/shellper-process.d.ts +75 -0
  287. package/dist/terminal/shellper-process.d.ts.map +1 -0
  288. package/dist/terminal/shellper-process.js +279 -0
  289. package/dist/terminal/shellper-process.js.map +1 -0
  290. package/dist/terminal/shellper-protocol.d.ts +115 -0
  291. package/dist/terminal/shellper-protocol.d.ts.map +1 -0
  292. package/dist/terminal/shellper-protocol.js +214 -0
  293. package/dist/terminal/shellper-protocol.js.map +1 -0
  294. package/dist/terminal/shellper-replay-buffer.d.ts +38 -0
  295. package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -0
  296. package/dist/terminal/shellper-replay-buffer.js +94 -0
  297. package/dist/terminal/shellper-replay-buffer.js.map +1 -0
  298. package/dist/terminal/ws-protocol.d.ts +27 -0
  299. package/dist/terminal/ws-protocol.d.ts.map +1 -0
  300. package/dist/terminal/ws-protocol.js +44 -0
  301. package/dist/terminal/ws-protocol.js.map +1 -0
  302. package/package.json +19 -5
  303. package/skeleton/.claude/skills/af/SKILL.md +89 -0
  304. package/skeleton/.claude/skills/codev/SKILL.md +41 -0
  305. package/skeleton/.claude/skills/consult/SKILL.md +81 -0
  306. package/skeleton/.claude/skills/generate-image/SKILL.md +56 -0
  307. package/skeleton/DEPENDENCIES.md +4 -62
  308. package/skeleton/builders.md +1 -1
  309. package/skeleton/consult-types/impl-review.md +18 -9
  310. package/skeleton/consult-types/integration-review.md +1 -1
  311. package/skeleton/consult-types/plan-review.md +1 -1
  312. package/skeleton/consult-types/pr-ready.md +1 -1
  313. package/skeleton/consult-types/spec-review.md +1 -1
  314. package/skeleton/porch/prompts/defend.md +1 -1
  315. package/skeleton/porch/prompts/evaluate.md +2 -2
  316. package/skeleton/porch/prompts/implement.md +1 -1
  317. package/skeleton/porch/prompts/plan.md +1 -1
  318. package/skeleton/porch/prompts/review.md +4 -4
  319. package/skeleton/porch/prompts/specify.md +1 -1
  320. package/skeleton/porch/prompts/understand.md +2 -2
  321. package/skeleton/protocol-schema.json +282 -0
  322. package/skeleton/protocols/bugfix/builder-prompt.md +60 -0
  323. package/skeleton/protocols/bugfix/prompts/fix.md +77 -0
  324. package/skeleton/protocols/bugfix/prompts/investigate.md +77 -0
  325. package/skeleton/protocols/bugfix/prompts/pr.md +84 -0
  326. package/skeleton/protocols/bugfix/protocol.json +20 -33
  327. package/skeleton/protocols/experiment/builder-prompt.md +52 -0
  328. package/skeleton/protocols/experiment/protocol.json +101 -0
  329. package/skeleton/protocols/experiment/protocol.md +3 -3
  330. package/skeleton/protocols/experiment/templates/notes.md +1 -1
  331. package/skeleton/protocols/maintain/builder-prompt.md +46 -0
  332. package/skeleton/protocols/maintain/prompts/audit.md +111 -0
  333. package/skeleton/protocols/maintain/prompts/clean.md +91 -0
  334. package/skeleton/protocols/maintain/prompts/sync.md +113 -0
  335. package/skeleton/protocols/maintain/prompts/verify.md +110 -0
  336. package/skeleton/protocols/maintain/protocol.json +141 -0
  337. package/skeleton/protocols/maintain/protocol.md +17 -11
  338. package/skeleton/protocols/protocol-schema.json +54 -1
  339. package/skeleton/protocols/spir/builder-prompt.md +66 -0
  340. package/skeleton/protocols/spir/prompts/implement.md +208 -0
  341. package/skeleton/protocols/{spider → spir}/prompts/plan.md +6 -70
  342. package/skeleton/protocols/{spider → spir}/prompts/review.md +20 -39
  343. package/skeleton/protocols/{spider → spir}/prompts/specify.md +33 -61
  344. package/skeleton/protocols/spir/protocol.json +156 -0
  345. package/skeleton/protocols/{spider → spir}/protocol.md +35 -21
  346. package/skeleton/protocols/{spider → spir}/templates/plan.md +14 -0
  347. package/skeleton/protocols/spir/templates/review.md +89 -0
  348. package/skeleton/protocols/tick/builder-prompt.md +56 -0
  349. package/skeleton/protocols/tick/protocol.json +7 -2
  350. package/skeleton/protocols/tick/protocol.md +18 -18
  351. package/skeleton/protocols/tick/templates/review.md +1 -1
  352. package/skeleton/resources/commands/agent-farm.md +63 -46
  353. package/skeleton/resources/commands/codev.md +0 -2
  354. package/skeleton/resources/commands/overview.md +7 -17
  355. package/skeleton/resources/workflow-reference.md +4 -4
  356. package/skeleton/roles/architect.md +152 -315
  357. package/skeleton/roles/builder.md +120 -214
  358. package/skeleton/roles/consultant.md +6 -6
  359. package/skeleton/templates/AGENTS.md +2 -2
  360. package/skeleton/templates/CLAUDE.md +2 -2
  361. package/skeleton/templates/cheatsheet.md +7 -5
  362. package/skeleton/templates/projectlist.md +1 -1
  363. package/templates/dashboard/index.html +17 -43
  364. package/templates/dashboard/js/dialogs.js +7 -7
  365. package/templates/dashboard/js/files.js +2 -2
  366. package/templates/dashboard/js/main.js +4 -4
  367. package/templates/dashboard/js/projects.js +3 -3
  368. package/templates/dashboard/js/tabs.js +1 -1
  369. package/templates/dashboard/js/utils.js +22 -87
  370. package/templates/open.html +26 -0
  371. package/templates/tower.html +731 -91
  372. package/dist/agent-farm/commands/kickoff.d.ts +0 -20
  373. package/dist/agent-farm/commands/kickoff.d.ts.map +0 -1
  374. package/dist/agent-farm/commands/kickoff.js +0 -337
  375. package/dist/agent-farm/commands/kickoff.js.map +0 -1
  376. package/dist/agent-farm/commands/rename.d.ts +0 -13
  377. package/dist/agent-farm/commands/rename.d.ts.map +0 -1
  378. package/dist/agent-farm/commands/rename.js +0 -33
  379. package/dist/agent-farm/commands/rename.js.map +0 -1
  380. package/dist/agent-farm/commands/tutorial.d.ts +0 -10
  381. package/dist/agent-farm/commands/tutorial.d.ts.map +0 -1
  382. package/dist/agent-farm/commands/tutorial.js +0 -49
  383. package/dist/agent-farm/commands/tutorial.js.map +0 -1
  384. package/dist/agent-farm/commands/util.d.ts +0 -15
  385. package/dist/agent-farm/commands/util.d.ts.map +0 -1
  386. package/dist/agent-farm/commands/util.js +0 -108
  387. package/dist/agent-farm/commands/util.js.map +0 -1
  388. package/dist/agent-farm/servers/dashboard-server.d.ts +0 -7
  389. package/dist/agent-farm/servers/dashboard-server.d.ts.map +0 -1
  390. package/dist/agent-farm/servers/dashboard-server.js +0 -1872
  391. package/dist/agent-farm/servers/dashboard-server.js.map +0 -1
  392. package/dist/agent-farm/servers/open-server.d.ts +0 -7
  393. package/dist/agent-farm/servers/open-server.d.ts.map +0 -1
  394. package/dist/agent-farm/servers/open-server.js +0 -315
  395. package/dist/agent-farm/servers/open-server.js.map +0 -1
  396. package/dist/agent-farm/tutorial/index.d.ts +0 -8
  397. package/dist/agent-farm/tutorial/index.d.ts.map +0 -1
  398. package/dist/agent-farm/tutorial/index.js +0 -8
  399. package/dist/agent-farm/tutorial/index.js.map +0 -1
  400. package/dist/agent-farm/tutorial/prompts.d.ts +0 -57
  401. package/dist/agent-farm/tutorial/prompts.d.ts.map +0 -1
  402. package/dist/agent-farm/tutorial/prompts.js +0 -147
  403. package/dist/agent-farm/tutorial/prompts.js.map +0 -1
  404. package/dist/agent-farm/tutorial/runner.d.ts +0 -52
  405. package/dist/agent-farm/tutorial/runner.d.ts.map +0 -1
  406. package/dist/agent-farm/tutorial/runner.js +0 -204
  407. package/dist/agent-farm/tutorial/runner.js.map +0 -1
  408. package/dist/agent-farm/tutorial/state.d.ts +0 -26
  409. package/dist/agent-farm/tutorial/state.d.ts.map +0 -1
  410. package/dist/agent-farm/tutorial/state.js +0 -89
  411. package/dist/agent-farm/tutorial/state.js.map +0 -1
  412. package/dist/agent-farm/tutorial/steps/first-spec.d.ts +0 -7
  413. package/dist/agent-farm/tutorial/steps/first-spec.d.ts.map +0 -1
  414. package/dist/agent-farm/tutorial/steps/first-spec.js +0 -136
  415. package/dist/agent-farm/tutorial/steps/first-spec.js.map +0 -1
  416. package/dist/agent-farm/tutorial/steps/implementation.d.ts +0 -7
  417. package/dist/agent-farm/tutorial/steps/implementation.d.ts.map +0 -1
  418. package/dist/agent-farm/tutorial/steps/implementation.js +0 -76
  419. package/dist/agent-farm/tutorial/steps/implementation.js.map +0 -1
  420. package/dist/agent-farm/tutorial/steps/index.d.ts +0 -10
  421. package/dist/agent-farm/tutorial/steps/index.d.ts.map +0 -1
  422. package/dist/agent-farm/tutorial/steps/index.js +0 -10
  423. package/dist/agent-farm/tutorial/steps/index.js.map +0 -1
  424. package/dist/agent-farm/tutorial/steps/planning.d.ts +0 -7
  425. package/dist/agent-farm/tutorial/steps/planning.d.ts.map +0 -1
  426. package/dist/agent-farm/tutorial/steps/planning.js +0 -143
  427. package/dist/agent-farm/tutorial/steps/planning.js.map +0 -1
  428. package/dist/agent-farm/tutorial/steps/review.d.ts +0 -7
  429. package/dist/agent-farm/tutorial/steps/review.d.ts.map +0 -1
  430. package/dist/agent-farm/tutorial/steps/review.js +0 -78
  431. package/dist/agent-farm/tutorial/steps/review.js.map +0 -1
  432. package/dist/agent-farm/tutorial/steps/setup.d.ts +0 -7
  433. package/dist/agent-farm/tutorial/steps/setup.d.ts.map +0 -1
  434. package/dist/agent-farm/tutorial/steps/setup.js +0 -126
  435. package/dist/agent-farm/tutorial/steps/setup.js.map +0 -1
  436. package/dist/agent-farm/tutorial/steps/welcome.d.ts +0 -7
  437. package/dist/agent-farm/tutorial/steps/welcome.d.ts.map +0 -1
  438. package/dist/agent-farm/tutorial/steps/welcome.js +0 -50
  439. package/dist/agent-farm/tutorial/steps/welcome.js.map +0 -1
  440. package/dist/agent-farm/utils/orphan-handler.d.ts +0 -27
  441. package/dist/agent-farm/utils/orphan-handler.d.ts.map +0 -1
  442. package/dist/agent-farm/utils/orphan-handler.js +0 -149
  443. package/dist/agent-farm/utils/orphan-handler.js.map +0 -1
  444. package/dist/agent-farm/utils/port-registry.d.ts +0 -58
  445. package/dist/agent-farm/utils/port-registry.d.ts.map +0 -1
  446. package/dist/agent-farm/utils/port-registry.js +0 -166
  447. package/dist/agent-farm/utils/port-registry.js.map +0 -1
  448. package/dist/agent-farm/utils/terminal-ports.d.ts +0 -18
  449. package/dist/agent-farm/utils/terminal-ports.d.ts.map +0 -1
  450. package/dist/agent-farm/utils/terminal-ports.js +0 -35
  451. package/dist/agent-farm/utils/terminal-ports.js.map +0 -1
  452. package/dist/commands/pcheck/cache.d.ts +0 -48
  453. package/dist/commands/pcheck/cache.d.ts.map +0 -1
  454. package/dist/commands/pcheck/cache.js +0 -170
  455. package/dist/commands/pcheck/cache.js.map +0 -1
  456. package/dist/commands/pcheck/evaluator.d.ts +0 -15
  457. package/dist/commands/pcheck/evaluator.d.ts.map +0 -1
  458. package/dist/commands/pcheck/evaluator.js +0 -246
  459. package/dist/commands/pcheck/evaluator.js.map +0 -1
  460. package/dist/commands/pcheck/index.d.ts +0 -12
  461. package/dist/commands/pcheck/index.d.ts.map +0 -1
  462. package/dist/commands/pcheck/index.js +0 -249
  463. package/dist/commands/pcheck/index.js.map +0 -1
  464. package/dist/commands/pcheck/parser.d.ts +0 -39
  465. package/dist/commands/pcheck/parser.d.ts.map +0 -1
  466. package/dist/commands/pcheck/parser.js +0 -155
  467. package/dist/commands/pcheck/parser.js.map +0 -1
  468. package/dist/commands/pcheck/types.d.ts +0 -82
  469. package/dist/commands/pcheck/types.d.ts.map +0 -1
  470. package/dist/commands/pcheck/types.js +0 -5
  471. package/dist/commands/pcheck/types.js.map +0 -1
  472. package/dist/commands/porch/consultation.d.ts +0 -56
  473. package/dist/commands/porch/consultation.d.ts.map +0 -1
  474. package/dist/commands/porch/consultation.js +0 -330
  475. package/dist/commands/porch/consultation.js.map +0 -1
  476. package/dist/commands/porch/notifications.d.ts +0 -99
  477. package/dist/commands/porch/notifications.d.ts.map +0 -1
  478. package/dist/commands/porch/notifications.js +0 -223
  479. package/dist/commands/porch/notifications.js.map +0 -1
  480. package/dist/commands/porch/plan-parser.d.ts +0 -38
  481. package/dist/commands/porch/plan-parser.d.ts.map +0 -1
  482. package/dist/commands/porch/plan-parser.js +0 -166
  483. package/dist/commands/porch/plan-parser.js.map +0 -1
  484. package/dist/commands/porch/protocol-loader.d.ts +0 -46
  485. package/dist/commands/porch/protocol-loader.d.ts.map +0 -1
  486. package/dist/commands/porch/protocol-loader.js +0 -253
  487. package/dist/commands/porch/protocol-loader.js.map +0 -1
  488. package/dist/commands/porch/signal-parser.d.ts +0 -88
  489. package/dist/commands/porch/signal-parser.d.ts.map +0 -1
  490. package/dist/commands/porch/signal-parser.js +0 -148
  491. package/dist/commands/porch/signal-parser.js.map +0 -1
  492. package/dist/commands/tower.d.ts +0 -16
  493. package/dist/commands/tower.d.ts.map +0 -1
  494. package/dist/commands/tower.js +0 -21
  495. package/dist/commands/tower.js.map +0 -1
  496. package/skeleton/config.json +0 -7
  497. package/skeleton/porch/protocols/bugfix.json +0 -85
  498. package/skeleton/porch/protocols/spider.json +0 -135
  499. package/skeleton/porch/protocols/tick.json +0 -76
  500. package/skeleton/protocols/spider/prompts/defend.md +0 -215
  501. package/skeleton/protocols/spider/prompts/evaluate.md +0 -241
  502. package/skeleton/protocols/spider/prompts/implement.md +0 -149
  503. package/skeleton/protocols/spider/protocol.json +0 -210
  504. package/skeleton/protocols/spider/templates/review.md +0 -207
  505. package/templates/dashboard/css/activity.css +0 -151
  506. package/templates/dashboard/js/activity.js +0 -112
  507. /package/skeleton/protocols/{spider → spir}/templates/spec.md +0 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * In-memory nonce store for OAuth registration state management.
3
+ *
4
+ * Bridges the gap between OAuth initiation (POST /api/tunnel/connect)
5
+ * and completion (GET /api/tunnel/connect/callback) by storing
6
+ * pending registration data keyed by a single-use nonce.
7
+ */
8
+ import { randomUUID } from 'node:crypto';
9
+ const NONCE_TTL_MS = 5 * 60 * 1000; // 5 minutes
10
+ const pendingRegistrations = new Map();
11
+ /**
12
+ * Create a pending registration with a unique nonce.
13
+ * Runs cleanup of expired entries on each call.
14
+ */
15
+ export function createPendingRegistration(name, serverUrl) {
16
+ cleanupExpired();
17
+ const nonce = randomUUID();
18
+ pendingRegistrations.set(nonce, {
19
+ nonce,
20
+ name,
21
+ serverUrl,
22
+ createdAt: Date.now(),
23
+ });
24
+ return nonce;
25
+ }
26
+ /**
27
+ * Consume a pending registration by nonce (single-use).
28
+ * Returns the registration data and deletes it, or null if not found/expired.
29
+ */
30
+ export function consumePendingRegistration(nonce) {
31
+ const entry = pendingRegistrations.get(nonce);
32
+ if (!entry)
33
+ return null;
34
+ // Check expiry
35
+ if (Date.now() - entry.createdAt > NONCE_TTL_MS) {
36
+ pendingRegistrations.delete(nonce);
37
+ return null;
38
+ }
39
+ // Single-use: delete after consumption
40
+ pendingRegistrations.delete(nonce);
41
+ return entry;
42
+ }
43
+ /**
44
+ * Remove all expired entries from the store.
45
+ */
46
+ function cleanupExpired() {
47
+ const now = Date.now();
48
+ for (const [nonce, entry] of pendingRegistrations) {
49
+ if (now - entry.createdAt > NONCE_TTL_MS) {
50
+ pendingRegistrations.delete(nonce);
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Clear all pending registrations. Used for testing.
56
+ */
57
+ export function clearPendingRegistrations() {
58
+ pendingRegistrations.clear();
59
+ }
60
+ //# sourceMappingURL=nonce-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce-store.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/nonce-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAShD,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA+B,CAAC;AAEpE;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAE,SAAiB;IACvE,cAAc,EAAE,CAAC;IAEjB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE;QAC9B,KAAK;QACL,IAAI;QACJ,SAAS;QACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,eAAe;IACf,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;QAChD,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uCAAuC;IACvC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,oBAAoB,EAAE,CAAC;QAClD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;YACzC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,oBAAoB,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Token exchange for Tower cloud registration.
3
+ *
4
+ * Shared between CLI (tower-cloud.ts) and Tower server (tower-tunnel.ts)
5
+ * for exchanging an OAuth registration token for API credentials.
6
+ */
7
+ /**
8
+ * Exchange a registration token for API key and tower ID.
9
+ *
10
+ * POSTs to {serverUrl}/api/towers/register/redeem with the token,
11
+ * tower name, and machine ID. Handles 301/302 redirects manually
12
+ * to preserve the POST method (fetch follows redirects as GET).
13
+ */
14
+ export declare function redeemToken(serverUrl: string, token: string, towerName: string, machineId: string): Promise<{
15
+ towerId: string;
16
+ apiKey: string;
17
+ }>;
18
+ //# sourceMappingURL=token-exchange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-exchange.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/token-exchange.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsC9C"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Token exchange for Tower cloud registration.
3
+ *
4
+ * Shared between CLI (tower-cloud.ts) and Tower server (tower-tunnel.ts)
5
+ * for exchanging an OAuth registration token for API credentials.
6
+ */
7
+ /**
8
+ * Exchange a registration token for API key and tower ID.
9
+ *
10
+ * POSTs to {serverUrl}/api/towers/register/redeem with the token,
11
+ * tower name, and machine ID. Handles 301/302 redirects manually
12
+ * to preserve the POST method (fetch follows redirects as GET).
13
+ */
14
+ export async function redeemToken(serverUrl, token, towerName, machineId) {
15
+ const url = `${serverUrl}/api/towers/register/redeem`;
16
+ const body = JSON.stringify({ token, name: towerName, machineId });
17
+ // Use manual redirect to preserve POST method across 301/302 redirects
18
+ const response = await fetch(url, {
19
+ method: 'POST',
20
+ headers: { 'Content-Type': 'application/json' },
21
+ body,
22
+ redirect: 'manual',
23
+ signal: AbortSignal.timeout(30_000),
24
+ }).then((res) => {
25
+ if (res.status >= 300 && res.status < 400) {
26
+ const location = res.headers.get('location');
27
+ if (location) {
28
+ return fetch(location, {
29
+ method: 'POST',
30
+ headers: { 'Content-Type': 'application/json' },
31
+ body,
32
+ signal: AbortSignal.timeout(30_000),
33
+ });
34
+ }
35
+ }
36
+ return res;
37
+ });
38
+ if (!response.ok) {
39
+ const text = await response.text().catch(() => '');
40
+ throw new Error(`Registration failed (${response.status}): ${text || response.statusText}`);
41
+ }
42
+ const data = (await response.json());
43
+ if (!data.towerId || !data.apiKey) {
44
+ throw new Error('Invalid response from registration server: missing towerId or apiKey');
45
+ }
46
+ return { towerId: data.towerId, apiKey: data.apiKey };
47
+ }
48
+ //# sourceMappingURL=token-exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-exchange.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/token-exchange.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,KAAa,EACb,SAAiB,EACjB,SAAiB;IAEjB,MAAM,GAAG,GAAG,GAAG,SAAS,6BAA6B,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAEnE,uEAAuE;IACvE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI;QACJ,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACd,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC,QAAQ,EAAE;oBACrB,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI;oBACJ,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;iBACpC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA0C,CAAC;IAE9E,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Tower API Client (Spec 0090 Phase 3)
3
+ *
4
+ * Provides a client for CLI commands to interact with the tower daemon.
5
+ * Handles local-key authentication and common API operations.
6
+ */
7
+ /**
8
+ * Project info returned by tower API
9
+ */
10
+ export interface TowerProject {
11
+ path: string;
12
+ name: string;
13
+ active: boolean;
14
+ proxyUrl: string;
15
+ terminals: number;
16
+ }
17
+ /**
18
+ * Project status with detailed info
19
+ */
20
+ export interface TowerProjectStatus {
21
+ path: string;
22
+ name: string;
23
+ active: boolean;
24
+ terminals: Array<{
25
+ type: 'architect' | 'builder' | 'shell';
26
+ id: string;
27
+ label: string;
28
+ url: string;
29
+ active: boolean;
30
+ }>;
31
+ gateStatus?: {
32
+ hasGate: boolean;
33
+ gateName?: string;
34
+ builderId?: string;
35
+ requestedAt?: string;
36
+ };
37
+ }
38
+ /**
39
+ * Health status from tower
40
+ */
41
+ export interface TowerHealth {
42
+ status: 'healthy' | 'degraded';
43
+ uptime: number;
44
+ activeProjects: number;
45
+ totalProjects: number;
46
+ memoryUsage: number;
47
+ timestamp: string;
48
+ }
49
+ /**
50
+ * Terminal info from tower
51
+ */
52
+ export interface TowerTerminal {
53
+ id: string;
54
+ pid: number;
55
+ cols: number;
56
+ rows: number;
57
+ label: string;
58
+ status: 'running' | 'exited';
59
+ createdAt: string;
60
+ wsPath: string;
61
+ }
62
+ /**
63
+ * Encode a project path for use in tower API URLs
64
+ */
65
+ export declare function encodeProjectPath(projectPath: string): string;
66
+ /**
67
+ * Decode a project path from tower API URL
68
+ */
69
+ export declare function decodeProjectPath(encoded: string): string;
70
+ /**
71
+ * Tower API client class
72
+ */
73
+ export declare class TowerClient {
74
+ private readonly baseUrl;
75
+ private readonly localKey;
76
+ constructor(port?: number);
77
+ /**
78
+ * Make a request to the tower API
79
+ */
80
+ request<T>(path: string, options?: RequestInit): Promise<{
81
+ ok: boolean;
82
+ status: number;
83
+ data?: T;
84
+ error?: string;
85
+ }>;
86
+ /**
87
+ * Check if tower is running and healthy
88
+ */
89
+ isRunning(): Promise<boolean>;
90
+ /**
91
+ * Get tower health status
92
+ */
93
+ getHealth(): Promise<TowerHealth | null>;
94
+ /**
95
+ * List all projects known to tower
96
+ */
97
+ listProjects(): Promise<TowerProject[]>;
98
+ /**
99
+ * Activate a project (start its dashboard)
100
+ */
101
+ activateProject(projectPath: string): Promise<{
102
+ ok: boolean;
103
+ adopted?: boolean;
104
+ error?: string;
105
+ }>;
106
+ /**
107
+ * Deactivate a project (stop its dashboard)
108
+ */
109
+ deactivateProject(projectPath: string): Promise<{
110
+ ok: boolean;
111
+ stopped?: number[];
112
+ error?: string;
113
+ }>;
114
+ /**
115
+ * Get status of a specific project
116
+ */
117
+ getProjectStatus(projectPath: string): Promise<TowerProjectStatus | null>;
118
+ /**
119
+ * Create a terminal session
120
+ */
121
+ createTerminal(options: {
122
+ command?: string;
123
+ args?: string[];
124
+ cols?: number;
125
+ rows?: number;
126
+ cwd?: string;
127
+ label?: string;
128
+ env?: Record<string, string>;
129
+ }): Promise<TowerTerminal | null>;
130
+ /**
131
+ * List all terminal sessions
132
+ */
133
+ listTerminals(): Promise<TowerTerminal[]>;
134
+ /**
135
+ * Get terminal info
136
+ */
137
+ getTerminal(terminalId: string): Promise<TowerTerminal | null>;
138
+ /**
139
+ * Write data to a terminal session
140
+ */
141
+ writeTerminal(terminalId: string, data: string): Promise<boolean>;
142
+ /**
143
+ * Kill a terminal session
144
+ */
145
+ killTerminal(terminalId: string): Promise<boolean>;
146
+ /**
147
+ * Resize a terminal
148
+ */
149
+ resizeTerminal(terminalId: string, cols: number, rows: number): Promise<TowerTerminal | null>;
150
+ /**
151
+ * Get the tower dashboard URL for a project
152
+ */
153
+ getProjectUrl(projectPath: string): string;
154
+ /**
155
+ * Get the WebSocket URL for a terminal
156
+ */
157
+ getTerminalWsUrl(terminalId: string): string;
158
+ }
159
+ /**
160
+ * Get the default tower client
161
+ */
162
+ export declare function getTowerClient(port?: number): TowerClient;
163
+ //# sourceMappingURL=tower-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-client.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/tower-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;QACf,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;QACxC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC,CAAC;IACH,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAmBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,IAAI,GAAE,MAA2B;IAK7C;;OAEG;IACG,OAAO,CAAC,CAAC,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA0CrE;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAKnC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK9C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAK7C;;OAEG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAkB9D;;OAEG;IACG,iBAAiB,CACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAkB/D;;OAEG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAM/E;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC9B,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAQjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAK/C;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAKpE;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQvE;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxD;;OAEG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAQhC;;OAEG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAK1C;;OAEG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;CAG7C;AAOD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAKzD"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Tower API Client (Spec 0090 Phase 3)
3
+ *
4
+ * Provides a client for CLI commands to interact with the tower daemon.
5
+ * Handles local-key authentication and common API operations.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ import { homedir } from 'node:os';
10
+ import { randomBytes } from 'node:crypto';
11
+ // Tower configuration
12
+ const DEFAULT_TOWER_PORT = 4100;
13
+ const AGENT_FARM_DIR = resolve(homedir(), '.agent-farm');
14
+ const LOCAL_KEY_PATH = resolve(AGENT_FARM_DIR, 'local-key');
15
+ // Request timeout
16
+ const REQUEST_TIMEOUT_MS = 10000;
17
+ /**
18
+ * Get or create the local key for CLI authentication
19
+ */
20
+ function getLocalKey() {
21
+ if (!existsSync(AGENT_FARM_DIR)) {
22
+ mkdirSync(AGENT_FARM_DIR, { recursive: true, mode: 0o700 });
23
+ }
24
+ if (!existsSync(LOCAL_KEY_PATH)) {
25
+ const key = randomBytes(32).toString('hex');
26
+ writeFileSync(LOCAL_KEY_PATH, key, { mode: 0o600 });
27
+ return key;
28
+ }
29
+ return readFileSync(LOCAL_KEY_PATH, 'utf-8').trim();
30
+ }
31
+ /**
32
+ * Encode a project path for use in tower API URLs
33
+ */
34
+ export function encodeProjectPath(projectPath) {
35
+ return Buffer.from(projectPath).toString('base64url');
36
+ }
37
+ /**
38
+ * Decode a project path from tower API URL
39
+ */
40
+ export function decodeProjectPath(encoded) {
41
+ return Buffer.from(encoded, 'base64url').toString('utf-8');
42
+ }
43
+ /**
44
+ * Tower API client class
45
+ */
46
+ export class TowerClient {
47
+ baseUrl;
48
+ localKey;
49
+ constructor(port = DEFAULT_TOWER_PORT) {
50
+ this.baseUrl = `http://localhost:${port}`;
51
+ this.localKey = getLocalKey();
52
+ }
53
+ /**
54
+ * Make a request to the tower API
55
+ */
56
+ async request(path, options = {}) {
57
+ try {
58
+ const response = await fetch(`${this.baseUrl}${path}`, {
59
+ ...options,
60
+ headers: {
61
+ ...options.headers,
62
+ 'codev-web-key': this.localKey,
63
+ 'Content-Type': 'application/json',
64
+ },
65
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
66
+ });
67
+ if (!response.ok) {
68
+ const text = await response.text();
69
+ let error;
70
+ try {
71
+ const json = JSON.parse(text);
72
+ error = json.error || json.message || text;
73
+ }
74
+ catch {
75
+ error = text;
76
+ }
77
+ return { ok: false, status: response.status, error };
78
+ }
79
+ if (response.status === 204) {
80
+ return { ok: true, status: 204 };
81
+ }
82
+ const data = (await response.json());
83
+ return { ok: true, status: response.status, data };
84
+ }
85
+ catch (err) {
86
+ const message = err instanceof Error ? err.message : String(err);
87
+ if (message.includes('ECONNREFUSED')) {
88
+ return { ok: false, status: 0, error: 'Tower not running' };
89
+ }
90
+ if (message.includes('timeout')) {
91
+ return { ok: false, status: 0, error: 'Request timeout' };
92
+ }
93
+ return { ok: false, status: 0, error: message };
94
+ }
95
+ }
96
+ /**
97
+ * Check if tower is running and healthy
98
+ */
99
+ async isRunning() {
100
+ const result = await this.request('/health');
101
+ return result.ok && result.data?.status === 'healthy';
102
+ }
103
+ /**
104
+ * Get tower health status
105
+ */
106
+ async getHealth() {
107
+ const result = await this.request('/health');
108
+ return result.ok ? result.data : null;
109
+ }
110
+ /**
111
+ * List all projects known to tower
112
+ */
113
+ async listProjects() {
114
+ const result = await this.request('/api/projects');
115
+ return result.ok ? result.data.projects : [];
116
+ }
117
+ /**
118
+ * Activate a project (start its dashboard)
119
+ */
120
+ async activateProject(projectPath) {
121
+ const encoded = encodeProjectPath(projectPath);
122
+ const result = await this.request(`/api/projects/${encoded}/activate`, { method: 'POST' });
123
+ if (!result.ok) {
124
+ return { ok: false, error: result.error };
125
+ }
126
+ return {
127
+ ok: result.data?.success ?? true,
128
+ adopted: result.data?.adopted,
129
+ error: result.data?.error,
130
+ };
131
+ }
132
+ /**
133
+ * Deactivate a project (stop its dashboard)
134
+ */
135
+ async deactivateProject(projectPath) {
136
+ const encoded = encodeProjectPath(projectPath);
137
+ const result = await this.request(`/api/projects/${encoded}/deactivate`, { method: 'POST' });
138
+ if (!result.ok) {
139
+ return { ok: false, error: result.error };
140
+ }
141
+ return {
142
+ ok: result.data?.success ?? true,
143
+ stopped: result.data?.stopped,
144
+ error: result.data?.error,
145
+ };
146
+ }
147
+ /**
148
+ * Get status of a specific project
149
+ */
150
+ async getProjectStatus(projectPath) {
151
+ const encoded = encodeProjectPath(projectPath);
152
+ const result = await this.request(`/api/projects/${encoded}/status`);
153
+ return result.ok ? result.data : null;
154
+ }
155
+ /**
156
+ * Create a terminal session
157
+ */
158
+ async createTerminal(options) {
159
+ const result = await this.request('/api/terminals', {
160
+ method: 'POST',
161
+ body: JSON.stringify(options),
162
+ });
163
+ return result.ok ? result.data : null;
164
+ }
165
+ /**
166
+ * List all terminal sessions
167
+ */
168
+ async listTerminals() {
169
+ const result = await this.request('/api/terminals');
170
+ return result.ok ? result.data.terminals : [];
171
+ }
172
+ /**
173
+ * Get terminal info
174
+ */
175
+ async getTerminal(terminalId) {
176
+ const result = await this.request(`/api/terminals/${terminalId}`);
177
+ return result.ok ? result.data : null;
178
+ }
179
+ /**
180
+ * Write data to a terminal session
181
+ */
182
+ async writeTerminal(terminalId, data) {
183
+ const result = await this.request(`/api/terminals/${terminalId}/write`, {
184
+ method: 'POST',
185
+ body: JSON.stringify({ data }),
186
+ });
187
+ return result.ok;
188
+ }
189
+ /**
190
+ * Kill a terminal session
191
+ */
192
+ async killTerminal(terminalId) {
193
+ const result = await this.request(`/api/terminals/${terminalId}`, { method: 'DELETE' });
194
+ return result.ok;
195
+ }
196
+ /**
197
+ * Resize a terminal
198
+ */
199
+ async resizeTerminal(terminalId, cols, rows) {
200
+ const result = await this.request(`/api/terminals/${terminalId}/resize`, {
201
+ method: 'POST',
202
+ body: JSON.stringify({ cols, rows }),
203
+ });
204
+ return result.ok ? result.data : null;
205
+ }
206
+ /**
207
+ * Get the tower dashboard URL for a project
208
+ */
209
+ getProjectUrl(projectPath) {
210
+ const encoded = encodeProjectPath(projectPath);
211
+ return `${this.baseUrl}/project/${encoded}/`;
212
+ }
213
+ /**
214
+ * Get the WebSocket URL for a terminal
215
+ */
216
+ getTerminalWsUrl(terminalId) {
217
+ return `ws://localhost:${new URL(this.baseUrl).port}/ws/terminal/${terminalId}`;
218
+ }
219
+ }
220
+ /**
221
+ * Default tower client instance
222
+ */
223
+ let defaultClient = null;
224
+ /**
225
+ * Get the default tower client
226
+ */
227
+ export function getTowerClient(port) {
228
+ if (!defaultClient || (port && port !== DEFAULT_TOWER_PORT)) {
229
+ defaultClient = new TowerClient(port);
230
+ }
231
+ return defaultClient;
232
+ }
233
+ //# sourceMappingURL=tower-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-client.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/tower-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * HTTP/2 Role-Reversal Tunnel Client (Spec 0097 Phase 3, TICK-001)
3
+ *
4
+ * Opens a WebSocket connection to codevos.ai/tunnel, authenticates
5
+ * with JSON messages, then runs an HTTP/2 *server* over the WebSocket
6
+ * stream. codevos.ai acts as the HTTP/2 *client*, sending requests
7
+ * through the tunnel. The tower proxies those requests to localhost.
8
+ *
9
+ * TICK-001: Transport changed from raw TCP/TLS to WebSocket.
10
+ * The H2 role-reversal is transport-agnostic — it works over any duplex stream.
11
+ */
12
+ export interface TunnelClientOptions {
13
+ serverUrl: string;
14
+ apiKey: string;
15
+ towerId: string;
16
+ localPort: number;
17
+ /** @deprecated Use serverUrl protocol (ws:// vs wss://) instead */
18
+ tunnelPort?: number;
19
+ /** @deprecated No longer needed — WebSocket handles TLS via wss:// */
20
+ usePlainTcp?: boolean;
21
+ }
22
+ export type TunnelState = 'disconnected' | 'connecting' | 'connected' | 'auth_failed';
23
+ export interface TowerMetadata {
24
+ projects: Array<{
25
+ path: string;
26
+ name: string;
27
+ }>;
28
+ terminals: Array<{
29
+ id: string;
30
+ projectPath: string;
31
+ }>;
32
+ }
33
+ type StateChangeCallback = (state: TunnelState, previousState: TunnelState) => void;
34
+ /**
35
+ * Calculate reconnection backoff with exponential increase and jitter.
36
+ * Exported for unit testing.
37
+ *
38
+ * Formula: min(1000 * 2^attempt + random(0, 1000), 60000)
39
+ * After 10 consecutive failures: 300000ms (5 min)
40
+ */
41
+ export declare function calculateBackoff(attempt: number, randomFn?: () => number): number;
42
+ /**
43
+ * Check if a request path should be blocked from tunnel proxying.
44
+ * Normalizes percent-encoding and collapses dot segments before checking,
45
+ * preventing bypass via encoded slashes (%2F), double dots, etc.
46
+ * Exported for unit testing.
47
+ */
48
+ export declare function isBlockedPath(path: string): boolean;
49
+ /**
50
+ * Filter hop-by-hop headers from a headers object.
51
+ * Returns a new object with only end-to-end headers.
52
+ * Exported for unit testing.
53
+ */
54
+ export declare function filterHopByHopHeaders(headers: Record<string, string | string[] | undefined>): Record<string, string | string[]>;
55
+ export declare class TunnelClient {
56
+ private options;
57
+ private state;
58
+ private connectedAt;
59
+ private stateListeners;
60
+ private ws;
61
+ private wsStream;
62
+ private h2Server;
63
+ private h2Session;
64
+ private reconnectTimer;
65
+ private consecutiveFailures;
66
+ private rateLimitCount;
67
+ private destroyed;
68
+ constructor(options: TunnelClientOptions);
69
+ getState(): TunnelState;
70
+ getUptime(): number | null;
71
+ onStateChange(callback: StateChangeCallback): void;
72
+ private setState;
73
+ /**
74
+ * Initiate tunnel connection. Non-blocking — connection happens asynchronously.
75
+ */
76
+ connect(): void;
77
+ /**
78
+ * Gracefully disconnect the tunnel.
79
+ */
80
+ disconnect(): void;
81
+ /**
82
+ * Reset the circuit breaker (e.g. after config change).
83
+ * Allows reconnection after auth_failed state.
84
+ */
85
+ resetCircuitBreaker(): void;
86
+ /**
87
+ * Send tower metadata to codevos.ai.
88
+ *
89
+ * Uses a dual mechanism:
90
+ * 1. Caches metadata for `GET /__tower/metadata` (served when codevos.ai H2 client polls)
91
+ * 2. When connected, proactively POSTs to `serverUrl/api/tower/metadata` via HTTPS
92
+ *
93
+ * Call before `connect()` to set initial metadata, or after to update it.
94
+ */
95
+ sendMetadata(metadata: TowerMetadata): void;
96
+ /** Stored metadata for serving via GET /__tower/metadata */
97
+ private _pendingMetadata;
98
+ /**
99
+ * Push metadata to codevos.ai via outbound HTTPS POST.
100
+ * Best-effort — failures are silently ignored since codevos.ai
101
+ * can also poll via the H2 tunnel's GET /__tower/metadata handler.
102
+ */
103
+ private pushMetadataViaHttp;
104
+ private clearReconnectTimer;
105
+ private scheduleReconnect;
106
+ private cleanup;
107
+ private doConnect;
108
+ private onWsOpen;
109
+ private handleAuthError;
110
+ private handleConnectionError;
111
+ private startH2Server;
112
+ private handleH2Stream;
113
+ private handleWebSocketConnect;
114
+ private proxyHttpRequest;
115
+ }
116
+ export {};
117
+ //# sourceMappingURL=tunnel-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-client.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/tunnel-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,aAAa,CAAC;AAEtF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED,KAAK,mBAAmB,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,KAAK,IAAI,CAAC;AAiBpF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,MAAoB,GAAG,MAAM,CAK9F;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAQnC;AAYD,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,mBAAmB;IAIxC,QAAQ,IAAI,WAAW;IAIvB,SAAS,IAAI,MAAM,GAAG,IAAI;IAK1B,aAAa,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIlD,OAAO,CAAC,QAAQ;IAwBhB;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;;OAGG;IACH,mBAAmB,IAAI,IAAI;IAS3B;;;;;;;;OAQG;IACH,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAQ3C,4DAA4D;IAC5D,OAAO,CAAC,gBAAgB,CAA8B;IAEtD;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,OAAO;IAsBf,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,QAAQ;IA2BhB,OAAO,CAAC,eAAe;IA6BvB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,sBAAsB;IAqE9B,OAAO,CAAC,gBAAgB;CA0DzB"}