@agent-native/core 0.6.1 → 0.7.1
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/README.md +43 -3
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +154 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/create-workspace.js +18 -0
- package/dist/cli/create-workspace.js.map +1 -0
- package/dist/cli/create.d.ts +35 -7
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +444 -251
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +59 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspacify.d.ts +18 -0
- package/dist/cli/workspacify.d.ts.map +1 -0
- package/dist/cli/workspacify.js +74 -0
- package/dist/cli/workspacify.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +63 -225
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +86 -5
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +15 -2
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +3 -1
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/types.d.ts +1 -1
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +22 -9
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.js +36 -0
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +360 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
- package/dist/client/onboarding/SetupButton.d.ts +10 -0
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
- package/dist/client/onboarding/SetupButton.js +26 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -0
- package/dist/client/onboarding/index.d.ts +12 -0
- package/dist/client/onboarding/index.d.ts.map +1 -0
- package/dist/client/onboarding/index.js +11 -0
- package/dist/client/onboarding/index.js.map +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +34 -0
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
- package/dist/client/onboarding/use-onboarding.js +101 -0
- package/dist/client/onboarding/use-onboarding.js.map +1 -0
- package/dist/client/org/TeamPage.d.ts +6 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +85 -14
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +48 -77
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +16 -3
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +135 -9
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +5 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts +2 -0
- package/dist/client/settings/AgentsSection.d.ts.map +1 -0
- package/dist/client/settings/AgentsSection.js +198 -0
- package/dist/client/settings/AgentsSection.js.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.js +46 -0
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
- package/dist/client/settings/BrowserSection.d.ts +2 -0
- package/dist/client/settings/BrowserSection.d.ts.map +1 -0
- package/dist/client/settings/BrowserSection.js +10 -0
- package/dist/client/settings/BrowserSection.js.map +1 -0
- package/dist/client/settings/ComingSoonSection.d.ts +13 -0
- package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
- package/dist/client/settings/ComingSoonSection.js +9 -0
- package/dist/client/settings/ComingSoonSection.js.map +1 -0
- package/dist/client/settings/LLMSection.d.ts +2 -0
- package/dist/client/settings/LLMSection.d.ts.map +1 -0
- package/dist/client/settings/LLMSection.js +64 -0
- package/dist/client/settings/LLMSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
- package/dist/client/settings/SettingsPanel.js +118 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -0
- package/dist/client/settings/SettingsSection.d.ts +19 -0
- package/dist/client/settings/SettingsSection.d.ts.map +1 -0
- package/dist/client/settings/SettingsSection.js +10 -0
- package/dist/client/settings/SettingsSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.d.ts.map +1 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/client/settings/index.js.map +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +22 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.js +41 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -0
- package/dist/deploy/build.js +198 -54
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +5 -0
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +38 -7
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +28 -0
- package/dist/deploy/workspace-core.d.ts.map +1 -0
- package/dist/deploy/workspace-core.js +223 -0
- package/dist/deploy/workspace-core.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts +11 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -0
- package/dist/deploy/workspace-deploy.js +148 -0
- package/dist/deploy/workspace-deploy.js.map +1 -0
- package/dist/file-upload/builder.d.ts +11 -0
- package/dist/file-upload/builder.d.ts.map +1 -0
- package/dist/file-upload/builder.js +53 -0
- package/dist/file-upload/builder.js.map +1 -0
- package/dist/file-upload/index.d.ts +4 -0
- package/dist/file-upload/index.d.ts.map +1 -0
- package/dist/file-upload/index.js +3 -0
- package/dist/file-upload/index.js.map +1 -0
- package/dist/file-upload/registry.d.ts +23 -0
- package/dist/file-upload/registry.d.ts.map +1 -0
- package/dist/file-upload/registry.js +52 -0
- package/dist/file-upload/registry.js.map +1 -0
- package/dist/file-upload/types.d.ts +37 -0
- package/dist/file-upload/types.d.ts.map +1 -0
- package/dist/file-upload/types.js +10 -0
- package/dist/file-upload/types.js.map +1 -0
- package/dist/integrations/adapters/google-docs.d.ts +89 -0
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
- package/dist/integrations/adapters/google-docs.js +261 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +34 -0
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +32 -0
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts +54 -0
- package/dist/integrations/google-docs-poller.d.ts.map +1 -0
- package/dist/integrations/google-docs-poller.js +442 -0
- package/dist/integrations/google-docs-poller.js.map +1 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +49 -2
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +33 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +10 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +13 -3
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +3 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +81 -60
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +20 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp-client/config.d.ts +46 -0
- package/dist/mcp-client/config.d.ts.map +1 -0
- package/dist/mcp-client/config.js +152 -0
- package/dist/mcp-client/config.js.map +1 -0
- package/dist/mcp-client/index.d.ts +17 -0
- package/dist/mcp-client/index.d.ts.map +1 -0
- package/dist/mcp-client/index.js +53 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/manager.d.ts +76 -0
- package/dist/mcp-client/manager.d.ts.map +1 -0
- package/dist/mcp-client/manager.js +212 -0
- package/dist/mcp-client/manager.js.map +1 -0
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +3 -1
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts +10 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -0
- package/dist/onboarding/default-steps.js +164 -0
- package/dist/onboarding/default-steps.js.map +1 -0
- package/dist/onboarding/index.d.ts +12 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +11 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/plugin.d.ts +19 -0
- package/dist/onboarding/plugin.d.ts.map +1 -0
- package/dist/onboarding/plugin.js +147 -0
- package/dist/onboarding/plugin.js.map +1 -0
- package/dist/onboarding/registry.d.ts +24 -0
- package/dist/onboarding/registry.d.ts.map +1 -0
- package/dist/onboarding/registry.js +40 -0
- package/dist/onboarding/registry.js.map +1 -0
- package/dist/onboarding/types.d.ts +71 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +10 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/resources/agents.d.ts +4 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +44 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/handlers.d.ts +17 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +49 -12
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts +48 -0
- package/dist/resources/metadata.d.ts.map +1 -0
- package/dist/resources/metadata.js +150 -0
- package/dist/resources/metadata.js.map +1 -0
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +3 -2
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +32 -17
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +3 -2
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +2 -1
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/core-scripts.d.ts.map +1 -1
- package/dist/scripts/core-scripts.js +2 -0
- package/dist/scripts/core-scripts.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +3 -2
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/docs/index.d.ts +2 -0
- package/dist/scripts/docs/index.d.ts.map +1 -0
- package/dist/scripts/docs/index.js +4 -0
- package/dist/scripts/docs/index.js.map +1 -0
- package/dist/scripts/docs/search.d.ts +13 -0
- package/dist/scripts/docs/search.d.ts.map +1 -0
- package/dist/scripts/docs/search.js +130 -0
- package/dist/scripts/docs/search.js.map +1 -0
- package/dist/scripts/resources/delete-memory.d.ts +7 -0
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
- package/dist/scripts/resources/delete-memory.js +49 -0
- package/dist/scripts/resources/delete-memory.js.map +1 -0
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/index.d.ts.map +1 -1
- package/dist/scripts/resources/index.js +2 -0
- package/dist/scripts/resources/index.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts +9 -0
- package/dist/scripts/resources/save-memory.d.ts.map +1 -0
- package/dist/scripts/resources/save-memory.js +78 -0
- package/dist/scripts/resources/save-memory.js.map +1 -0
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/scripts/utils.d.ts +10 -1
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +45 -2
- package/dist/scripts/utils.js.map +1 -1
- package/dist/server/action-discovery.d.ts +5 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +51 -20
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +63 -57
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +3 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +363 -48
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +11 -23
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +2 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +33 -5
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +108 -64
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +172 -60
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +202 -6
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +40 -0
- package/dist/server/builder-browser.d.ts.map +1 -0
- package/dist/server/builder-browser.js +166 -0
- package/dist/server/builder-browser.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +152 -6
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +37 -0
- package/dist/server/credential-provider.d.ts.map +1 -0
- package/dist/server/credential-provider.js +49 -0
- package/dist/server/credential-provider.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +42 -3
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.js +1 -1
- package/dist/server/google-oauth.d.ts +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +15 -10
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +1 -0
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +5 -4
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +94 -3
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +20 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +41 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/dist/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/dist/templates/default/_gitignore +1 -0
- package/dist/templates/default/app/root.tsx +4 -1
- package/dist/templates/workspace-core/AGENTS.md +62 -0
- package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
- package/dist/templates/workspace-core/package.json +39 -0
- package/dist/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/dist/templates/workspace-core/src/client/index.ts +26 -0
- package/dist/templates/workspace-core/src/credentials.ts +29 -0
- package/dist/templates/workspace-core/src/index.ts +21 -0
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/dist/templates/workspace-core/src/server/index.ts +22 -0
- package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
- package/dist/templates/workspace-core/tsconfig.json +9 -0
- package/dist/templates/workspace-root/.env.example +37 -0
- package/dist/templates/workspace-root/README.md +62 -0
- package/dist/templates/workspace-root/_gitignore +23 -0
- package/dist/templates/workspace-root/package.json +18 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/dist/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +65 -15
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +16 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +75 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.md +223 -0
- package/docs/content/actions.md +129 -0
- package/docs/content/agent-mentions.md +171 -0
- package/docs/content/authentication.md +155 -0
- package/docs/content/cli-adapters.md +244 -0
- package/docs/content/client.md +175 -0
- package/docs/content/context-awareness.md +168 -0
- package/docs/content/creating-templates.md +311 -0
- package/docs/content/database.md +82 -0
- package/docs/content/deployment.md +180 -0
- package/docs/content/enterprise-workspace.md +235 -0
- package/docs/content/faq.md +101 -0
- package/docs/content/file-uploads.md +102 -0
- package/docs/content/frames.md +47 -0
- package/docs/content/getting-started.md +104 -0
- package/docs/content/integrations.md +198 -0
- package/docs/content/key-concepts.md +246 -0
- package/docs/content/mcp-clients.md +110 -0
- package/docs/content/mcp-protocol.md +168 -0
- package/docs/content/onboarding.md +107 -0
- package/docs/content/real-time-collaboration.md +185 -0
- package/docs/content/resources.md +277 -0
- package/docs/content/security.md +158 -0
- package/docs/content/server.md +200 -0
- package/docs/content/skills-guide.md +107 -0
- package/docs/content/what-is-agent-native.md +100 -0
- package/docs/content/workspace-management.md +224 -0
- package/package.json +12 -2
- package/src/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/src/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/src/templates/default/_gitignore +1 -0
- package/src/templates/default/app/root.tsx +4 -1
- package/src/templates/workspace-core/AGENTS.md +62 -0
- package/src/templates/workspace-core/actions/company-directory.ts +38 -0
- package/src/templates/workspace-core/package.json +39 -0
- package/src/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/src/templates/workspace-core/src/client/index.ts +26 -0
- package/src/templates/workspace-core/src/credentials.ts +29 -0
- package/src/templates/workspace-core/src/index.ts +21 -0
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/src/templates/workspace-core/src/server/index.ts +22 -0
- package/src/templates/workspace-core/tailwind.preset.ts +34 -0
- package/src/templates/workspace-core/tsconfig.json +9 -0
- package/src/templates/workspace-root/.env.example +37 -0
- package/src/templates/workspace-root/README.md +62 -0
- package/src/templates/workspace-root/_gitignore +23 -0
- package/src/templates/workspace-root/package.json +18 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/src/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/templates/templates/default/.agents/skills/actions/SKILL.md +0 -142
- package/dist/templates/templates/default/.agents/skills/agent-engines/SKILL.md +0 -127
- package/dist/templates/templates/default/.agents/skills/capture-learnings/SKILL.md +0 -50
- package/dist/templates/templates/default/.agents/skills/create-skill/SKILL.md +0 -167
- package/dist/templates/templates/default/.agents/skills/delegate-to-agent/SKILL.md +0 -90
- package/dist/templates/templates/default/.agents/skills/frontend-design/SKILL.md +0 -69
- package/dist/templates/templates/default/.agents/skills/real-time-collab/SKILL.md +0 -183
- package/dist/templates/templates/default/.agents/skills/real-time-sync/SKILL.md +0 -112
- package/dist/templates/templates/default/.agents/skills/security/SKILL.md +0 -108
- package/dist/templates/templates/default/.agents/skills/self-modifying-code/SKILL.md +0 -79
- package/dist/templates/templates/default/.agents/skills/storing-data/SKILL.md +0 -110
- package/dist/templates/templates/default/.claude/settings.json +0 -100
- package/dist/templates/templates/default/.env.example +0 -5
- package/dist/templates/templates/default/.ignore +0 -0
- package/dist/templates/templates/default/.prettierrc +0 -5
- package/dist/templates/templates/default/AGENTS.md +0 -110
- package/dist/templates/templates/default/DEVELOPING.md +0 -117
- package/dist/templates/templates/default/_gitignore +0 -37
- package/dist/templates/templates/default/actions/hello.ts +0 -20
- package/dist/templates/templates/default/actions/navigate.ts +0 -53
- package/dist/templates/templates/default/actions/run.ts +0 -2
- package/dist/templates/templates/default/actions/view-screen.ts +0 -39
- package/dist/templates/templates/default/app/entry.client.tsx +0 -4
- package/dist/templates/templates/default/app/entry.server.tsx +0 -56
- package/dist/templates/templates/default/app/global.css +0 -95
- package/dist/templates/templates/default/app/lib/utils.ts +0 -1
- package/dist/templates/templates/default/app/root.tsx +0 -107
- package/dist/templates/templates/default/app/routes/_index.tsx +0 -62
- package/dist/templates/templates/default/app/routes.ts +0 -4
- package/dist/templates/templates/default/app/vite-env.d.ts +0 -6
- package/dist/templates/templates/default/components.json +0 -20
- package/dist/templates/templates/default/data/.gitkeep +0 -0
- package/dist/templates/templates/default/data/sync-config.json +0 -1
- package/dist/templates/templates/default/learnings.defaults.md +0 -5
- package/dist/templates/templates/default/learnings.md +0 -0
- package/dist/templates/templates/default/package.json +0 -46
- package/dist/templates/templates/default/postcss.config.js +0 -6
- package/dist/templates/templates/default/public/icon-180.svg +0 -4
- package/dist/templates/templates/default/public/icon-192.svg +0 -4
- package/dist/templates/templates/default/public/icon-512.svg +0 -4
- package/dist/templates/templates/default/public/manifest.json +0 -13
- package/dist/templates/templates/default/react-router.config.ts +0 -6
- package/dist/templates/templates/default/server/middleware/auth.ts +0 -15
- package/dist/templates/templates/default/server/plugins/.gitkeep +0 -0
- package/dist/templates/templates/default/server/routes/[...page].get.ts +0 -5
- package/dist/templates/templates/default/server/routes/api/hello.get.ts +0 -5
- package/dist/templates/templates/default/shared/api.ts +0 -6
- package/dist/templates/templates/default/ssr-entry.ts +0 -20
- package/dist/templates/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/templates/default/tsconfig.json +0 -11
- package/dist/templates/templates/default/vite.config.ts +0 -6
package/dist/cli/create.js
CHANGED
|
@@ -3,286 +3,306 @@ import path from "path";
|
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { execFileSync } from "child_process";
|
|
5
5
|
import { setupAgentSymlinks } from "./setup-agents.js";
|
|
6
|
+
import { workspacifyApp, parseWorkspaceScope } from "./workspacify.js";
|
|
7
|
+
import { visibleTemplates, allTemplateNames, } from "@agent-native/shared-app-config";
|
|
6
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
9
|
const __dirname = path.dirname(__filename);
|
|
8
10
|
const REPO = "BuilderIO/agent-native";
|
|
9
11
|
const TEMPLATES_DIR = "templates";
|
|
12
|
+
/** Blank scaffold option appended to every picker. */
|
|
13
|
+
const BLANK_OPTION = {
|
|
14
|
+
name: "blank",
|
|
15
|
+
label: "Blank",
|
|
16
|
+
hint: "Empty starter — build from scratch",
|
|
17
|
+
};
|
|
10
18
|
/**
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
value: "blank",
|
|
16
|
-
label: "Blank",
|
|
17
|
-
hint: "Empty starter — build from scratch",
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
value: "mail",
|
|
21
|
-
label: "Mail",
|
|
22
|
-
hint: "AI-native Superhuman — email client with keyboard shortcuts and AI triage",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
value: "calendar",
|
|
26
|
-
label: "Calendar",
|
|
27
|
-
hint: "AI-native Google Calendar — manage events, sync, and public booking",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
value: "content",
|
|
31
|
-
label: "Content",
|
|
32
|
-
hint: "AI-native Notion/Google Docs — write and organize with agent assistance",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
value: "slides",
|
|
36
|
-
label: "Slides",
|
|
37
|
-
hint: "AI-native Google Slides — generate and edit React presentations",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
value: "videos",
|
|
41
|
-
label: "Video",
|
|
42
|
-
hint: "AI-native video editing with Remotion",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
value: "analytics",
|
|
46
|
-
label: "Analytics",
|
|
47
|
-
hint: "AI-native Amplitude/Mixpanel — connect data sources, prompt for charts",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
value: "forms",
|
|
51
|
-
label: "Forms",
|
|
52
|
-
hint: "AI-native form builder — create, edit, and manage forms",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
value: "issues",
|
|
56
|
-
label: "Issues",
|
|
57
|
-
hint: "AI-native Jira — project management and issue tracking",
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
value: "recruiting",
|
|
61
|
-
label: "Recruiting",
|
|
62
|
-
hint: "AI-native Greenhouse — manage candidates and recruiting pipelines",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
value: "starter",
|
|
66
|
-
label: "Starter",
|
|
67
|
-
hint: "Minimal scaffold with the agent chat and core architecture wired up",
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
/**
|
|
71
|
-
* Known first-party template names (for validation).
|
|
72
|
-
* Includes the alias "video" → "videos" for backwards compat.
|
|
73
|
-
*/
|
|
74
|
-
const KNOWN_TEMPLATES = [
|
|
75
|
-
...TEMPLATES.map((t) => t.value).filter((v) => v !== "blank"),
|
|
76
|
-
"video",
|
|
77
|
-
];
|
|
78
|
-
/**
|
|
79
|
-
* Scaffold a new agent-native app.
|
|
19
|
+
* Main entry for `agent-native create [name]`.
|
|
20
|
+
*
|
|
21
|
+
* Default behavior: scaffold a workspace at <name>/ with a multi-select
|
|
22
|
+
* template picker. Use --standalone for the single-app standalone flow.
|
|
80
23
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* With --template github:user/repo: downloads from a custom GitHub repo.
|
|
24
|
+
* If run *inside* an existing workspace, falls through to the add-app
|
|
25
|
+
* flow that scaffolds one new app under apps/<name>/.
|
|
84
26
|
*/
|
|
85
27
|
export async function createApp(name, opts) {
|
|
86
28
|
const clack = await import("@clack/prompts");
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
validate(value) {
|
|
94
|
-
if (!value)
|
|
95
|
-
return "App name is required";
|
|
96
|
-
if (!/^[a-z][a-z0-9-]*$/.test(value)) {
|
|
97
|
-
return "Use lowercase letters, numbers, and hyphens (must start with a letter)";
|
|
98
|
-
}
|
|
99
|
-
if (fs.existsSync(path.resolve(process.cwd(), value))) {
|
|
100
|
-
return `Directory "${value}" already exists`;
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
if (clack.isCancel(nameResult)) {
|
|
105
|
-
clack.cancel("Cancelled.");
|
|
106
|
-
process.exit(0);
|
|
107
|
-
}
|
|
108
|
-
name = nameResult;
|
|
29
|
+
// If we're already inside a workspace, the meaning of `create <name>` is
|
|
30
|
+
// "add a new app to this workspace". Delegate to add-app.
|
|
31
|
+
const workspace = detectWorkspace(process.cwd());
|
|
32
|
+
if (workspace) {
|
|
33
|
+
await addAppToWorkspace(name, opts);
|
|
34
|
+
return;
|
|
109
35
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
36
|
+
// Standalone escape hatch — behaves like the old single-app flow.
|
|
37
|
+
if (opts?.standalone) {
|
|
38
|
+
await createStandaloneApp(name, opts, clack);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// When exactly one template is specified explicitly, treat it as a
|
|
42
|
+
// standalone scaffold (script-friendly, matches historic behavior).
|
|
43
|
+
// Use `--template a,b` or pass no --template to opt into the workspace
|
|
44
|
+
// flow with the multi-select picker.
|
|
45
|
+
const parsed = parseTemplateList(opts?.template);
|
|
46
|
+
if (parsed.length === 1) {
|
|
47
|
+
await createStandaloneApp(name, opts, clack);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Default: create a workspace.
|
|
51
|
+
await createWorkspaceInteractive(name, opts, clack);
|
|
52
|
+
}
|
|
53
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
54
|
+
* Workspace creation (new default)
|
|
55
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
56
|
+
async function createWorkspaceInteractive(name, opts, clack) {
|
|
57
|
+
clack.intro("Create a new agent-native workspace");
|
|
58
|
+
name = await promptNameIfMissing(name, clack, "workspace", "my-platform");
|
|
59
|
+
// Multi-select picker for apps to include.
|
|
60
|
+
const preselected = parseTemplateList(opts?.template);
|
|
61
|
+
const templates = await promptTemplatePicker(preselected, clack);
|
|
62
|
+
if (templates.length === 0) {
|
|
63
|
+
clack.cancel("No apps selected. Cancelled.");
|
|
64
|
+
process.exit(0);
|
|
116
65
|
}
|
|
117
66
|
const targetDir = path.resolve(process.cwd(), name);
|
|
118
67
|
if (fs.existsSync(targetDir)) {
|
|
119
68
|
clack.cancel(`Directory "${name}" already exists.`);
|
|
120
69
|
process.exit(1);
|
|
121
70
|
}
|
|
122
|
-
// Prompt for template if not provided
|
|
123
|
-
let template = opts?.template;
|
|
124
|
-
if (!template) {
|
|
125
|
-
const templateResult = await clack.select({
|
|
126
|
-
message: "Which template would you like to use?",
|
|
127
|
-
options: TEMPLATES.map((t) => ({
|
|
128
|
-
value: t.value,
|
|
129
|
-
label: t.label,
|
|
130
|
-
hint: t.hint,
|
|
131
|
-
})),
|
|
132
|
-
});
|
|
133
|
-
if (clack.isCancel(templateResult)) {
|
|
134
|
-
clack.cancel("Cancelled.");
|
|
135
|
-
process.exit(0);
|
|
136
|
-
}
|
|
137
|
-
template = templateResult;
|
|
138
|
-
}
|
|
139
71
|
const s = clack.spinner();
|
|
140
|
-
s.start(
|
|
72
|
+
s.start(`Scaffolding workspace with ${templates.length} app(s)...`);
|
|
141
73
|
try {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
await
|
|
74
|
+
await scaffoldWorkspaceRoot(targetDir, name);
|
|
75
|
+
const workspaceCoreName = `@${name}/core-module`;
|
|
76
|
+
for (const t of templates) {
|
|
77
|
+
const appDir = path.join(targetDir, "apps", t);
|
|
78
|
+
await scaffoldAppTemplate(appDir, t);
|
|
79
|
+
workspacifyApp({
|
|
80
|
+
appDir,
|
|
81
|
+
appName: t,
|
|
82
|
+
workspaceRoot: targetDir,
|
|
83
|
+
workspaceCoreName,
|
|
84
|
+
});
|
|
85
|
+
fixPackageJsonName(appDir, t);
|
|
86
|
+
renameGitignore(appDir);
|
|
87
|
+
// Each app owns its own .claude / .agents symlinks.
|
|
88
|
+
setupAgentSymlinks(appDir);
|
|
147
89
|
}
|
|
148
|
-
s.stop("
|
|
90
|
+
s.stop("Workspace scaffolded.");
|
|
149
91
|
}
|
|
150
92
|
catch (err) {
|
|
151
|
-
s.stop("Failed to
|
|
93
|
+
s.stop("Failed to scaffold workspace.");
|
|
152
94
|
throw err;
|
|
153
95
|
}
|
|
154
|
-
|
|
96
|
+
const firstApp = templates[0];
|
|
97
|
+
clack.outro([
|
|
98
|
+
`Done! Next steps:`,
|
|
99
|
+
``,
|
|
100
|
+
` cd ${name}`,
|
|
101
|
+
` cp .env.example .env # ANTHROPIC_API_KEY, DATABASE_URL, BETTER_AUTH_SECRET`,
|
|
102
|
+
` pnpm install`,
|
|
103
|
+
` pnpm --filter ${firstApp} dev`,
|
|
104
|
+
``,
|
|
105
|
+
`Add another app later: agent-native add-app`,
|
|
106
|
+
`Deploy the whole workspace: agent-native deploy`,
|
|
107
|
+
].join("\n"));
|
|
155
108
|
}
|
|
156
|
-
|
|
157
|
-
* Create from the bundled default template (no --template flag).
|
|
158
|
-
*/
|
|
159
|
-
function createFromDefault(name, targetDir) {
|
|
109
|
+
async function scaffoldWorkspaceRoot(targetDir, name) {
|
|
160
110
|
const packageRoot = path.resolve(__dirname, "../..");
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
111
|
+
const rootTemplate = path.join(packageRoot, "src/templates/workspace-root");
|
|
112
|
+
const coreTemplate = path.join(packageRoot, "src/templates/workspace-core");
|
|
113
|
+
copyDir(rootTemplate, targetDir);
|
|
114
|
+
replacePlaceholders(targetDir, name, titleCase(name));
|
|
115
|
+
renameGitignore(targetDir);
|
|
116
|
+
const corePackageDir = path.join(targetDir, "packages", "core-module");
|
|
117
|
+
fs.mkdirSync(path.join(targetDir, "packages"), { recursive: true });
|
|
118
|
+
copyDir(coreTemplate, corePackageDir);
|
|
119
|
+
replacePlaceholders(corePackageDir, name, titleCase(name));
|
|
120
|
+
// Ensure apps/ exists (even if empty).
|
|
121
|
+
fs.mkdirSync(path.join(targetDir, "apps"), { recursive: true });
|
|
168
122
|
}
|
|
123
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
124
|
+
* Adding an app into an existing workspace
|
|
125
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
169
126
|
/**
|
|
170
|
-
*
|
|
127
|
+
* Entry for `agent-native add-app [name]`. Called from inside a workspace.
|
|
128
|
+
* Shows the multi-select picker (excluding already-installed apps) and
|
|
129
|
+
* scaffolds each selected template under apps/<name>/.
|
|
171
130
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* --template github:user/repo (community template from a GitHub repo)
|
|
131
|
+
* When `name` is provided with `--template foo`, scaffolds exactly one app
|
|
132
|
+
* named <name> using template foo (non-interactive).
|
|
175
133
|
*/
|
|
176
|
-
async function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// Community template: github:user/repo
|
|
183
|
-
const repo = resolvedTemplate.slice("github:".length);
|
|
184
|
-
await downloadGitHubRepo(repo, targetDir);
|
|
134
|
+
export async function addAppToWorkspace(name, opts) {
|
|
135
|
+
const clack = await import("@clack/prompts");
|
|
136
|
+
const workspace = detectWorkspace(process.cwd());
|
|
137
|
+
if (!workspace) {
|
|
138
|
+
clack.cancel("Not inside a workspace. Run `agent-native create` to make one first, or use `--standalone`.");
|
|
139
|
+
process.exit(1);
|
|
185
140
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
141
|
+
clack.intro("Add an app to your workspace");
|
|
142
|
+
const installed = listInstalledApps(workspace.workspaceRoot);
|
|
143
|
+
// Non-interactive path: name + single --template
|
|
144
|
+
const preselected = parseTemplateList(opts?.template);
|
|
145
|
+
if (name && preselected.length === 1) {
|
|
146
|
+
const tpl = preselected[0];
|
|
147
|
+
await scaffoldOneAppIntoWorkspace(workspace, name, tpl, clack);
|
|
148
|
+
return;
|
|
189
149
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
150
|
+
const templates = await promptTemplatePicker(preselected, clack, {
|
|
151
|
+
excludeNames: installed,
|
|
152
|
+
message: "Which apps do you want to add?",
|
|
153
|
+
});
|
|
154
|
+
if (templates.length === 0) {
|
|
155
|
+
clack.cancel("No apps selected. Cancelled.");
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
for (const t of templates) {
|
|
159
|
+
await scaffoldOneAppIntoWorkspace(workspace, t, t, clack);
|
|
194
160
|
}
|
|
195
|
-
postProcess(name, targetDir);
|
|
196
161
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
|
|
162
|
+
async function scaffoldOneAppIntoWorkspace(workspace, appName, templateName, clack) {
|
|
163
|
+
const appsDir = path.join(workspace.workspaceRoot, "apps");
|
|
164
|
+
fs.mkdirSync(appsDir, { recursive: true });
|
|
165
|
+
const appDir = path.join(appsDir, appName);
|
|
166
|
+
if (fs.existsSync(appDir)) {
|
|
167
|
+
clack.cancel(`Directory "apps/${appName}" already exists.`);
|
|
203
168
|
process.exit(1);
|
|
204
169
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
* Download a tarball from a URL and extract it to a directory.
|
|
208
|
-
* Uses execFileSync with array args to avoid shell injection.
|
|
209
|
-
*/
|
|
210
|
-
function downloadAndExtract(url, destDir) {
|
|
211
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
212
|
-
// Download with curl (no shell — execFileSync passes args directly)
|
|
213
|
-
const tarball = execFileSync("curl", ["-sL", url], {
|
|
214
|
-
maxBuffer: 100 * 1024 * 1024,
|
|
215
|
-
});
|
|
216
|
-
// Write tarball to a temp file, then extract (avoids pipe through shell)
|
|
217
|
-
const tarPath = path.join(destDir, ".download.tar.gz");
|
|
218
|
-
fs.writeFileSync(tarPath, tarball);
|
|
170
|
+
const s = clack.spinner();
|
|
171
|
+
s.start(`Scaffolding apps/${appName} from ${templateName}...`);
|
|
219
172
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
173
|
+
await scaffoldAppTemplate(appDir, templateName);
|
|
174
|
+
workspacifyApp({
|
|
175
|
+
appDir,
|
|
176
|
+
appName,
|
|
177
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
178
|
+
workspaceCoreName: workspace.workspaceCoreName,
|
|
222
179
|
});
|
|
180
|
+
fixPackageJsonName(appDir, appName);
|
|
181
|
+
renameGitignore(appDir);
|
|
182
|
+
setupAgentSymlinks(appDir);
|
|
183
|
+
s.stop(`Scaffolded apps/${appName}.`);
|
|
223
184
|
}
|
|
224
|
-
|
|
225
|
-
|
|
185
|
+
catch (err) {
|
|
186
|
+
s.stop(`Failed to scaffold apps/${appName}.`);
|
|
187
|
+
throw err;
|
|
226
188
|
}
|
|
189
|
+
clack.outro(`Done!\n\n pnpm install\n pnpm --filter ${appName} dev`);
|
|
227
190
|
}
|
|
228
|
-
|
|
229
|
-
*
|
|
230
|
-
*/
|
|
231
|
-
async function
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
191
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
192
|
+
* Standalone creation (escape hatch)
|
|
193
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
194
|
+
async function createStandaloneApp(name, opts, clack) {
|
|
195
|
+
clack.intro("Create a new standalone agent-native app");
|
|
196
|
+
name = await promptNameIfMissing(name, clack, "app", "my-app");
|
|
197
|
+
const targetDir = path.resolve(process.cwd(), name);
|
|
198
|
+
if (fs.existsSync(targetDir)) {
|
|
199
|
+
clack.cancel(`Directory "${name}" already exists.`);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
// Standalone is single-select — pick one template.
|
|
203
|
+
let template = opts?.template && !opts.template.includes(",") ? opts.template : undefined;
|
|
204
|
+
if (!template) {
|
|
205
|
+
const picked = await clack.select({
|
|
206
|
+
message: "Which template would you like to use?",
|
|
207
|
+
options: [
|
|
208
|
+
...visibleTemplates().map((t) => ({
|
|
209
|
+
value: t.name,
|
|
210
|
+
label: t.label,
|
|
211
|
+
hint: t.hint,
|
|
212
|
+
})),
|
|
213
|
+
{
|
|
214
|
+
value: BLANK_OPTION.name,
|
|
215
|
+
label: BLANK_OPTION.label,
|
|
216
|
+
hint: BLANK_OPTION.hint,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
if (clack.isCancel(picked)) {
|
|
221
|
+
clack.cancel("Cancelled.");
|
|
222
|
+
process.exit(0);
|
|
242
223
|
}
|
|
243
|
-
|
|
244
|
-
copyDir(srcDir, targetDir);
|
|
224
|
+
template = picked;
|
|
245
225
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
226
|
+
const s = clack.spinner();
|
|
227
|
+
s.start("Scaffolding your app...");
|
|
228
|
+
try {
|
|
229
|
+
await scaffoldAppTemplate(targetDir, template);
|
|
230
|
+
postProcessStandalone(name, targetDir);
|
|
231
|
+
s.stop("App created!");
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
s.stop("Failed to create app.");
|
|
235
|
+
throw err;
|
|
249
236
|
}
|
|
237
|
+
clack.outro(`Done! Next steps:\n\n cd ${name}\n pnpm install\n pnpm dev`);
|
|
250
238
|
}
|
|
239
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
240
|
+
* Shared scaffolding helpers
|
|
241
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
251
242
|
/**
|
|
252
|
-
*
|
|
243
|
+
* Scaffold a single app template into `targetDir`. Resolves:
|
|
244
|
+
* - "blank" → bundled default template
|
|
245
|
+
* - "github:user/repo" → download the whole repo
|
|
246
|
+
* - first-party template name → download that subdir from BuilderIO/agent-native
|
|
253
247
|
*/
|
|
254
|
-
async function
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
248
|
+
async function scaffoldAppTemplate(targetDir, template) {
|
|
249
|
+
fs.mkdirSync(path.dirname(targetDir), { recursive: true });
|
|
250
|
+
if (template === "blank") {
|
|
251
|
+
const packageRoot = path.resolve(__dirname, "../..");
|
|
252
|
+
const defaultDir = path.join(packageRoot, "src/templates/default");
|
|
253
|
+
if (!fs.existsSync(defaultDir)) {
|
|
254
|
+
throw new Error(`Default template not found at ${defaultDir}. Is the package installed correctly?`);
|
|
255
|
+
}
|
|
256
|
+
copyDir(defaultDir, targetDir);
|
|
257
|
+
return;
|
|
259
258
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
// Normalize legacy alias
|
|
260
|
+
let resolved = template === "video" ? "videos" : template;
|
|
261
|
+
if (resolved.startsWith("github:")) {
|
|
262
|
+
const repo = resolved.slice("github:".length);
|
|
263
|
+
await downloadGitHubRepo(repo, targetDir);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (!allTemplateNames().includes(resolved)) {
|
|
267
|
+
throw new Error(`Unknown template "${template}". Known: ${allTemplateNames().join(", ")} — or use github:user/repo for community templates.`);
|
|
268
|
+
}
|
|
269
|
+
// If running from the framework monorepo with a local templates/ dir, use
|
|
270
|
+
// that. Otherwise download from GitHub. This keeps `agent-native create`
|
|
271
|
+
// fast during framework development.
|
|
272
|
+
const localTemplate = findLocalTemplate(resolved);
|
|
273
|
+
if (localTemplate) {
|
|
274
|
+
copyDir(localTemplate, targetDir);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
await downloadGitHubSubdir(REPO, `${TEMPLATES_DIR}/${resolved}`, targetDir);
|
|
263
278
|
}
|
|
264
279
|
}
|
|
265
280
|
/**
|
|
266
|
-
*
|
|
281
|
+
* When developing the framework itself, prefer the sibling templates/<name>
|
|
282
|
+
* directory. Returns undefined when running as a published package.
|
|
267
283
|
*/
|
|
268
|
-
function
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
.
|
|
272
|
-
.
|
|
273
|
-
|
|
274
|
-
replacePlaceholders(targetDir, name, appTitle);
|
|
275
|
-
// Update package.json name field (templates have their own name)
|
|
276
|
-
const pkgPath = path.join(targetDir, "package.json");
|
|
277
|
-
if (fs.existsSync(pkgPath)) {
|
|
278
|
-
try {
|
|
279
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
280
|
-
pkg.name = name;
|
|
281
|
-
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
284
|
+
function findLocalTemplate(name) {
|
|
285
|
+
let dir = path.resolve(__dirname);
|
|
286
|
+
for (let i = 0; i < 10; i++) {
|
|
287
|
+
const candidate = path.join(dir, "templates", name);
|
|
288
|
+
if (fs.existsSync(path.join(candidate, "package.json"))) {
|
|
289
|
+
return candidate;
|
|
282
290
|
}
|
|
283
|
-
|
|
291
|
+
const parent = path.dirname(dir);
|
|
292
|
+
if (parent === dir)
|
|
293
|
+
break;
|
|
294
|
+
dir = parent;
|
|
284
295
|
}
|
|
285
|
-
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Post-process a standalone scaffold: replace placeholders, strip
|
|
300
|
+
* workspace:* deps, set up agent symlinks, etc.
|
|
301
|
+
*/
|
|
302
|
+
function postProcessStandalone(name, targetDir) {
|
|
303
|
+
const appTitle = titleCase(name);
|
|
304
|
+
replacePlaceholders(targetDir, name, appTitle);
|
|
305
|
+
fixPackageJsonName(targetDir, name);
|
|
286
306
|
for (const base of ["learnings"]) {
|
|
287
307
|
const defaultsFile = path.join(targetDir, `${base}.defaults.md`);
|
|
288
308
|
const targetFile = path.join(targetDir, `${base}.md`);
|
|
@@ -290,19 +310,15 @@ function postProcess(name, targetDir) {
|
|
|
290
310
|
fs.copyFileSync(defaultsFile, targetFile);
|
|
291
311
|
}
|
|
292
312
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const gitignoreDst = path.join(targetDir, ".gitignore");
|
|
296
|
-
if (fs.existsSync(gitignoreSrc)) {
|
|
297
|
-
fs.renameSync(gitignoreSrc, gitignoreDst);
|
|
298
|
-
}
|
|
299
|
-
// Remove monorepo-specific files that don't belong in standalone apps
|
|
313
|
+
renameGitignore(targetDir);
|
|
314
|
+
// Drop monorepo-only files that standalone apps shouldn't ship.
|
|
300
315
|
for (const f of ["DEVELOPING.md"]) {
|
|
301
316
|
const p = path.join(targetDir, f);
|
|
302
317
|
if (fs.existsSync(p))
|
|
303
318
|
fs.unlinkSync(p);
|
|
304
319
|
}
|
|
305
|
-
//
|
|
320
|
+
// Resolve workspace:* deps to `latest` for standalone.
|
|
321
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
306
322
|
if (fs.existsSync(pkgPath)) {
|
|
307
323
|
try {
|
|
308
324
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
@@ -316,7 +332,6 @@ function postProcess(name, targetDir) {
|
|
|
316
332
|
continue;
|
|
317
333
|
for (const [key, val] of Object.entries(deps)) {
|
|
318
334
|
if (typeof val === "string" && val.startsWith("workspace:")) {
|
|
319
|
-
// Replace workspace:* with "latest"
|
|
320
335
|
deps[key] = "latest";
|
|
321
336
|
}
|
|
322
337
|
}
|
|
@@ -325,19 +340,194 @@ function postProcess(name, targetDir) {
|
|
|
325
340
|
}
|
|
326
341
|
catch { }
|
|
327
342
|
}
|
|
328
|
-
// Create symlinks for all agent tools (Claude, Cursor, Windsurf, etc.)
|
|
329
343
|
setupAgentSymlinks(targetDir);
|
|
330
344
|
}
|
|
345
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
346
|
+
* Prompting helpers
|
|
347
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
348
|
+
async function promptNameIfMissing(name, clack, kind, placeholder) {
|
|
349
|
+
if (name) {
|
|
350
|
+
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
|
|
351
|
+
clack.cancel(`Invalid ${kind} name "${name}". Use lowercase letters, numbers, and hyphens.`);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
return name;
|
|
355
|
+
}
|
|
356
|
+
const result = await clack.text({
|
|
357
|
+
message: `What is your ${kind} name?`,
|
|
358
|
+
placeholder,
|
|
359
|
+
validate(value) {
|
|
360
|
+
if (!value)
|
|
361
|
+
return `${kind[0].toUpperCase() + kind.slice(1)} name is required`;
|
|
362
|
+
if (!/^[a-z][a-z0-9-]*$/.test(value)) {
|
|
363
|
+
return "Use lowercase letters, numbers, and hyphens (must start with a letter)";
|
|
364
|
+
}
|
|
365
|
+
if (fs.existsSync(path.resolve(process.cwd(), value))) {
|
|
366
|
+
return `Directory "${value}" already exists`;
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
if (clack.isCancel(result)) {
|
|
371
|
+
clack.cancel("Cancelled.");
|
|
372
|
+
process.exit(0);
|
|
373
|
+
}
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
async function promptTemplatePicker(preselected, clack, opts) {
|
|
377
|
+
const excluded = new Set(opts?.excludeNames ?? []);
|
|
378
|
+
const options = visibleTemplates()
|
|
379
|
+
.filter((t) => !excluded.has(t.name))
|
|
380
|
+
.map((t) => ({
|
|
381
|
+
value: t.name,
|
|
382
|
+
label: t.label,
|
|
383
|
+
hint: t.hint,
|
|
384
|
+
}));
|
|
385
|
+
// If there's nothing left to pick, the caller gets an empty selection —
|
|
386
|
+
// they decide how to handle it.
|
|
387
|
+
if (options.length === 0)
|
|
388
|
+
return [];
|
|
389
|
+
// Default pre-selection: what the user passed via --template, falling
|
|
390
|
+
// back to "starter" when that's available and nothing else is pre-picked.
|
|
391
|
+
const defaults = preselected.length > 0
|
|
392
|
+
? preselected.filter((p) => options.some((o) => o.value === p))
|
|
393
|
+
: options.some((o) => o.value === "starter")
|
|
394
|
+
? ["starter"]
|
|
395
|
+
: [];
|
|
396
|
+
const result = await clack.multiselect({
|
|
397
|
+
message: opts?.message ?? "Which apps would you like to include?",
|
|
398
|
+
options,
|
|
399
|
+
initialValues: defaults,
|
|
400
|
+
required: false,
|
|
401
|
+
});
|
|
402
|
+
if (clack.isCancel(result)) {
|
|
403
|
+
clack.cancel("Cancelled.");
|
|
404
|
+
process.exit(0);
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
function parseTemplateList(input) {
|
|
409
|
+
if (!input)
|
|
410
|
+
return [];
|
|
411
|
+
return input
|
|
412
|
+
.split(",")
|
|
413
|
+
.map((s) => s.trim())
|
|
414
|
+
.filter(Boolean);
|
|
415
|
+
}
|
|
416
|
+
function listInstalledApps(workspaceRoot) {
|
|
417
|
+
const appsDir = path.join(workspaceRoot, "apps");
|
|
418
|
+
if (!fs.existsSync(appsDir))
|
|
419
|
+
return [];
|
|
420
|
+
return fs
|
|
421
|
+
.readdirSync(appsDir, { withFileTypes: true })
|
|
422
|
+
.filter((e) => e.isDirectory())
|
|
423
|
+
.map((e) => e.name);
|
|
424
|
+
}
|
|
425
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
426
|
+
* Workspace detection
|
|
427
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
331
428
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
429
|
+
* Walk up from startDir looking for a package.json with
|
|
430
|
+
* `agent-native.workspaceCore` set. Returns the workspace root and core
|
|
431
|
+
* package name, or null if not inside a workspace.
|
|
334
432
|
*/
|
|
335
|
-
function
|
|
433
|
+
export function detectWorkspace(startDir) {
|
|
434
|
+
let dir = path.resolve(startDir);
|
|
435
|
+
for (let i = 0; i < 20; i++) {
|
|
436
|
+
const pkgPath = path.join(dir, "package.json");
|
|
437
|
+
if (fs.existsSync(pkgPath)) {
|
|
438
|
+
try {
|
|
439
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
440
|
+
const wsCore = pkg?.["agent-native"]?.workspaceCore;
|
|
441
|
+
if (typeof wsCore === "string" && wsCore.length > 0) {
|
|
442
|
+
return { workspaceRoot: dir, workspaceCoreName: wsCore };
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
catch { }
|
|
446
|
+
}
|
|
447
|
+
const parent = path.dirname(dir);
|
|
448
|
+
if (parent === dir)
|
|
449
|
+
break;
|
|
450
|
+
dir = parent;
|
|
451
|
+
}
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
export { parseWorkspaceScope };
|
|
455
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
456
|
+
* Download / copy helpers
|
|
457
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
458
|
+
function validateRepoName(repo) {
|
|
459
|
+
if (!/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(repo)) {
|
|
460
|
+
throw new Error(`Invalid repository name "${repo}". Expected format: user/repo`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
function downloadAndExtract(url, destDir) {
|
|
464
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
465
|
+
const tarball = execFileSync("curl", ["-sL", url], {
|
|
466
|
+
maxBuffer: 100 * 1024 * 1024,
|
|
467
|
+
});
|
|
468
|
+
const tarPath = path.join(destDir, ".download.tar.gz");
|
|
469
|
+
fs.writeFileSync(tarPath, tarball);
|
|
470
|
+
try {
|
|
471
|
+
execFileSync("tar", ["xzf", tarPath, "--strip-components=1", "-C", destDir], { stdio: "pipe" });
|
|
472
|
+
}
|
|
473
|
+
finally {
|
|
474
|
+
fs.unlinkSync(tarPath);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async function downloadGitHubSubdir(repo, subdir, targetDir) {
|
|
478
|
+
validateRepoName(repo);
|
|
479
|
+
const tarUrl = `https://api.github.com/repos/${repo}/tarball/main`;
|
|
480
|
+
const tmpDir = path.join(targetDir, "..", `.agent-native-tmp-${Date.now()}`);
|
|
481
|
+
try {
|
|
482
|
+
downloadAndExtract(tarUrl, tmpDir);
|
|
483
|
+
const srcDir = path.join(tmpDir, subdir);
|
|
484
|
+
if (!fs.existsSync(srcDir)) {
|
|
485
|
+
throw new Error(`Template directory "${subdir}" not found in ${repo}.`);
|
|
486
|
+
}
|
|
487
|
+
copyDir(srcDir, targetDir);
|
|
488
|
+
}
|
|
489
|
+
finally {
|
|
490
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
async function downloadGitHubRepo(repo, targetDir) {
|
|
494
|
+
validateRepoName(repo);
|
|
495
|
+
const tarUrl = `https://api.github.com/repos/${repo}/tarball/main`;
|
|
496
|
+
downloadAndExtract(tarUrl, targetDir);
|
|
497
|
+
}
|
|
498
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
499
|
+
* Text / filesystem helpers
|
|
500
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
501
|
+
function titleCase(name) {
|
|
502
|
+
return name
|
|
503
|
+
.split("-")
|
|
504
|
+
.map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w))
|
|
505
|
+
.join(" ");
|
|
506
|
+
}
|
|
507
|
+
function fixPackageJsonName(appDir, name) {
|
|
508
|
+
const pkgPath = path.join(appDir, "package.json");
|
|
509
|
+
if (!fs.existsSync(pkgPath))
|
|
510
|
+
return;
|
|
511
|
+
try {
|
|
512
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
513
|
+
pkg.name = name;
|
|
514
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
515
|
+
}
|
|
516
|
+
catch { }
|
|
517
|
+
}
|
|
518
|
+
function renameGitignore(dir) {
|
|
519
|
+
const src = path.join(dir, "_gitignore");
|
|
520
|
+
const dst = path.join(dir, ".gitignore");
|
|
521
|
+
if (fs.existsSync(src))
|
|
522
|
+
fs.renameSync(src, dst);
|
|
523
|
+
}
|
|
524
|
+
function replacePlaceholders(dir, appName, appTitle, workspaceName) {
|
|
336
525
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
337
526
|
const p = path.join(dir, entry.name);
|
|
338
|
-
if (entry.isSymbolicLink()
|
|
339
|
-
|
|
340
|
-
|
|
527
|
+
if (entry.isSymbolicLink())
|
|
528
|
+
continue;
|
|
529
|
+
if (entry.isDirectory()) {
|
|
530
|
+
replacePlaceholders(p, appName, appTitle, workspaceName);
|
|
341
531
|
continue;
|
|
342
532
|
}
|
|
343
533
|
let content;
|
|
@@ -345,15 +535,22 @@ function replacePlaceholders(dir, appName, appTitle) {
|
|
|
345
535
|
content = fs.readFileSync(p, "utf-8");
|
|
346
536
|
}
|
|
347
537
|
catch {
|
|
348
|
-
continue;
|
|
538
|
+
continue;
|
|
349
539
|
}
|
|
540
|
+
const hasWs = workspaceName !== undefined && content.includes("{{WORKSPACE_NAME}}");
|
|
350
541
|
if (!content.includes("{{APP_NAME}}") &&
|
|
351
|
-
!content.includes("{{APP_TITLE}}")
|
|
542
|
+
!content.includes("{{APP_TITLE}}") &&
|
|
543
|
+
!hasWs) {
|
|
352
544
|
continue;
|
|
353
545
|
}
|
|
354
|
-
|
|
546
|
+
let next = content;
|
|
547
|
+
if (workspaceName !== undefined) {
|
|
548
|
+
next = next.replace(/\{\{WORKSPACE_NAME\}\}/g, workspaceName);
|
|
549
|
+
}
|
|
550
|
+
next = next
|
|
355
551
|
.replace(/\{\{APP_NAME\}\}/g, appName)
|
|
356
|
-
.replace(/\{\{APP_TITLE\}\}/g, appTitle)
|
|
552
|
+
.replace(/\{\{APP_TITLE\}\}/g, appTitle);
|
|
553
|
+
fs.writeFileSync(p, next);
|
|
357
554
|
}
|
|
358
555
|
}
|
|
359
556
|
function copyDir(src, dest, root) {
|
|
@@ -364,15 +561,11 @@ function copyDir(src, dest, root) {
|
|
|
364
561
|
const destPath = path.join(dest, entry.name);
|
|
365
562
|
if (entry.isSymbolicLink()) {
|
|
366
563
|
const target = fs.readlinkSync(srcPath);
|
|
367
|
-
// Resolve one level (path math only, no disk follow) to check
|
|
368
|
-
// whether the symlink stays inside the template tree.
|
|
369
564
|
const resolvedTarget = path.resolve(path.dirname(srcPath), target);
|
|
370
565
|
if (resolvedTarget.startsWith(resolvedRoot)) {
|
|
371
|
-
// Internal symlink (e.g. .claude/skills -> ../.agents/skills) — preserve it
|
|
372
566
|
fs.symlinkSync(target, destPath);
|
|
373
567
|
}
|
|
374
568
|
else if (fs.statSync(srcPath).isDirectory()) {
|
|
375
|
-
// External symlink to directory — dereference and copy contents
|
|
376
569
|
copyDir(srcPath, destPath, resolvedRoot);
|
|
377
570
|
}
|
|
378
571
|
else {
|