@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,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {CommandModule} from 'yargs';
|
|
8
|
+
|
|
9
|
+
const DEFAULT_URL = 'http://localhost:3847';
|
|
10
|
+
|
|
11
|
+
interface AutomationEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
title: string;
|
|
14
|
+
schedule?: string;
|
|
15
|
+
webhookTriggered: boolean;
|
|
16
|
+
running: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function fetchJson(url: string, method: 'GET' | 'POST' = 'GET'): Promise<unknown> {
|
|
20
|
+
const res = await fetch(url, {method});
|
|
21
|
+
const body = await res.json();
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSON response
|
|
24
|
+
const err = (body as Record<string, unknown>)['error'] ?? res.statusText;
|
|
25
|
+
throw new Error(String(err));
|
|
26
|
+
}
|
|
27
|
+
return body;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface AutomationsOptions {
|
|
31
|
+
url?: string;
|
|
32
|
+
json?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* List automations from a running server.
|
|
37
|
+
*/
|
|
38
|
+
export async function runAutomationsList(options: AutomationsOptions = {}): Promise<number> {
|
|
39
|
+
const base = options.url ?? DEFAULT_URL;
|
|
40
|
+
try {
|
|
41
|
+
const data = await fetchJson(`${base}/automations`);
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSON response
|
|
43
|
+
const automations = (data as {automations: AutomationEntry[]}).automations;
|
|
44
|
+
|
|
45
|
+
if (automations.length === 0) {
|
|
46
|
+
process.stderr.write('[automations] No automations defined.\n');
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.json) {
|
|
51
|
+
process.stdout.write(JSON.stringify(automations, null, 2) + '\n');
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const nameW = Math.max(4, ...automations.map((a) => a.name.length));
|
|
56
|
+
const titleW = Math.max(5, ...automations.map((a) => a.title.length));
|
|
57
|
+
const typeW = 8;
|
|
58
|
+
const statusW = 7;
|
|
59
|
+
|
|
60
|
+
const header = [
|
|
61
|
+
'NAME'.padEnd(nameW),
|
|
62
|
+
'TITLE'.padEnd(titleW),
|
|
63
|
+
'TYPE'.padEnd(typeW),
|
|
64
|
+
'STATUS'.padEnd(statusW),
|
|
65
|
+
'SCHEDULE',
|
|
66
|
+
].join(' ');
|
|
67
|
+
|
|
68
|
+
process.stdout.write(header + '\n');
|
|
69
|
+
|
|
70
|
+
for (const a of automations) {
|
|
71
|
+
const type = a.webhookTriggered ? 'webhook' : 'cron';
|
|
72
|
+
const status = a.running ? 'running' : 'stopped';
|
|
73
|
+
const row = [
|
|
74
|
+
a.name.padEnd(nameW),
|
|
75
|
+
a.title.padEnd(titleW),
|
|
76
|
+
type.padEnd(typeW),
|
|
77
|
+
status.padEnd(statusW),
|
|
78
|
+
a.schedule ?? '-',
|
|
79
|
+
].join(' ');
|
|
80
|
+
process.stdout.write(row + '\n');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return 0;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
86
|
+
process.stderr.write(`[automations] ${msg}\n`);
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Start a cron automation on a running server.
|
|
93
|
+
*/
|
|
94
|
+
export async function runAutomationsStart(name: string, options: AutomationsOptions = {}): Promise<number> {
|
|
95
|
+
const base = options.url ?? DEFAULT_URL;
|
|
96
|
+
try {
|
|
97
|
+
await fetchJson(`${base}/automations/${encodeURIComponent(name)}/start`, 'POST');
|
|
98
|
+
process.stderr.write(`[automations] Started "${name}"\n`);
|
|
99
|
+
return 0;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
102
|
+
process.stderr.write(`[automations] ${msg}\n`);
|
|
103
|
+
return 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Stop a running cron automation on a running server.
|
|
109
|
+
*/
|
|
110
|
+
export async function runAutomationsStop(name: string, options: AutomationsOptions = {}): Promise<number> {
|
|
111
|
+
const base = options.url ?? DEFAULT_URL;
|
|
112
|
+
try {
|
|
113
|
+
await fetchJson(`${base}/automations/${encodeURIComponent(name)}/stop`, 'POST');
|
|
114
|
+
process.stderr.write(`[automations] Stopped "${name}"\n`);
|
|
115
|
+
return 0;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
118
|
+
process.stderr.write(`[automations] ${msg}\n`);
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Manually trigger an automation on a running server.
|
|
125
|
+
*/
|
|
126
|
+
export async function runAutomationsRun(name: string, options: AutomationsOptions = {}): Promise<number> {
|
|
127
|
+
const base = options.url ?? DEFAULT_URL;
|
|
128
|
+
try {
|
|
129
|
+
await fetchJson(`${base}/automations/${encodeURIComponent(name)}/run`, 'POST');
|
|
130
|
+
process.stderr.write(`[automations] Triggered "${name}"\n`);
|
|
131
|
+
return 0;
|
|
132
|
+
} catch (err) {
|
|
133
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
134
|
+
process.stderr.write(`[automations] ${msg}\n`);
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const automationsCommand: CommandModule = {
|
|
140
|
+
command: 'automations <action> [name]',
|
|
141
|
+
describe: 'Manage automations on a running server',
|
|
142
|
+
builder: (yargs) =>
|
|
143
|
+
yargs
|
|
144
|
+
.positional('action', {
|
|
145
|
+
type: 'string',
|
|
146
|
+
choices: ['list', 'start', 'stop', 'run'] as const,
|
|
147
|
+
describe: 'Action to perform',
|
|
148
|
+
})
|
|
149
|
+
.positional('name', {
|
|
150
|
+
type: 'string',
|
|
151
|
+
describe: 'Automation name (required for start/stop/run)',
|
|
152
|
+
})
|
|
153
|
+
.option('url', {
|
|
154
|
+
type: 'string',
|
|
155
|
+
describe: `Server URL (default: ${DEFAULT_URL})`,
|
|
156
|
+
})
|
|
157
|
+
.option('json', {
|
|
158
|
+
type: 'boolean',
|
|
159
|
+
default: false,
|
|
160
|
+
describe: 'Output as JSON (list only)',
|
|
161
|
+
}),
|
|
162
|
+
handler: async (argv) => {
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
164
|
+
const action = argv['action'] as string;
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
166
|
+
const name = argv['name'] as string | undefined;
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
168
|
+
const url = argv['url'] as string | undefined;
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
170
|
+
const json = argv['json'] as boolean;
|
|
171
|
+
|
|
172
|
+
let code: number;
|
|
173
|
+
switch (action) {
|
|
174
|
+
case 'list':
|
|
175
|
+
code = await runAutomationsList({url, json});
|
|
176
|
+
break;
|
|
177
|
+
case 'start':
|
|
178
|
+
if (!name) {
|
|
179
|
+
process.stderr.write('[automations] Name required for start\n');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
code = await runAutomationsStart(name, {url});
|
|
183
|
+
break;
|
|
184
|
+
case 'stop':
|
|
185
|
+
if (!name) {
|
|
186
|
+
process.stderr.write('[automations] Name required for stop\n');
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
code = await runAutomationsStop(name, {url});
|
|
190
|
+
break;
|
|
191
|
+
case 'run':
|
|
192
|
+
if (!name) {
|
|
193
|
+
process.stderr.write('[automations] Name required for run\n');
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
code = await runAutomationsRun(name, {url});
|
|
197
|
+
break;
|
|
198
|
+
default:
|
|
199
|
+
process.stderr.write(`[automations] Unknown action: ${action}\n`);
|
|
200
|
+
code = 1;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
process.exit(code);
|
|
204
|
+
},
|
|
205
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {z} from 'zod';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Schema for a single tool entry in the build manifest.
|
|
11
|
+
*/
|
|
12
|
+
export const BuildManifestToolSchema = z.object({
|
|
13
|
+
/** Daytona snapshot ID for fast workspace creation */
|
|
14
|
+
snapshotId: z.string().min(1),
|
|
15
|
+
/** Content hash of the tool's source files */
|
|
16
|
+
imageHash: z.string().min(1),
|
|
17
|
+
/** Sandbox language runtime */
|
|
18
|
+
sandboxLanguage: z.string().default('typescript'),
|
|
19
|
+
/** Whether the tool was built from a Dockerfile */
|
|
20
|
+
hasDockerfile: z.boolean().default(false),
|
|
21
|
+
/** Whether the tool has a setup.sh script */
|
|
22
|
+
hasSetupScript: z.boolean().default(false),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Schema for .amodal/build-manifest.json.
|
|
27
|
+
*/
|
|
28
|
+
export const BuildManifestSchema = z.object({
|
|
29
|
+
version: z.literal(1),
|
|
30
|
+
builtAt: z.string().datetime(),
|
|
31
|
+
tools: z.record(z.string(), BuildManifestToolSchema),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export type BuildManifest = z.infer<typeof BuildManifestSchema>;
|
|
35
|
+
export type BuildManifestTool = z.infer<typeof BuildManifestToolSchema>;
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {createHash} from 'node:crypto';
|
|
8
|
+
import {readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync} from 'node:fs';
|
|
9
|
+
import {join, relative} from 'node:path';
|
|
10
|
+
import {execSync} from 'node:child_process';
|
|
11
|
+
import type {LoadedTool} from '@amodalai/core';
|
|
12
|
+
import type {BuildManifest} from './build-manifest-types.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Recursively list all files in a directory, returning paths relative to root.
|
|
16
|
+
* Skips node_modules, .git, __pycache__.
|
|
17
|
+
*/
|
|
18
|
+
export function listFilesRecursive(dir: string, root?: string): string[] {
|
|
19
|
+
const base = root ?? dir;
|
|
20
|
+
const results: string[] = [];
|
|
21
|
+
try {
|
|
22
|
+
const entries = readdirSync(dir, {withFileTypes: true});
|
|
23
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
24
|
+
const fullPath = join(dir, entry.name);
|
|
25
|
+
if (entry.isDirectory()) {
|
|
26
|
+
if (['node_modules', '.git', '__pycache__', '.venv', 'dist'].includes(entry.name)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
results.push(...listFilesRecursive(fullPath, base));
|
|
30
|
+
} else if (entry.isFile()) {
|
|
31
|
+
results.push(relative(base, fullPath));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// Directory unreadable
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Compute a content hash for all files in the tool directory (recursive).
|
|
42
|
+
*/
|
|
43
|
+
function computeToolHash(tool: LoadedTool): string {
|
|
44
|
+
const hash = createHash('sha256');
|
|
45
|
+
const files = listFilesRecursive(tool.location);
|
|
46
|
+
|
|
47
|
+
for (const relPath of files) {
|
|
48
|
+
hash.update(`file:${relPath}:`);
|
|
49
|
+
try {
|
|
50
|
+
hash.update(readFileSync(join(tool.location, relPath)));
|
|
51
|
+
} catch {
|
|
52
|
+
hash.update('unreadable');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
hash.update(`sandbox-language:${tool.sandboxLanguage}`);
|
|
57
|
+
|
|
58
|
+
return hash.digest('hex');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Load the existing build manifest if it exists.
|
|
63
|
+
*/
|
|
64
|
+
function loadExistingManifest(repoPath: string): BuildManifest | null {
|
|
65
|
+
const manifestPath = join(repoPath, '.amodal', 'build-manifest.json');
|
|
66
|
+
if (!existsSync(manifestPath)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const content = readFileSync(manifestPath, 'utf-8');
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
72
|
+
return JSON.parse(content) as BuildManifest;
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Read the platform config from amodal.json.
|
|
80
|
+
*/
|
|
81
|
+
function getPlatformConfig(repoPath: string): {apiUrl: string; apiKey: string} | null {
|
|
82
|
+
try {
|
|
83
|
+
const configPath = join(repoPath, 'amodal.json');
|
|
84
|
+
const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
86
|
+
const config = raw as Record<string, unknown>;
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
88
|
+
const platform = config['platform'] as {projectId?: string; apiKey?: string} | undefined;
|
|
89
|
+
if (!platform?.apiKey) return null;
|
|
90
|
+
|
|
91
|
+
const apiUrl = (process.env['PLATFORM_API_URL'] ?? 'https://api.amodal.dev').replace(/\/$/, '');
|
|
92
|
+
return {apiUrl, apiKey: platform.apiKey};
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Create a tar.gz archive of the tool directory.
|
|
100
|
+
* Excludes node_modules, .git, __pycache__, etc.
|
|
101
|
+
*/
|
|
102
|
+
export function createToolArchive(tool: LoadedTool): Buffer {
|
|
103
|
+
// Use system tar — available on macOS and Linux
|
|
104
|
+
const tarOutput = execSync(
|
|
105
|
+
'tar -czf - ' +
|
|
106
|
+
'--exclude=node_modules --exclude=.git --exclude=__pycache__ ' +
|
|
107
|
+
'--exclude=.venv --exclude=dist ' +
|
|
108
|
+
'-C ' + JSON.stringify(tool.location) + ' .',
|
|
109
|
+
{maxBuffer: 50 * 1024 * 1024}, // 50MB max
|
|
110
|
+
);
|
|
111
|
+
return Buffer.from(tarOutput);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const POLL_INTERVAL_MS = 3000;
|
|
115
|
+
const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes max
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Upload a tool bundle to the platform API and wait for the build to complete.
|
|
119
|
+
*
|
|
120
|
+
* 1. POST /api/tools/build — starts the build (Vercel creates a Daytona
|
|
121
|
+
* sandbox, uploads files, kicks off setup commands asynchronously)
|
|
122
|
+
* 2. Poll GET /api/tools/build/:id — waits for setup to finish, then
|
|
123
|
+
* the platform snapshots the sandbox and returns the snapshotId
|
|
124
|
+
*
|
|
125
|
+
* The ISV never needs Daytona credentials. The platform owns the infra.
|
|
126
|
+
*/
|
|
127
|
+
async function buildToolOnPlatform(
|
|
128
|
+
platformUrl: string,
|
|
129
|
+
apiKey: string,
|
|
130
|
+
tool: LoadedTool,
|
|
131
|
+
imageHash: string,
|
|
132
|
+
): Promise<string> {
|
|
133
|
+
const archive = createToolArchive(tool);
|
|
134
|
+
const fileCount = listFilesRecursive(tool.location).length;
|
|
135
|
+
|
|
136
|
+
process.stderr.write(`[build-tools] ${tool.name}: uploading ${fileCount} files (${(archive.length / 1024).toFixed(1)} KB)\n`);
|
|
137
|
+
|
|
138
|
+
// 1. Start the build
|
|
139
|
+
const startResponse = await fetch(`${platformUrl}/api/tools/build`, {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
headers: {
|
|
142
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
143
|
+
'Content-Type': 'application/gzip',
|
|
144
|
+
'X-Tool-Name': tool.name,
|
|
145
|
+
'X-Tool-Hash': imageHash,
|
|
146
|
+
'X-Sandbox-Language': tool.sandboxLanguage,
|
|
147
|
+
'X-Has-Setup-Script': String(tool.hasSetupScript),
|
|
148
|
+
'X-Has-Requirements-Txt': String(tool.hasRequirementsTxt),
|
|
149
|
+
'X-Has-Dockerfile': String(tool.hasDockerfile),
|
|
150
|
+
'X-Has-Package-Json': String(tool.hasPackageJson),
|
|
151
|
+
},
|
|
152
|
+
body: archive,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (!startResponse.ok) {
|
|
156
|
+
const text = await startResponse.text().catch(() => '');
|
|
157
|
+
throw new Error(`Platform tool build failed to start (${startResponse.status}): ${text}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
161
|
+
const buildResult = await startResponse.json() as {id: string; status: string; snapshotId?: string; error?: string};
|
|
162
|
+
|
|
163
|
+
// If already complete (no setup needed), return immediately
|
|
164
|
+
if (buildResult.status === 'complete' && buildResult.snapshotId) {
|
|
165
|
+
return buildResult.snapshotId;
|
|
166
|
+
}
|
|
167
|
+
if (buildResult.status === 'failed') {
|
|
168
|
+
throw new Error(`Tool build failed: ${buildResult.error ?? 'unknown error'}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 2. Poll until complete
|
|
172
|
+
const buildId = buildResult.id;
|
|
173
|
+
const startTime = Date.now();
|
|
174
|
+
|
|
175
|
+
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
176
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
177
|
+
|
|
178
|
+
const pollResponse = await fetch(`${platformUrl}/api/tools/build/${buildId}`, {
|
|
179
|
+
headers: {'Authorization': `Bearer ${apiKey}`},
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
if (!pollResponse.ok) {
|
|
183
|
+
throw new Error(`Failed to poll build status (${pollResponse.status})`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
187
|
+
const poll = await pollResponse.json() as {status: string; snapshotId?: string; error?: string};
|
|
188
|
+
|
|
189
|
+
if (poll.status === 'complete' && poll.snapshotId) {
|
|
190
|
+
return poll.snapshotId;
|
|
191
|
+
}
|
|
192
|
+
if (poll.status === 'failed') {
|
|
193
|
+
throw new Error(`Tool build failed: ${poll.error ?? 'unknown error'}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
process.stderr.write(`[build-tools] ${tool.name}: ${poll.status}...\n`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
throw new Error(`Tool build timed out after ${POLL_TIMEOUT_MS / 1000}s`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Build Daytona sandbox snapshots for custom tools.
|
|
204
|
+
*
|
|
205
|
+
* For each tool:
|
|
206
|
+
* 1. Compute a content hash of all files in the tool directory
|
|
207
|
+
* 2. If hash matches existing manifest entry, skip (cached)
|
|
208
|
+
* 3. Otherwise, upload to the platform API which builds the image
|
|
209
|
+
* and creates the Daytona snapshot using the platform's Daytona key
|
|
210
|
+
*
|
|
211
|
+
* The ISV never touches Daytona directly. The platform owns the infra.
|
|
212
|
+
*
|
|
213
|
+
* Writes .amodal/build-manifest.json locally for caching.
|
|
214
|
+
* The manifest is also included in the deploy snapshot.
|
|
215
|
+
*/
|
|
216
|
+
export async function buildToolTemplates(
|
|
217
|
+
repoPath: string,
|
|
218
|
+
tools: LoadedTool[],
|
|
219
|
+
): Promise<BuildManifest> {
|
|
220
|
+
const existing = loadExistingManifest(repoPath);
|
|
221
|
+
const existingTools = existing?.tools ?? {};
|
|
222
|
+
|
|
223
|
+
const platform = getPlatformConfig(repoPath);
|
|
224
|
+
|
|
225
|
+
const builtTools: Record<string, {snapshotId: string; imageHash: string; sandboxLanguage: string; hasDockerfile: boolean; hasSetupScript: boolean}> = {};
|
|
226
|
+
let skipped = 0;
|
|
227
|
+
let built = 0;
|
|
228
|
+
|
|
229
|
+
for (const tool of tools) {
|
|
230
|
+
const imageHash = computeToolHash(tool);
|
|
231
|
+
const existingEntry = existingTools[tool.name];
|
|
232
|
+
|
|
233
|
+
if (existingEntry && existingEntry.imageHash === imageHash) {
|
|
234
|
+
builtTools[tool.name] = existingEntry;
|
|
235
|
+
skipped++;
|
|
236
|
+
process.stderr.write(`[build-tools] ${tool.name}: cached (hash match)\n`);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (tool.hasSetupScript) {
|
|
241
|
+
process.stderr.write(`[build-tools] ${tool.name}: building with setup.sh (${tool.sandboxLanguage})\n`);
|
|
242
|
+
} else {
|
|
243
|
+
process.stderr.write(`[build-tools] ${tool.name}: building (${tool.sandboxLanguage})\n`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
let snapshotId: string;
|
|
247
|
+
if (platform) {
|
|
248
|
+
// Upload to platform API → platform builds on Daytona
|
|
249
|
+
snapshotId = await buildToolOnPlatform(platform.apiUrl, platform.apiKey, tool, imageHash);
|
|
250
|
+
} else {
|
|
251
|
+
// No platform configured — generate a placeholder
|
|
252
|
+
// (local dev mode — tools run in-process, snapshots not needed)
|
|
253
|
+
snapshotId = `local-${imageHash.slice(0, 16)}`;
|
|
254
|
+
process.stderr.write(`[build-tools] ${tool.name}: no platform configured, using local placeholder\n`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
builtTools[tool.name] = {snapshotId, imageHash, sandboxLanguage: tool.sandboxLanguage, hasDockerfile: tool.hasDockerfile, hasSetupScript: tool.hasSetupScript};
|
|
258
|
+
built++;
|
|
259
|
+
process.stderr.write(`[build-tools] ${tool.name}: snapshot ${snapshotId}\n`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const manifest: BuildManifest = {
|
|
263
|
+
version: 1,
|
|
264
|
+
builtAt: new Date().toISOString(),
|
|
265
|
+
tools: builtTools,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// Write manifest locally for caching
|
|
269
|
+
const amodalDir = join(repoPath, '.amodal');
|
|
270
|
+
if (!existsSync(amodalDir)) {
|
|
271
|
+
mkdirSync(amodalDir, {recursive: true});
|
|
272
|
+
}
|
|
273
|
+
writeFileSync(
|
|
274
|
+
join(amodalDir, 'build-manifest.json'),
|
|
275
|
+
JSON.stringify(manifest, null, 2),
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
process.stderr.write(`[build-tools] Done: ${built} built, ${skipped} cached\n`);
|
|
279
|
+
|
|
280
|
+
return manifest;
|
|
281
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
import {mkdirSync, writeFileSync, rmSync, existsSync, readFileSync} from 'node:fs';
|
|
9
|
+
import {join} from 'node:path';
|
|
10
|
+
import {tmpdir} from 'node:os';
|
|
11
|
+
import {randomBytes} from 'node:crypto';
|
|
12
|
+
|
|
13
|
+
// Mock process.exit to not actually exit
|
|
14
|
+
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
15
|
+
const stderrWrites: string[] = [];
|
|
16
|
+
vi.spyOn(process.stderr, 'write').mockImplementation((s) => {
|
|
17
|
+
stderrWrites.push(String(s));
|
|
18
|
+
return true;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const testDir = join(tmpdir(), `build-test-${randomBytes(4).toString('hex')}`);
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
stderrWrites.length = 0;
|
|
25
|
+
mockExit.mockClear();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
rmSync(testDir, {recursive: true, force: true});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('runBuild', () => {
|
|
33
|
+
it('returns 1 when no amodal.json found', async () => {
|
|
34
|
+
mkdirSync(testDir, {recursive: true});
|
|
35
|
+
|
|
36
|
+
const {runBuild} = await import('./build.js');
|
|
37
|
+
const code = await runBuild({cwd: testDir});
|
|
38
|
+
expect(code).toBe(1);
|
|
39
|
+
expect(stderrWrites.some((s) => s.includes('amodal.json'))).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('builds a snapshot and writes resolved-config.json', async () => {
|
|
43
|
+
mkdirSync(testDir, {recursive: true});
|
|
44
|
+
writeFileSync(join(testDir, 'amodal.json'), JSON.stringify({
|
|
45
|
+
name: 'test-agent',
|
|
46
|
+
version: '1.0.0',
|
|
47
|
+
models: {main: {provider: 'anthropic', model: 'claude-sonnet-4-20250514'}},
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
const {runBuild} = await import('./build.js');
|
|
51
|
+
const outputPath = join(testDir, 'output.json');
|
|
52
|
+
const code = await runBuild({cwd: testDir, output: outputPath});
|
|
53
|
+
|
|
54
|
+
expect(code).toBe(0);
|
|
55
|
+
expect(existsSync(outputPath)).toBe(true);
|
|
56
|
+
|
|
57
|
+
const snapshot = JSON.parse(readFileSync(outputPath, 'utf-8'));
|
|
58
|
+
expect(snapshot.deployId).toMatch(/^deploy-[0-9a-f]{7}$/);
|
|
59
|
+
expect(snapshot.config.name).toBe('test-agent');
|
|
60
|
+
expect(snapshot.source).toBe('cli');
|
|
61
|
+
expect(stderrWrites.some((s) => s.includes('Snapshot'))).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
});
|