@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.
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/src/auth/index.d.ts +13 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +10 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/oauth2.d.ts +51 -0
- package/dist/src/auth/oauth2.d.ts.map +1 -0
- package/dist/src/auth/oauth2.js +196 -0
- package/dist/src/auth/oauth2.js.map +1 -0
- package/dist/src/auth/prompt.d.ts +21 -0
- package/dist/src/auth/prompt.d.ts.map +1 -0
- package/dist/src/auth/prompt.js +81 -0
- package/dist/src/auth/prompt.js.map +1 -0
- package/dist/src/auth/test-connection.d.ts +27 -0
- package/dist/src/auth/test-connection.d.ts.map +1 -0
- package/dist/src/auth/test-connection.js +153 -0
- package/dist/src/auth/test-connection.js.map +1 -0
- package/dist/src/auth/types.d.ts +32 -0
- package/dist/src/auth/types.d.ts.map +1 -0
- package/dist/src/auth/types.js +7 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/commands/audit.d.ts +18 -0
- package/dist/src/commands/audit.d.ts.map +1 -0
- package/dist/src/commands/audit.js +86 -0
- package/dist/src/commands/audit.js.map +1 -0
- package/dist/src/commands/automations.d.ts +28 -0
- package/dist/src/commands/automations.d.ts.map +1 -0
- package/dist/src/commands/automations.js +179 -0
- package/dist/src/commands/automations.js.map +1 -0
- package/dist/src/commands/build-manifest-types.d.ts +33 -0
- package/dist/src/commands/build-manifest-types.d.ts.map +1 -0
- package/dist/src/commands/build-manifest-types.js +30 -0
- package/dist/src/commands/build-manifest-types.js.map +1 -0
- package/dist/src/commands/build-tools.d.ts +33 -0
- package/dist/src/commands/build-tools.d.ts.map +1 -0
- package/dist/src/commands/build-tools.js +237 -0
- package/dist/src/commands/build-tools.js.map +1 -0
- package/dist/src/commands/build.d.ts +23 -0
- package/dist/src/commands/build.d.ts.map +1 -0
- package/dist/src/commands/build.js +120 -0
- package/dist/src/commands/build.js.map +1 -0
- package/dist/src/commands/chat.d.ts +26 -0
- package/dist/src/commands/chat.d.ts.map +1 -0
- package/dist/src/commands/chat.js +123 -0
- package/dist/src/commands/chat.js.map +1 -0
- package/dist/src/commands/connect.d.ts +18 -0
- package/dist/src/commands/connect.d.ts.map +1 -0
- package/dist/src/commands/connect.js +198 -0
- package/dist/src/commands/connect.js.map +1 -0
- package/dist/src/commands/deploy.d.ts +20 -0
- package/dist/src/commands/deploy.d.ts.map +1 -0
- package/dist/src/commands/deploy.js +137 -0
- package/dist/src/commands/deploy.js.map +1 -0
- package/dist/src/commands/deployments.d.ts +17 -0
- package/dist/src/commands/deployments.d.ts.map +1 -0
- package/dist/src/commands/deployments.js +77 -0
- package/dist/src/commands/deployments.js.map +1 -0
- package/dist/src/commands/dev.d.ts +17 -0
- package/dist/src/commands/dev.d.ts.map +1 -0
- package/dist/src/commands/dev.js +109 -0
- package/dist/src/commands/dev.js.map +1 -0
- package/dist/src/commands/diff.d.ts +19 -0
- package/dist/src/commands/diff.d.ts.map +1 -0
- package/dist/src/commands/diff.js +120 -0
- package/dist/src/commands/diff.js.map +1 -0
- package/dist/src/commands/docker.d.ts +21 -0
- package/dist/src/commands/docker.d.ts.map +1 -0
- package/dist/src/commands/docker.js +215 -0
- package/dist/src/commands/docker.js.map +1 -0
- package/dist/src/commands/eval.d.ts +20 -0
- package/dist/src/commands/eval.d.ts.map +1 -0
- package/dist/src/commands/eval.js +236 -0
- package/dist/src/commands/eval.js.map +1 -0
- package/dist/src/commands/experiment.d.ts +21 -0
- package/dist/src/commands/experiment.d.ts.map +1 -0
- package/dist/src/commands/experiment.js +133 -0
- package/dist/src/commands/experiment.js.map +1 -0
- package/dist/src/commands/index.d.ts +10 -0
- package/dist/src/commands/index.d.ts.map +1 -0
- package/dist/src/commands/index.js +75 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/init.d.ts +17 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +73 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/inspect.d.ts +22 -0
- package/dist/src/commands/inspect.d.ts.map +1 -0
- package/dist/src/commands/inspect.js +131 -0
- package/dist/src/commands/inspect.js.map +1 -0
- package/dist/src/commands/install-pkg.d.ts +29 -0
- package/dist/src/commands/install-pkg.d.ts.map +1 -0
- package/dist/src/commands/install-pkg.js +202 -0
- package/dist/src/commands/install-pkg.js.map +1 -0
- package/dist/src/commands/link.d.ts +32 -0
- package/dist/src/commands/link.d.ts.map +1 -0
- package/dist/src/commands/link.js +227 -0
- package/dist/src/commands/link.js.map +1 -0
- package/dist/src/commands/list.d.ts +19 -0
- package/dist/src/commands/list.d.ts.map +1 -0
- package/dist/src/commands/list.js +78 -0
- package/dist/src/commands/list.js.map +1 -0
- package/dist/src/commands/login.d.ts +31 -0
- package/dist/src/commands/login.d.ts.map +1 -0
- package/dist/src/commands/login.js +205 -0
- package/dist/src/commands/login.js.map +1 -0
- package/dist/src/commands/promote.d.ts +16 -0
- package/dist/src/commands/promote.d.ts.map +1 -0
- package/dist/src/commands/promote.js +55 -0
- package/dist/src/commands/promote.js.map +1 -0
- package/dist/src/commands/publish.d.ts +18 -0
- package/dist/src/commands/publish.d.ts.map +1 -0
- package/dist/src/commands/publish.js +122 -0
- package/dist/src/commands/publish.js.map +1 -0
- package/dist/src/commands/rollback.d.ts +17 -0
- package/dist/src/commands/rollback.d.ts.map +1 -0
- package/dist/src/commands/rollback.js +62 -0
- package/dist/src/commands/rollback.js.map +1 -0
- package/dist/src/commands/search.d.ts +20 -0
- package/dist/src/commands/search.d.ts.map +1 -0
- package/dist/src/commands/search.js +133 -0
- package/dist/src/commands/search.js.map +1 -0
- package/dist/src/commands/secrets.d.ts +20 -0
- package/dist/src/commands/secrets.d.ts.map +1 -0
- package/dist/src/commands/secrets.js +137 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/serve.d.ts +23 -0
- package/dist/src/commands/serve.d.ts.map +1 -0
- package/dist/src/commands/serve.js +144 -0
- package/dist/src/commands/serve.js.map +1 -0
- package/dist/src/commands/status.d.ts +16 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +83 -0
- package/dist/src/commands/status.js.map +1 -0
- package/dist/src/commands/sync.d.ts +21 -0
- package/dist/src/commands/sync.d.ts.map +1 -0
- package/dist/src/commands/sync.js +94 -0
- package/dist/src/commands/sync.js.map +1 -0
- package/dist/src/commands/test-query.d.ts +19 -0
- package/dist/src/commands/test-query.d.ts.map +1 -0
- package/dist/src/commands/test-query.js +116 -0
- package/dist/src/commands/test-query.js.map +1 -0
- package/dist/src/commands/uninstall.d.ts +19 -0
- package/dist/src/commands/uninstall.d.ts.map +1 -0
- package/dist/src/commands/uninstall.js +84 -0
- package/dist/src/commands/uninstall.js.map +1 -0
- package/dist/src/commands/update.d.ts +21 -0
- package/dist/src/commands/update.d.ts.map +1 -0
- package/dist/src/commands/update.js +145 -0
- package/dist/src/commands/update.js.map +1 -0
- package/dist/src/commands/validate.d.ts +19 -0
- package/dist/src/commands/validate.d.ts.map +1 -0
- package/dist/src/commands/validate.js +114 -0
- package/dist/src/commands/validate.js.map +1 -0
- package/dist/src/fixtures/incident-response.d.ts +91 -0
- package/dist/src/fixtures/incident-response.d.ts.map +1 -0
- package/dist/src/fixtures/incident-response.js +208 -0
- package/dist/src/fixtures/incident-response.js.map +1 -0
- package/dist/src/main.d.ts +8 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +30 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/shared/platform-client.d.ts +92 -0
- package/dist/src/shared/platform-client.d.ts.map +1 -0
- package/dist/src/shared/platform-client.js +155 -0
- package/dist/src/shared/platform-client.js.map +1 -0
- package/dist/src/shared/repo-discovery.d.ts +11 -0
- package/dist/src/shared/repo-discovery.d.ts.map +1 -0
- package/dist/src/shared/repo-discovery.js +33 -0
- package/dist/src/shared/repo-discovery.js.map +1 -0
- package/dist/src/templates/compose-template.d.ts +10 -0
- package/dist/src/templates/compose-template.d.ts.map +1 -0
- package/dist/src/templates/compose-template.js +30 -0
- package/dist/src/templates/compose-template.js.map +1 -0
- package/dist/src/templates/config-template.d.ts +14 -0
- package/dist/src/templates/config-template.d.ts.map +1 -0
- package/dist/src/templates/config-template.js +35 -0
- package/dist/src/templates/config-template.js.map +1 -0
- package/dist/src/templates/dockerfile-template.d.ts +10 -0
- package/dist/src/templates/dockerfile-template.d.ts.map +1 -0
- package/dist/src/templates/dockerfile-template.js +30 -0
- package/dist/src/templates/dockerfile-template.js.map +1 -0
- package/dist/src/templates/env-template.d.ts +12 -0
- package/dist/src/templates/env-template.d.ts.map +1 -0
- package/dist/src/templates/env-template.js +24 -0
- package/dist/src/templates/env-template.js.map +1 -0
- package/dist/src/templates/knowledge-template.d.ts +10 -0
- package/dist/src/templates/knowledge-template.d.ts.map +1 -0
- package/dist/src/templates/knowledge-template.js +24 -0
- package/dist/src/templates/knowledge-template.js.map +1 -0
- package/dist/src/templates/skill-template.d.ts +10 -0
- package/dist/src/templates/skill-template.d.ts.map +1 -0
- package/dist/src/templates/skill-template.js +27 -0
- package/dist/src/templates/skill-template.js.map +1 -0
- package/dist/src/ui/AskUserPrompt.d.ts +14 -0
- package/dist/src/ui/AskUserPrompt.d.ts.map +1 -0
- package/dist/src/ui/AskUserPrompt.js +17 -0
- package/dist/src/ui/AskUserPrompt.js.map +1 -0
- package/dist/src/ui/AssistantMessage.d.ts +14 -0
- package/dist/src/ui/AssistantMessage.d.ts.map +1 -0
- package/dist/src/ui/AssistantMessage.js +8 -0
- package/dist/src/ui/AssistantMessage.js.map +1 -0
- package/dist/src/ui/ChatApp.d.ts +15 -0
- package/dist/src/ui/ChatApp.d.ts.map +1 -0
- package/dist/src/ui/ChatApp.js +144 -0
- package/dist/src/ui/ChatApp.js.map +1 -0
- package/dist/src/ui/ConfirmationPrompt.d.ts +17 -0
- package/dist/src/ui/ConfirmationPrompt.d.ts.map +1 -0
- package/dist/src/ui/ConfirmationPrompt.js +21 -0
- package/dist/src/ui/ConfirmationPrompt.js.map +1 -0
- package/dist/src/ui/DiffRenderer.d.ts +32 -0
- package/dist/src/ui/DiffRenderer.d.ts.map +1 -0
- package/dist/src/ui/DiffRenderer.js +118 -0
- package/dist/src/ui/DiffRenderer.js.map +1 -0
- package/dist/src/ui/ExpandableContent.d.ts +15 -0
- package/dist/src/ui/ExpandableContent.d.ts.map +1 -0
- package/dist/src/ui/ExpandableContent.js +22 -0
- package/dist/src/ui/ExpandableContent.js.map +1 -0
- package/dist/src/ui/ExploreIndicator.d.ts +13 -0
- package/dist/src/ui/ExploreIndicator.d.ts.map +1 -0
- package/dist/src/ui/ExploreIndicator.js +14 -0
- package/dist/src/ui/ExploreIndicator.js.map +1 -0
- package/dist/src/ui/Footer.d.ts +19 -0
- package/dist/src/ui/Footer.d.ts.map +1 -0
- package/dist/src/ui/Footer.js +57 -0
- package/dist/src/ui/Footer.js.map +1 -0
- package/dist/src/ui/FullScreenLayout.d.ts +18 -0
- package/dist/src/ui/FullScreenLayout.d.ts.map +1 -0
- package/dist/src/ui/FullScreenLayout.js +14 -0
- package/dist/src/ui/FullScreenLayout.js.map +1 -0
- package/dist/src/ui/Header.d.ts +14 -0
- package/dist/src/ui/Header.d.ts.map +1 -0
- package/dist/src/ui/Header.js +11 -0
- package/dist/src/ui/Header.js.map +1 -0
- package/dist/src/ui/InputBar.d.ts +17 -0
- package/dist/src/ui/InputBar.d.ts.map +1 -0
- package/dist/src/ui/InputBar.js +49 -0
- package/dist/src/ui/InputBar.js.map +1 -0
- package/dist/src/ui/MessageList.d.ts +18 -0
- package/dist/src/ui/MessageList.d.ts.map +1 -0
- package/dist/src/ui/MessageList.js +9 -0
- package/dist/src/ui/MessageList.js.map +1 -0
- package/dist/src/ui/NotificationBar.d.ts +14 -0
- package/dist/src/ui/NotificationBar.d.ts.map +1 -0
- package/dist/src/ui/NotificationBar.js +38 -0
- package/dist/src/ui/NotificationBar.js.map +1 -0
- package/dist/src/ui/ScrollableMessageList.d.ts +27 -0
- package/dist/src/ui/ScrollableMessageList.d.ts.map +1 -0
- package/dist/src/ui/ScrollableMessageList.js +16 -0
- package/dist/src/ui/ScrollableMessageList.js.map +1 -0
- package/dist/src/ui/SessionBrowser.d.ts +20 -0
- package/dist/src/ui/SessionBrowser.d.ts.map +1 -0
- package/dist/src/ui/SessionBrowser.js +93 -0
- package/dist/src/ui/SessionBrowser.js.map +1 -0
- package/dist/src/ui/StatusMessage.d.ts +13 -0
- package/dist/src/ui/StatusMessage.d.ts.map +1 -0
- package/dist/src/ui/StatusMessage.js +17 -0
- package/dist/src/ui/StatusMessage.js.map +1 -0
- package/dist/src/ui/StreamingView.d.ts +19 -0
- package/dist/src/ui/StreamingView.d.ts.map +1 -0
- package/dist/src/ui/StreamingView.js +18 -0
- package/dist/src/ui/StreamingView.js.map +1 -0
- package/dist/src/ui/SubagentDisplay.d.ts +13 -0
- package/dist/src/ui/SubagentDisplay.d.ts.map +1 -0
- package/dist/src/ui/SubagentDisplay.js +22 -0
- package/dist/src/ui/SubagentDisplay.js.map +1 -0
- package/dist/src/ui/ThinkingDisplay.d.ts +13 -0
- package/dist/src/ui/ThinkingDisplay.d.ts.map +1 -0
- package/dist/src/ui/ThinkingDisplay.js +15 -0
- package/dist/src/ui/ThinkingDisplay.js.map +1 -0
- package/dist/src/ui/ToolCallDisplay.d.ts +16 -0
- package/dist/src/ui/ToolCallDisplay.d.ts.map +1 -0
- package/dist/src/ui/ToolCallDisplay.js +136 -0
- package/dist/src/ui/ToolCallDisplay.js.map +1 -0
- package/dist/src/ui/UserMessage.d.ts +12 -0
- package/dist/src/ui/UserMessage.d.ts.map +1 -0
- package/dist/src/ui/UserMessage.js +5 -0
- package/dist/src/ui/UserMessage.js.map +1 -0
- package/dist/src/ui/commands/clear.d.ts +7 -0
- package/dist/src/ui/commands/clear.d.ts.map +1 -0
- package/dist/src/ui/commands/clear.js +13 -0
- package/dist/src/ui/commands/clear.js.map +1 -0
- package/dist/src/ui/commands/help.d.ts +7 -0
- package/dist/src/ui/commands/help.d.ts.map +1 -0
- package/dist/src/ui/commands/help.js +26 -0
- package/dist/src/ui/commands/help.js.map +1 -0
- package/dist/src/ui/commands/index.d.ts +14 -0
- package/dist/src/ui/commands/index.d.ts.map +1 -0
- package/dist/src/ui/commands/index.js +15 -0
- package/dist/src/ui/commands/index.js.map +1 -0
- package/dist/src/ui/commands/model.d.ts +7 -0
- package/dist/src/ui/commands/model.d.ts.map +1 -0
- package/dist/src/ui/commands/model.js +16 -0
- package/dist/src/ui/commands/model.js.map +1 -0
- package/dist/src/ui/commands/registry.d.ts +30 -0
- package/dist/src/ui/commands/registry.d.ts.map +1 -0
- package/dist/src/ui/commands/registry.js +45 -0
- package/dist/src/ui/commands/registry.js.map +1 -0
- package/dist/src/ui/commands/sessions.d.ts +7 -0
- package/dist/src/ui/commands/sessions.d.ts.map +1 -0
- package/dist/src/ui/commands/sessions.js +13 -0
- package/dist/src/ui/commands/sessions.js.map +1 -0
- package/dist/src/ui/commands/stats.d.ts +7 -0
- package/dist/src/ui/commands/stats.d.ts.map +1 -0
- package/dist/src/ui/commands/stats.js +33 -0
- package/dist/src/ui/commands/stats.js.map +1 -0
- package/dist/src/ui/commands/theme.d.ts +7 -0
- package/dist/src/ui/commands/theme.d.ts.map +1 -0
- package/dist/src/ui/commands/theme.js +35 -0
- package/dist/src/ui/commands/theme.js.map +1 -0
- package/dist/src/ui/markdown/CodeBlock.d.ts +14 -0
- package/dist/src/ui/markdown/CodeBlock.d.ts.map +1 -0
- package/dist/src/ui/markdown/CodeBlock.js +55 -0
- package/dist/src/ui/markdown/CodeBlock.js.map +1 -0
- package/dist/src/ui/markdown/InlineRenderer.d.ts +12 -0
- package/dist/src/ui/markdown/InlineRenderer.d.ts.map +1 -0
- package/dist/src/ui/markdown/InlineRenderer.js +70 -0
- package/dist/src/ui/markdown/InlineRenderer.js.map +1 -0
- package/dist/src/ui/markdown/MarkdownDisplay.d.ts +17 -0
- package/dist/src/ui/markdown/MarkdownDisplay.d.ts.map +1 -0
- package/dist/src/ui/markdown/MarkdownDisplay.js +142 -0
- package/dist/src/ui/markdown/MarkdownDisplay.js.map +1 -0
- package/dist/src/ui/markdown/Table.d.ts +14 -0
- package/dist/src/ui/markdown/Table.d.ts.map +1 -0
- package/dist/src/ui/markdown/Table.js +31 -0
- package/dist/src/ui/markdown/Table.js.map +1 -0
- package/dist/src/ui/theme.d.ts +39 -0
- package/dist/src/ui/theme.d.ts.map +1 -0
- package/dist/src/ui/theme.js +39 -0
- package/dist/src/ui/theme.js.map +1 -0
- package/dist/src/ui/themes/index.d.ts +45 -0
- package/dist/src/ui/themes/index.d.ts.map +1 -0
- package/dist/src/ui/themes/index.js +73 -0
- package/dist/src/ui/themes/index.js.map +1 -0
- package/dist/src/ui/themes/light.d.ts +8 -0
- package/dist/src/ui/themes/light.d.ts.map +1 -0
- package/dist/src/ui/themes/light.js +37 -0
- package/dist/src/ui/themes/light.js.map +1 -0
- package/dist/src/ui/themes/monochrome.d.ts +8 -0
- package/dist/src/ui/themes/monochrome.d.ts.map +1 -0
- package/dist/src/ui/themes/monochrome.js +37 -0
- package/dist/src/ui/themes/monochrome.js.map +1 -0
- package/dist/src/ui/types.d.ts +191 -0
- package/dist/src/ui/types.d.ts.map +1 -0
- package/dist/src/ui/types.js +7 -0
- package/dist/src/ui/types.js.map +1 -0
- package/dist/src/ui/useAlternateBuffer.d.ts +11 -0
- package/dist/src/ui/useAlternateBuffer.d.ts.map +1 -0
- package/dist/src/ui/useAlternateBuffer.js +25 -0
- package/dist/src/ui/useAlternateBuffer.js.map +1 -0
- package/dist/src/ui/useChat.d.ts +18 -0
- package/dist/src/ui/useChat.d.ts.map +1 -0
- package/dist/src/ui/useChat.js +599 -0
- package/dist/src/ui/useChat.js.map +1 -0
- package/dist/src/ui/useElapsedTime.d.ts +11 -0
- package/dist/src/ui/useElapsedTime.d.ts.map +1 -0
- package/dist/src/ui/useElapsedTime.js +39 -0
- package/dist/src/ui/useElapsedTime.js.map +1 -0
- package/dist/src/ui/useResponsiveLayout.d.ts +16 -0
- package/dist/src/ui/useResponsiveLayout.d.ts.map +1 -0
- package/dist/src/ui/useResponsiveLayout.js +24 -0
- package/dist/src/ui/useResponsiveLayout.js.map +1 -0
- package/dist/src/ui/useScroll.d.ts +20 -0
- package/dist/src/ui/useScroll.d.ts.map +1 -0
- package/dist/src/ui/useScroll.js +64 -0
- package/dist/src/ui/useScroll.js.map +1 -0
- package/dist/src/ui/useSessionResume.d.ts +20 -0
- package/dist/src/ui/useSessionResume.d.ts.map +1 -0
- package/dist/src/ui/useSessionResume.js +77 -0
- package/dist/src/ui/useSessionResume.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +60 -0
- package/src/auth/index.ts +13 -0
- package/src/auth/oauth2.test.ts +305 -0
- package/src/auth/oauth2.ts +269 -0
- package/src/auth/prompt.test.ts +205 -0
- package/src/auth/prompt.ts +111 -0
- package/src/auth/test-connection.test.ts +224 -0
- package/src/auth/test-connection.ts +196 -0
- package/src/auth/types.ts +34 -0
- package/src/commands/audit.test.ts +92 -0
- package/src/commands/audit.ts +113 -0
- package/src/commands/automations.test.ts +85 -0
- package/src/commands/automations.ts +205 -0
- package/src/commands/build-manifest-types.ts +35 -0
- package/src/commands/build-tools.ts +281 -0
- package/src/commands/build.test.ts +63 -0
- package/src/commands/build.ts +135 -0
- package/src/commands/chat.ts +147 -0
- package/src/commands/command-exports.test.ts +88 -0
- package/src/commands/connect.test.ts +343 -0
- package/src/commands/connect.ts +237 -0
- package/src/commands/deploy.test.ts +124 -0
- package/src/commands/deploy.ts +153 -0
- package/src/commands/deployments.ts +90 -0
- package/src/commands/dev.test.ts +63 -0
- package/src/commands/dev.ts +124 -0
- package/src/commands/diff.test.ts +183 -0
- package/src/commands/diff.ts +143 -0
- package/src/commands/docker.ts +232 -0
- package/src/commands/eval.test.ts +88 -0
- package/src/commands/eval.ts +268 -0
- package/src/commands/experiment.test.ts +125 -0
- package/src/commands/experiment.ts +153 -0
- package/src/commands/index.ts +76 -0
- package/src/commands/init.test.ts +109 -0
- package/src/commands/init.ts +98 -0
- package/src/commands/inspect.test.ts +234 -0
- package/src/commands/inspect.ts +157 -0
- package/src/commands/install-pkg.test.ts +265 -0
- package/src/commands/install-pkg.ts +234 -0
- package/src/commands/link.ts +270 -0
- package/src/commands/list.test.ts +152 -0
- package/src/commands/list.ts +95 -0
- package/src/commands/login.test.ts +195 -0
- package/src/commands/login.ts +258 -0
- package/src/commands/promote.ts +64 -0
- package/src/commands/publish.test.ts +203 -0
- package/src/commands/publish.ts +142 -0
- package/src/commands/rollback.ts +72 -0
- package/src/commands/search.test.ts +174 -0
- package/src/commands/search.ts +154 -0
- package/src/commands/secrets.test.ts +168 -0
- package/src/commands/secrets.ts +163 -0
- package/src/commands/serve.ts +166 -0
- package/src/commands/status.ts +94 -0
- package/src/commands/sync.test.ts +130 -0
- package/src/commands/sync.ts +119 -0
- package/src/commands/test-query.test.ts +42 -0
- package/src/commands/test-query.ts +129 -0
- package/src/commands/uninstall.test.ts +162 -0
- package/src/commands/uninstall.ts +107 -0
- package/src/commands/update.test.ts +281 -0
- package/src/commands/update.ts +180 -0
- package/src/commands/validate.test.ts +260 -0
- package/src/commands/validate.ts +139 -0
- package/src/e2e-automations.test.ts +305 -0
- package/src/e2e-commands.test.ts +587 -0
- package/src/e2e-incident-response.test.ts +345 -0
- package/src/e2e-plugin-connections.test.ts +415 -0
- package/src/e2e-plugins.test.ts +492 -0
- package/src/e2e.test.ts +602 -0
- package/src/fixtures/incident-response.ts +232 -0
- package/src/main.ts +35 -0
- package/src/shared/platform-client.test.ts +106 -0
- package/src/shared/platform-client.ts +193 -0
- package/src/shared/repo-discovery.test.ts +56 -0
- package/src/shared/repo-discovery.ts +40 -0
- package/src/templates/compose-template.ts +30 -0
- package/src/templates/config-template.ts +44 -0
- package/src/templates/deployment-templates.test.ts +99 -0
- package/src/templates/dockerfile-template.ts +30 -0
- package/src/templates/env-template.ts +27 -0
- package/src/templates/knowledge-template.ts +24 -0
- package/src/templates/skill-template.ts +27 -0
- package/src/ui/AskUserPrompt.tsx +58 -0
- package/src/ui/AssistantMessage.tsx +51 -0
- package/src/ui/ChatApp.tsx +283 -0
- package/src/ui/ConfirmationPrompt.tsx +75 -0
- package/src/ui/DiffRenderer.test.ts +104 -0
- package/src/ui/DiffRenderer.tsx +188 -0
- package/src/ui/ExpandableContent.tsx +68 -0
- package/src/ui/ExploreIndicator.tsx +44 -0
- package/src/ui/Footer.tsx +87 -0
- package/src/ui/FullScreenLayout.tsx +45 -0
- package/src/ui/Header.tsx +50 -0
- package/src/ui/InputBar.tsx +105 -0
- package/src/ui/MessageList.tsx +31 -0
- package/src/ui/NotificationBar.tsx +64 -0
- package/src/ui/ScrollableMessageList.tsx +82 -0
- package/src/ui/SessionBrowser.test.ts +49 -0
- package/src/ui/SessionBrowser.tsx +179 -0
- package/src/ui/StatusMessage.tsx +35 -0
- package/src/ui/StreamingView.tsx +87 -0
- package/src/ui/SubagentDisplay.tsx +57 -0
- package/src/ui/ThinkingDisplay.tsx +45 -0
- package/src/ui/ToolCallDisplay.tsx +268 -0
- package/src/ui/UserMessage.tsx +22 -0
- package/src/ui/chat-e2e.test.ts +581 -0
- package/src/ui/commands/clear.ts +15 -0
- package/src/ui/commands/help.ts +31 -0
- package/src/ui/commands/index.ts +22 -0
- package/src/ui/commands/model.ts +19 -0
- package/src/ui/commands/registry.test.ts +76 -0
- package/src/ui/commands/registry.ts +66 -0
- package/src/ui/commands/sessions.ts +16 -0
- package/src/ui/commands/stats.ts +35 -0
- package/src/ui/commands/theme.ts +41 -0
- package/src/ui/markdown/CodeBlock.tsx +118 -0
- package/src/ui/markdown/InlineRenderer.tsx +115 -0
- package/src/ui/markdown/MarkdownDisplay.tsx +223 -0
- package/src/ui/markdown/Table.tsx +75 -0
- package/src/ui/theme.ts +39 -0
- package/src/ui/themes/index.ts +113 -0
- package/src/ui/themes/light.ts +39 -0
- package/src/ui/themes/monochrome.ts +39 -0
- package/src/ui/types.ts +157 -0
- package/src/ui/useAlternateBuffer.ts +27 -0
- package/src/ui/useChat.test.ts +492 -0
- package/src/ui/useChat.ts +693 -0
- package/src/ui/useElapsedTime.test.ts +33 -0
- package/src/ui/useElapsedTime.ts +43 -0
- package/src/ui/useResponsiveLayout.test.ts +54 -0
- package/src/ui/useResponsiveLayout.ts +32 -0
- package/src/ui/useScroll.test.ts +99 -0
- package/src/ui/useScroll.ts +97 -0
- package/src/ui/useSessionResume.test.ts +80 -0
- package/src/ui/useSessionResume.ts +102 -0
- package/tsconfig.json +17 -0
- 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
|
+
});
|