@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.
Files changed (473) hide show
  1. package/README.md +43 -3
  2. package/dist/agent/production-agent.d.ts.map +1 -1
  3. package/dist/agent/production-agent.js +154 -4
  4. package/dist/agent/production-agent.js.map +1 -1
  5. package/dist/agent/types.d.ts +1 -1
  6. package/dist/agent/types.d.ts.map +1 -1
  7. package/dist/cli/create-workspace.d.ts +8 -0
  8. package/dist/cli/create-workspace.d.ts.map +1 -0
  9. package/dist/cli/create-workspace.js +18 -0
  10. package/dist/cli/create-workspace.js.map +1 -0
  11. package/dist/cli/create.d.ts +35 -7
  12. package/dist/cli/create.d.ts.map +1 -1
  13. package/dist/cli/create.js +444 -251
  14. package/dist/cli/create.js.map +1 -1
  15. package/dist/cli/index.js +59 -5
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/workspacify.d.ts +18 -0
  18. package/dist/cli/workspacify.d.ts.map +1 -0
  19. package/dist/cli/workspacify.js +74 -0
  20. package/dist/cli/workspacify.js.map +1 -0
  21. package/dist/client/AgentPanel.d.ts +1 -1
  22. package/dist/client/AgentPanel.d.ts.map +1 -1
  23. package/dist/client/AgentPanel.js +63 -225
  24. package/dist/client/AgentPanel.js.map +1 -1
  25. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  26. package/dist/client/components/CodeRequiredDialog.js +86 -5
  27. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  28. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  29. package/dist/client/composer/MentionPopover.js +15 -2
  30. package/dist/client/composer/MentionPopover.js.map +1 -1
  31. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  32. package/dist/client/composer/TiptapComposer.js +3 -1
  33. package/dist/client/composer/TiptapComposer.js.map +1 -1
  34. package/dist/client/composer/types.d.ts +1 -1
  35. package/dist/client/composer/types.d.ts.map +1 -1
  36. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  37. package/dist/client/integrations/IntegrationsPanel.js +22 -9
  38. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  39. package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
  40. package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
  41. package/dist/client/onboarding/OnboardingBanner.js +36 -0
  42. package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
  43. package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
  44. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
  45. package/dist/client/onboarding/OnboardingPanel.js +360 -0
  46. package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
  47. package/dist/client/onboarding/SetupButton.d.ts +10 -0
  48. package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
  49. package/dist/client/onboarding/SetupButton.js +26 -0
  50. package/dist/client/onboarding/SetupButton.js.map +1 -0
  51. package/dist/client/onboarding/index.d.ts +12 -0
  52. package/dist/client/onboarding/index.d.ts.map +1 -0
  53. package/dist/client/onboarding/index.js +11 -0
  54. package/dist/client/onboarding/index.js.map +1 -0
  55. package/dist/client/onboarding/use-onboarding.d.ts +34 -0
  56. package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
  57. package/dist/client/onboarding/use-onboarding.js +101 -0
  58. package/dist/client/onboarding/use-onboarding.js.map +1 -0
  59. package/dist/client/org/TeamPage.d.ts +6 -1
  60. package/dist/client/org/TeamPage.d.ts.map +1 -1
  61. package/dist/client/org/TeamPage.js +85 -14
  62. package/dist/client/org/TeamPage.js.map +1 -1
  63. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  64. package/dist/client/resources/ResourceEditor.js +48 -77
  65. package/dist/client/resources/ResourceEditor.js.map +1 -1
  66. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  67. package/dist/client/resources/ResourceTree.js +16 -3
  68. package/dist/client/resources/ResourceTree.js.map +1 -1
  69. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  70. package/dist/client/resources/ResourcesPanel.js +135 -9
  71. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  72. package/dist/client/resources/use-resources.d.ts +5 -0
  73. package/dist/client/resources/use-resources.d.ts.map +1 -1
  74. package/dist/client/resources/use-resources.js.map +1 -1
  75. package/dist/client/settings/AgentsSection.d.ts +2 -0
  76. package/dist/client/settings/AgentsSection.d.ts.map +1 -0
  77. package/dist/client/settings/AgentsSection.js +198 -0
  78. package/dist/client/settings/AgentsSection.js.map +1 -0
  79. package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
  80. package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
  81. package/dist/client/settings/BackgroundAgentSection.js +46 -0
  82. package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
  83. package/dist/client/settings/BrowserSection.d.ts +2 -0
  84. package/dist/client/settings/BrowserSection.d.ts.map +1 -0
  85. package/dist/client/settings/BrowserSection.js +10 -0
  86. package/dist/client/settings/BrowserSection.js.map +1 -0
  87. package/dist/client/settings/ComingSoonSection.d.ts +13 -0
  88. package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
  89. package/dist/client/settings/ComingSoonSection.js +9 -0
  90. package/dist/client/settings/ComingSoonSection.js.map +1 -0
  91. package/dist/client/settings/LLMSection.d.ts +2 -0
  92. package/dist/client/settings/LLMSection.d.ts.map +1 -0
  93. package/dist/client/settings/LLMSection.js +64 -0
  94. package/dist/client/settings/LLMSection.js.map +1 -0
  95. package/dist/client/settings/SettingsPanel.d.ts +8 -0
  96. package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
  97. package/dist/client/settings/SettingsPanel.js +118 -0
  98. package/dist/client/settings/SettingsPanel.js.map +1 -0
  99. package/dist/client/settings/SettingsSection.d.ts +19 -0
  100. package/dist/client/settings/SettingsSection.d.ts.map +1 -0
  101. package/dist/client/settings/SettingsSection.js +10 -0
  102. package/dist/client/settings/SettingsSection.js.map +1 -0
  103. package/dist/client/settings/index.d.ts +3 -0
  104. package/dist/client/settings/index.d.ts.map +1 -0
  105. package/dist/client/settings/index.js +3 -0
  106. package/dist/client/settings/index.js.map +1 -0
  107. package/dist/client/settings/useBuilderStatus.d.ts +22 -0
  108. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
  109. package/dist/client/settings/useBuilderStatus.js +41 -0
  110. package/dist/client/settings/useBuilderStatus.js.map +1 -0
  111. package/dist/deploy/build.js +198 -54
  112. package/dist/deploy/build.js.map +1 -1
  113. package/dist/deploy/route-discovery.d.ts +5 -0
  114. package/dist/deploy/route-discovery.d.ts.map +1 -1
  115. package/dist/deploy/route-discovery.js +38 -7
  116. package/dist/deploy/route-discovery.js.map +1 -1
  117. package/dist/deploy/workspace-core.d.ts +28 -0
  118. package/dist/deploy/workspace-core.d.ts.map +1 -0
  119. package/dist/deploy/workspace-core.js +223 -0
  120. package/dist/deploy/workspace-core.js.map +1 -0
  121. package/dist/deploy/workspace-deploy.d.ts +11 -0
  122. package/dist/deploy/workspace-deploy.d.ts.map +1 -0
  123. package/dist/deploy/workspace-deploy.js +148 -0
  124. package/dist/deploy/workspace-deploy.js.map +1 -0
  125. package/dist/file-upload/builder.d.ts +11 -0
  126. package/dist/file-upload/builder.d.ts.map +1 -0
  127. package/dist/file-upload/builder.js +53 -0
  128. package/dist/file-upload/builder.js.map +1 -0
  129. package/dist/file-upload/index.d.ts +4 -0
  130. package/dist/file-upload/index.d.ts.map +1 -0
  131. package/dist/file-upload/index.js +3 -0
  132. package/dist/file-upload/index.js.map +1 -0
  133. package/dist/file-upload/registry.d.ts +23 -0
  134. package/dist/file-upload/registry.d.ts.map +1 -0
  135. package/dist/file-upload/registry.js +52 -0
  136. package/dist/file-upload/registry.js.map +1 -0
  137. package/dist/file-upload/types.d.ts +37 -0
  138. package/dist/file-upload/types.d.ts.map +1 -0
  139. package/dist/file-upload/types.js +10 -0
  140. package/dist/file-upload/types.js.map +1 -0
  141. package/dist/integrations/adapters/google-docs.d.ts +89 -0
  142. package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
  143. package/dist/integrations/adapters/google-docs.js +261 -0
  144. package/dist/integrations/adapters/google-docs.js.map +1 -0
  145. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  146. package/dist/integrations/adapters/slack.js +34 -0
  147. package/dist/integrations/adapters/slack.js.map +1 -1
  148. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  149. package/dist/integrations/adapters/telegram.js +32 -0
  150. package/dist/integrations/adapters/telegram.js.map +1 -1
  151. package/dist/integrations/google-docs-poller.d.ts +54 -0
  152. package/dist/integrations/google-docs-poller.d.ts.map +1 -0
  153. package/dist/integrations/google-docs-poller.js +442 -0
  154. package/dist/integrations/google-docs-poller.js.map +1 -0
  155. package/dist/integrations/index.d.ts +2 -0
  156. package/dist/integrations/index.d.ts.map +1 -1
  157. package/dist/integrations/index.js +3 -0
  158. package/dist/integrations/index.js.map +1 -1
  159. package/dist/integrations/plugin.d.ts.map +1 -1
  160. package/dist/integrations/plugin.js +49 -2
  161. package/dist/integrations/plugin.js.map +1 -1
  162. package/dist/integrations/types.d.ts +33 -0
  163. package/dist/integrations/types.d.ts.map +1 -1
  164. package/dist/integrations/webhook-handler.d.ts +10 -1
  165. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  166. package/dist/integrations/webhook-handler.js +13 -3
  167. package/dist/integrations/webhook-handler.js.map +1 -1
  168. package/dist/jobs/scheduler.d.ts +3 -0
  169. package/dist/jobs/scheduler.d.ts.map +1 -1
  170. package/dist/jobs/scheduler.js +81 -60
  171. package/dist/jobs/scheduler.js.map +1 -1
  172. package/dist/jobs/tools.d.ts.map +1 -1
  173. package/dist/jobs/tools.js +20 -3
  174. package/dist/jobs/tools.js.map +1 -1
  175. package/dist/mcp-client/config.d.ts +46 -0
  176. package/dist/mcp-client/config.d.ts.map +1 -0
  177. package/dist/mcp-client/config.js +152 -0
  178. package/dist/mcp-client/config.js.map +1 -0
  179. package/dist/mcp-client/index.d.ts +17 -0
  180. package/dist/mcp-client/index.d.ts.map +1 -0
  181. package/dist/mcp-client/index.js +53 -0
  182. package/dist/mcp-client/index.js.map +1 -0
  183. package/dist/mcp-client/manager.d.ts +76 -0
  184. package/dist/mcp-client/manager.d.ts.map +1 -0
  185. package/dist/mcp-client/manager.js +212 -0
  186. package/dist/mcp-client/manager.js.map +1 -0
  187. package/dist/oauth-tokens/store.d.ts.map +1 -1
  188. package/dist/oauth-tokens/store.js +3 -1
  189. package/dist/oauth-tokens/store.js.map +1 -1
  190. package/dist/onboarding/default-steps.d.ts +10 -0
  191. package/dist/onboarding/default-steps.d.ts.map +1 -0
  192. package/dist/onboarding/default-steps.js +164 -0
  193. package/dist/onboarding/default-steps.js.map +1 -0
  194. package/dist/onboarding/index.d.ts +12 -0
  195. package/dist/onboarding/index.d.ts.map +1 -0
  196. package/dist/onboarding/index.js +11 -0
  197. package/dist/onboarding/index.js.map +1 -0
  198. package/dist/onboarding/plugin.d.ts +19 -0
  199. package/dist/onboarding/plugin.d.ts.map +1 -0
  200. package/dist/onboarding/plugin.js +147 -0
  201. package/dist/onboarding/plugin.js.map +1 -0
  202. package/dist/onboarding/registry.d.ts +24 -0
  203. package/dist/onboarding/registry.d.ts.map +1 -0
  204. package/dist/onboarding/registry.js +40 -0
  205. package/dist/onboarding/registry.js.map +1 -0
  206. package/dist/onboarding/types.d.ts +71 -0
  207. package/dist/onboarding/types.d.ts.map +1 -0
  208. package/dist/onboarding/types.js +10 -0
  209. package/dist/onboarding/types.js.map +1 -0
  210. package/dist/resources/agents.d.ts +4 -0
  211. package/dist/resources/agents.d.ts.map +1 -0
  212. package/dist/resources/agents.js +44 -0
  213. package/dist/resources/agents.js.map +1 -0
  214. package/dist/resources/handlers.d.ts +17 -0
  215. package/dist/resources/handlers.d.ts.map +1 -1
  216. package/dist/resources/handlers.js +49 -12
  217. package/dist/resources/handlers.js.map +1 -1
  218. package/dist/resources/metadata.d.ts +48 -0
  219. package/dist/resources/metadata.d.ts.map +1 -0
  220. package/dist/resources/metadata.js +150 -0
  221. package/dist/resources/metadata.js.map +1 -0
  222. package/dist/resources/script-helpers.d.ts.map +1 -1
  223. package/dist/resources/script-helpers.js +3 -2
  224. package/dist/resources/script-helpers.js.map +1 -1
  225. package/dist/resources/store.d.ts.map +1 -1
  226. package/dist/resources/store.js +32 -17
  227. package/dist/resources/store.js.map +1 -1
  228. package/dist/scripts/call-agent.d.ts.map +1 -1
  229. package/dist/scripts/call-agent.js +3 -2
  230. package/dist/scripts/call-agent.js.map +1 -1
  231. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  232. package/dist/scripts/chat/search-chats.js +2 -1
  233. package/dist/scripts/chat/search-chats.js.map +1 -1
  234. package/dist/scripts/core-scripts.d.ts.map +1 -1
  235. package/dist/scripts/core-scripts.js +2 -0
  236. package/dist/scripts/core-scripts.js.map +1 -1
  237. package/dist/scripts/db/scoping.d.ts.map +1 -1
  238. package/dist/scripts/db/scoping.js +3 -2
  239. package/dist/scripts/db/scoping.js.map +1 -1
  240. package/dist/scripts/docs/index.d.ts +2 -0
  241. package/dist/scripts/docs/index.d.ts.map +1 -0
  242. package/dist/scripts/docs/index.js +4 -0
  243. package/dist/scripts/docs/index.js.map +1 -0
  244. package/dist/scripts/docs/search.d.ts +13 -0
  245. package/dist/scripts/docs/search.d.ts.map +1 -0
  246. package/dist/scripts/docs/search.js +130 -0
  247. package/dist/scripts/docs/search.js.map +1 -0
  248. package/dist/scripts/resources/delete-memory.d.ts +7 -0
  249. package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
  250. package/dist/scripts/resources/delete-memory.js +49 -0
  251. package/dist/scripts/resources/delete-memory.js.map +1 -0
  252. package/dist/scripts/resources/delete.d.ts.map +1 -1
  253. package/dist/scripts/resources/delete.js +2 -1
  254. package/dist/scripts/resources/delete.js.map +1 -1
  255. package/dist/scripts/resources/index.d.ts.map +1 -1
  256. package/dist/scripts/resources/index.js +2 -0
  257. package/dist/scripts/resources/index.js.map +1 -1
  258. package/dist/scripts/resources/list.d.ts.map +1 -1
  259. package/dist/scripts/resources/list.js +2 -1
  260. package/dist/scripts/resources/list.js.map +1 -1
  261. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  262. package/dist/scripts/resources/migrate-learnings.js +2 -1
  263. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  264. package/dist/scripts/resources/read.d.ts.map +1 -1
  265. package/dist/scripts/resources/read.js +2 -1
  266. package/dist/scripts/resources/read.js.map +1 -1
  267. package/dist/scripts/resources/save-memory.d.ts +9 -0
  268. package/dist/scripts/resources/save-memory.d.ts.map +1 -0
  269. package/dist/scripts/resources/save-memory.js +78 -0
  270. package/dist/scripts/resources/save-memory.js.map +1 -0
  271. package/dist/scripts/resources/write.d.ts.map +1 -1
  272. package/dist/scripts/resources/write.js +2 -1
  273. package/dist/scripts/resources/write.js.map +1 -1
  274. package/dist/scripts/utils.d.ts +10 -1
  275. package/dist/scripts/utils.d.ts.map +1 -1
  276. package/dist/scripts/utils.js +45 -2
  277. package/dist/scripts/utils.js.map +1 -1
  278. package/dist/server/action-discovery.d.ts +5 -0
  279. package/dist/server/action-discovery.d.ts.map +1 -1
  280. package/dist/server/action-discovery.js +51 -20
  281. package/dist/server/action-discovery.js.map +1 -1
  282. package/dist/server/action-routes.d.ts.map +1 -1
  283. package/dist/server/action-routes.js +63 -57
  284. package/dist/server/action-routes.js.map +1 -1
  285. package/dist/server/agent-chat-plugin.d.ts +3 -0
  286. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  287. package/dist/server/agent-chat-plugin.js +363 -48
  288. package/dist/server/agent-chat-plugin.js.map +1 -1
  289. package/dist/server/agent-discovery.d.ts.map +1 -1
  290. package/dist/server/agent-discovery.js +11 -23
  291. package/dist/server/agent-discovery.js.map +1 -1
  292. package/dist/server/agent-teams.d.ts.map +1 -1
  293. package/dist/server/agent-teams.js +2 -1
  294. package/dist/server/agent-teams.js.map +1 -1
  295. package/dist/server/agents-bundle.d.ts +33 -5
  296. package/dist/server/agents-bundle.d.ts.map +1 -1
  297. package/dist/server/agents-bundle.js +108 -64
  298. package/dist/server/agents-bundle.js.map +1 -1
  299. package/dist/server/auth.d.ts +1 -0
  300. package/dist/server/auth.d.ts.map +1 -1
  301. package/dist/server/auth.js +172 -60
  302. package/dist/server/auth.js.map +1 -1
  303. package/dist/server/better-auth-instance.d.ts.map +1 -1
  304. package/dist/server/better-auth-instance.js +202 -6
  305. package/dist/server/better-auth-instance.js.map +1 -1
  306. package/dist/server/builder-browser.d.ts +40 -0
  307. package/dist/server/builder-browser.d.ts.map +1 -0
  308. package/dist/server/builder-browser.js +166 -0
  309. package/dist/server/builder-browser.js.map +1 -0
  310. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  311. package/dist/server/core-routes-plugin.js +152 -6
  312. package/dist/server/core-routes-plugin.js.map +1 -1
  313. package/dist/server/credential-provider.d.ts +37 -0
  314. package/dist/server/credential-provider.d.ts.map +1 -0
  315. package/dist/server/credential-provider.js +49 -0
  316. package/dist/server/credential-provider.js.map +1 -0
  317. package/dist/server/framework-request-handler.d.ts.map +1 -1
  318. package/dist/server/framework-request-handler.js +42 -3
  319. package/dist/server/framework-request-handler.js.map +1 -1
  320. package/dist/server/google-auth-plugin.js +1 -1
  321. package/dist/server/google-oauth.d.ts +1 -1
  322. package/dist/server/google-oauth.d.ts.map +1 -1
  323. package/dist/server/google-oauth.js +15 -10
  324. package/dist/server/google-oauth.js.map +1 -1
  325. package/dist/server/index.d.ts +3 -0
  326. package/dist/server/index.d.ts.map +1 -1
  327. package/dist/server/index.js +3 -0
  328. package/dist/server/index.js.map +1 -1
  329. package/dist/server/oauth-helpers.d.ts +1 -0
  330. package/dist/server/oauth-helpers.d.ts.map +1 -1
  331. package/dist/server/oauth-helpers.js +5 -4
  332. package/dist/server/oauth-helpers.js.map +1 -1
  333. package/dist/server/onboarding-html.d.ts.map +1 -1
  334. package/dist/server/onboarding-html.js +94 -3
  335. package/dist/server/onboarding-html.js.map +1 -1
  336. package/dist/server/request-context.d.ts +20 -0
  337. package/dist/server/request-context.d.ts.map +1 -0
  338. package/dist/server/request-context.js +41 -0
  339. package/dist/server/request-context.js.map +1 -0
  340. package/dist/templates/default/.agents/skills/actions/SKILL.md +2 -1
  341. package/dist/templates/default/.agents/skills/security/SKILL.md +145 -40
  342. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
  343. package/dist/templates/default/_gitignore +1 -0
  344. package/dist/templates/default/app/root.tsx +4 -1
  345. package/dist/templates/workspace-core/AGENTS.md +62 -0
  346. package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
  347. package/dist/templates/workspace-core/package.json +39 -0
  348. package/dist/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
  349. package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
  350. package/dist/templates/workspace-core/src/client/index.ts +26 -0
  351. package/dist/templates/workspace-core/src/credentials.ts +29 -0
  352. package/dist/templates/workspace-core/src/index.ts +21 -0
  353. package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
  354. package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
  355. package/dist/templates/workspace-core/src/server/index.ts +22 -0
  356. package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
  357. package/dist/templates/workspace-core/tsconfig.json +9 -0
  358. package/dist/templates/workspace-root/.env.example +37 -0
  359. package/dist/templates/workspace-root/README.md +62 -0
  360. package/dist/templates/workspace-root/_gitignore +23 -0
  361. package/dist/templates/workspace-root/package.json +18 -0
  362. package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
  363. package/dist/templates/workspace-root/tsconfig.base.json +21 -0
  364. package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
  365. package/dist/vite/agents-bundle-plugin.js +65 -15
  366. package/dist/vite/agents-bundle-plugin.js.map +1 -1
  367. package/dist/vite/client.d.ts +16 -0
  368. package/dist/vite/client.d.ts.map +1 -1
  369. package/dist/vite/client.js +75 -0
  370. package/dist/vite/client.js.map +1 -1
  371. package/docs/content/a2a-protocol.md +223 -0
  372. package/docs/content/actions.md +129 -0
  373. package/docs/content/agent-mentions.md +171 -0
  374. package/docs/content/authentication.md +155 -0
  375. package/docs/content/cli-adapters.md +244 -0
  376. package/docs/content/client.md +175 -0
  377. package/docs/content/context-awareness.md +168 -0
  378. package/docs/content/creating-templates.md +311 -0
  379. package/docs/content/database.md +82 -0
  380. package/docs/content/deployment.md +180 -0
  381. package/docs/content/enterprise-workspace.md +235 -0
  382. package/docs/content/faq.md +101 -0
  383. package/docs/content/file-uploads.md +102 -0
  384. package/docs/content/frames.md +47 -0
  385. package/docs/content/getting-started.md +104 -0
  386. package/docs/content/integrations.md +198 -0
  387. package/docs/content/key-concepts.md +246 -0
  388. package/docs/content/mcp-clients.md +110 -0
  389. package/docs/content/mcp-protocol.md +168 -0
  390. package/docs/content/onboarding.md +107 -0
  391. package/docs/content/real-time-collaboration.md +185 -0
  392. package/docs/content/resources.md +277 -0
  393. package/docs/content/security.md +158 -0
  394. package/docs/content/server.md +200 -0
  395. package/docs/content/skills-guide.md +107 -0
  396. package/docs/content/what-is-agent-native.md +100 -0
  397. package/docs/content/workspace-management.md +224 -0
  398. package/package.json +12 -2
  399. package/src/templates/default/.agents/skills/actions/SKILL.md +2 -1
  400. package/src/templates/default/.agents/skills/security/SKILL.md +145 -40
  401. package/src/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
  402. package/src/templates/default/_gitignore +1 -0
  403. package/src/templates/default/app/root.tsx +4 -1
  404. package/src/templates/workspace-core/AGENTS.md +62 -0
  405. package/src/templates/workspace-core/actions/company-directory.ts +38 -0
  406. package/src/templates/workspace-core/package.json +39 -0
  407. package/src/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
  408. package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
  409. package/src/templates/workspace-core/src/client/index.ts +26 -0
  410. package/src/templates/workspace-core/src/credentials.ts +29 -0
  411. package/src/templates/workspace-core/src/index.ts +21 -0
  412. package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
  413. package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
  414. package/src/templates/workspace-core/src/server/index.ts +22 -0
  415. package/src/templates/workspace-core/tailwind.preset.ts +34 -0
  416. package/src/templates/workspace-core/tsconfig.json +9 -0
  417. package/src/templates/workspace-root/.env.example +37 -0
  418. package/src/templates/workspace-root/README.md +62 -0
  419. package/src/templates/workspace-root/_gitignore +23 -0
  420. package/src/templates/workspace-root/package.json +18 -0
  421. package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
  422. package/src/templates/workspace-root/tsconfig.base.json +21 -0
  423. package/dist/templates/templates/default/.agents/skills/actions/SKILL.md +0 -142
  424. package/dist/templates/templates/default/.agents/skills/agent-engines/SKILL.md +0 -127
  425. package/dist/templates/templates/default/.agents/skills/capture-learnings/SKILL.md +0 -50
  426. package/dist/templates/templates/default/.agents/skills/create-skill/SKILL.md +0 -167
  427. package/dist/templates/templates/default/.agents/skills/delegate-to-agent/SKILL.md +0 -90
  428. package/dist/templates/templates/default/.agents/skills/frontend-design/SKILL.md +0 -69
  429. package/dist/templates/templates/default/.agents/skills/real-time-collab/SKILL.md +0 -183
  430. package/dist/templates/templates/default/.agents/skills/real-time-sync/SKILL.md +0 -112
  431. package/dist/templates/templates/default/.agents/skills/security/SKILL.md +0 -108
  432. package/dist/templates/templates/default/.agents/skills/self-modifying-code/SKILL.md +0 -79
  433. package/dist/templates/templates/default/.agents/skills/storing-data/SKILL.md +0 -110
  434. package/dist/templates/templates/default/.claude/settings.json +0 -100
  435. package/dist/templates/templates/default/.env.example +0 -5
  436. package/dist/templates/templates/default/.ignore +0 -0
  437. package/dist/templates/templates/default/.prettierrc +0 -5
  438. package/dist/templates/templates/default/AGENTS.md +0 -110
  439. package/dist/templates/templates/default/DEVELOPING.md +0 -117
  440. package/dist/templates/templates/default/_gitignore +0 -37
  441. package/dist/templates/templates/default/actions/hello.ts +0 -20
  442. package/dist/templates/templates/default/actions/navigate.ts +0 -53
  443. package/dist/templates/templates/default/actions/run.ts +0 -2
  444. package/dist/templates/templates/default/actions/view-screen.ts +0 -39
  445. package/dist/templates/templates/default/app/entry.client.tsx +0 -4
  446. package/dist/templates/templates/default/app/entry.server.tsx +0 -56
  447. package/dist/templates/templates/default/app/global.css +0 -95
  448. package/dist/templates/templates/default/app/lib/utils.ts +0 -1
  449. package/dist/templates/templates/default/app/root.tsx +0 -107
  450. package/dist/templates/templates/default/app/routes/_index.tsx +0 -62
  451. package/dist/templates/templates/default/app/routes.ts +0 -4
  452. package/dist/templates/templates/default/app/vite-env.d.ts +0 -6
  453. package/dist/templates/templates/default/components.json +0 -20
  454. package/dist/templates/templates/default/data/.gitkeep +0 -0
  455. package/dist/templates/templates/default/data/sync-config.json +0 -1
  456. package/dist/templates/templates/default/learnings.defaults.md +0 -5
  457. package/dist/templates/templates/default/learnings.md +0 -0
  458. package/dist/templates/templates/default/package.json +0 -46
  459. package/dist/templates/templates/default/postcss.config.js +0 -6
  460. package/dist/templates/templates/default/public/icon-180.svg +0 -4
  461. package/dist/templates/templates/default/public/icon-192.svg +0 -4
  462. package/dist/templates/templates/default/public/icon-512.svg +0 -4
  463. package/dist/templates/templates/default/public/manifest.json +0 -13
  464. package/dist/templates/templates/default/react-router.config.ts +0 -6
  465. package/dist/templates/templates/default/server/middleware/auth.ts +0 -15
  466. package/dist/templates/templates/default/server/plugins/.gitkeep +0 -0
  467. package/dist/templates/templates/default/server/routes/[...page].get.ts +0 -5
  468. package/dist/templates/templates/default/server/routes/api/hello.get.ts +0 -5
  469. package/dist/templates/templates/default/shared/api.ts +0 -6
  470. package/dist/templates/templates/default/ssr-entry.ts +0 -20
  471. package/dist/templates/templates/default/tailwind.config.ts +0 -7
  472. package/dist/templates/templates/default/tsconfig.json +0 -11
  473. package/dist/templates/templates/default/vite.config.ts +0 -6
