@aoagents/ao-web 0.2.3 → 0.2.5

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 (265) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +228 -221
  3. package/.next/app-path-routes-manifest.json +7 -6
  4. package/.next/build-manifest.json +14 -14
  5. package/.next/next-minimal-server.js.nft.json +1 -1
  6. package/.next/next-server.js.nft.json +1 -1
  7. package/.next/prerender-manifest.json +31 -31
  8. package/.next/react-loadable-manifest.json +14 -14
  9. package/.next/required-server-files.json +7 -4
  10. package/.next/server/app/_not-found/page.js +2 -2
  11. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  12. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_not-found.html +1 -1
  14. package/.next/server/app/_not-found.rsc +15 -15
  15. package/.next/server/app/api/backlog/route.js +1 -1
  16. package/.next/server/app/api/backlog/route.js.nft.json +1 -1
  17. package/.next/server/app/api/backlog/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/events/route.js +2 -2
  19. package/.next/server/app/api/events/route.js.nft.json +1 -1
  20. package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/issues/route.js +1 -1
  22. package/.next/server/app/api/issues/route.js.nft.json +1 -1
  23. package/.next/server/app/api/issues/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/observability/route.js +1 -1
  25. package/.next/server/app/api/observability/route.js.nft.json +1 -1
  26. package/.next/server/app/api/observability/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/orchestrators/route.js +1 -1
  28. package/.next/server/app/api/orchestrators/route.js.nft.json +1 -1
  29. package/.next/server/app/api/orchestrators/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/projects/route.js +1 -1
  31. package/.next/server/app/api/projects/route.js.nft.json +1 -1
  32. package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/prs/[id]/merge/route.js +1 -1
  34. package/.next/server/app/api/prs/[id]/merge/route.js.nft.json +1 -1
  35. package/.next/server/app/api/prs/[id]/merge/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/runtime/terminal/route.js +1 -1
  37. package/.next/server/app/api/runtime/terminal/route.js.nft.json +1 -1
  38. package/.next/server/app/api/runtime/terminal/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/sessions/[id]/kill/route.js +1 -1
  40. package/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -1
  41. package/.next/server/app/api/sessions/[id]/kill/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/sessions/[id]/message/route.js +1 -1
  43. package/.next/server/app/api/sessions/[id]/message/route.js.nft.json +1 -1
  44. package/.next/server/app/api/sessions/[id]/message/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/sessions/[id]/remap/route.js +1 -1
  46. package/.next/server/app/api/sessions/[id]/remap/route.js.nft.json +1 -1
  47. package/.next/server/app/api/sessions/[id]/remap/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/sessions/[id]/restore/route.js +1 -1
  49. package/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -1
  50. package/.next/server/app/api/sessions/[id]/restore/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  52. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  53. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/sessions/[id]/send/route.js +1 -1
  55. package/.next/server/app/api/sessions/[id]/send/route.js.nft.json +1 -1
  56. package/.next/server/app/api/sessions/[id]/send/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/sessions/patches/route.js +1 -0
  58. package/.next/server/app/api/sessions/patches/route.js.nft.json +1 -0
  59. package/.next/server/app/api/sessions/patches/route_client-reference-manifest.js +1 -0
  60. package/.next/server/app/api/sessions/route.js +1 -1
  61. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  62. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/setup-labels/route.js +1 -1
  64. package/.next/server/app/api/setup-labels/route.js.nft.json +1 -1
  65. package/.next/server/app/api/setup-labels/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/spawn/route.js +1 -1
  67. package/.next/server/app/api/spawn/route.js.nft.json +1 -1
  68. package/.next/server/app/api/spawn/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/verify/route.js +1 -1
  70. package/.next/server/app/api/verify/route.js.nft.json +1 -1
  71. package/.next/server/app/api/verify/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/webhooks/[...slug]/route.js +1 -1
  73. package/.next/server/app/api/webhooks/[...slug]/route.js.nft.json +1 -1
  74. package/.next/server/app/api/webhooks/[...slug]/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/apple-icon/route.js +1 -1
  76. package/.next/server/app/apple-icon/route.js.nft.json +1 -1
  77. package/.next/server/app/apple-icon/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/dev/terminal-test/page.js +3 -3
  79. package/.next/server/app/dev/terminal-test/page.js.nft.json +1 -1
  80. package/.next/server/app/dev/terminal-test/page_client-reference-manifest.js +1 -1
  81. package/.next/server/app/dev/terminal-test.html +1 -1
  82. package/.next/server/app/dev/terminal-test.rsc +17 -17
  83. package/.next/server/app/icon/route.js +1 -1
  84. package/.next/server/app/icon/route.js.nft.json +1 -1
  85. package/.next/server/app/icon/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/icon-192/route.js +1 -1
  87. package/.next/server/app/icon-192/route.js.nft.json +1 -1
  88. package/.next/server/app/icon-192/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/icon-512/route.js +1 -1
  90. package/.next/server/app/icon-512/route.js.nft.json +1 -1
  91. package/.next/server/app/icon-512/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/manifest.webmanifest/route.js +2 -2
  93. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  94. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/manifest.webmanifest.body +1 -1
  96. package/.next/server/app/orchestrators/page.js +2 -2
  97. package/.next/server/app/orchestrators/page.js.nft.json +1 -1
  98. package/.next/server/app/orchestrators/page_client-reference-manifest.js +1 -1
  99. package/.next/server/app/page.js +2 -2
  100. package/.next/server/app/page.js.nft.json +1 -1
  101. package/.next/server/app/page_client-reference-manifest.js +1 -1
  102. package/.next/server/app/prs/page.js +2 -2
  103. package/.next/server/app/prs/page.js.nft.json +1 -1
  104. package/.next/server/app/prs/page_client-reference-manifest.js +1 -1
  105. package/.next/server/app/sessions/[id]/page.js +5 -5
  106. package/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  107. package/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  108. package/.next/server/app/test-direct/page.js +2 -2
  109. package/.next/server/app/test-direct/page.js.nft.json +1 -1
  110. package/.next/server/app/test-direct/page_client-reference-manifest.js +1 -1
  111. package/.next/server/app/test-direct.html +1 -1
  112. package/.next/server/app/test-direct.rsc +17 -17
  113. package/.next/server/app-paths-manifest.json +7 -6
  114. package/.next/server/chunks/100.js +1 -0
  115. package/.next/server/chunks/106.js +1 -0
  116. package/.next/server/chunks/172.js +9 -0
  117. package/.next/server/chunks/180.js +25 -0
  118. package/.next/server/chunks/333.js +1 -0
  119. package/.next/server/chunks/367.js +3 -0
  120. package/.next/server/chunks/561.js +22 -0
  121. package/.next/server/chunks/627.js +380 -363
  122. package/.next/server/chunks/803.js +6 -0
  123. package/.next/server/chunks/886.js +384 -0
  124. package/.next/server/chunks/907.js +1 -0
  125. package/.next/server/middleware-build-manifest.js +1 -1
  126. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  127. package/.next/server/next-font-manifest.js +1 -1
  128. package/.next/server/next-font-manifest.json +1 -1
  129. package/.next/server/pages/404.html +1 -1
  130. package/.next/server/pages/500.html +1 -1
  131. package/.next/server/pages/_app.js +1 -1
  132. package/.next/server/pages/_app.js.nft.json +1 -1
  133. package/.next/server/pages/_document.js +1 -1
  134. package/.next/server/pages/_document.js.nft.json +1 -1
  135. package/.next/server/pages/_error.js +3 -3
  136. package/.next/server/pages/_error.js.nft.json +1 -1
  137. package/.next/server/server-reference-manifest.json +1 -1
  138. package/.next/static/OyzSw2fQpoJHXyoBWoZ2X/_buildManifest.js +1 -0
  139. package/.next/static/chunks/1461-af7c54935f21d56d.js +1 -0
  140. package/.next/static/chunks/{9393.acf1934a190d793b.js → 2529.32352c1ce5253e3e.js} +1 -1
  141. package/.next/static/chunks/{7411.ecda44797fb514a0.js → 5491.fd98884d48631149.js} +1 -1
  142. package/.next/static/chunks/6923-ef8434dfec6f2a3c.js +1 -0
  143. package/.next/static/chunks/7097.fc904e5f313c4994.js +1 -0
  144. package/.next/static/chunks/7317.685aa5231218e8d3.js +1 -0
  145. package/.next/static/chunks/8713-d3d663f55dc00e48.js +1 -0
  146. package/.next/static/chunks/8785-6b4b3ff260617997.js +1 -0
  147. package/.next/static/chunks/88a6fc35-f836b4b72df5eafa.js +1 -0
  148. package/.next/static/chunks/9478.656c9c263bc55893.js +1 -0
  149. package/.next/static/chunks/app/_not-found/page-019391920005654f.js +1 -0
  150. package/.next/static/chunks/app/api/backlog/route-019391920005654f.js +1 -0
  151. package/.next/static/chunks/app/api/events/route-019391920005654f.js +1 -0
  152. package/.next/static/chunks/app/api/issues/route-019391920005654f.js +1 -0
  153. package/.next/static/chunks/app/api/observability/route-019391920005654f.js +1 -0
  154. package/.next/static/chunks/app/api/orchestrators/route-019391920005654f.js +1 -0
  155. package/.next/static/chunks/app/api/projects/route-019391920005654f.js +1 -0
  156. package/.next/static/chunks/app/api/prs/[id]/merge/route-019391920005654f.js +1 -0
  157. package/.next/static/chunks/app/api/runtime/terminal/route-019391920005654f.js +1 -0
  158. package/.next/static/chunks/app/api/sessions/[id]/kill/route-019391920005654f.js +1 -0
  159. package/.next/static/chunks/app/api/sessions/[id]/message/route-019391920005654f.js +1 -0
  160. package/.next/static/chunks/app/api/sessions/[id]/remap/route-019391920005654f.js +1 -0
  161. package/.next/static/chunks/app/api/sessions/[id]/restore/route-019391920005654f.js +1 -0
  162. package/.next/static/chunks/app/api/sessions/[id]/route-019391920005654f.js +1 -0
  163. package/.next/static/chunks/app/api/sessions/[id]/send/route-019391920005654f.js +1 -0
  164. package/.next/static/chunks/app/api/sessions/patches/route-019391920005654f.js +1 -0
  165. package/.next/static/chunks/app/api/sessions/route-019391920005654f.js +1 -0
  166. package/.next/static/chunks/app/api/setup-labels/route-019391920005654f.js +1 -0
  167. package/.next/static/chunks/app/api/spawn/route-019391920005654f.js +1 -0
  168. package/.next/static/chunks/app/api/verify/route-019391920005654f.js +1 -0
  169. package/.next/static/chunks/app/api/webhooks/[...slug]/route-019391920005654f.js +1 -0
  170. package/.next/static/chunks/app/apple-icon/route-019391920005654f.js +1 -0
  171. package/.next/static/chunks/app/dev/terminal-test/page-4912fa9e6459f124.js +1 -0
  172. package/.next/static/chunks/app/error-670f1d8bf2b6859c.js +1 -0
  173. package/.next/static/chunks/app/{global-error-7b5c8ae45329c659.js → global-error-ca06d2b1be2d4ae0.js} +1 -1
  174. package/.next/static/chunks/app/icon/route-019391920005654f.js +1 -0
  175. package/.next/static/chunks/app/icon-192/route-019391920005654f.js +1 -0
  176. package/.next/static/chunks/app/icon-512/route-019391920005654f.js +1 -0
  177. package/.next/static/chunks/app/layout-ddf79478d9a673bb.js +1 -0
  178. package/.next/static/chunks/app/loading-019391920005654f.js +1 -0
  179. package/.next/static/chunks/app/manifest.webmanifest/route-019391920005654f.js +1 -0
  180. package/.next/static/chunks/app/{not-found-3772c2e09c29d80f.js → not-found-824d5d3c6e296eeb.js} +1 -1
  181. package/.next/static/chunks/app/orchestrators/page-4da04720a09483d2.js +1 -0
  182. package/.next/static/chunks/app/page-abf3e3c98cac072f.js +1 -0
  183. package/.next/static/chunks/app/prs/page-46455c406183ffbf.js +1 -0
  184. package/.next/static/chunks/app/sessions/[id]/error-eb0973907da68a37.js +1 -0
  185. package/.next/static/chunks/app/sessions/[id]/loading-019391920005654f.js +1 -0
  186. package/.next/static/chunks/app/sessions/[id]/{not-found-3772c2e09c29d80f.js → not-found-824d5d3c6e296eeb.js} +1 -1
  187. package/.next/static/chunks/app/sessions/[id]/page-7eb67fd32f39b15f.js +1 -0
  188. package/.next/static/chunks/app/test-direct/page-1fd63edb9a9ca8be.js +1 -0
  189. package/.next/static/chunks/{df4ed4d4.6a752eba3933e9a8.js → df4ed4d4.b6997d8b8ce9d79b.js} +1 -1
  190. package/.next/static/chunks/framework-7060e2ac4971c604.js +1 -0
  191. package/.next/static/chunks/main-app-690acf9d5d2050c9.js +1 -0
  192. package/.next/static/chunks/main-ed1610689fbd6f0d.js +1 -0
  193. package/.next/static/chunks/pages/_app-f4baf4dbe88f6f54.js +1 -0
  194. package/.next/static/chunks/pages/_error-a7f6723f42093f29.js +1 -0
  195. package/.next/static/chunks/{webpack-e12ceebeb7a1cc7e.js → webpack-ab6c08c78ffc8113.js} +1 -1
  196. package/.next/static/css/a5398483e6b75ad3.css +1 -0
  197. package/LICENSE +21 -0
  198. package/dist-server/direct-terminal-ws.js +33 -236
  199. package/dist-server/mux-websocket.js +516 -0
  200. package/dist-server/start-all.js +0 -2
  201. package/next.config.js +1 -0
  202. package/package.json +27 -27
  203. package/.next/server/chunks/27.js +0 -438
  204. package/.next/server/chunks/377.js +0 -1
  205. package/.next/server/chunks/393.js +0 -1
  206. package/.next/server/chunks/639.js +0 -6
  207. package/.next/server/chunks/693.js +0 -1
  208. package/.next/server/chunks/705.js +0 -22
  209. package/.next/server/chunks/787.js +0 -29
  210. package/.next/server/chunks/796.js +0 -1
  211. package/.next/server/chunks/934.js +0 -1
  212. package/.next/server/chunks/956.js +0 -9
  213. package/.next/static/chunks/1250-e7cf6b069fbb03ed.js +0 -1
  214. package/.next/static/chunks/2205.498806f73783aa54.js +0 -1
  215. package/.next/static/chunks/3698-9c12c45b8184022c.js +0 -1
  216. package/.next/static/chunks/6381.1541d5695a727108.js +0 -1
  217. package/.next/static/chunks/7505-2d2422d31862995f.js +0 -1
  218. package/.next/static/chunks/8597-1385f90ec1cebf47.js +0 -1
  219. package/.next/static/chunks/8762.f3d526855363db16.js +0 -1
  220. package/.next/static/chunks/a51c26f2-a21e680a5df6764e.js +0 -1
  221. package/.next/static/chunks/app/_not-found/page-2224bc1d3dce1b3e.js +0 -1
  222. package/.next/static/chunks/app/api/backlog/route-2224bc1d3dce1b3e.js +0 -1
  223. package/.next/static/chunks/app/api/events/route-2224bc1d3dce1b3e.js +0 -1
  224. package/.next/static/chunks/app/api/issues/route-2224bc1d3dce1b3e.js +0 -1
  225. package/.next/static/chunks/app/api/observability/route-2224bc1d3dce1b3e.js +0 -1
  226. package/.next/static/chunks/app/api/orchestrators/route-2224bc1d3dce1b3e.js +0 -1
  227. package/.next/static/chunks/app/api/projects/route-2224bc1d3dce1b3e.js +0 -1
  228. package/.next/static/chunks/app/api/prs/[id]/merge/route-2224bc1d3dce1b3e.js +0 -1
  229. package/.next/static/chunks/app/api/runtime/terminal/route-2224bc1d3dce1b3e.js +0 -1
  230. package/.next/static/chunks/app/api/sessions/[id]/kill/route-2224bc1d3dce1b3e.js +0 -1
  231. package/.next/static/chunks/app/api/sessions/[id]/message/route-2224bc1d3dce1b3e.js +0 -1
  232. package/.next/static/chunks/app/api/sessions/[id]/remap/route-2224bc1d3dce1b3e.js +0 -1
  233. package/.next/static/chunks/app/api/sessions/[id]/restore/route-2224bc1d3dce1b3e.js +0 -1
  234. package/.next/static/chunks/app/api/sessions/[id]/route-2224bc1d3dce1b3e.js +0 -1
  235. package/.next/static/chunks/app/api/sessions/[id]/send/route-2224bc1d3dce1b3e.js +0 -1
  236. package/.next/static/chunks/app/api/sessions/route-2224bc1d3dce1b3e.js +0 -1
  237. package/.next/static/chunks/app/api/setup-labels/route-2224bc1d3dce1b3e.js +0 -1
  238. package/.next/static/chunks/app/api/spawn/route-2224bc1d3dce1b3e.js +0 -1
  239. package/.next/static/chunks/app/api/verify/route-2224bc1d3dce1b3e.js +0 -1
  240. package/.next/static/chunks/app/api/webhooks/[...slug]/route-2224bc1d3dce1b3e.js +0 -1
  241. package/.next/static/chunks/app/apple-icon/route-2224bc1d3dce1b3e.js +0 -1
  242. package/.next/static/chunks/app/dev/terminal-test/page-ac0ce5b046fcad82.js +0 -1
  243. package/.next/static/chunks/app/error-4896c9d3b7681a80.js +0 -1
  244. package/.next/static/chunks/app/icon/route-2224bc1d3dce1b3e.js +0 -1
  245. package/.next/static/chunks/app/icon-192/route-2224bc1d3dce1b3e.js +0 -1
  246. package/.next/static/chunks/app/icon-512/route-2224bc1d3dce1b3e.js +0 -1
  247. package/.next/static/chunks/app/layout-023f2083204e4f68.js +0 -1
  248. package/.next/static/chunks/app/loading-2224bc1d3dce1b3e.js +0 -1
  249. package/.next/static/chunks/app/manifest.webmanifest/route-2224bc1d3dce1b3e.js +0 -1
  250. package/.next/static/chunks/app/orchestrators/page-df85236df674fc5a.js +0 -1
  251. package/.next/static/chunks/app/page-e97da633b7ef25f2.js +0 -1
  252. package/.next/static/chunks/app/prs/page-8cc0fce584d238c5.js +0 -1
  253. package/.next/static/chunks/app/sessions/[id]/error-90bc99b777fecabf.js +0 -1
  254. package/.next/static/chunks/app/sessions/[id]/loading-2224bc1d3dce1b3e.js +0 -1
  255. package/.next/static/chunks/app/sessions/[id]/page-c9c95a8604786cff.js +0 -1
  256. package/.next/static/chunks/app/test-direct/page-16ceeb9f7664394a.js +0 -1
  257. package/.next/static/chunks/framework-f8b8ba0f71d38056.js +0 -1
  258. package/.next/static/chunks/main-2bc85c765bf1fc49.js +0 -1
  259. package/.next/static/chunks/main-app-93fb36c3bd1a6739.js +0 -1
  260. package/.next/static/chunks/pages/_app-a0b975794f15bd68.js +0 -1
  261. package/.next/static/chunks/pages/_error-5f4e3b5eea57917d.js +0 -1
  262. package/.next/static/css/908f93fdd7ffba42.css +0 -1
  263. package/.next/static/oB_TdR1wCu7ot1D0AG_cw/_buildManifest.js +0 -1
  264. package/dist-server/terminal-websocket.js +0 -375
  265. /package/.next/static/{oB_TdR1wCu7ot1D0AG_cw → OyzSw2fQpoJHXyoBWoZ2X}/_ssgManifest.js +0 -0
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:22,errorRate:1e-4,numBits:422,numHashes:14,bitArray:[1,0,1,e,e,0,r,r,e,r,e,e,r,r,r,r,r,e,r,e,r,e,e,e,e,e,r,e,r,r,e,r,r,r,e,e,r,r,r,e,e,r,r,r,r,r,r,e,e,e,r,r,r,e,r,r,r,e,e,e,e,e,r,e,r,e,e,e,e,e,e,r,r,e,e,e,r,e,r,e,e,r,r,e,r,e,r,r,r,r,r,e,e,r,e,e,r,e,r,e,r,e,r,r,e,r,e,e,r,e,e,r,r,r,r,e,e,r,e,e,e,e,r,e,e,e,e,e,e,e,e,e,e,e,e,r,r,r,r,r,r,e,e,e,r,r,r,r,r,r,e,e,e,r,r,r,e,e,e,e,e,r,e,r,e,e,e,r,e,e,r,e,e,e,r,r,r,e,r,e,r,e,e,r,e,e,e,r,r,r,e,e,r,e,e,r,r,r,r,e,r,r,e,r,e,e,e,r,e,e,e,r,e,e,e,r,r,e,e,e,r,e,r,e,r,r,r,r,r,e,r,r,e,r,e,r,r,e,e,r,r,r,r,r,e,e,r,e,e,r,e,e,e,r,r,r,e,r,e,r,e,e,r,r,r,r,e,e,e,e,r,r,r,e,e,e,r,r,e,e,r,r,r,r,e,r,r,e,e,r,r,e,e,r,r,r,e,r,e,r,r,e,r,r,r,r,e,e,e,r,r,e,r,r,e,r,e,e,r,r,e,r,r,r,e,e,r,r,r,e,e,e,e,e,r,r,r,e,e,e,r,e,r,r,r,r,r,r,e,e,e,r,e,r,r,r,r,r,r,r,e,e,e,r,e,e,e,e,e,e,r,e,e,e,e,e,r,e,e,e,r,e,e,r,r,r,e,e,e,r,r,e,r,e,r,r,e,r,r,e,r,e,e,r,e,r,e,e,e,e,e,r,e,e,r,e,r,e,r,e,e,e]},__routerFilterDynamic:{numItems:4,errorRate:1e-4,numBits:77,numHashes:14,bitArray:[r,r,e,r,r,e,r,e,e,r,e,r,e,e,r,e,e,e,r,e,r,e,e,e,r,e,r,r,e,r,e,e,e,e,e,e,e,r,r,r,e,e,e,e,e,e,e,e,e,e,e,r,r,r,r,r,e,e,e,e,r,r,r,r,e,e,r,e,e,r,e,e,r,r,r,r,e]},"/_error":["static/chunks/pages/_error-5f4e3b5eea57917d.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -1,375 +0,0 @@
1
- /**
2
- * Terminal server that manages ttyd instances for tmux sessions.
3
- *
4
- * Runs alongside Next.js. Spawns a ttyd process per session on demand,
5
- * each on a unique port. The dashboard embeds ttyd via iframe.
6
- *
7
- * ttyd handles all the hard parts: xterm.js, WebSocket, ANSI rendering,
8
- * cursor positioning, resize, input — battle-tested and correct.
9
- *
10
- * TODO: Add authentication middleware to verify:
11
- * - User is authenticated
12
- * - User owns the requested session
13
- * - Rate limiting for terminal access
14
- */
15
- import { spawn } from "node:child_process";
16
- import { createServer, request } from "node:http";
17
- import { createCorrelationId } from "@aoagents/ao-core";
18
- import { findTmux, resolveTmuxSession, validateSessionId } from "./tmux-utils.js";
19
- import { createObserverContext, inferProjectId } from "./terminal-observability.js";
20
- /** Cached full path to tmux binary */
21
- const TMUX = findTmux();
22
- console.log(`[Terminal] Using tmux: ${TMUX}`);
23
- const instances = new Map();
24
- const metrics = {
25
- activeInstances: 0,
26
- totalSpawns: 0,
27
- totalErrors: 0,
28
- totalReused: 0,
29
- };
30
- const availablePorts = new Set(); // Pool of recycled ports
31
- let nextPort = 7800; // Start ttyd instances from port 7800
32
- const MAX_PORT = 7900; // Prevent unbounded port allocation
33
- const { config: observabilityConfig, observer } = createObserverContext("terminal-websocket");
34
- function recordWebsocketMetric(input) {
35
- if (!observer) {
36
- return;
37
- }
38
- const correlationId = createCorrelationId("ws");
39
- observer.recordOperation({
40
- metric: input.metric,
41
- operation: `terminal.websocket.${input.metric}`,
42
- outcome: input.outcome,
43
- correlationId,
44
- projectId: input.sessionId ? inferProjectId(observabilityConfig, input.sessionId) : undefined,
45
- sessionId: input.sessionId,
46
- reason: input.reason,
47
- data: input.data,
48
- level: input.outcome === "failure" ? "error" : "info",
49
- });
50
- }
51
- /**
52
- * Check if ttyd is ready to accept connections by making a test request.
53
- * Returns a promise that resolves when ttyd is ready or rejects after timeout.
54
- * Properly cancels pending timeouts and requests to prevent memory leaks.
55
- */
56
- function waitForTtyd(port, sessionId, timeoutMs = 3000) {
57
- const startTime = Date.now();
58
- let timeoutId = null;
59
- let pendingReq = null;
60
- let settled = false;
61
- return new Promise((resolve, reject) => {
62
- const cleanup = () => {
63
- settled = true;
64
- if (timeoutId) {
65
- clearTimeout(timeoutId);
66
- timeoutId = null;
67
- }
68
- if (pendingReq) {
69
- pendingReq.destroy();
70
- pendingReq = null;
71
- }
72
- };
73
- const checkReady = () => {
74
- if (settled)
75
- return;
76
- if (Date.now() - startTime > timeoutMs) {
77
- cleanup();
78
- reject(new Error(`ttyd did not become ready within ${timeoutMs}ms`));
79
- return;
80
- }
81
- const req = request({
82
- hostname: "localhost",
83
- port,
84
- path: `/${sessionId}/`,
85
- method: "GET",
86
- timeout: 500,
87
- }, (_res) => {
88
- // Any response (even 404) means ttyd is listening
89
- cleanup();
90
- resolve();
91
- });
92
- pendingReq = req;
93
- req.on("timeout", () => {
94
- if (settled)
95
- return;
96
- req.destroy();
97
- pendingReq = null;
98
- // Schedule retry but track the timeout ID
99
- timeoutId = setTimeout(checkReady, 100);
100
- });
101
- req.on("error", () => {
102
- if (settled)
103
- return;
104
- pendingReq = null;
105
- // Connection refused or other error - ttyd not ready yet, retry
106
- timeoutId = setTimeout(checkReady, 100);
107
- });
108
- req.end();
109
- };
110
- checkReady();
111
- });
112
- }
113
- /**
114
- * Spawn or reuse a ttyd instance for a tmux session.
115
- *
116
- * @param sessionId - User-facing session ID (used for base-path and URL)
117
- * @param tmuxSessionName - Actual tmux session name (may be hash-prefixed)
118
- */
119
- function getOrSpawnTtyd(sessionId, tmuxSessionName) {
120
- const existing = instances.get(sessionId);
121
- if (existing) {
122
- metrics.totalReused += 1;
123
- recordWebsocketMetric({
124
- metric: "websocket_connect",
125
- outcome: "success",
126
- sessionId,
127
- data: { reused: true, port: existing.port },
128
- });
129
- return existing;
130
- }
131
- // Allocate port: reuse from pool if available, otherwise increment
132
- let port;
133
- if (availablePorts.size > 0) {
134
- // Reuse a recycled port
135
- port = availablePorts.values().next().value;
136
- availablePorts.delete(port);
137
- }
138
- else {
139
- // Allocate new port
140
- if (nextPort >= MAX_PORT) {
141
- throw new Error(`Port exhaustion: reached maximum of ${MAX_PORT - 7800} terminal instances`);
142
- }
143
- port = nextPort++;
144
- }
145
- console.log(`[Terminal] Spawning ttyd for ${tmuxSessionName} on port ${port}`);
146
- metrics.totalSpawns += 1;
147
- metrics.lastSpawnAt = new Date().toISOString();
148
- // Enable mouse mode for scrollback support
149
- const mouseProc = spawn(TMUX, ["set-option", "-t", tmuxSessionName, "mouse", "on"]);
150
- mouseProc.on("error", (err) => {
151
- console.error(`[Terminal] Failed to set mouse mode for ${tmuxSessionName}:`, err.message);
152
- });
153
- // Hide the green status bar for cleaner appearance
154
- const statusProc = spawn(TMUX, ["set-option", "-t", tmuxSessionName, "status", "off"]);
155
- statusProc.on("error", (err) => {
156
- console.error(`[Terminal] Failed to hide status bar for ${tmuxSessionName}:`, err.message);
157
- });
158
- // Use user-facing sessionId for base-path (matches URL the dashboard uses)
159
- // Use tmuxSessionName for tmux attach (may be hash-prefixed)
160
- const proc = spawn("ttyd", [
161
- "--writable",
162
- "--port",
163
- String(port),
164
- "--base-path",
165
- `/${sessionId}`,
166
- TMUX,
167
- "attach-session",
168
- "-t",
169
- tmuxSessionName,
170
- ], {
171
- stdio: ["ignore", "pipe", "pipe"],
172
- });
173
- proc.stdout?.on("data", (data) => {
174
- console.log(`[Terminal] ttyd ${sessionId}: ${data.toString().trim()}`);
175
- });
176
- proc.stderr?.on("data", (data) => {
177
- console.log(`[Terminal] ttyd ${sessionId}: ${data.toString().trim()}`);
178
- });
179
- // Use once() for cleanup handlers to prevent race condition when both exit and error fire
180
- proc.once("exit", (code) => {
181
- console.log(`[Terminal] ttyd ${sessionId} exited with code ${code}`);
182
- // Only delete if this is still the current instance (prevents race with error handler)
183
- const current = instances.get(sessionId);
184
- if (current?.process === proc) {
185
- instances.delete(sessionId);
186
- metrics.activeInstances = instances.size;
187
- // Only recycle port on clean exit (code 0), not on errors
188
- // Failed ttyd processes may leave ports in TIME_WAIT state
189
- if (code === 0) {
190
- availablePorts.add(port);
191
- }
192
- }
193
- recordWebsocketMetric({
194
- metric: "websocket_disconnect",
195
- outcome: code === 0 ? "success" : "failure",
196
- sessionId,
197
- reason: `ttyd_exit:${code}`,
198
- data: { port },
199
- });
200
- });
201
- proc.once("error", (err) => {
202
- console.error(`[Terminal] ttyd ${sessionId} error:`, err.message);
203
- // Only delete if this is still the current instance (prevents race with exit handler)
204
- const current = instances.get(sessionId);
205
- if (current?.process === proc) {
206
- instances.delete(sessionId);
207
- metrics.activeInstances = instances.size;
208
- // Don't recycle port on error - may still be in use or TIME_WAIT
209
- }
210
- metrics.totalErrors += 1;
211
- metrics.lastErrorAt = new Date().toISOString();
212
- metrics.lastErrorReason = err.message;
213
- recordWebsocketMetric({
214
- metric: "websocket_error",
215
- outcome: "failure",
216
- sessionId,
217
- reason: err.message,
218
- data: { port },
219
- });
220
- // Kill any running process
221
- try {
222
- proc.kill();
223
- }
224
- catch {
225
- // Ignore kill errors if process already dead
226
- }
227
- });
228
- const instance = { sessionId, port, process: proc };
229
- instances.set(sessionId, instance);
230
- metrics.activeInstances = instances.size;
231
- recordWebsocketMetric({
232
- metric: "websocket_connect",
233
- outcome: "success",
234
- sessionId,
235
- data: { reused: false, port },
236
- });
237
- return instance;
238
- }
239
- // Simple HTTP API for the dashboard to request terminal URLs
240
- const server = createServer(async (req, res) => {
241
- const url = new URL(req.url ?? "/", "http://localhost");
242
- // CORS for dashboard - allow requests from the same host as the dashboard
243
- // TODO: Replace with proper session-based authentication
244
- const origin = req.headers.origin;
245
- if (origin && origin !== "null") {
246
- // Extract hostname from origin and compare with request host
247
- try {
248
- const originUrl = new URL(origin);
249
- const requestHost = req.headers.host;
250
- // Allow if origin hostname matches request host (supports remote deployments)
251
- if (requestHost && originUrl.hostname === requestHost.split(":")[0]) {
252
- res.setHeader("Access-Control-Allow-Origin", origin);
253
- }
254
- }
255
- catch {
256
- // Invalid origin URL, don't set CORS header
257
- }
258
- }
259
- else {
260
- // Allow null origin (file:// or local HTML files)
261
- res.setHeader("Access-Control-Allow-Origin", "*");
262
- }
263
- res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
264
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
265
- if (req.method === "OPTIONS") {
266
- res.writeHead(204);
267
- res.end();
268
- return;
269
- }
270
- // GET /terminal?session=ao-1 → returns { url, port }
271
- if (url.pathname === "/terminal") {
272
- const sessionId = url.searchParams.get("session");
273
- if (!sessionId) {
274
- res.writeHead(400, { "Content-Type": "application/json" });
275
- res.end(JSON.stringify({ error: "Missing session parameter" }));
276
- recordWebsocketMetric({
277
- metric: "websocket_error",
278
- outcome: "failure",
279
- reason: "Missing session parameter",
280
- });
281
- return;
282
- }
283
- // Validate session ID to prevent path traversal and injection
284
- if (!validateSessionId(sessionId)) {
285
- res.writeHead(400, { "Content-Type": "application/json" });
286
- res.end(JSON.stringify({ error: "Invalid session ID" }));
287
- recordWebsocketMetric({
288
- metric: "websocket_error",
289
- outcome: "failure",
290
- sessionId,
291
- reason: "Invalid session ID",
292
- });
293
- return;
294
- }
295
- // Resolve tmux session name: try exact match first, then suffix match
296
- // (hash-prefixed sessions like "8474d6f29887-ao-15" are accessed by user-facing ID "ao-15")
297
- const tmuxSessionId = resolveTmuxSession(sessionId, TMUX);
298
- if (!tmuxSessionId) {
299
- res.writeHead(404, { "Content-Type": "application/json" });
300
- res.end(JSON.stringify({ error: "Session not found" }));
301
- recordWebsocketMetric({
302
- metric: "websocket_error",
303
- outcome: "failure",
304
- sessionId,
305
- reason: "Session not found",
306
- });
307
- return;
308
- }
309
- // Spawn ttyd and wait for it to be ready (catch port exhaustion and startup failures)
310
- try {
311
- const instance = getOrSpawnTtyd(sessionId, tmuxSessionId);
312
- await waitForTtyd(instance.port, sessionId);
313
- // Use the request host to construct the terminal URL (supports remote access)
314
- const host = req.headers.host ?? "localhost";
315
- const protocol = req.headers["x-forwarded-proto"] ?? "http";
316
- res.writeHead(200, { "Content-Type": "application/json" });
317
- res.end(JSON.stringify({
318
- url: `${protocol}://${host.split(":")[0]}:${instance.port}/${sessionId}/`,
319
- port: instance.port,
320
- sessionId,
321
- }));
322
- }
323
- catch (err) {
324
- const errorMsg = err instanceof Error ? err.message : String(err);
325
- console.error(`[Terminal] Failed to start terminal for ${sessionId}:`, errorMsg);
326
- metrics.totalErrors += 1;
327
- metrics.lastErrorAt = new Date().toISOString();
328
- metrics.lastErrorReason = errorMsg;
329
- recordWebsocketMetric({
330
- metric: "websocket_error",
331
- outcome: "failure",
332
- sessionId,
333
- reason: errorMsg,
334
- });
335
- res.writeHead(503, { "Content-Type": "application/json" });
336
- res.end(JSON.stringify({ error: "Failed to start terminal" }));
337
- }
338
- return;
339
- }
340
- // GET /health
341
- if (url.pathname === "/health") {
342
- res.writeHead(200, { "Content-Type": "application/json" });
343
- res.end(JSON.stringify({
344
- instances: Object.fromEntries([...instances.entries()].map(([id, inst]) => [id, { port: inst.port }])),
345
- metrics,
346
- }));
347
- return;
348
- }
349
- res.writeHead(404);
350
- res.end("Not found");
351
- });
352
- const PORT = parseInt(process.env.TERMINAL_PORT ?? "14800", 10);
353
- server.listen(PORT, () => {
354
- console.log(`[Terminal] Server listening on port ${PORT}`);
355
- });
356
- // Graceful shutdown — kill all ttyd instances
357
- function shutdown(signal) {
358
- console.log(`[Terminal] Received ${signal}, shutting down...`);
359
- for (const [, instance] of instances) {
360
- instance.process.kill();
361
- }
362
- server.close(() => {
363
- console.log("[Terminal] Server closed");
364
- process.exit(0);
365
- });
366
- // Force exit after 5s if graceful shutdown hangs
367
- // Use unref() so this timer doesn't prevent process exit if server closes quickly
368
- const forceExitTimer = setTimeout(() => {
369
- console.error("[Terminal] Forced shutdown after timeout");
370
- process.exit(1);
371
- }, 5000);
372
- forceExitTimer.unref();
373
- }
374
- process.on("SIGINT", () => shutdown("SIGINT"));
375
- process.on("SIGTERM", () => shutdown("SIGTERM"));