@amodalai/amodal 0.1.2

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 (511) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +42 -0
  4. package/dist/src/auth/index.d.ts +13 -0
  5. package/dist/src/auth/index.d.ts.map +1 -0
  6. package/dist/src/auth/index.js +10 -0
  7. package/dist/src/auth/index.js.map +1 -0
  8. package/dist/src/auth/oauth2.d.ts +51 -0
  9. package/dist/src/auth/oauth2.d.ts.map +1 -0
  10. package/dist/src/auth/oauth2.js +196 -0
  11. package/dist/src/auth/oauth2.js.map +1 -0
  12. package/dist/src/auth/prompt.d.ts +21 -0
  13. package/dist/src/auth/prompt.d.ts.map +1 -0
  14. package/dist/src/auth/prompt.js +81 -0
  15. package/dist/src/auth/prompt.js.map +1 -0
  16. package/dist/src/auth/test-connection.d.ts +27 -0
  17. package/dist/src/auth/test-connection.d.ts.map +1 -0
  18. package/dist/src/auth/test-connection.js +153 -0
  19. package/dist/src/auth/test-connection.js.map +1 -0
  20. package/dist/src/auth/types.d.ts +32 -0
  21. package/dist/src/auth/types.d.ts.map +1 -0
  22. package/dist/src/auth/types.js +7 -0
  23. package/dist/src/auth/types.js.map +1 -0
  24. package/dist/src/commands/audit.d.ts +18 -0
  25. package/dist/src/commands/audit.d.ts.map +1 -0
  26. package/dist/src/commands/audit.js +86 -0
  27. package/dist/src/commands/audit.js.map +1 -0
  28. package/dist/src/commands/automations.d.ts +28 -0
  29. package/dist/src/commands/automations.d.ts.map +1 -0
  30. package/dist/src/commands/automations.js +179 -0
  31. package/dist/src/commands/automations.js.map +1 -0
  32. package/dist/src/commands/build-manifest-types.d.ts +33 -0
  33. package/dist/src/commands/build-manifest-types.d.ts.map +1 -0
  34. package/dist/src/commands/build-manifest-types.js +30 -0
  35. package/dist/src/commands/build-manifest-types.js.map +1 -0
  36. package/dist/src/commands/build-tools.d.ts +33 -0
  37. package/dist/src/commands/build-tools.d.ts.map +1 -0
  38. package/dist/src/commands/build-tools.js +237 -0
  39. package/dist/src/commands/build-tools.js.map +1 -0
  40. package/dist/src/commands/build.d.ts +23 -0
  41. package/dist/src/commands/build.d.ts.map +1 -0
  42. package/dist/src/commands/build.js +120 -0
  43. package/dist/src/commands/build.js.map +1 -0
  44. package/dist/src/commands/chat.d.ts +26 -0
  45. package/dist/src/commands/chat.d.ts.map +1 -0
  46. package/dist/src/commands/chat.js +123 -0
  47. package/dist/src/commands/chat.js.map +1 -0
  48. package/dist/src/commands/connect.d.ts +18 -0
  49. package/dist/src/commands/connect.d.ts.map +1 -0
  50. package/dist/src/commands/connect.js +198 -0
  51. package/dist/src/commands/connect.js.map +1 -0
  52. package/dist/src/commands/deploy.d.ts +20 -0
  53. package/dist/src/commands/deploy.d.ts.map +1 -0
  54. package/dist/src/commands/deploy.js +137 -0
  55. package/dist/src/commands/deploy.js.map +1 -0
  56. package/dist/src/commands/deployments.d.ts +17 -0
  57. package/dist/src/commands/deployments.d.ts.map +1 -0
  58. package/dist/src/commands/deployments.js +77 -0
  59. package/dist/src/commands/deployments.js.map +1 -0
  60. package/dist/src/commands/dev.d.ts +17 -0
  61. package/dist/src/commands/dev.d.ts.map +1 -0
  62. package/dist/src/commands/dev.js +109 -0
  63. package/dist/src/commands/dev.js.map +1 -0
  64. package/dist/src/commands/diff.d.ts +19 -0
  65. package/dist/src/commands/diff.d.ts.map +1 -0
  66. package/dist/src/commands/diff.js +120 -0
  67. package/dist/src/commands/diff.js.map +1 -0
  68. package/dist/src/commands/docker.d.ts +21 -0
  69. package/dist/src/commands/docker.d.ts.map +1 -0
  70. package/dist/src/commands/docker.js +215 -0
  71. package/dist/src/commands/docker.js.map +1 -0
  72. package/dist/src/commands/eval.d.ts +20 -0
  73. package/dist/src/commands/eval.d.ts.map +1 -0
  74. package/dist/src/commands/eval.js +236 -0
  75. package/dist/src/commands/eval.js.map +1 -0
  76. package/dist/src/commands/experiment.d.ts +21 -0
  77. package/dist/src/commands/experiment.d.ts.map +1 -0
  78. package/dist/src/commands/experiment.js +133 -0
  79. package/dist/src/commands/experiment.js.map +1 -0
  80. package/dist/src/commands/index.d.ts +10 -0
  81. package/dist/src/commands/index.d.ts.map +1 -0
  82. package/dist/src/commands/index.js +75 -0
  83. package/dist/src/commands/index.js.map +1 -0
  84. package/dist/src/commands/init.d.ts +17 -0
  85. package/dist/src/commands/init.d.ts.map +1 -0
  86. package/dist/src/commands/init.js +73 -0
  87. package/dist/src/commands/init.js.map +1 -0
  88. package/dist/src/commands/inspect.d.ts +22 -0
  89. package/dist/src/commands/inspect.d.ts.map +1 -0
  90. package/dist/src/commands/inspect.js +131 -0
  91. package/dist/src/commands/inspect.js.map +1 -0
  92. package/dist/src/commands/install-pkg.d.ts +29 -0
  93. package/dist/src/commands/install-pkg.d.ts.map +1 -0
  94. package/dist/src/commands/install-pkg.js +202 -0
  95. package/dist/src/commands/install-pkg.js.map +1 -0
  96. package/dist/src/commands/link.d.ts +32 -0
  97. package/dist/src/commands/link.d.ts.map +1 -0
  98. package/dist/src/commands/link.js +227 -0
  99. package/dist/src/commands/link.js.map +1 -0
  100. package/dist/src/commands/list.d.ts +19 -0
  101. package/dist/src/commands/list.d.ts.map +1 -0
  102. package/dist/src/commands/list.js +78 -0
  103. package/dist/src/commands/list.js.map +1 -0
  104. package/dist/src/commands/login.d.ts +31 -0
  105. package/dist/src/commands/login.d.ts.map +1 -0
  106. package/dist/src/commands/login.js +205 -0
  107. package/dist/src/commands/login.js.map +1 -0
  108. package/dist/src/commands/promote.d.ts +16 -0
  109. package/dist/src/commands/promote.d.ts.map +1 -0
  110. package/dist/src/commands/promote.js +55 -0
  111. package/dist/src/commands/promote.js.map +1 -0
  112. package/dist/src/commands/publish.d.ts +18 -0
  113. package/dist/src/commands/publish.d.ts.map +1 -0
  114. package/dist/src/commands/publish.js +122 -0
  115. package/dist/src/commands/publish.js.map +1 -0
  116. package/dist/src/commands/rollback.d.ts +17 -0
  117. package/dist/src/commands/rollback.d.ts.map +1 -0
  118. package/dist/src/commands/rollback.js +62 -0
  119. package/dist/src/commands/rollback.js.map +1 -0
  120. package/dist/src/commands/search.d.ts +20 -0
  121. package/dist/src/commands/search.d.ts.map +1 -0
  122. package/dist/src/commands/search.js +133 -0
  123. package/dist/src/commands/search.js.map +1 -0
  124. package/dist/src/commands/secrets.d.ts +20 -0
  125. package/dist/src/commands/secrets.d.ts.map +1 -0
  126. package/dist/src/commands/secrets.js +137 -0
  127. package/dist/src/commands/secrets.js.map +1 -0
  128. package/dist/src/commands/serve.d.ts +23 -0
  129. package/dist/src/commands/serve.d.ts.map +1 -0
  130. package/dist/src/commands/serve.js +144 -0
  131. package/dist/src/commands/serve.js.map +1 -0
  132. package/dist/src/commands/status.d.ts +16 -0
  133. package/dist/src/commands/status.d.ts.map +1 -0
  134. package/dist/src/commands/status.js +83 -0
  135. package/dist/src/commands/status.js.map +1 -0
  136. package/dist/src/commands/sync.d.ts +21 -0
  137. package/dist/src/commands/sync.d.ts.map +1 -0
  138. package/dist/src/commands/sync.js +94 -0
  139. package/dist/src/commands/sync.js.map +1 -0
  140. package/dist/src/commands/test-query.d.ts +19 -0
  141. package/dist/src/commands/test-query.d.ts.map +1 -0
  142. package/dist/src/commands/test-query.js +116 -0
  143. package/dist/src/commands/test-query.js.map +1 -0
  144. package/dist/src/commands/uninstall.d.ts +19 -0
  145. package/dist/src/commands/uninstall.d.ts.map +1 -0
  146. package/dist/src/commands/uninstall.js +84 -0
  147. package/dist/src/commands/uninstall.js.map +1 -0
  148. package/dist/src/commands/update.d.ts +21 -0
  149. package/dist/src/commands/update.d.ts.map +1 -0
  150. package/dist/src/commands/update.js +145 -0
  151. package/dist/src/commands/update.js.map +1 -0
  152. package/dist/src/commands/validate.d.ts +19 -0
  153. package/dist/src/commands/validate.d.ts.map +1 -0
  154. package/dist/src/commands/validate.js +114 -0
  155. package/dist/src/commands/validate.js.map +1 -0
  156. package/dist/src/fixtures/incident-response.d.ts +91 -0
  157. package/dist/src/fixtures/incident-response.d.ts.map +1 -0
  158. package/dist/src/fixtures/incident-response.js +208 -0
  159. package/dist/src/fixtures/incident-response.js.map +1 -0
  160. package/dist/src/main.d.ts +8 -0
  161. package/dist/src/main.d.ts.map +1 -0
  162. package/dist/src/main.js +30 -0
  163. package/dist/src/main.js.map +1 -0
  164. package/dist/src/shared/platform-client.d.ts +92 -0
  165. package/dist/src/shared/platform-client.d.ts.map +1 -0
  166. package/dist/src/shared/platform-client.js +155 -0
  167. package/dist/src/shared/platform-client.js.map +1 -0
  168. package/dist/src/shared/repo-discovery.d.ts +11 -0
  169. package/dist/src/shared/repo-discovery.d.ts.map +1 -0
  170. package/dist/src/shared/repo-discovery.js +33 -0
  171. package/dist/src/shared/repo-discovery.js.map +1 -0
  172. package/dist/src/templates/compose-template.d.ts +10 -0
  173. package/dist/src/templates/compose-template.d.ts.map +1 -0
  174. package/dist/src/templates/compose-template.js +30 -0
  175. package/dist/src/templates/compose-template.js.map +1 -0
  176. package/dist/src/templates/config-template.d.ts +14 -0
  177. package/dist/src/templates/config-template.d.ts.map +1 -0
  178. package/dist/src/templates/config-template.js +35 -0
  179. package/dist/src/templates/config-template.js.map +1 -0
  180. package/dist/src/templates/dockerfile-template.d.ts +10 -0
  181. package/dist/src/templates/dockerfile-template.d.ts.map +1 -0
  182. package/dist/src/templates/dockerfile-template.js +30 -0
  183. package/dist/src/templates/dockerfile-template.js.map +1 -0
  184. package/dist/src/templates/env-template.d.ts +12 -0
  185. package/dist/src/templates/env-template.d.ts.map +1 -0
  186. package/dist/src/templates/env-template.js +24 -0
  187. package/dist/src/templates/env-template.js.map +1 -0
  188. package/dist/src/templates/knowledge-template.d.ts +10 -0
  189. package/dist/src/templates/knowledge-template.d.ts.map +1 -0
  190. package/dist/src/templates/knowledge-template.js +24 -0
  191. package/dist/src/templates/knowledge-template.js.map +1 -0
  192. package/dist/src/templates/skill-template.d.ts +10 -0
  193. package/dist/src/templates/skill-template.d.ts.map +1 -0
  194. package/dist/src/templates/skill-template.js +27 -0
  195. package/dist/src/templates/skill-template.js.map +1 -0
  196. package/dist/src/ui/AskUserPrompt.d.ts +14 -0
  197. package/dist/src/ui/AskUserPrompt.d.ts.map +1 -0
  198. package/dist/src/ui/AskUserPrompt.js +17 -0
  199. package/dist/src/ui/AskUserPrompt.js.map +1 -0
  200. package/dist/src/ui/AssistantMessage.d.ts +14 -0
  201. package/dist/src/ui/AssistantMessage.d.ts.map +1 -0
  202. package/dist/src/ui/AssistantMessage.js +8 -0
  203. package/dist/src/ui/AssistantMessage.js.map +1 -0
  204. package/dist/src/ui/ChatApp.d.ts +15 -0
  205. package/dist/src/ui/ChatApp.d.ts.map +1 -0
  206. package/dist/src/ui/ChatApp.js +144 -0
  207. package/dist/src/ui/ChatApp.js.map +1 -0
  208. package/dist/src/ui/ConfirmationPrompt.d.ts +17 -0
  209. package/dist/src/ui/ConfirmationPrompt.d.ts.map +1 -0
  210. package/dist/src/ui/ConfirmationPrompt.js +21 -0
  211. package/dist/src/ui/ConfirmationPrompt.js.map +1 -0
  212. package/dist/src/ui/DiffRenderer.d.ts +32 -0
  213. package/dist/src/ui/DiffRenderer.d.ts.map +1 -0
  214. package/dist/src/ui/DiffRenderer.js +118 -0
  215. package/dist/src/ui/DiffRenderer.js.map +1 -0
  216. package/dist/src/ui/ExpandableContent.d.ts +15 -0
  217. package/dist/src/ui/ExpandableContent.d.ts.map +1 -0
  218. package/dist/src/ui/ExpandableContent.js +22 -0
  219. package/dist/src/ui/ExpandableContent.js.map +1 -0
  220. package/dist/src/ui/ExploreIndicator.d.ts +13 -0
  221. package/dist/src/ui/ExploreIndicator.d.ts.map +1 -0
  222. package/dist/src/ui/ExploreIndicator.js +14 -0
  223. package/dist/src/ui/ExploreIndicator.js.map +1 -0
  224. package/dist/src/ui/Footer.d.ts +19 -0
  225. package/dist/src/ui/Footer.d.ts.map +1 -0
  226. package/dist/src/ui/Footer.js +57 -0
  227. package/dist/src/ui/Footer.js.map +1 -0
  228. package/dist/src/ui/FullScreenLayout.d.ts +18 -0
  229. package/dist/src/ui/FullScreenLayout.d.ts.map +1 -0
  230. package/dist/src/ui/FullScreenLayout.js +14 -0
  231. package/dist/src/ui/FullScreenLayout.js.map +1 -0
  232. package/dist/src/ui/Header.d.ts +14 -0
  233. package/dist/src/ui/Header.d.ts.map +1 -0
  234. package/dist/src/ui/Header.js +11 -0
  235. package/dist/src/ui/Header.js.map +1 -0
  236. package/dist/src/ui/InputBar.d.ts +17 -0
  237. package/dist/src/ui/InputBar.d.ts.map +1 -0
  238. package/dist/src/ui/InputBar.js +49 -0
  239. package/dist/src/ui/InputBar.js.map +1 -0
  240. package/dist/src/ui/MessageList.d.ts +18 -0
  241. package/dist/src/ui/MessageList.d.ts.map +1 -0
  242. package/dist/src/ui/MessageList.js +9 -0
  243. package/dist/src/ui/MessageList.js.map +1 -0
  244. package/dist/src/ui/NotificationBar.d.ts +14 -0
  245. package/dist/src/ui/NotificationBar.d.ts.map +1 -0
  246. package/dist/src/ui/NotificationBar.js +38 -0
  247. package/dist/src/ui/NotificationBar.js.map +1 -0
  248. package/dist/src/ui/ScrollableMessageList.d.ts +27 -0
  249. package/dist/src/ui/ScrollableMessageList.d.ts.map +1 -0
  250. package/dist/src/ui/ScrollableMessageList.js +16 -0
  251. package/dist/src/ui/ScrollableMessageList.js.map +1 -0
  252. package/dist/src/ui/SessionBrowser.d.ts +20 -0
  253. package/dist/src/ui/SessionBrowser.d.ts.map +1 -0
  254. package/dist/src/ui/SessionBrowser.js +93 -0
  255. package/dist/src/ui/SessionBrowser.js.map +1 -0
  256. package/dist/src/ui/StatusMessage.d.ts +13 -0
  257. package/dist/src/ui/StatusMessage.d.ts.map +1 -0
  258. package/dist/src/ui/StatusMessage.js +17 -0
  259. package/dist/src/ui/StatusMessage.js.map +1 -0
  260. package/dist/src/ui/StreamingView.d.ts +19 -0
  261. package/dist/src/ui/StreamingView.d.ts.map +1 -0
  262. package/dist/src/ui/StreamingView.js +18 -0
  263. package/dist/src/ui/StreamingView.js.map +1 -0
  264. package/dist/src/ui/SubagentDisplay.d.ts +13 -0
  265. package/dist/src/ui/SubagentDisplay.d.ts.map +1 -0
  266. package/dist/src/ui/SubagentDisplay.js +22 -0
  267. package/dist/src/ui/SubagentDisplay.js.map +1 -0
  268. package/dist/src/ui/ThinkingDisplay.d.ts +13 -0
  269. package/dist/src/ui/ThinkingDisplay.d.ts.map +1 -0
  270. package/dist/src/ui/ThinkingDisplay.js +15 -0
  271. package/dist/src/ui/ThinkingDisplay.js.map +1 -0
  272. package/dist/src/ui/ToolCallDisplay.d.ts +16 -0
  273. package/dist/src/ui/ToolCallDisplay.d.ts.map +1 -0
  274. package/dist/src/ui/ToolCallDisplay.js +136 -0
  275. package/dist/src/ui/ToolCallDisplay.js.map +1 -0
  276. package/dist/src/ui/UserMessage.d.ts +12 -0
  277. package/dist/src/ui/UserMessage.d.ts.map +1 -0
  278. package/dist/src/ui/UserMessage.js +5 -0
  279. package/dist/src/ui/UserMessage.js.map +1 -0
  280. package/dist/src/ui/commands/clear.d.ts +7 -0
  281. package/dist/src/ui/commands/clear.d.ts.map +1 -0
  282. package/dist/src/ui/commands/clear.js +13 -0
  283. package/dist/src/ui/commands/clear.js.map +1 -0
  284. package/dist/src/ui/commands/help.d.ts +7 -0
  285. package/dist/src/ui/commands/help.d.ts.map +1 -0
  286. package/dist/src/ui/commands/help.js +26 -0
  287. package/dist/src/ui/commands/help.js.map +1 -0
  288. package/dist/src/ui/commands/index.d.ts +14 -0
  289. package/dist/src/ui/commands/index.d.ts.map +1 -0
  290. package/dist/src/ui/commands/index.js +15 -0
  291. package/dist/src/ui/commands/index.js.map +1 -0
  292. package/dist/src/ui/commands/model.d.ts +7 -0
  293. package/dist/src/ui/commands/model.d.ts.map +1 -0
  294. package/dist/src/ui/commands/model.js +16 -0
  295. package/dist/src/ui/commands/model.js.map +1 -0
  296. package/dist/src/ui/commands/registry.d.ts +30 -0
  297. package/dist/src/ui/commands/registry.d.ts.map +1 -0
  298. package/dist/src/ui/commands/registry.js +45 -0
  299. package/dist/src/ui/commands/registry.js.map +1 -0
  300. package/dist/src/ui/commands/sessions.d.ts +7 -0
  301. package/dist/src/ui/commands/sessions.d.ts.map +1 -0
  302. package/dist/src/ui/commands/sessions.js +13 -0
  303. package/dist/src/ui/commands/sessions.js.map +1 -0
  304. package/dist/src/ui/commands/stats.d.ts +7 -0
  305. package/dist/src/ui/commands/stats.d.ts.map +1 -0
  306. package/dist/src/ui/commands/stats.js +33 -0
  307. package/dist/src/ui/commands/stats.js.map +1 -0
  308. package/dist/src/ui/commands/theme.d.ts +7 -0
  309. package/dist/src/ui/commands/theme.d.ts.map +1 -0
  310. package/dist/src/ui/commands/theme.js +35 -0
  311. package/dist/src/ui/commands/theme.js.map +1 -0
  312. package/dist/src/ui/markdown/CodeBlock.d.ts +14 -0
  313. package/dist/src/ui/markdown/CodeBlock.d.ts.map +1 -0
  314. package/dist/src/ui/markdown/CodeBlock.js +55 -0
  315. package/dist/src/ui/markdown/CodeBlock.js.map +1 -0
  316. package/dist/src/ui/markdown/InlineRenderer.d.ts +12 -0
  317. package/dist/src/ui/markdown/InlineRenderer.d.ts.map +1 -0
  318. package/dist/src/ui/markdown/InlineRenderer.js +70 -0
  319. package/dist/src/ui/markdown/InlineRenderer.js.map +1 -0
  320. package/dist/src/ui/markdown/MarkdownDisplay.d.ts +17 -0
  321. package/dist/src/ui/markdown/MarkdownDisplay.d.ts.map +1 -0
  322. package/dist/src/ui/markdown/MarkdownDisplay.js +142 -0
  323. package/dist/src/ui/markdown/MarkdownDisplay.js.map +1 -0
  324. package/dist/src/ui/markdown/Table.d.ts +14 -0
  325. package/dist/src/ui/markdown/Table.d.ts.map +1 -0
  326. package/dist/src/ui/markdown/Table.js +31 -0
  327. package/dist/src/ui/markdown/Table.js.map +1 -0
  328. package/dist/src/ui/theme.d.ts +39 -0
  329. package/dist/src/ui/theme.d.ts.map +1 -0
  330. package/dist/src/ui/theme.js +39 -0
  331. package/dist/src/ui/theme.js.map +1 -0
  332. package/dist/src/ui/themes/index.d.ts +45 -0
  333. package/dist/src/ui/themes/index.d.ts.map +1 -0
  334. package/dist/src/ui/themes/index.js +73 -0
  335. package/dist/src/ui/themes/index.js.map +1 -0
  336. package/dist/src/ui/themes/light.d.ts +8 -0
  337. package/dist/src/ui/themes/light.d.ts.map +1 -0
  338. package/dist/src/ui/themes/light.js +37 -0
  339. package/dist/src/ui/themes/light.js.map +1 -0
  340. package/dist/src/ui/themes/monochrome.d.ts +8 -0
  341. package/dist/src/ui/themes/monochrome.d.ts.map +1 -0
  342. package/dist/src/ui/themes/monochrome.js +37 -0
  343. package/dist/src/ui/themes/monochrome.js.map +1 -0
  344. package/dist/src/ui/types.d.ts +191 -0
  345. package/dist/src/ui/types.d.ts.map +1 -0
  346. package/dist/src/ui/types.js +7 -0
  347. package/dist/src/ui/types.js.map +1 -0
  348. package/dist/src/ui/useAlternateBuffer.d.ts +11 -0
  349. package/dist/src/ui/useAlternateBuffer.d.ts.map +1 -0
  350. package/dist/src/ui/useAlternateBuffer.js +25 -0
  351. package/dist/src/ui/useAlternateBuffer.js.map +1 -0
  352. package/dist/src/ui/useChat.d.ts +18 -0
  353. package/dist/src/ui/useChat.d.ts.map +1 -0
  354. package/dist/src/ui/useChat.js +599 -0
  355. package/dist/src/ui/useChat.js.map +1 -0
  356. package/dist/src/ui/useElapsedTime.d.ts +11 -0
  357. package/dist/src/ui/useElapsedTime.d.ts.map +1 -0
  358. package/dist/src/ui/useElapsedTime.js +39 -0
  359. package/dist/src/ui/useElapsedTime.js.map +1 -0
  360. package/dist/src/ui/useResponsiveLayout.d.ts +16 -0
  361. package/dist/src/ui/useResponsiveLayout.d.ts.map +1 -0
  362. package/dist/src/ui/useResponsiveLayout.js +24 -0
  363. package/dist/src/ui/useResponsiveLayout.js.map +1 -0
  364. package/dist/src/ui/useScroll.d.ts +20 -0
  365. package/dist/src/ui/useScroll.d.ts.map +1 -0
  366. package/dist/src/ui/useScroll.js +64 -0
  367. package/dist/src/ui/useScroll.js.map +1 -0
  368. package/dist/src/ui/useSessionResume.d.ts +20 -0
  369. package/dist/src/ui/useSessionResume.d.ts.map +1 -0
  370. package/dist/src/ui/useSessionResume.js +77 -0
  371. package/dist/src/ui/useSessionResume.js.map +1 -0
  372. package/dist/tsconfig.tsbuildinfo +1 -0
  373. package/package.json +60 -0
  374. package/src/auth/index.ts +13 -0
  375. package/src/auth/oauth2.test.ts +305 -0
  376. package/src/auth/oauth2.ts +269 -0
  377. package/src/auth/prompt.test.ts +205 -0
  378. package/src/auth/prompt.ts +111 -0
  379. package/src/auth/test-connection.test.ts +224 -0
  380. package/src/auth/test-connection.ts +196 -0
  381. package/src/auth/types.ts +34 -0
  382. package/src/commands/audit.test.ts +92 -0
  383. package/src/commands/audit.ts +113 -0
  384. package/src/commands/automations.test.ts +85 -0
  385. package/src/commands/automations.ts +205 -0
  386. package/src/commands/build-manifest-types.ts +35 -0
  387. package/src/commands/build-tools.ts +281 -0
  388. package/src/commands/build.test.ts +63 -0
  389. package/src/commands/build.ts +135 -0
  390. package/src/commands/chat.ts +147 -0
  391. package/src/commands/command-exports.test.ts +88 -0
  392. package/src/commands/connect.test.ts +343 -0
  393. package/src/commands/connect.ts +237 -0
  394. package/src/commands/deploy.test.ts +124 -0
  395. package/src/commands/deploy.ts +153 -0
  396. package/src/commands/deployments.ts +90 -0
  397. package/src/commands/dev.test.ts +63 -0
  398. package/src/commands/dev.ts +124 -0
  399. package/src/commands/diff.test.ts +183 -0
  400. package/src/commands/diff.ts +143 -0
  401. package/src/commands/docker.ts +232 -0
  402. package/src/commands/eval.test.ts +88 -0
  403. package/src/commands/eval.ts +268 -0
  404. package/src/commands/experiment.test.ts +125 -0
  405. package/src/commands/experiment.ts +153 -0
  406. package/src/commands/index.ts +76 -0
  407. package/src/commands/init.test.ts +109 -0
  408. package/src/commands/init.ts +98 -0
  409. package/src/commands/inspect.test.ts +234 -0
  410. package/src/commands/inspect.ts +157 -0
  411. package/src/commands/install-pkg.test.ts +265 -0
  412. package/src/commands/install-pkg.ts +234 -0
  413. package/src/commands/link.ts +270 -0
  414. package/src/commands/list.test.ts +152 -0
  415. package/src/commands/list.ts +95 -0
  416. package/src/commands/login.test.ts +195 -0
  417. package/src/commands/login.ts +258 -0
  418. package/src/commands/promote.ts +64 -0
  419. package/src/commands/publish.test.ts +203 -0
  420. package/src/commands/publish.ts +142 -0
  421. package/src/commands/rollback.ts +72 -0
  422. package/src/commands/search.test.ts +174 -0
  423. package/src/commands/search.ts +154 -0
  424. package/src/commands/secrets.test.ts +168 -0
  425. package/src/commands/secrets.ts +163 -0
  426. package/src/commands/serve.ts +166 -0
  427. package/src/commands/status.ts +94 -0
  428. package/src/commands/sync.test.ts +130 -0
  429. package/src/commands/sync.ts +119 -0
  430. package/src/commands/test-query.test.ts +42 -0
  431. package/src/commands/test-query.ts +129 -0
  432. package/src/commands/uninstall.test.ts +162 -0
  433. package/src/commands/uninstall.ts +107 -0
  434. package/src/commands/update.test.ts +281 -0
  435. package/src/commands/update.ts +180 -0
  436. package/src/commands/validate.test.ts +260 -0
  437. package/src/commands/validate.ts +139 -0
  438. package/src/e2e-automations.test.ts +305 -0
  439. package/src/e2e-commands.test.ts +587 -0
  440. package/src/e2e-incident-response.test.ts +345 -0
  441. package/src/e2e-plugin-connections.test.ts +415 -0
  442. package/src/e2e-plugins.test.ts +492 -0
  443. package/src/e2e.test.ts +602 -0
  444. package/src/fixtures/incident-response.ts +232 -0
  445. package/src/main.ts +35 -0
  446. package/src/shared/platform-client.test.ts +106 -0
  447. package/src/shared/platform-client.ts +193 -0
  448. package/src/shared/repo-discovery.test.ts +56 -0
  449. package/src/shared/repo-discovery.ts +40 -0
  450. package/src/templates/compose-template.ts +30 -0
  451. package/src/templates/config-template.ts +44 -0
  452. package/src/templates/deployment-templates.test.ts +99 -0
  453. package/src/templates/dockerfile-template.ts +30 -0
  454. package/src/templates/env-template.ts +27 -0
  455. package/src/templates/knowledge-template.ts +24 -0
  456. package/src/templates/skill-template.ts +27 -0
  457. package/src/ui/AskUserPrompt.tsx +58 -0
  458. package/src/ui/AssistantMessage.tsx +51 -0
  459. package/src/ui/ChatApp.tsx +283 -0
  460. package/src/ui/ConfirmationPrompt.tsx +75 -0
  461. package/src/ui/DiffRenderer.test.ts +104 -0
  462. package/src/ui/DiffRenderer.tsx +188 -0
  463. package/src/ui/ExpandableContent.tsx +68 -0
  464. package/src/ui/ExploreIndicator.tsx +44 -0
  465. package/src/ui/Footer.tsx +87 -0
  466. package/src/ui/FullScreenLayout.tsx +45 -0
  467. package/src/ui/Header.tsx +50 -0
  468. package/src/ui/InputBar.tsx +105 -0
  469. package/src/ui/MessageList.tsx +31 -0
  470. package/src/ui/NotificationBar.tsx +64 -0
  471. package/src/ui/ScrollableMessageList.tsx +82 -0
  472. package/src/ui/SessionBrowser.test.ts +49 -0
  473. package/src/ui/SessionBrowser.tsx +179 -0
  474. package/src/ui/StatusMessage.tsx +35 -0
  475. package/src/ui/StreamingView.tsx +87 -0
  476. package/src/ui/SubagentDisplay.tsx +57 -0
  477. package/src/ui/ThinkingDisplay.tsx +45 -0
  478. package/src/ui/ToolCallDisplay.tsx +268 -0
  479. package/src/ui/UserMessage.tsx +22 -0
  480. package/src/ui/chat-e2e.test.ts +581 -0
  481. package/src/ui/commands/clear.ts +15 -0
  482. package/src/ui/commands/help.ts +31 -0
  483. package/src/ui/commands/index.ts +22 -0
  484. package/src/ui/commands/model.ts +19 -0
  485. package/src/ui/commands/registry.test.ts +76 -0
  486. package/src/ui/commands/registry.ts +66 -0
  487. package/src/ui/commands/sessions.ts +16 -0
  488. package/src/ui/commands/stats.ts +35 -0
  489. package/src/ui/commands/theme.ts +41 -0
  490. package/src/ui/markdown/CodeBlock.tsx +118 -0
  491. package/src/ui/markdown/InlineRenderer.tsx +115 -0
  492. package/src/ui/markdown/MarkdownDisplay.tsx +223 -0
  493. package/src/ui/markdown/Table.tsx +75 -0
  494. package/src/ui/theme.ts +39 -0
  495. package/src/ui/themes/index.ts +113 -0
  496. package/src/ui/themes/light.ts +39 -0
  497. package/src/ui/themes/monochrome.ts +39 -0
  498. package/src/ui/types.ts +157 -0
  499. package/src/ui/useAlternateBuffer.ts +27 -0
  500. package/src/ui/useChat.test.ts +492 -0
  501. package/src/ui/useChat.ts +693 -0
  502. package/src/ui/useElapsedTime.test.ts +33 -0
  503. package/src/ui/useElapsedTime.ts +43 -0
  504. package/src/ui/useResponsiveLayout.test.ts +54 -0
  505. package/src/ui/useResponsiveLayout.ts +32 -0
  506. package/src/ui/useScroll.test.ts +99 -0
  507. package/src/ui/useScroll.ts +97 -0
  508. package/src/ui/useSessionResume.test.ts +80 -0
  509. package/src/ui/useSessionResume.ts +102 -0
  510. package/tsconfig.json +17 -0
  511. package/vitest.config.ts +20 -0
