@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,154 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import type {CommandModule} from 'yargs';
8
+ import {
9
+ ensureNpmContext,
10
+ fromNpmName,
11
+ npmSearch,
12
+ } from '@amodalai/core';
13
+ import type {PackageType} from '@amodalai/core';
14
+ import {findRepoRoot} from '../shared/repo-discovery.js';
15
+
16
+ export interface SearchOptions {
17
+ cwd?: string;
18
+ query?: string;
19
+ type?: PackageType;
20
+ json?: boolean;
21
+ }
22
+
23
+ /**
24
+ * Search the registry for packages.
25
+ * Returns 0 on success, 1 on error.
26
+ */
27
+ export async function runSearch(options: SearchOptions = {}): Promise<number> {
28
+ let repoPath: string | undefined;
29
+ try {
30
+ repoPath = findRepoRoot(options.cwd);
31
+ } catch {
32
+ // Not in a repo — use temp context
33
+ }
34
+
35
+ let paths;
36
+ try {
37
+ paths = await ensureNpmContext(repoPath ?? process.cwd());
38
+ } catch (err) {
39
+ const msg = err instanceof Error ? err.message : String(err);
40
+ process.stderr.write(`[search] Failed to set up npm context: ${msg}\n`);
41
+ return 1;
42
+ }
43
+
44
+ // Build query
45
+ let query = options.type ? `@amodalai/${options.type}-` : '@amodalai/';
46
+ if (options.query) {
47
+ query += options.query;
48
+ }
49
+
50
+ process.stderr.write(`[search] Searching for "${query}"...\n`);
51
+
52
+ let results;
53
+ try {
54
+ results = await npmSearch(paths, query);
55
+ } catch (err) {
56
+ const msg = err instanceof Error ? err.message : String(err);
57
+ process.stderr.write(`[search] Search failed: ${msg}\n`);
58
+ return 1;
59
+ }
60
+
61
+ // Filter to @amodalai/ packages only
62
+ results = results.filter((r) => r.name.startsWith('@amodalai/'));
63
+
64
+ // Further filter by type if specified
65
+ if (options.type) {
66
+ results = results.filter((r) => {
67
+ try {
68
+ const parsed = fromNpmName(r.name);
69
+ return parsed.type === options.type;
70
+ } catch {
71
+ return false;
72
+ }
73
+ });
74
+ }
75
+
76
+ if (results.length === 0) {
77
+ process.stderr.write('[search] No packages found.\n');
78
+ return 0;
79
+ }
80
+
81
+ if (options.json) {
82
+ const output = results.map((r) => {
83
+ let type: string | undefined;
84
+ let name: string | undefined;
85
+ try {
86
+ const parsed = fromNpmName(r.name);
87
+ type = parsed.type;
88
+ name = parsed.name;
89
+ } catch {
90
+ // Not a parseable amodal name
91
+ }
92
+ return {
93
+ npm: r.name,
94
+ version: r.version,
95
+ description: r.description,
96
+ type,
97
+ name,
98
+ };
99
+ });
100
+ process.stdout.write(JSON.stringify(output, null, 2) + '\n');
101
+ return 0;
102
+ }
103
+
104
+ // Categorize results
105
+ const grouped = new Map<string, Array<{name: string; version: string; description: string; npm: string}>>();
106
+ for (const r of results) {
107
+ let category = 'other';
108
+ let pkgName = r.name;
109
+ try {
110
+ const parsed = fromNpmName(r.name);
111
+ category = parsed.type;
112
+ pkgName = parsed.name;
113
+ } catch {
114
+ // Not parseable
115
+ }
116
+ if (!grouped.has(category)) {
117
+ grouped.set(category, []);
118
+ }
119
+ grouped.get(category)!.push({name: pkgName, version: r.version, description: r.description, npm: r.name});
120
+ }
121
+
122
+ for (const [category, items] of grouped) {
123
+ process.stdout.write(`\n ${category.toUpperCase()}\n`);
124
+ const nameWidth = Math.max(4, ...items.map((i) => i.name.length));
125
+ const versionWidth = Math.max(7, ...items.map((i) => i.version.length));
126
+ for (const item of items) {
127
+ process.stdout.write(` ${item.name.padEnd(nameWidth)} ${item.version.padEnd(versionWidth)} ${item.description}\n`);
128
+ }
129
+ }
130
+
131
+ process.stderr.write(`\n[search] ${results.length} package${results.length === 1 ? '' : 's'} found.\n`);
132
+ return 0;
133
+ }
134
+
135
+ export const searchCommand: CommandModule = {
136
+ command: 'search [query]',
137
+ describe: 'Search the registry for packages',
138
+ builder: (yargs) =>
139
+ yargs
140
+ .positional('query', {type: 'string', describe: 'Search query'})
141
+ .option('type', {type: 'string', choices: ['connection', 'skill', 'automation', 'knowledge'] as const, describe: 'Filter by type'})
142
+ .option('json', {type: 'boolean', default: false, describe: 'Output as JSON'}),
143
+ handler: async (argv) => {
144
+ const code = await runSearch({
145
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
146
+ query: argv['query'] as string | undefined,
147
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
148
+ type: argv['type'] as PackageType | undefined,
149
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
150
+ json: argv['json'] as boolean,
151
+ });
152
+ process.exit(code);
153
+ },
154
+ };
@@ -0,0 +1,168 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
8
+
9
+ describe('runSecrets', () => {
10
+ let stderrOutput: string;
11
+ let stdoutOutput: string;
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ let fetchSpy: any;
14
+ const originalEnv = process.env;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ process.env = {
19
+ ...originalEnv,
20
+ PLATFORM_API_URL: 'https://api.example.com',
21
+ PLATFORM_API_KEY: 'test-key',
22
+ };
23
+ stderrOutput = '';
24
+ stdoutOutput = '';
25
+ vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
26
+ stderrOutput += String(chunk);
27
+ return true;
28
+ });
29
+ vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
30
+ stdoutOutput += String(chunk);
31
+ return true;
32
+ });
33
+ fetchSpy = vi.spyOn(globalThis, 'fetch');
34
+ });
35
+
36
+ afterEach(() => {
37
+ process.env = originalEnv;
38
+ fetchSpy.mockRestore();
39
+ });
40
+
41
+ it('should set a secret', async () => {
42
+ fetchSpy.mockResolvedValue(new Response('{}', {status: 200}));
43
+
44
+ const {runSecrets} = await import('./secrets.js');
45
+ const result = await runSecrets({subcommand: 'set', key: 'DB_URL', value: 'postgres://...'});
46
+ expect(result).toBe(0);
47
+ expect(stderrOutput).toContain('set successfully');
48
+ });
49
+
50
+ it('should return 1 when key missing for set', async () => {
51
+ const {runSecrets} = await import('./secrets.js');
52
+ const result = await runSecrets({subcommand: 'set'});
53
+ expect(result).toBe(1);
54
+ expect(stderrOutput).toContain('Missing key');
55
+ });
56
+
57
+ it('should return 1 when value missing for set', async () => {
58
+ const {runSecrets} = await import('./secrets.js');
59
+ const result = await runSecrets({subcommand: 'set', key: 'DB_URL'});
60
+ expect(result).toBe(1);
61
+ expect(stderrOutput).toContain('Missing value');
62
+ });
63
+
64
+ it('should list secrets', async () => {
65
+ fetchSpy.mockResolvedValue(new Response(JSON.stringify([
66
+ {key: 'DB_URL'},
67
+ {key: 'API_KEY'},
68
+ ]), {status: 200}));
69
+
70
+ const {runSecrets} = await import('./secrets.js');
71
+ const result = await runSecrets({subcommand: 'list'});
72
+ expect(result).toBe(0);
73
+ expect(stdoutOutput).toContain('DB_URL');
74
+ expect(stdoutOutput).toContain('API_KEY');
75
+ });
76
+
77
+ it('should list secrets as JSON', async () => {
78
+ fetchSpy.mockResolvedValue(new Response(JSON.stringify([{key: 'DB_URL'}]), {status: 200}));
79
+
80
+ const {runSecrets} = await import('./secrets.js');
81
+ const result = await runSecrets({subcommand: 'list', json: true});
82
+ expect(result).toBe(0);
83
+ const parsed = JSON.parse(stdoutOutput);
84
+ expect(parsed).toHaveLength(1);
85
+ });
86
+
87
+ it('should handle empty secrets list', async () => {
88
+ fetchSpy.mockResolvedValue(new Response('[]', {status: 200}));
89
+
90
+ const {runSecrets} = await import('./secrets.js');
91
+ const result = await runSecrets({subcommand: 'list'});
92
+ expect(result).toBe(0);
93
+ expect(stderrOutput).toContain('No secrets configured');
94
+ });
95
+
96
+ it('should delete a secret', async () => {
97
+ fetchSpy.mockResolvedValue(new Response('{}', {status: 200}));
98
+
99
+ const {runSecrets} = await import('./secrets.js');
100
+ const result = await runSecrets({subcommand: 'delete', key: 'DB_URL'});
101
+ expect(result).toBe(0);
102
+ expect(stderrOutput).toContain('deleted');
103
+ });
104
+
105
+ it('should return 1 when key missing for delete', async () => {
106
+ const {runSecrets} = await import('./secrets.js');
107
+ const result = await runSecrets({subcommand: 'delete'});
108
+ expect(result).toBe(1);
109
+ expect(stderrOutput).toContain('Missing key');
110
+ });
111
+
112
+ it('should return 1 when platform not configured', async () => {
113
+ delete process.env['PLATFORM_API_URL'];
114
+ delete process.env['PLATFORM_API_KEY'];
115
+
116
+ const {runSecrets} = await import('./secrets.js');
117
+ const result = await runSecrets({subcommand: 'list'});
118
+ expect(result).toBe(1);
119
+ });
120
+
121
+ it('should handle auth failure', async () => {
122
+ fetchSpy.mockResolvedValue(new Response('Unauthorized', {status: 401}));
123
+
124
+ const {runSecrets} = await import('./secrets.js');
125
+ const result = await runSecrets({subcommand: 'list'});
126
+ expect(result).toBe(1);
127
+ expect(stderrOutput).toContain('401');
128
+ });
129
+
130
+ it('should handle network error', async () => {
131
+ fetchSpy.mockRejectedValue(new Error('ECONNREFUSED'));
132
+
133
+ const {runSecrets} = await import('./secrets.js');
134
+ const result = await runSecrets({subcommand: 'set', key: 'K', value: 'V'});
135
+ expect(result).toBe(1);
136
+ expect(stderrOutput).toContain('ECONNREFUSED');
137
+ });
138
+
139
+ it('should handle set server error', async () => {
140
+ fetchSpy.mockResolvedValue(new Response('Internal Error', {status: 500}));
141
+
142
+ const {runSecrets} = await import('./secrets.js');
143
+ const result = await runSecrets({subcommand: 'set', key: 'K', value: 'V'});
144
+ expect(result).toBe(1);
145
+ expect(stderrOutput).toContain('500');
146
+ });
147
+
148
+ it('should show count for listed secrets', async () => {
149
+ fetchSpy.mockResolvedValue(new Response(JSON.stringify([
150
+ {key: 'A'},
151
+ {key: 'B'},
152
+ {key: 'C'},
153
+ ]), {status: 200}));
154
+
155
+ const {runSecrets} = await import('./secrets.js');
156
+ await runSecrets({subcommand: 'list'});
157
+ expect(stderrOutput).toContain('3 secrets');
158
+ });
159
+
160
+ it('should use singular for single secret', async () => {
161
+ fetchSpy.mockResolvedValue(new Response(JSON.stringify([{key: 'ONLY'}]), {status: 200}));
162
+
163
+ const {runSecrets} = await import('./secrets.js');
164
+ await runSecrets({subcommand: 'list'});
165
+ expect(stderrOutput).toContain('1 secret configured');
166
+ expect(stderrOutput).not.toContain('1 secrets');
167
+ });
168
+ });
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import type {CommandModule} from 'yargs';
8
+ import {resolvePlatformConfig} from '../shared/platform-client.js';
9
+
10
+ export interface SecretsOptions {
11
+ cwd?: string;
12
+ subcommand: 'set' | 'list' | 'delete';
13
+ key?: string;
14
+ value?: string;
15
+ json?: boolean;
16
+ }
17
+
18
+ /**
19
+ * Manage platform secrets.
20
+ * Returns 0 on success, 1 on error.
21
+ */
22
+ export async function runSecrets(options: SecretsOptions): Promise<number> {
23
+ let config: {url: string; apiKey: string};
24
+ try {
25
+ config = await resolvePlatformConfig();
26
+ } catch (err) {
27
+ const msg = err instanceof Error ? err.message : String(err);
28
+ process.stderr.write(`[secrets] ${msg}\n`);
29
+ return 1;
30
+ }
31
+
32
+ const headers: Record<string, string> = {
33
+ 'Authorization': `Bearer ${config.apiKey}`,
34
+ 'Content-Type': 'application/json',
35
+ };
36
+
37
+ switch (options.subcommand) {
38
+ case 'set': {
39
+ if (!options.key) {
40
+ process.stderr.write('[secrets] Missing key. Usage: amodal secrets set <key> <value>\n');
41
+ return 1;
42
+ }
43
+ if (options.value === undefined) {
44
+ process.stderr.write('[secrets] Missing value. Usage: amodal secrets set <key> <value>\n');
45
+ return 1;
46
+ }
47
+
48
+ try {
49
+ const response = await fetch(`${config.url}/api/secrets`, {
50
+ method: 'PUT',
51
+ headers,
52
+ body: JSON.stringify({key: options.key, value: options.value}),
53
+ });
54
+
55
+ if (!response.ok) {
56
+ process.stderr.write(`[secrets] Failed to set secret: ${response.status} ${response.statusText}\n`);
57
+ return 1;
58
+ }
59
+
60
+ process.stderr.write(`[secrets] Secret "${options.key}" set successfully.\n`);
61
+ return 0;
62
+ } catch (err) {
63
+ const msg = err instanceof Error ? err.message : String(err);
64
+ process.stderr.write(`[secrets] Failed to set secret: ${msg}\n`);
65
+ return 1;
66
+ }
67
+ }
68
+
69
+ case 'list': {
70
+ try {
71
+ const response = await fetch(`${config.url}/api/secrets`, {
72
+ method: 'GET',
73
+ headers,
74
+ });
75
+
76
+ if (!response.ok) {
77
+ process.stderr.write(`[secrets] Failed to list secrets: ${response.status} ${response.statusText}\n`);
78
+ return 1;
79
+ }
80
+
81
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
82
+ const secrets = (await response.json()) as Array<{key: string}>;
83
+
84
+ if (secrets.length === 0) {
85
+ process.stderr.write('[secrets] No secrets configured.\n');
86
+ return 0;
87
+ }
88
+
89
+ if (options.json) {
90
+ process.stdout.write(JSON.stringify(secrets, null, 2) + '\n');
91
+ return 0;
92
+ }
93
+
94
+ process.stdout.write('KEY\n');
95
+ for (const secret of secrets) {
96
+ process.stdout.write(`${secret.key}\n`);
97
+ }
98
+
99
+ process.stderr.write(`[secrets] ${secrets.length} secret${secrets.length === 1 ? '' : 's'} configured.\n`);
100
+ return 0;
101
+ } catch (err) {
102
+ const msg = err instanceof Error ? err.message : String(err);
103
+ process.stderr.write(`[secrets] Failed to list secrets: ${msg}\n`);
104
+ return 1;
105
+ }
106
+ }
107
+
108
+ case 'delete': {
109
+ if (!options.key) {
110
+ process.stderr.write('[secrets] Missing key. Usage: amodal secrets delete <key>\n');
111
+ return 1;
112
+ }
113
+
114
+ try {
115
+ const response = await fetch(`${config.url}/api/secrets/${encodeURIComponent(options.key)}`, {
116
+ method: 'DELETE',
117
+ headers,
118
+ });
119
+
120
+ if (!response.ok) {
121
+ process.stderr.write(`[secrets] Failed to delete secret: ${response.status} ${response.statusText}\n`);
122
+ return 1;
123
+ }
124
+
125
+ process.stderr.write(`[secrets] Secret "${options.key}" deleted.\n`);
126
+ return 0;
127
+ } catch (err) {
128
+ const msg = err instanceof Error ? err.message : String(err);
129
+ process.stderr.write(`[secrets] Failed to delete secret: ${msg}\n`);
130
+ return 1;
131
+ }
132
+ }
133
+
134
+ default:
135
+ break;
136
+ }
137
+
138
+ return 1;
139
+ }
140
+
141
+ export const secretsCommand: CommandModule = {
142
+ command: 'secrets <subcommand> [key] [value]',
143
+ describe: 'Manage platform secrets',
144
+ builder: (yargs) =>
145
+ yargs
146
+ .positional('subcommand', {type: 'string', demandOption: true, choices: ['set', 'list', 'delete'] as const, describe: 'Action'})
147
+ .positional('key', {type: 'string', describe: 'Secret key'})
148
+ .positional('value', {type: 'string', describe: 'Secret value (for set)'})
149
+ .option('json', {type: 'boolean', default: false, describe: 'Output as JSON'}),
150
+ handler: async (argv) => {
151
+ const code = await runSecrets({
152
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
153
+ subcommand: argv['subcommand'] as 'set' | 'list' | 'delete',
154
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
155
+ key: argv['key'] as string | undefined,
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
157
+ value: argv['value'] as string | undefined,
158
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
159
+ json: argv['json'] as boolean,
160
+ });
161
+ process.exit(code);
162
+ },
163
+ };
@@ -0,0 +1,166 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import type {CommandModule} from 'yargs';
8
+ import {loadSnapshotFromFile, snapshotToRepo} from '@amodalai/core';
9
+ import type {AmodalRepo} from '@amodalai/core';
10
+ import {createLocalServer} from '@amodalai/runtime';
11
+ import {PlatformClient} from '../shared/platform-client.js';
12
+
13
+ export interface ServeOptions {
14
+ config?: string;
15
+ platform?: boolean;
16
+ project?: string;
17
+ env?: string;
18
+ port?: number;
19
+ host?: string;
20
+ }
21
+
22
+ const DEFAULT_PORT = 3847;
23
+
24
+ /**
25
+ * Load a repo from a snapshot file or from the platform.
26
+ */
27
+ async function loadFromSource(options: ServeOptions): Promise<AmodalRepo | null> {
28
+ if (options.config) {
29
+ process.stderr.write(`[serve] Loading snapshot from ${options.config}...\n`);
30
+ try {
31
+ const snapshot = await loadSnapshotFromFile(options.config);
32
+ const repo = snapshotToRepo(snapshot, options.config);
33
+ process.stderr.write(`[serve] Loaded ${snapshot.deployId} (${snapshot.skills.length} skills, ${Object.keys(snapshot.connections).length} connections)\n`);
34
+ return repo;
35
+ } catch (err) {
36
+ const msg = err instanceof Error ? err.message : String(err);
37
+ process.stderr.write(`[serve] Failed to load snapshot: ${msg}\n`);
38
+ return null;
39
+ }
40
+ }
41
+
42
+ if (options.platform) {
43
+ process.stderr.write('[serve] Fetching active snapshot from platform...\n');
44
+ let client: PlatformClient;
45
+ try {
46
+ client = await PlatformClient.create();
47
+ } catch (err) {
48
+ const msg = err instanceof Error ? err.message : String(err);
49
+ process.stderr.write(`[serve] ${msg}\n`);
50
+ return null;
51
+ }
52
+
53
+ const environment = options.env ?? 'production';
54
+ try {
55
+ const snapshot = await client.getActiveSnapshot(environment);
56
+ const repo = snapshotToRepo(snapshot, `platform:${environment}`);
57
+ process.stderr.write(`[serve] Loaded ${snapshot.deployId} from ${environment}\n`);
58
+ return repo;
59
+ } catch (err) {
60
+ const msg = err instanceof Error ? err.message : String(err);
61
+ process.stderr.write(`[serve] Failed to fetch snapshot: ${msg}\n`);
62
+ return null;
63
+ }
64
+ }
65
+
66
+ process.stderr.write('[serve] Specify --config <file> or --platform to load a snapshot.\n');
67
+ return null;
68
+ }
69
+
70
+ /**
71
+ * Load an agent runtime from a snapshot (file or platform) and start the server.
72
+ *
73
+ * Returns the loaded repo, or exits with error.
74
+ */
75
+ export async function runServe(options: ServeOptions): Promise<AmodalRepo | null> {
76
+ const repo = await loadFromSource(options);
77
+ if (!repo) return null;
78
+
79
+ // Start the runtime server
80
+ const port = options.port ?? DEFAULT_PORT;
81
+ const host = options.host ?? '0.0.0.0';
82
+
83
+ process.stderr.write(`[serve] Starting server on ${host}:${port}...\n`);
84
+
85
+ try {
86
+ const server = await createLocalServer({
87
+ repoPath: repo.origin,
88
+ port,
89
+ host,
90
+ hotReload: false,
91
+ corsOrigin: '*',
92
+ });
93
+
94
+ await server.start();
95
+
96
+ process.stderr.write(`[serve] Agent "${repo.config.name}" serving at http://${host}:${port}\n`);
97
+
98
+ // Graceful shutdown
99
+ const shutdown = async (signal: string): Promise<void> => {
100
+ process.stderr.write(`\n[serve] Received ${signal}, shutting down...\n`);
101
+ await server.stop();
102
+ process.exit(0);
103
+ };
104
+
105
+ process.on('SIGTERM', () => void shutdown('SIGTERM'));
106
+ process.on('SIGINT', () => void shutdown('SIGINT'));
107
+ } catch (err) {
108
+ const msg = err instanceof Error ? err.message : String(err);
109
+ process.stderr.write(`[serve] Failed to start server: ${msg}\n`);
110
+ return null;
111
+ }
112
+
113
+ return repo;
114
+ }
115
+
116
+ export const serveCommand: CommandModule = {
117
+ command: 'serve',
118
+ describe: 'Load and serve an agent from a snapshot',
119
+ builder: (yargs) =>
120
+ yargs
121
+ .option('config', {
122
+ type: 'string',
123
+ describe: 'Path to resolved-config.json snapshot file',
124
+ })
125
+ .option('platform', {
126
+ type: 'boolean',
127
+ describe: 'Fetch active snapshot from platform',
128
+ default: false,
129
+ })
130
+ .option('project', {
131
+ type: 'string',
132
+ describe: 'Platform project name',
133
+ })
134
+ .option('env', {
135
+ type: 'string',
136
+ describe: 'Platform environment (default: production)',
137
+ })
138
+ .option('port', {
139
+ type: 'number',
140
+ describe: `Port to listen on (default: ${DEFAULT_PORT})`,
141
+ })
142
+ .option('host', {
143
+ type: 'string',
144
+ describe: 'Host to bind to (default: 0.0.0.0)',
145
+ }),
146
+ handler: async (argv) => {
147
+ const repo = await runServe({
148
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
149
+ config: argv['config'] as string | undefined,
150
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
151
+ platform: argv['platform'] as boolean | undefined,
152
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
153
+ project: argv['project'] as string | undefined,
154
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
155
+ env: argv['env'] as string | undefined,
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
157
+ port: argv['port'] as number | undefined,
158
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
159
+ host: argv['host'] as string | undefined,
160
+ });
161
+ if (!repo) {
162
+ process.exit(1);
163
+ }
164
+ // Server is running — process stays alive until SIGTERM/SIGINT
165
+ },
166
+ };