@@ -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
- * Template definitions with descriptions for the interactive picker.
12
- */
13
- const TEMPLATES = [
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
- * Interactive mode: prompts for app name and template if not provided.
82
- * With --template <name>: downloads the template from GitHub.
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
- clack.intro("Create a new agent-native app");
88
- // Prompt for name if not provided
89
- if (!name) {
90
- const nameResult = await clack.text({
91
- message: "What is your app name?",
92
- placeholder: "my-app",
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
- else {
111
- // Validate provided name
112
- if (!/^[a-z][a-z0-9-]*$/.test(name)) {
113
- clack.cancel(`Invalid app name "${name}". Use lowercase letters, numbers, and hyphens.`);
114
- process.exit(1);
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("Scaffolding your app...");
72
+ s.start(`Scaffolding workspace with ${templates.length} app(s)...`);
141
73
  try {
142
- if (template === "blank") {
143
- createFromDefault(name, targetDir);
144
- }
145
- else {
146
- await createFromTemplate(name, targetDir, template);
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("App created!");
90
+ s.stop("Workspace scaffolded.");
149
91
  }
150
92
  catch (err) {
151
- s.stop("Failed to create app.");
93
+ s.stop("Failed to scaffold workspace.");
152
94
  throw err;
153
95
  }
154
- clack.outro(`Done! Next steps:\n\n cd ${name}\n pnpm install\n pnpm dev`);
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 templateDir = path.join(packageRoot, "src/templates/default");
162
- if (!fs.existsSync(templateDir)) {
163
- console.error(`Template directory not found at ${templateDir}. Is the package installed correctly?`);
164
- process.exit(1);
165
- }
166
- copyDir(templateDir, targetDir);
167
- postProcess(name, targetDir);
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
- * Create from a named template or GitHub repo.
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
- * Supports:
173
- * --template mail (first-party template from BuilderIO/agent-native)
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 createFromTemplate(name, targetDir, template) {
177
- // Normalize "video" "videos" (docs use singular, dir is plural)
178
- let resolvedTemplate = template;
179
- if (resolvedTemplate === "video")
180
- resolvedTemplate = "videos";
181
- if (resolvedTemplate.startsWith("github:")) {
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
- else if (KNOWN_TEMPLATES.includes(resolvedTemplate)) {
187
- // First-party template from monorepo
188
- await downloadGitHubSubdir(REPO, `${TEMPLATES_DIR}/${resolvedTemplate}`, targetDir);
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
- else {
191
- console.error(`Unknown template "${template}". Available templates: ${KNOWN_TEMPLATES.filter((t) => t !== "videos").join(", ")}`);
192
- console.error(`For community templates, use: --template github:user/repo`);
193
- process.exit(1);
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
- * Validate a GitHub repo string (user/repo) to prevent injection.
199
- */
200
- function validateRepoName(repo) {
201
- if (!/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(repo)) {
202
- console.error(`Invalid repository name "${repo}". Expected format: user/repo`);
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
- execFileSync("tar", ["xzf", tarPath, "--strip-components=1", "-C", destDir], {
221
- stdio: "pipe",
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
- finally {
225
- fs.unlinkSync(tarPath);
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
- * Download a subdirectory from a GitHub repo using the tarball API.
230
- */
231
- async function downloadGitHubSubdir(repo, subdir, targetDir) {
232
- validateRepoName(repo);
233
- const tarUrl = `https://api.github.com/repos/${repo}/tarball/main`;
234
- // Download and extract into a temp dir, then copy the subdir
235
- const tmpDir = path.join(targetDir, "..", `.agent-native-tmp-${Date.now()}`);
236
- try {
237
- downloadAndExtract(tarUrl, tmpDir);
238
- const srcDir = path.join(tmpDir, subdir);
239
- if (!fs.existsSync(srcDir)) {
240
- console.error(`Template directory "${subdir}" not found in ${repo}. Check the template name.`);
241
- process.exit(1);
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
- // Copy template to target
244
- copyDir(srcDir, targetDir);
224
+ template = picked;
245
225
  }
246
- finally {
247
- // Clean up temp dir
248
- fs.rmSync(tmpDir, { recursive: true, force: true });
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
- * Download an entire GitHub repo (for community templates).
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 downloadGitHubRepo(repo, targetDir) {
255
- validateRepoName(repo);
256
- const tarUrl = `https://api.github.com/repos/${repo}/tarball/main`;
257
- try {
258
- downloadAndExtract(tarUrl, targetDir);
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
- catch {
261
- console.error(`Failed to download template from ${repo}. Check the repo name and that it's public.`);
262
- process.exit(1);
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
- * Post-process a scaffolded template: replace placeholders, set up symlinks, etc.
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 postProcess(name, targetDir) {
269
- // Replace {{APP_NAME}} and {{APP_TITLE}} placeholders in all text files
270
- const appTitle = name
271
- .split("-")
272
- .map((w) => w[0].toUpperCase() + w.slice(1))
273
- .join(" ");
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
- catch { }
291
+ const parent = path.dirname(dir);
292
+ if (parent === dir)
293
+ break;
294
+ dir = parent;
284
295
  }
285
- // Copy defaults files
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
- // Rename gitignore (npm strips .gitignore from packages)
294
- const gitignoreSrc = path.join(targetDir, "_gitignore");
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
- // Fix package.json: remove workspace: references
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
- * Recursively replace {{APP_NAME}} and {{APP_TITLE}} placeholders in all
333
- * text files under `dir`. Binary files are skipped silently.
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 replacePlaceholders(dir, appName, appTitle) {
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() || entry.isDirectory()) {
339
- if (!entry.isSymbolicLink())
340
- replacePlaceholders(p, appName, appTitle);
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; // skip unreadable / binary files
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
- fs.writeFileSync(p, content
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 {