@@ -0,0 +1,587 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ /**
8
+ * End-to-end tests for ALL CLI commands.
9
+ *
10
+ * Every command gets its handler invoked against real infrastructure:
11
+ * - Local repo commands run against a real temp directory
12
+ * - Platform commands run against a real mock HTTP server
13
+ * - Runtime commands run against a real @amodalai/runtime server
14
+ *
15
+ * No vi.mock, no vi.spyOn, no vi.fn — everything is real.
16
+ */
17
+
18
+ import {describe, it, expect, beforeAll, afterAll} from 'vitest';
19
+ import {mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync} from 'node:fs';
20
+ import {join, resolve,dirname} from 'node:path';
21
+ import {tmpdir} from 'node:os';
22
+ import type http from 'node:http';
23
+ import {spawn} from 'node:child_process';
24
+ import type {ChildProcess} from 'node:child_process';
25
+ import {fileURLToPath} from 'node:url';
26
+
27
+ import {runInit} from './commands/init.js';
28
+ import {runValidate} from './commands/validate.js';
29
+ import {runInspect} from './commands/inspect.js';
30
+ import {runBuild} from './commands/build.js';
31
+ import {runDeploy} from './commands/deploy.js';
32
+ import {runList} from './commands/list.js';
33
+ import {runDocker} from './commands/docker.js';
34
+ import {runStatus} from './commands/status.js';
35
+ import {runDeployments} from './commands/deployments.js';
36
+ import {runRollback} from './commands/rollback.js';
37
+ import {runPromote} from './commands/promote.js';
38
+ import {runExperimentCommand} from './commands/experiment.js';
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Shared: Create a repo on disk for local-repo commands
42
+ // ---------------------------------------------------------------------------
43
+
44
+ function createTestRepo(): string {
45
+ const dir = mkdtempSync(join(tmpdir(), 'amodal-e2e-cmds-'));
46
+
47
+ // amodal.json
48
+ writeFileSync(join(dir, 'amodal.json'), JSON.stringify({
49
+ name: 'e2e-commands-test',
50
+ version: '1.0.0',
51
+ description: 'Test agent for e2e command tests',
52
+ models: {main: {provider: 'anthropic', model: 'claude-sonnet-4-20250514'}},
53
+ }, null, 2));
54
+
55
+ // Connection
56
+ const connDir = join(dir, 'connections', 'test-api');
57
+ mkdirSync(connDir, {recursive: true});
58
+ writeFileSync(join(connDir, 'spec.json'), JSON.stringify({
59
+ source: 'https://api.example.com/openapi.json',
60
+ format: 'openapi',
61
+ auth: {type: 'bearer', header: 'Authorization', prefix: 'Bearer', token: 'env:TEST_API_TOKEN'},
62
+ }, null, 2));
63
+ writeFileSync(join(connDir, 'access.json'), JSON.stringify({
64
+ endpoints: {
65
+ 'GET /items': {returns: ['id', 'name', 'status']},
66
+ 'GET /items/:id': {returns: ['id', 'name', 'status', 'details']},
67
+ },
68
+ }, null, 2));
69
+ writeFileSync(join(connDir, 'surface.md'), [
70
+ '## Included',
71
+ '- [x] GET /items — List all items',
72
+ '- [x] GET /items/:id — Get item by ID',
73
+ '## Excluded',
74
+ '- [ ] POST /items — Create new item (write)',
75
+ ].join('\n'));
76
+
77
+ // Skill
78
+ const skillDir = join(dir, 'skills', 'test-triage');
79
+ mkdirSync(skillDir, {recursive: true});
80
+ writeFileSync(join(skillDir, 'SKILL.md'), [
81
+ '---',
82
+ 'trigger: when asked to analyze items',
83
+ '---',
84
+ '# Test Triage',
85
+ 'Step 1: Query items',
86
+ 'Step 2: Analyze status',
87
+ 'Step 3: Report findings',
88
+ ].join('\n'));
89
+
90
+ // Knowledge
91
+ const kbDir = join(dir, 'knowledge');
92
+ mkdirSync(kbDir, {recursive: true});
93
+ writeFileSync(join(kbDir, 'team-contacts.md'), [
94
+ '# Team Contacts',
95
+ '- Alice: alice@example.com (oncall)',
96
+ '- Bob: bob@example.com (backup)',
97
+ ].join('\n'));
98
+
99
+ // Automation
100
+ const autoDir = join(dir, 'automations');
101
+ mkdirSync(autoDir, {recursive: true});
102
+ writeFileSync(join(autoDir, 'daily-check.md'), [
103
+ '---',
104
+ 'title: Daily Health Check',
105
+ 'schedule: "0 9 * * *"',
106
+ 'output:',
107
+ ' channel: slack',
108
+ ' target: "#ops"',
109
+ '---',
110
+ 'Check the status of all items and report any issues.',
111
+ ].join('\n'));
112
+
113
+ return dir;
114
+ }
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // Shared: Start the real @amodalai/platform-api (Next.js) server
118
+ // ---------------------------------------------------------------------------
119
+
120
+ const __filename = fileURLToPath(import.meta.url);
121
+ const __dirname = dirname(__filename);
122
+ // In vitest forks, __dirname is the source dir (packages/cli/src).
123
+ // Go up to packages/ then into platform-api/.
124
+ const PLATFORM_API_DIR = resolve(__dirname, '../../platform-api');
125
+
126
+ async function waitForServer(url: string, timeoutMs = 30000): Promise<void> {
127
+ const deadline = Date.now() + timeoutMs;
128
+ while (Date.now() < deadline) {
129
+ try {
130
+ const res = await fetch(url);
131
+ if (res.ok) return;
132
+ } catch {
133
+ // not ready yet
134
+ }
135
+ await new Promise((r) => setTimeout(r, 300));
136
+ }
137
+ throw new Error(`Server at ${url} did not become ready within ${timeoutMs}ms`);
138
+ }
139
+
140
+ function startPlatformApi(port: number): ChildProcess {
141
+ // Run next dev via node directly — avoids PATH/shell issues in vitest forks
142
+ const nextCli = resolve(PLATFORM_API_DIR, 'node_modules/next/dist/bin/next');
143
+ const child = spawn(process.execPath, [nextCli, 'dev', '--port', String(port)], {
144
+ cwd: PLATFORM_API_DIR,
145
+ stdio: ['ignore', 'pipe', 'pipe'],
146
+ env: {
147
+ ...process.env,
148
+ PORT: String(port),
149
+ // No DATABASE_URL → uses PGlite in-memory (zero external deps)
150
+ DATABASE_URL: '',
151
+ NODE_ENV: 'development',
152
+ },
153
+ });
154
+ return child;
155
+ }
156
+
157
+ interface OnboardingResult {
158
+ org: {id: string};
159
+ app: {id: string};
160
+ tenant: {id: string};
161
+ api_key: {id: string; key: string};
162
+ }
163
+
164
+ async function onboard(baseUrl: string): Promise<OnboardingResult> {
165
+ const resp = await fetch(`${baseUrl}/api/onboarding`, {
166
+ method: 'POST',
167
+ headers: {'Content-Type': 'application/json'},
168
+ body: JSON.stringify({
169
+ app_name: 'e2e-commands-test',
170
+ agent_context: 'E2E test agent for CLI command testing',
171
+ provider: 'anthropic',
172
+ model: 'claude-sonnet-4-20250514',
173
+ }),
174
+ });
175
+ if (!resp.ok) {
176
+ const text = await resp.text();
177
+ throw new Error(`Onboarding failed (${resp.status}): ${text}`);
178
+ }
179
+
180
+ return resp.json() as Promise<OnboardingResult>;
181
+ }
182
+
183
+ // ===========================================================================
184
+ // GROUP 1: Local Repo Commands
185
+ // ===========================================================================
186
+
187
+ describe('E2E Commands: Local repo', () => {
188
+ let repoDir: string;
189
+
190
+ beforeAll(() => {
191
+ repoDir = createTestRepo();
192
+ });
193
+
194
+ afterAll(() => {
195
+ if (repoDir && existsSync(repoDir)) rmSync(repoDir, {recursive: true, force: true});
196
+ });
197
+
198
+ // --- init ---
199
+
200
+ it('should init a new project from template', async () => {
201
+ const dir = mkdtempSync(join(tmpdir(), 'amodal-e2e-init-'));
202
+ try {
203
+ await runInit({cwd: dir, name: 'test-init', provider: 'anthropic'});
204
+ expect(existsSync(join(dir, 'amodal.json'))).toBe(true);
205
+ const config = JSON.parse(readFileSync(join(dir, 'amodal.json'), 'utf-8')) as Record<string, unknown>;
206
+ expect(config['name']).toBe('test-init');
207
+ } finally {
208
+ rmSync(dir, {recursive: true, force: true});
209
+ }
210
+ });
211
+
212
+ // --- validate ---
213
+
214
+ it('should validate the repo and return 0 errors', async () => {
215
+ const code = await runValidate({cwd: repoDir});
216
+ expect(code).toBe(0);
217
+ });
218
+
219
+ it('should validate and report warnings for missing connections', async () => {
220
+ const dir = mkdtempSync(join(tmpdir(), 'amodal-e2e-validate-'));
221
+ writeFileSync(join(dir, 'amodal.json'), JSON.stringify({
222
+ name: 'empty-agent', version: '1.0.0',
223
+ models: {main: {provider: 'anthropic', model: 'claude-sonnet-4-20250514'}},
224
+ }));
225
+ try {
226
+ // 0 errors but should have warnings
227
+ const code = await runValidate({cwd: dir});
228
+ expect(code).toBe(0);
229
+ } finally {
230
+ rmSync(dir, {recursive: true, force: true});
231
+ }
232
+ });
233
+
234
+ // --- inspect ---
235
+
236
+ it('should inspect the repo and print compiled context', async () => {
237
+ // runInspect writes to stdout — we just verify it doesn't throw
238
+ await runInspect({cwd: repoDir});
239
+ });
240
+
241
+ it('should inspect with --connections flag', async () => {
242
+ await runInspect({cwd: repoDir, connections: true});
243
+ });
244
+
245
+ it('should inspect with --tools flag', async () => {
246
+ await runInspect({cwd: repoDir, tools: true});
247
+ });
248
+
249
+ // --- build ---
250
+
251
+ it('should build a snapshot from the repo', async () => {
252
+ const outputPath = join(repoDir, 'test-snapshot.json');
253
+ const code = await runBuild({cwd: repoDir, output: outputPath});
254
+ expect(code).toBe(0);
255
+ expect(existsSync(outputPath)).toBe(true);
256
+
257
+ const snapshot = JSON.parse(readFileSync(outputPath, 'utf-8')) as Record<string, unknown>;
258
+ expect(snapshot['deployId']).toBeDefined();
259
+ expect((snapshot['config'] as Record<string, unknown>)['name']).toBe('e2e-commands-test');
260
+ });
261
+
262
+ // --- list ---
263
+
264
+ it('should list packages (empty lock file)', async () => {
265
+ const code = await runList({cwd: repoDir});
266
+ // No lock file = returns 0 with "no packages" message
267
+ expect(code).toBe(0);
268
+ });
269
+
270
+ // --- docker init ---
271
+
272
+ it('should generate docker files from repo', async () => {
273
+ const dir = mkdtempSync(join(tmpdir(), 'amodal-e2e-docker-'));
274
+ writeFileSync(join(dir, 'amodal.json'), JSON.stringify({
275
+ name: 'docker-test-agent', version: '1.0.0',
276
+ models: {main: {provider: 'anthropic', model: 'claude-sonnet-4-20250514'}},
277
+ }));
278
+ try {
279
+ await runDocker({cwd: dir, subcommand: 'init'});
280
+ expect(existsSync(join(dir, 'Dockerfile'))).toBe(true);
281
+ expect(existsSync(join(dir, 'docker-compose.yml'))).toBe(true);
282
+ expect(existsSync(join(dir, '.env.production'))).toBe(true);
283
+
284
+ const compose = readFileSync(join(dir, 'docker-compose.yml'), 'utf-8');
285
+ expect(compose).toContain('docker-test-agent');
286
+ } finally {
287
+ rmSync(dir, {recursive: true, force: true});
288
+ }
289
+ });
290
+
291
+ // --- deploy (dry-run, local only) ---
292
+
293
+ it('should dry-run deploy without uploading', async () => {
294
+ const code = await runDeploy({cwd: repoDir, dryRun: true, message: 'e2e dry run'});
295
+ expect(code).toBe(0);
296
+ });
297
+ });
298
+
299
+ // ===========================================================================
300
+ // GROUP 2: Platform API Commands (real @amodalai/platform-api server)
301
+ // ===========================================================================
302
+
303
+ describe('E2E Commands: Platform API', () => {
304
+ let platformProc: ChildProcess;
305
+ let platformPort: number;
306
+ let apiKey: string;
307
+ let origUrl: string | undefined;
308
+ let origKey: string | undefined;
309
+ let origHome: string | undefined;
310
+
311
+ beforeAll(async () => {
312
+ // Pick a random port in the ephemeral range
313
+ platformPort = 14000 + Math.floor(Math.random() * 1000);
314
+ const baseUrl = `http://127.0.0.1:${platformPort}`;
315
+
316
+ // Start the real platform-api (Next.js dev server with PGlite in-memory)
317
+ platformProc = startPlatformApi(platformPort);
318
+ await waitForServer(`${baseUrl}/api/health`, 60000);
319
+
320
+ // Onboard to create org + app + tenant + API key
321
+ const result = await onboard(baseUrl);
322
+ apiKey = result.api_key.key;
323
+
324
+ // Deploy two snapshots so status/deployments/rollback/promote have data
325
+ const repoDir = createTestRepo();
326
+ try {
327
+ // First deploy to production
328
+ const snap1 = join(repoDir, 'snap1.json');
329
+ await runBuild({cwd: repoDir, output: snap1});
330
+ const snap1Data = JSON.parse(readFileSync(snap1, 'utf-8')) as Record<string, unknown>;
331
+ await fetch(`${baseUrl}/api/snapshot-deployments`, {
332
+ method: 'POST',
333
+ headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}`},
334
+ body: JSON.stringify({snapshot: snap1Data, environment: 'production'}),
335
+ });
336
+
337
+ // Second deploy to staging
338
+ const snap2 = join(repoDir, 'snap2.json');
339
+ await runBuild({cwd: repoDir, output: snap2});
340
+ const snap2Data = JSON.parse(readFileSync(snap2, 'utf-8')) as Record<string, unknown>;
341
+ await fetch(`${baseUrl}/api/snapshot-deployments`, {
342
+ method: 'POST',
343
+ headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}`},
344
+ body: JSON.stringify({snapshot: snap2Data, environment: 'staging'}),
345
+ });
346
+
347
+ // Third deploy to production (so rollback has a previous version)
348
+ const snap3 = join(repoDir, 'snap3.json');
349
+ await runBuild({cwd: repoDir, output: snap3});
350
+ const snap3Data = JSON.parse(readFileSync(snap3, 'utf-8')) as Record<string, unknown>;
351
+ await fetch(`${baseUrl}/api/snapshot-deployments`, {
352
+ method: 'POST',
353
+ headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}`},
354
+ body: JSON.stringify({snapshot: snap3Data, environment: 'production'}),
355
+ });
356
+ } finally {
357
+ rmSync(repoDir, {recursive: true, force: true});
358
+ }
359
+
360
+ // Set env vars so PlatformClient and resolvePlatformConfig use the real server
361
+ origUrl = process.env['PLATFORM_API_URL'];
362
+ origKey = process.env['PLATFORM_API_KEY'];
363
+ origHome = process.env['HOME'];
364
+ process.env['PLATFORM_API_URL'] = baseUrl;
365
+ process.env['PLATFORM_API_KEY'] = apiKey;
366
+ // Isolate from real ~/.amodalrc
367
+ process.env['HOME'] = mkdtempSync(join(tmpdir(), 'amodal-e2e-home-'));
368
+ }, 120000);
369
+
370
+ afterAll(async () => {
371
+ if (origUrl !== undefined) process.env['PLATFORM_API_URL'] = origUrl;
372
+ else delete process.env['PLATFORM_API_URL'];
373
+ if (origKey !== undefined) process.env['PLATFORM_API_KEY'] = origKey;
374
+ else delete process.env['PLATFORM_API_KEY'];
375
+ if (origHome !== undefined) process.env['HOME'] = origHome;
376
+ else delete process.env['HOME'];
377
+
378
+ if (platformProc) {
379
+ platformProc.kill('SIGTERM');
380
+ // Give it a moment to shut down gracefully
381
+ await new Promise((r) => setTimeout(r, 1000));
382
+ if (!platformProc.killed) platformProc.kill('SIGKILL');
383
+ }
384
+ });
385
+
386
+ // --- status ---
387
+
388
+ it('should show deployment status', async () => {
389
+ const code = await runStatus({});
390
+ expect(code).toBe(0);
391
+ });
392
+
393
+ it('should show status for specific environment', async () => {
394
+ const code = await runStatus({env: 'staging'});
395
+ expect(code).toBe(0);
396
+ });
397
+
398
+ it('should show status as JSON', async () => {
399
+ const code = await runStatus({json: true});
400
+ expect(code).toBe(0);
401
+ });
402
+
403
+ // --- deployments ---
404
+
405
+ it('should list deployments', async () => {
406
+ const code = await runDeployments({});
407
+ expect(code).toBe(0);
408
+ });
409
+
410
+ it('should list deployments filtered by env', async () => {
411
+ const code = await runDeployments({env: 'production'});
412
+ expect(code).toBe(0);
413
+ });
414
+
415
+ it('should list deployments as JSON', async () => {
416
+ const code = await runDeployments({json: true});
417
+ expect(code).toBe(0);
418
+ });
419
+
420
+ it('should list deployments with limit', async () => {
421
+ const code = await runDeployments({limit: 1});
422
+ expect(code).toBe(0);
423
+ });
424
+
425
+ // --- rollback ---
426
+
427
+ it('should rollback production deployment', async () => {
428
+ const code = await runRollback({env: 'production'});
429
+ expect(code).toBe(0);
430
+ });
431
+
432
+ // --- promote ---
433
+
434
+ it('should promote staging to production', async () => {
435
+ const code = await runPromote({fromEnv: 'staging', toEnv: 'production'});
436
+ expect(code).toBe(0);
437
+ });
438
+
439
+ // --- experiment ---
440
+
441
+ it('should list experiments', async () => {
442
+ await runExperimentCommand({
443
+ action: 'list',
444
+ platformUrl: `http://127.0.0.1:${platformPort}`,
445
+ platformApiKey: apiKey,
446
+ });
447
+ });
448
+
449
+ it('should create an experiment', async () => {
450
+ await runExperimentCommand({
451
+ action: 'create',
452
+ name: 'new-experiment',
453
+ platformUrl: `http://127.0.0.1:${platformPort}`,
454
+ platformApiKey: apiKey,
455
+ });
456
+ });
457
+
458
+ // --- deploy (real upload to real platform) ---
459
+
460
+ it('should deploy snapshot to platform', async () => {
461
+ const repoDir = createTestRepo();
462
+ try {
463
+ const code = await runDeploy({cwd: repoDir, message: 'e2e platform deploy', env: 'staging'});
464
+ expect(code).toBe(0);
465
+ } finally {
466
+ rmSync(repoDir, {recursive: true, force: true});
467
+ }
468
+ });
469
+ });
470
+
471
+ // ===========================================================================
472
+ // GROUP 3: Runtime Commands (boots a real @amodalai/runtime server)
473
+ // ===========================================================================
474
+
475
+ describe('E2E Commands: Runtime', () => {
476
+ let repoDir: string;
477
+ let localServer: {app: unknown; start: () => Promise<unknown>; stop: () => Promise<void>} | null = null;
478
+ let localPort: number;
479
+
480
+ beforeAll(async () => {
481
+ repoDir = createTestRepo();
482
+
483
+ // Boot a real local server from the repo (not snapshot — so automations routes are available)
484
+ const {createLocalServer} = await import('@amodalai/runtime');
485
+ localServer = await createLocalServer({
486
+ repoPath: repoDir,
487
+ port: 0,
488
+ host: '127.0.0.1',
489
+ hotReload: false,
490
+ });
491
+
492
+ const httpServer = await localServer.start();
493
+ const addr = (httpServer as http.Server).address();
494
+ localPort = typeof addr === 'object' && addr ? addr.port : 0;
495
+ }, 60000);
496
+
497
+ afterAll(async () => {
498
+ if (localServer) await localServer.stop();
499
+ if (repoDir && existsSync(repoDir)) rmSync(repoDir, {recursive: true, force: true});
500
+ });
501
+
502
+ // --- serve / dev (health check proves the server works) ---
503
+
504
+ it('should serve a health endpoint from the repo', async () => {
505
+ const resp = await fetch(`http://127.0.0.1:${localPort}/health`);
506
+ expect(resp.ok).toBe(true);
507
+ const data = (await resp.json()) as Record<string, unknown>;
508
+ expect(data['status']).toBe('ok');
509
+ expect(data['mode']).toBe('repo');
510
+ expect(data['repo_path']).toBe(repoDir);
511
+ });
512
+
513
+ // --- chat (via /chat endpoint) ---
514
+
515
+ it('should handle a chat query and stream SSE events', async () => {
516
+ const resp = await fetch(`http://127.0.0.1:${localPort}/chat`, {
517
+ method: 'POST',
518
+ headers: {'Content-Type': 'application/json'},
519
+ body: JSON.stringify({message: 'Hello', tenant_id: 'e2e-cmd-test'}),
520
+ });
521
+
522
+ expect(resp.ok).toBe(true);
523
+ const text = await resp.text();
524
+ const events: Array<Record<string, unknown>> = [];
525
+ for (const line of text.split('\n')) {
526
+ if (line.startsWith('data: ')) {
527
+ try { events.push(JSON.parse(line.slice(6)) as Record<string, unknown>); } catch { /* skip */ }
528
+ }
529
+ }
530
+
531
+ expect(events.find((e) => e['type'] === 'init')).toBeDefined();
532
+ expect(events.find((e) => e['type'] === 'done')).toBeDefined();
533
+ });
534
+
535
+ // --- test-query (runs its own ephemeral server) ---
536
+
537
+ it('should run test-query command end-to-end', async () => {
538
+ const {runTestQuery} = await import('./commands/test-query.js');
539
+ await runTestQuery({cwd: repoDir, message: 'What can you help me with?'});
540
+ });
541
+
542
+ // --- automations ---
543
+
544
+ it('should list automations on the running server', async () => {
545
+ const {runAutomationsList} = await import('./commands/automations.js');
546
+ const code = await runAutomationsList({url: `http://127.0.0.1:${localPort}`});
547
+ expect(code).toBe(0);
548
+ });
549
+
550
+ // --- eval (exits early — no evals/ dir in our test repo) ---
551
+
552
+ it('should run eval and exit when no evals found', async () => {
553
+ const {runEval} = await import('./commands/eval.js');
554
+ // runEval boots its own server — it will exit early since there are no evals
555
+ await runEval({cwd: repoDir});
556
+ });
557
+
558
+ // --- snapshot server ---
559
+
560
+ it('should boot a snapshot server and serve health', async () => {
561
+ const snapshotPath = join(repoDir, 'cmd-test-snapshot.json');
562
+ const buildCode = await runBuild({cwd: repoDir, output: snapshotPath});
563
+ expect(buildCode).toBe(0);
564
+
565
+ const {createSnapshotServer} = await import('@amodalai/runtime');
566
+ const snapServer = await createSnapshotServer({
567
+ snapshotPath,
568
+ port: 0,
569
+ host: '127.0.0.1',
570
+ });
571
+
572
+ const httpServer = await snapServer.start();
573
+ const addr = (httpServer).address();
574
+ const snapPort = typeof addr === 'object' && addr ? addr.port : 0;
575
+
576
+ try {
577
+ const resp = await fetch(`http://127.0.0.1:${snapPort}/health`);
578
+ expect(resp.ok).toBe(true);
579
+ const data = (await resp.json()) as Record<string, unknown>;
580
+ expect(data['status']).toBe('ok');
581
+ expect(data['mode']).toBe('snapshot');
582
+ expect(data['agent_name']).toBe('e2e-commands-test');
583
+ } finally {
584
+ await snapServer.stop();
585
+ }
586
+ });
587
+ });