@agent-native/core 0.137.7 → 0.138.0

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 (446) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +23 -3
  4. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  5. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +15 -0
  6. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +23 -2
  7. package/corpus/templates/analytics/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  8. package/corpus/templates/analytics/AGENTS.md +2 -2
  9. package/corpus/templates/analytics/actions/get-first-party-analytics-health.ts +65 -0
  10. package/corpus/templates/analytics/actions/provider-api-catalog.ts +3 -6
  11. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -6
  12. package/corpus/templates/analytics/actions/provider-api-request.ts +3 -6
  13. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +3 -3
  14. package/corpus/templates/analytics/agent-native.json +12 -0
  15. package/corpus/templates/analytics/app/i18n-data.ts +162 -0
  16. package/corpus/templates/analytics/app/pages/DataSources.tsx +126 -1
  17. package/corpus/templates/analytics/changelog/2026-08-05-analytics-now-flags-neon-pressure-and-guides-high-volume-tra.md +6 -0
  18. package/corpus/templates/analytics/changelog/2026-08-05-first-party-analytics-uses-compact-rollups-for-faster-usage-.md +6 -0
  19. package/corpus/templates/analytics/server/db/schema.ts +52 -0
  20. package/corpus/templates/analytics/server/lib/credential-keys.ts +3 -0
  21. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +397 -0
  22. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +182 -0
  23. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +86 -15
  24. package/corpus/templates/analytics/server/lib/provider-api.ts +20 -1
  25. package/corpus/templates/analytics/server/lib/replay-storage.ts +1 -1
  26. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  27. package/corpus/templates/analytics/server/plugins/db.ts +60 -0
  28. package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +23 -3
  29. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  30. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +23 -2
  31. package/corpus/templates/assets/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  32. package/corpus/templates/assets/agent-native.json +12 -0
  33. package/corpus/templates/assets/server/lib/generation.ts +8 -8
  34. package/corpus/templates/assets/server/lib/storage.ts +1 -1
  35. package/corpus/templates/assets/server/plugins/onboarding.ts +1 -1
  36. package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +23 -3
  37. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  38. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +23 -2
  39. package/corpus/templates/brain/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  40. package/corpus/templates/brain/agent-native.json +12 -0
  41. package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +23 -3
  42. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  43. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +23 -2
  44. package/corpus/templates/calendar/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  45. package/corpus/templates/calendar/agent-native.json +12 -0
  46. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  47. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  48. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  49. package/corpus/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  50. package/corpus/templates/chat/AGENTS.md +3 -0
  51. package/corpus/templates/chat/DESIGN.md +28 -0
  52. package/corpus/templates/chat/agent-native.json +12 -0
  53. package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +23 -3
  54. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  55. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +23 -2
  56. package/corpus/templates/clips/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  57. package/corpus/templates/clips/actions/cleanup-transcript.ts +2 -2
  58. package/corpus/templates/clips/actions/delete-recording-permanent.ts +3 -0
  59. package/corpus/templates/clips/actions/get-playback-position.ts +68 -0
  60. package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
  61. package/corpus/templates/clips/actions/save-playback-position.ts +80 -0
  62. package/corpus/templates/clips/actions/set-thumbnail.ts +1 -1
  63. package/corpus/templates/clips/agent-native.json +12 -0
  64. package/corpus/templates/clips/app/components/player/video-player.tsx +54 -5
  65. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +65 -18
  66. package/corpus/templates/clips/app/hooks/use-playback-position.ts +188 -0
  67. package/corpus/templates/clips/app/hooks/use-view-tracking.ts +6 -24
  68. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  69. package/corpus/templates/clips/app/lib/playback-position.ts +99 -0
  70. package/corpus/templates/clips/app/lib/viewer-session.ts +29 -0
  71. package/corpus/templates/clips/changelog/2026-08-05-clip-buffering-now-uses-buffering-copy-after-playback.md +6 -0
  72. package/corpus/templates/clips/changelog/2026-08-05-clips-remembers-your-playback-position-when-you-reopen-a-cli.md +6 -0
  73. package/corpus/templates/clips/desktop/package.json +1 -0
  74. package/corpus/templates/clips/desktop/src/app.tsx +70 -6
  75. package/corpus/templates/clips/desktop/src/components/AlertDialog.tsx +131 -0
  76. package/corpus/templates/clips/desktop/src/styles.css +129 -0
  77. package/corpus/templates/clips/learnings.defaults.md +1 -1
  78. package/corpus/templates/clips/server/db/schema.ts +18 -0
  79. package/corpus/templates/clips/server/lib/public-agent-context.ts +1 -1
  80. package/corpus/templates/clips/server/lib/video-storage.ts +1 -1
  81. package/corpus/templates/clips/server/plugins/db.ts +15 -0
  82. package/corpus/templates/clips/server/routes/api/media/index.post.ts +1 -1
  83. package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +23 -3
  84. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  85. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +13 -0
  86. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +23 -2
  87. package/corpus/templates/content/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  88. package/corpus/templates/content/AGENTS.md +1 -0
  89. package/corpus/templates/content/actions/_content-database-mutation-lock.ts +41 -0
  90. package/corpus/templates/content/actions/_content-database-row-migration.ts +569 -0
  91. package/corpus/templates/content/actions/_database-source-utils.ts +82 -36
  92. package/corpus/templates/content/actions/_database-utils.ts +5 -0
  93. package/corpus/templates/content/actions/_delete-content-space.ts +25 -11
  94. package/corpus/templates/content/actions/add-database-item.ts +60 -42
  95. package/corpus/templates/content/actions/attach-content-database-source.ts +2 -0
  96. package/corpus/templates/content/actions/configure-document-property.ts +99 -104
  97. package/corpus/templates/content/actions/delete-content-database.ts +19 -7
  98. package/corpus/templates/content/actions/delete-document-property.ts +47 -58
  99. package/corpus/templates/content/actions/delete-document.ts +390 -167
  100. package/corpus/templates/content/actions/disconnect-content-database-source.ts +41 -24
  101. package/corpus/templates/content/actions/duplicate-database-item.ts +63 -31
  102. package/corpus/templates/content/actions/duplicate-database-items.ts +86 -43
  103. package/corpus/templates/content/actions/duplicate-document-property.ts +37 -14
  104. package/corpus/templates/content/actions/migrate-content-database-rows.ts +830 -0
  105. package/corpus/templates/content/actions/move-database-item.ts +14 -0
  106. package/corpus/templates/content/actions/permanently-delete-document.ts +27 -6
  107. package/corpus/templates/content/actions/remove-database-items.ts +13 -0
  108. package/corpus/templates/content/actions/reorder-document-property.ts +45 -46
  109. package/corpus/templates/content/actions/set-document-property.ts +68 -28
  110. package/corpus/templates/content/actions/submit-content-database-form.ts +49 -0
  111. package/corpus/templates/content/actions/transcribe-media.ts +1 -1
  112. package/corpus/templates/content/agent-native.json +12 -0
  113. package/corpus/templates/content/app/components/editor/image-upload.ts +2 -2
  114. package/corpus/templates/content/app/i18n-data.ts +1 -1
  115. package/corpus/templates/content/changelog/2026-08-01-content-can-reorganize-every-row-in-an-existing-database-as-.md +6 -0
  116. package/corpus/templates/content/parity/matrix.md +1 -1
  117. package/corpus/templates/content/parity/matrix.ts +4 -2
  118. package/corpus/templates/content/server/db/schema.ts +30 -0
  119. package/corpus/templates/content/server/plugins/db.ts +24 -0
  120. package/corpus/templates/content/server/plugins/onboarding.ts +2 -2
  121. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +23 -3
  122. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  123. package/corpus/templates/crm/agent-native.json +12 -0
  124. package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +23 -3
  125. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  126. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +2 -0
  127. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +23 -2
  128. package/corpus/templates/design/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  129. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +2 -2
  130. package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +2 -2
  131. package/corpus/templates/design/actions/apply-design-token-edit.ts +1 -1
  132. package/corpus/templates/design/actions/capture-design-state.ts +1 -1
  133. package/corpus/templates/design/actions/connect-builder-app.ts +2 -2
  134. package/corpus/templates/design/actions/create-design-branch.ts +1 -1
  135. package/corpus/templates/design/actions/create-fusion-app.ts +3 -3
  136. package/corpus/templates/design/actions/deploy-design-preview.ts +1 -1
  137. package/corpus/templates/design/actions/generate-design.ts +3 -2
  138. package/corpus/templates/design/actions/get-component-details.ts +1 -1
  139. package/corpus/templates/design/actions/get-design-branch-diff.ts +1 -1
  140. package/corpus/templates/design/actions/index-components.ts +3 -3
  141. package/corpus/templates/design/actions/index-design-system-with-builder.ts +1 -1
  142. package/corpus/templates/design/actions/migrate-inline-design-to-app.ts +3 -3
  143. package/corpus/templates/design/actions/open-component-source.ts +1 -1
  144. package/corpus/templates/design/actions/update-design.ts +96 -14
  145. package/corpus/templates/design/agent-native.json +12 -0
  146. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +7 -2
  147. package/corpus/templates/design/app/components/design/FigmaHydrationDialog.tsx +11 -2
  148. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +1 -1
  149. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +8 -1
  150. package/corpus/templates/design/app/i18n-data.ts +53 -22
  151. package/corpus/templates/design/app/lib/design-file-upload.ts +2 -3
  152. package/corpus/templates/design/app/lib/upload-limits.ts +4 -0
  153. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +1 -1
  154. package/corpus/templates/design/changelog/2026-08-05-chat-attachments-now-warn-before-upload-when-they-exceed-the.md +6 -0
  155. package/corpus/templates/design/changelog/2026-08-05-figma-fig-uploads-now-show-a-clear-4-mb-limit-up-front-inste.md +6 -0
  156. package/corpus/templates/design/scripts/qa-figma-stress-import.ts +1 -1
  157. package/corpus/templates/design/server/handlers/import-design-file.ts +9 -5
  158. package/corpus/templates/design/server/handlers/uploads.ts +13 -9
  159. package/corpus/templates/design/server/lib/fig-file-limits.ts +2 -1
  160. package/corpus/templates/design/server/lib/figma-image-hydration.ts +1 -1
  161. package/corpus/templates/design/server/lib/figma-node-import.ts +1 -1
  162. package/corpus/templates/design/server/lib/request-body-limits.ts +11 -0
  163. package/corpus/templates/design/shared/canvas-frames.ts +81 -0
  164. package/corpus/templates/design/shared/design-source-capabilities.ts +25 -9
  165. package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +23 -3
  166. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  167. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +23 -2
  168. package/corpus/templates/dispatch/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  169. package/corpus/templates/dispatch/agent-native.json +12 -0
  170. package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +23 -3
  171. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  172. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +23 -2
  173. package/corpus/templates/factory/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  174. package/corpus/templates/factory/agent-native.json +12 -0
  175. package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +23 -3
  176. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  177. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +23 -2
  178. package/corpus/templates/forms/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  179. package/corpus/templates/forms/actions/export-responses.ts +1 -1
  180. package/corpus/templates/forms/agent-native.json +12 -0
  181. package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +23 -3
  182. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  183. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +23 -2
  184. package/corpus/templates/macros/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  185. package/corpus/templates/macros/agent-native.json +12 -0
  186. package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +23 -3
  187. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  188. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +23 -2
  189. package/corpus/templates/mail/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  190. package/corpus/templates/mail/agent-native.json +12 -0
  191. package/corpus/templates/mail/app/i18n/en-US.ts +1 -1
  192. package/corpus/templates/mail/server/lib/media-upload.ts +1 -1
  193. package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +23 -3
  194. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  195. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +23 -2
  196. package/corpus/templates/plan/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  197. package/corpus/templates/plan/agent-native.json +12 -0
  198. package/corpus/templates/plan/server/lib/plan-assets.ts +1 -1
  199. package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +23 -3
  200. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  201. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +23 -2
  202. package/corpus/templates/slides/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  203. package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
  204. package/corpus/templates/slides/actions/generate-slides-ai.ts +1 -1
  205. package/corpus/templates/slides/actions/import-file.ts +2 -2
  206. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
  207. package/corpus/templates/slides/agent-native.json +12 -0
  208. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  209. package/corpus/templates/slides/app/i18n/en-US.ts +2 -2
  210. package/corpus/templates/slides/app/lib/deck-sorting.ts +19 -0
  211. package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +1 -1
  212. package/corpus/templates/slides/app/pages/Index.tsx +7 -2
  213. package/corpus/templates/slides/changelog/2026-08-05-decks-are-now-sorted-by-most-recently-updated.md +6 -0
  214. package/corpus/templates/slides/server/handlers/assets.ts +1 -1
  215. package/corpus/templates/slides/server/handlers/uploads.ts +1 -1
  216. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +23 -3
  217. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  218. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +23 -2
  219. package/corpus/templates/tasks/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  220. package/corpus/templates/tasks/agent-native.json +12 -0
  221. package/dist/action.d.ts +6 -0
  222. package/dist/agent/engine/builder-engine.js +2 -2
  223. package/dist/agent/engine/credential-errors.d.ts +1 -1
  224. package/dist/agent/engine/credential-errors.js +2 -2
  225. package/dist/agent/production-agent.js +3 -2
  226. package/dist/brand-kit/fig/index.js +1 -1
  227. package/dist/cli/agent.js +45 -3
  228. package/dist/cli/code-agent-executor.js +2 -1
  229. package/dist/cli/create.d.ts +9 -1
  230. package/dist/cli/create.js +94 -1
  231. package/dist/cli/doctor.d.ts +8 -11
  232. package/dist/cli/doctor.js +92 -24
  233. package/dist/cli/index.js +6 -5
  234. package/dist/client/AgentAskPopover.d.ts +3 -1
  235. package/dist/client/AgentAskPopover.js +2 -2
  236. package/dist/client/AgentPanel.js +9 -3
  237. package/dist/client/AssistantChat.js +54 -33
  238. package/dist/client/MultiTabAssistantChat.js +1 -1
  239. package/dist/client/RouteTransitionIndicator.d.ts +7 -0
  240. package/dist/client/RouteTransitionIndicator.js +31 -0
  241. package/dist/client/agent-engine-key.js +1 -1
  242. package/dist/client/app-providers.js +11 -2
  243. package/dist/client/chat/message-components.js +1 -1
  244. package/dist/client/chat/run-recovery.js +1 -1
  245. package/dist/client/chat/tool-call-display.d.ts +3 -1
  246. package/dist/client/chat/tool-call-display.js +4 -3
  247. package/dist/client/chat-model-groups.d.ts +6 -0
  248. package/dist/client/chat-model-groups.js +11 -0
  249. package/dist/client/error-format.js +1 -1
  250. package/dist/client/i18n.js +1 -1
  251. package/dist/client/onboarding/FirstRunOnboarding.d.ts +5 -1
  252. package/dist/client/onboarding/FirstRunOnboarding.js +29 -13
  253. package/dist/client/onboarding/first-run-enabled.d.ts +6 -1
  254. package/dist/client/onboarding/first-run-enabled.js +33 -3
  255. package/dist/client/onboarding/use-onboarding.js +16 -11
  256. package/dist/client/require-session.js +13 -4
  257. package/dist/client/resources/mcp-integration-catalog.js +26 -0
  258. package/dist/client/resources/mcp-integration-logos.js +4 -0
  259. package/dist/client/route-warmup.js +56 -10
  260. package/dist/client/settings/AccountSettingsCard.js +78 -3
  261. package/dist/client/settings/SettingsPanel.js +1 -1
  262. package/dist/client/settings/VoiceTranscriptionSection.js +2 -2
  263. package/dist/client/settings/useBuilderStatus.js +1 -1
  264. package/dist/client/setup-connections/useBuilderConnectCardController.js +1 -1
  265. package/dist/client/ui/index.d.ts +1 -0
  266. package/dist/client/ui/index.js +1 -0
  267. package/dist/client/uploads/upload-editor-image.js +1 -1
  268. package/dist/client/use-chat-threads.js +3 -0
  269. package/dist/client/use-session.d.ts +11 -0
  270. package/dist/client/use-session.js +34 -6
  271. package/dist/collab/routes.d.ts +2 -2
  272. package/dist/config.d.ts +48 -0
  273. package/dist/config.js +111 -0
  274. package/dist/db/migrations.js +5 -0
  275. package/dist/eject/provider-api-definitions.d.ts +1 -1
  276. package/dist/eject/provider-api-definitions.js +1 -0
  277. package/dist/eject/remote-mcp-presets.js +1 -0
  278. package/dist/extensions/web-search-tool.js +2 -2
  279. package/dist/file-upload/actions/upload-image.js +1 -1
  280. package/dist/file-upload/registry.js +1 -1
  281. package/dist/guards/index.d.ts +3 -0
  282. package/dist/guards/index.js +2 -0
  283. package/dist/guards/no-empty-migrations.d.ts +14 -0
  284. package/dist/guards/no-empty-migrations.js +126 -0
  285. package/dist/index.browser.d.ts +1 -0
  286. package/dist/index.browser.js +3 -0
  287. package/dist/index.d.ts +1 -0
  288. package/dist/index.js +1 -0
  289. package/dist/localization/default-messages.d.ts +24 -0
  290. package/dist/localization/default-messages.js +26 -2
  291. package/dist/notifications/routes.d.ts +6 -6
  292. package/dist/onboarding/app-profile.js +1 -1
  293. package/dist/onboarding/plugin.d.ts +2 -0
  294. package/dist/onboarding/plugin.js +29 -2
  295. package/dist/progress/routes.d.ts +1 -1
  296. package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
  297. package/dist/provider-api/actions/provider-api.d.ts +13 -13
  298. package/dist/provider-api/index.d.ts +4 -4
  299. package/dist/provider-api/index.js +35 -0
  300. package/dist/resources/handlers.d.ts +1 -1
  301. package/dist/resources/handlers.js +1 -1
  302. package/dist/scripts/docs/framework-search.d.ts +9 -0
  303. package/dist/scripts/docs/framework-search.js +239 -0
  304. package/dist/scripts/docs/index.js +1 -0
  305. package/dist/scripts/docs/search.d.ts +10 -0
  306. package/dist/scripts/docs/search.js +1 -1
  307. package/dist/scripts/docs/source-search.d.ts +10 -2
  308. package/dist/scripts/docs/source-search.js +108 -41
  309. package/dist/search-utils/index.d.ts +11 -0
  310. package/dist/search-utils/index.js +72 -0
  311. package/dist/server/action-change.d.ts +6 -0
  312. package/dist/server/action-change.js +28 -14
  313. package/dist/server/action-discovery.js +9 -0
  314. package/dist/server/action-routes.js +1 -0
  315. package/dist/server/agent-chat/browser-team-tools.js +1 -1
  316. package/dist/server/agent-chat/script-entries.js +43 -2
  317. package/dist/server/auth-login-mode.d.ts +8 -0
  318. package/dist/server/auth-login-mode.js +17 -0
  319. package/dist/server/auth.js +100 -15
  320. package/dist/server/better-auth-instance.d.ts +36 -0
  321. package/dist/server/better-auth-instance.js +25 -3
  322. package/dist/server/builder-design-systems.js +1 -1
  323. package/dist/server/core-routes-plugin.js +17 -14
  324. package/dist/server/credential-provider.js +3 -3
  325. package/dist/server/email-templates.d.ts +7 -0
  326. package/dist/server/email-templates.js +24 -0
  327. package/dist/server/email.d.ts +17 -0
  328. package/dist/server/email.js +22 -1
  329. package/dist/server/framework-request-handler.js +6 -0
  330. package/dist/server/onboarding-html.d.ts +2 -0
  331. package/dist/server/onboarding-html.js +169 -8
  332. package/dist/server/realtime-token.d.ts +1 -1
  333. package/dist/server/realtime-voice.js +1 -1
  334. package/dist/server/sentry.d.ts +1 -1
  335. package/dist/server/transcribe-voice.js +3 -3
  336. package/dist/shared/first-run-onboarding.d.ts +1 -0
  337. package/dist/shared/first-run-onboarding.js +1 -0
  338. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  339. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  340. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  341. package/dist/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  342. package/dist/templates/chat/AGENTS.md +3 -0
  343. package/dist/templates/chat/DESIGN.md +28 -0
  344. package/dist/templates/chat/agent-native.json +12 -0
  345. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +23 -3
  346. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  347. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +23 -2
  348. package/dist/templates/default/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  349. package/dist/templates/default/AGENTS.md +4 -0
  350. package/dist/templates/default/DESIGN.md +30 -0
  351. package/dist/templates/default/agent-native.json +9 -0
  352. package/dist/templates/default/app/i18n/ar-SA.ts +2 -2
  353. package/dist/templates/default/app/i18n/de-DE.ts +2 -2
  354. package/dist/templates/default/app/i18n/en-US.ts +2 -2
  355. package/dist/templates/default/app/i18n/es-ES.ts +2 -2
  356. package/dist/templates/default/app/i18n/fr-FR.ts +2 -2
  357. package/dist/templates/default/app/i18n/hi-IN.ts +2 -2
  358. package/dist/templates/default/app/i18n/ja-JP.ts +2 -2
  359. package/dist/templates/default/app/i18n/ko-KR.ts +2 -2
  360. package/dist/templates/default/app/i18n/pt-BR.ts +2 -2
  361. package/dist/templates/default/app/i18n/zh-CN.ts +2 -2
  362. package/dist/templates/default/app/i18n/zh-TW.ts +1 -1
  363. package/dist/templates/default/package.json +1 -0
  364. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +23 -3
  365. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  366. package/dist/templates/headless/agent-native.json +9 -0
  367. package/dist/templates/headless/package.json +2 -0
  368. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +23 -3
  369. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  370. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +23 -2
  371. package/dist/templates/workspace-core/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  372. package/dist/templates/workspace-core/AGENTS.md +3 -0
  373. package/dist/templates/workspace-core/DESIGN.md +35 -0
  374. package/dist/templates/workspace-root/AGENTS.md +3 -0
  375. package/dist/templates/workspace-root/DESIGN.md +35 -0
  376. package/dist/templates/workspace-root/agent-native.json +9 -0
  377. package/dist/templates/workspace-root/package.json +3 -0
  378. package/dist/transcription/builder-transcription.js +1 -1
  379. package/dist/user-profile/actions/change-password.d.ts +8 -0
  380. package/dist/user-profile/actions/change-password.js +24 -0
  381. package/dist/user-profile/actions/get-auth-methods.d.ts +6 -0
  382. package/dist/user-profile/actions/get-auth-methods.js +23 -0
  383. package/dist/user-profile/actions/set-password.d.ts +7 -0
  384. package/dist/user-profile/actions/set-password.js +23 -0
  385. package/dist/vite/client.d.ts +8 -1
  386. package/dist/vite/client.js +63 -12
  387. package/dist/vite/index.d.ts +1 -0
  388. package/dist/vite/index.js +1 -0
  389. package/docs/AGENTS.md +7 -2
  390. package/docs/SKILL.md +7 -5
  391. package/docs/content/agent-native-config.mdx +165 -0
  392. package/docs/content/agent-native-toolkit.mdx +1 -1
  393. package/docs/content/deployment.mdx +7 -2
  394. package/docs/content/doctor.mdx +21 -13
  395. package/docs/content/environment-variables.mdx +158 -0
  396. package/docs/content/file-uploads.mdx +1 -1
  397. package/docs/content/getting-started.mdx +1 -1
  398. package/docs/content/key-concepts.mdx +1 -1
  399. package/docs/content/multi-app-workspace.mdx +1 -1
  400. package/docs/content/template-clips-ai-and-editing.mdx +6 -6
  401. package/docs/content/template-clips-developers.mdx +3 -3
  402. package/docs/content/toolkit-settings.mdx +1 -1
  403. package/docs/content/voice-input.mdx +4 -4
  404. package/package.json +6 -2
  405. package/src/eject/provider-api-definitions.ts +1 -0
  406. package/src/eject/remote-mcp-presets.ts +1 -0
  407. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  408. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  409. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  410. package/src/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  411. package/src/templates/chat/AGENTS.md +3 -0
  412. package/src/templates/chat/DESIGN.md +28 -0
  413. package/src/templates/chat/agent-native.json +12 -0
  414. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +23 -3
  415. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  416. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +23 -2
  417. package/src/templates/default/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  418. package/src/templates/default/AGENTS.md +4 -0
  419. package/src/templates/default/DESIGN.md +30 -0
  420. package/src/templates/default/agent-native.json +9 -0
  421. package/src/templates/default/app/i18n/ar-SA.ts +2 -2
  422. package/src/templates/default/app/i18n/de-DE.ts +2 -2
  423. package/src/templates/default/app/i18n/en-US.ts +2 -2
  424. package/src/templates/default/app/i18n/es-ES.ts +2 -2
  425. package/src/templates/default/app/i18n/fr-FR.ts +2 -2
  426. package/src/templates/default/app/i18n/hi-IN.ts +2 -2
  427. package/src/templates/default/app/i18n/ja-JP.ts +2 -2
  428. package/src/templates/default/app/i18n/ko-KR.ts +2 -2
  429. package/src/templates/default/app/i18n/pt-BR.ts +2 -2
  430. package/src/templates/default/app/i18n/zh-CN.ts +2 -2
  431. package/src/templates/default/app/i18n/zh-TW.ts +1 -1
  432. package/src/templates/default/package.json +1 -0
  433. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +23 -3
  434. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  435. package/src/templates/headless/agent-native.json +9 -0
  436. package/src/templates/headless/package.json +2 -0
  437. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +23 -3
  438. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  439. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +23 -2
  440. package/src/templates/workspace-core/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  441. package/src/templates/workspace-core/AGENTS.md +3 -0
  442. package/src/templates/workspace-core/DESIGN.md +35 -0
  443. package/src/templates/workspace-root/AGENTS.md +3 -0
  444. package/src/templates/workspace-root/DESIGN.md +35 -0
  445. package/src/templates/workspace-root/agent-native.json +9 -0
  446. package/src/templates/workspace-root/package.json +3 -0
package/dist/cli/agent.js CHANGED
@@ -199,8 +199,8 @@ function buildHeadlessSystemPrompt(actionNames) {
199
199
  return [
200
200
  "You are the app agent for this Agent-Native project.",
201
201
  "Use the registered app actions as your source of truth for doing work.",
202
- "Use docs-search before implementing or answering advanced Agent Native framework questions; it reads the version-matched docs bundled with @agent-native/core.",
203
- "Use source-search when examples or implementation details matter; it reads the version-matched core and template source corpus bundled with @agent-native/core.",
202
+ "Use framework-search first for questions that may span the version-matched docs and source; it supports bounded substring, wildcard, SQL-like, and safe-regex matching.",
203
+ "Use docs-search or source-search for a focused page/file read after framework-search identifies the relevant evidence.",
204
204
  "Use connected GitHub repository tools for repo context when a repository is configured; do not assume a local clone or sandbox exists.",
205
205
  "You are running headlessly from the command line, so reply with the final useful result in plain text.",
206
206
  actionList,
@@ -224,7 +224,49 @@ function cliArgsFromToolArgs(args) {
224
224
  export async function createHeadlessBuiltinActions() {
225
225
  const docsSearch = await import("../scripts/docs/search.js");
226
226
  const sourceSearch = await import("../scripts/docs/source-search.js");
227
+ const frameworkSearch = await import("../scripts/docs/framework-search.js");
227
228
  return {
229
+ "framework-search": {
230
+ readOnly: true,
231
+ tool: {
232
+ description: "Search version-matched Agent Native docs and readable Core, Toolkit, and first-party template source together. Use this first when a docs answer may require implementation evidence; supports substring, glob, SQL-like, and safe regex modes.",
233
+ parameters: {
234
+ type: "object",
235
+ properties: {
236
+ pattern: {
237
+ type: "string",
238
+ description: "Text pattern to search across docs and source.",
239
+ },
240
+ scope: {
241
+ type: "string",
242
+ description: "Search corpus: all, docs, or source (default: all).",
243
+ enum: ["all", "docs", "source"],
244
+ },
245
+ mode: {
246
+ type: "string",
247
+ description: "Match mode: substring, glob, sql-like, or safe regex (default: substring).",
248
+ enum: ["substring", "glob", "sql-like", "regex"],
249
+ },
250
+ path: {
251
+ type: "string",
252
+ description: "Optional glob path filter.",
253
+ },
254
+ limit: {
255
+ type: "string",
256
+ description: "Maximum matching files to return, from 1 to 50.",
257
+ },
258
+ list: {
259
+ type: "string",
260
+ description: 'Set to "true" to list searchable docs and source roots.',
261
+ enum: ["true"],
262
+ },
263
+ },
264
+ },
265
+ },
266
+ run: async (args) => {
267
+ return captureCliOutput(() => frameworkSearch.default(cliArgsFromToolArgs(args)));
268
+ },
269
+ },
228
270
  "docs-search": {
229
271
  readOnly: true,
230
272
  tool: {
@@ -255,7 +297,7 @@ export async function createHeadlessBuiltinActions() {
255
297
  "source-search": {
256
298
  readOnly: true,
257
299
  tool: {
258
- description: "Search and read the packaged Agent Native first-party template corpus under node_modules/@agent-native/core/corpus. Use --list for sections, --query to search template source, and --path to read a file.",
300
+ description: "Search and read readable version-matched Core, Toolkit, and first-party template source. Use framework-search for one combined docs/source search with glob, SQL-like, or regex matching; use --list, --query, or --path for focused source lookup.",
259
301
  parameters: {
260
302
  type: "object",
261
303
  properties: {
@@ -1338,7 +1338,8 @@ Current run mode: ${mode} mode (${permissionMode}).
1338
1338
  # Autonomy and verification
1339
1339
 
1340
1340
  - Stay with the work until the task is handled end to end within this turn whenever feasible. Don't stop at analysis or a proposal — implement the fix, and work through blockers yourself before handing them back. The exception is Plan mode, where you propose only.
1341
- - Done means verified, not generated. After code changes (not docs-only), run the repo's checks before reporting success: \`pnpm run prep\` (format + typecheck + test + guards), or a focused subset like \`pnpm typecheck\` or a single package's tests for a small change. Fix all errors before you call it done.
1341
+ - Done means verified, not generated. Match the check to the change: use the narrowest relevant test, typecheck, formatter, or direct invocation for a localized edit; use \`pnpm run prep\` for shared or cross-cutting changes. Do not restart a dev server or run broad checks as a generic post-edit ritual. Fix failures before you call it done, and keep any repository-required guards or doctor checks that apply.
1342
+ - In an Agent-Native app or workspace, also run \`pnpm agent-native:doctor\` (or \`pnpm doctor\`) after source changes. Treat every finding as a fix-required security issue; do not disable a guard without a reviewer-readable reason.
1342
1343
  - Do not claim a change works, tests pass, or a build succeeds unless you actually ran it and saw the result. If you could not verify something, say exactly what is unverified and why.
1343
1344
 
1344
1345
  # Tools beyond the basics
@@ -131,6 +131,14 @@ declare function communityTemplateTrustMessage(selection: string): string | unde
131
131
  * templates need it.
132
132
  */
133
133
  declare function scaffoldRequiredPackages(templateNames: string[], workspaceRoot: string): Promise<void>;
134
+ /**
135
+ * Keep the portable guard contract attached to every app/workspace created by
136
+ * the CLI, including community templates whose package.json was not authored
137
+ * by this repository. The scanners stay versioned in @agent-native/core; a
138
+ * generated project only receives the small command/config/instructions
139
+ * surface needed to run them locally and in hosted builds.
140
+ */
141
+ declare function ensureGuardedScaffold(appDir: string): void;
134
142
  /**
135
143
  * Post-process a standalone scaffold: replace placeholders, strip
136
144
  * workspace:* deps, set up agent symlinks, etc.
@@ -147,7 +155,7 @@ export declare function detectWorkspace(startDir: string): {
147
155
  } | null;
148
156
  export { parseWorkspaceScope };
149
157
  /** @internal — exported for E2E tests */
150
- export { scaffoldWorkspaceRoot as _scaffoldWorkspaceRoot, scaffoldAppTemplate as _scaffoldAppTemplate, scaffoldRequiredPackages as _scaffoldRequiredPackages, postProcessStandalone as _postProcessStandalone, loadCatalog as _loadCatalog, fixPackageJsonName as _fixPackageJsonName, renameGitignore as _renameGitignore, rewriteNetlifyToml as _rewriteNetlifyToml, getCoreDependencyVersion as _getCoreDependencyVersion, getDispatchDependencyVersion as _getDispatchDependencyVersion, getToolkitDependencyVersion as _getToolkitDependencyVersion, getCorePackageVersion as _getCorePackageVersion, getGitHubTemplateRef as _getGitHubTemplateRef, getGitHubTemplateRefCandidates as _getGitHubTemplateRefCandidates, githubTarballUrl as _githubTarballUrl, findLocalTemplateFrom as _findLocalTemplateFrom, workspaceAppNameForTemplateSelection as _workspaceAppNameForTemplateSelection, startShapePromptOptions as _startShapePromptOptions, standaloneTemplatePromptOptions as _standaloneTemplatePromptOptions, parseCommunityTemplateSelection as _parseCommunityTemplateSelection, communityTemplateTrustMessage as _communityTemplateTrustMessage, communityTemplateTarballUrl as _communityTemplateTarballUrl, assertCommunityTemplateRoot as _assertCommunityTemplateRoot, assertSafeCommunityArchiveListing as _assertSafeCommunityArchiveListing, validateCommunityArchive as _validateCommunityArchive, resolveCommunityTemplateSource as _resolveCommunityTemplateSource, discoverCommunityWorkspaceApps as _discoverCommunityWorkspaceApps, normalizeCommunityWorkspaceAppDependencies as _normalizeCommunityWorkspaceAppDependencies, shouldSkipScaffoldEntry as _shouldSkipScaffoldEntry, tarExtractArgs as _tarExtractArgs, downloadGitHubSubdir as _downloadGitHubSubdir, findLocalTemplate as _findLocalTemplate, templateSourceName as _templateSourceName, normalizeTemplateName as _normalizeTemplateName, appTitleForScaffold as _appTitleForScaffold, replacePlaceholders as _replacePlaceholders, rewriteTrackingAppId as _rewriteTrackingAppId, rewriteAgentChatAppId as _rewriteAgentChatAppId, applyScaffoldIdentity as _applyScaffoldIdentity, fixWebManifestName as _fixWebManifestName, copyDir as _copyDir, localTemplateSourceKind as _localTemplateSourceKind, REPO as _REPO, TEMPLATES_DIR as _TEMPLATES_DIR, };
158
+ export { scaffoldWorkspaceRoot as _scaffoldWorkspaceRoot, ensureGuardedScaffold as _ensureGuardedScaffold, scaffoldAppTemplate as _scaffoldAppTemplate, scaffoldRequiredPackages as _scaffoldRequiredPackages, postProcessStandalone as _postProcessStandalone, loadCatalog as _loadCatalog, fixPackageJsonName as _fixPackageJsonName, renameGitignore as _renameGitignore, rewriteNetlifyToml as _rewriteNetlifyToml, getCoreDependencyVersion as _getCoreDependencyVersion, getDispatchDependencyVersion as _getDispatchDependencyVersion, getToolkitDependencyVersion as _getToolkitDependencyVersion, getCorePackageVersion as _getCorePackageVersion, getGitHubTemplateRef as _getGitHubTemplateRef, getGitHubTemplateRefCandidates as _getGitHubTemplateRefCandidates, githubTarballUrl as _githubTarballUrl, findLocalTemplateFrom as _findLocalTemplateFrom, workspaceAppNameForTemplateSelection as _workspaceAppNameForTemplateSelection, startShapePromptOptions as _startShapePromptOptions, standaloneTemplatePromptOptions as _standaloneTemplatePromptOptions, parseCommunityTemplateSelection as _parseCommunityTemplateSelection, communityTemplateTrustMessage as _communityTemplateTrustMessage, communityTemplateTarballUrl as _communityTemplateTarballUrl, assertCommunityTemplateRoot as _assertCommunityTemplateRoot, assertSafeCommunityArchiveListing as _assertSafeCommunityArchiveListing, validateCommunityArchive as _validateCommunityArchive, resolveCommunityTemplateSource as _resolveCommunityTemplateSource, discoverCommunityWorkspaceApps as _discoverCommunityWorkspaceApps, normalizeCommunityWorkspaceAppDependencies as _normalizeCommunityWorkspaceAppDependencies, shouldSkipScaffoldEntry as _shouldSkipScaffoldEntry, tarExtractArgs as _tarExtractArgs, downloadGitHubSubdir as _downloadGitHubSubdir, findLocalTemplate as _findLocalTemplate, templateSourceName as _templateSourceName, normalizeTemplateName as _normalizeTemplateName, appTitleForScaffold as _appTitleForScaffold, replacePlaceholders as _replacePlaceholders, rewriteTrackingAppId as _rewriteTrackingAppId, rewriteAgentChatAppId as _rewriteAgentChatAppId, applyScaffoldIdentity as _applyScaffoldIdentity, fixWebManifestName as _fixWebManifestName, copyDir as _copyDir, localTemplateSourceKind as _localTemplateSourceKind, REPO as _REPO, TEMPLATES_DIR as _TEMPLATES_DIR, };
151
159
  declare function tarExtractArgs(tarPath: string, destDir: string, options?: {
152
160
  skipAgentSymlinks?: boolean;
153
161
  untrustedCommunityArchive?: boolean;
@@ -395,6 +395,7 @@ async function createWorkspaceInteractive(name, opts, clack) {
395
395
  ...resolution,
396
396
  shape: "workspace",
397
397
  });
398
+ ensureGuardedScaffold(appDir);
398
399
  fixWebManifestName(appDir, appName, templateName, resolution.sourceIdentity);
399
400
  rewriteNetlifyToml(appDir, appName, "workspace");
400
401
  renameGitignore(appDir);
@@ -523,6 +524,7 @@ async function scaffoldWorkspaceRoot(targetDir, name) {
523
524
  // Root-level agent instructions apply before an agent descends into an app.
524
525
  linkWorkspaceRootSkills(targetDir);
525
526
  setupAgentSymlinks(targetDir);
527
+ ensureGuardedScaffold(targetDir);
526
528
  }
527
529
  function linkWorkspaceRootSkills(targetDir) {
528
530
  const sharedSkillsDir = path.join(targetDir, "packages", "shared", ".agents", "skills");
@@ -650,6 +652,7 @@ async function scaffoldOneAppIntoWorkspace(workspace, appName, templateName, cla
650
652
  ...resolution,
651
653
  shape: "workspace",
652
654
  });
655
+ ensureGuardedScaffold(appDir);
653
656
  fixWebManifestName(appDir, appName, templateName, resolution.sourceIdentity);
654
657
  rewriteNetlifyToml(appDir, appName, "workspace");
655
658
  renameGitignore(appDir);
@@ -1266,6 +1269,95 @@ async function scaffoldRequiredPackages(templateNames, workspaceRoot) {
1266
1269
  }
1267
1270
  }
1268
1271
  }
1272
+ const AGENT_NATIVE_DOCTOR = "agent-native doctor";
1273
+ const AGENT_NATIVE_DOCTOR_STRICT = `${AGENT_NATIVE_DOCTOR} --strict`;
1274
+ const GUARDED_VERIFICATION_MARKER = "Guarded verification";
1275
+ const GUARDED_VERIFICATION_GUIDANCE = "- Guarded verification: run `pnpm agent-native:doctor`; fix findings before done.\n";
1276
+ /**
1277
+ * Keep the portable guard contract attached to every app/workspace created by
1278
+ * the CLI, including community templates whose package.json was not authored
1279
+ * by this repository. The scanners stay versioned in @agent-native/core; a
1280
+ * generated project only receives the small command/config/instructions
1281
+ * surface needed to run them locally and in hosted builds.
1282
+ */
1283
+ function ensureGuardedScaffold(appDir) {
1284
+ const packagePath = path.join(appDir, "package.json");
1285
+ if (!fs.existsSync(packagePath))
1286
+ return;
1287
+ const parsedPackage = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
1288
+ if (!parsedPackage ||
1289
+ typeof parsedPackage !== "object" ||
1290
+ Array.isArray(parsedPackage)) {
1291
+ throw new Error(`${packagePath} must contain a JSON object`);
1292
+ }
1293
+ const packageJson = parsedPackage;
1294
+ const existingScripts = packageJson.scripts;
1295
+ if (existingScripts !== undefined &&
1296
+ (!existingScripts ||
1297
+ typeof existingScripts !== "object" ||
1298
+ Array.isArray(existingScripts))) {
1299
+ throw new Error(`${packagePath} has an invalid scripts object`);
1300
+ }
1301
+ const scripts = existingScripts ?? {};
1302
+ // Keep an existing project-specific `doctor` script intact while providing
1303
+ // a collision-free framework entry point that every generated project has.
1304
+ const existingNativeDoctor = scripts["agent-native:doctor"];
1305
+ scripts["agent-native:doctor"] =
1306
+ typeof existingNativeDoctor === "string" &&
1307
+ existingNativeDoctor !== AGENT_NATIVE_DOCTOR &&
1308
+ !existingNativeDoctor.includes(AGENT_NATIVE_DOCTOR)
1309
+ ? `${existingNativeDoctor} && ${AGENT_NATIVE_DOCTOR}`
1310
+ : AGENT_NATIVE_DOCTOR;
1311
+ if (typeof scripts.doctor !== "string") {
1312
+ scripts.doctor = AGENT_NATIVE_DOCTOR;
1313
+ }
1314
+ // Community templates may use vite/next/another build command instead of
1315
+ // `agent-native build`, so attach the strict check to the package lifecycle.
1316
+ // Agent-Native builds already run doctor and get strictness from the config.
1317
+ if (typeof scripts.build === "string" &&
1318
+ !/\bagent-native\s+build\b/.test(scripts.build) &&
1319
+ !String(scripts.prebuild ?? "").includes(AGENT_NATIVE_DOCTOR_STRICT)) {
1320
+ const existingPrebuild = typeof scripts.prebuild === "string" ? scripts.prebuild.trim() : "";
1321
+ scripts.prebuild = existingPrebuild
1322
+ ? `${existingPrebuild} && ${AGENT_NATIVE_DOCTOR_STRICT}`
1323
+ : AGENT_NATIVE_DOCTOR_STRICT;
1324
+ }
1325
+ packageJson.scripts = scripts;
1326
+ fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + "\n");
1327
+ const manifestPath = path.join(appDir, "agent-native.json");
1328
+ let manifest = {};
1329
+ if (fs.existsSync(manifestPath)) {
1330
+ const parsedManifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
1331
+ if (!parsedManifest ||
1332
+ typeof parsedManifest !== "object" ||
1333
+ Array.isArray(parsedManifest)) {
1334
+ throw new Error(`${manifestPath} must contain a JSON object`);
1335
+ }
1336
+ manifest = parsedManifest;
1337
+ }
1338
+ const doctor = manifest.doctor &&
1339
+ typeof manifest.doctor === "object" &&
1340
+ !Array.isArray(manifest.doctor)
1341
+ ? manifest.doctor
1342
+ : {};
1343
+ // An explicit false remains an intentional, reviewable opt-out. Missing
1344
+ // configuration is strict so a hosted build cannot publish a finding.
1345
+ if (typeof doctor.failOnBuild !== "boolean")
1346
+ doctor.failOnBuild = true;
1347
+ manifest.doctor = doctor;
1348
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
1349
+ const agentsPath = path.join(appDir, "AGENTS.md");
1350
+ if (fs.existsSync(agentsPath)) {
1351
+ const agents = fs.readFileSync(agentsPath, "utf-8");
1352
+ if (!agents.includes(GUARDED_VERIFICATION_MARKER)) {
1353
+ fs.writeFileSync(agentsPath, `${agents.trimEnd()}\n\n${GUARDED_VERIFICATION_GUIDANCE}`);
1354
+ }
1355
+ }
1356
+ else {
1357
+ fs.writeFileSync(agentsPath, `# Agent-Native project instructions\n\n${GUARDED_VERIFICATION_GUIDANCE}`);
1358
+ setupAgentSymlinks(appDir);
1359
+ }
1360
+ }
1269
1361
  /**
1270
1362
  * Post-process a standalone scaffold: replace placeholders, strip
1271
1363
  * workspace:* deps, set up agent symlinks, etc.
@@ -1278,6 +1370,7 @@ function postProcessStandalone(name, targetDir, templateName, resolution) {
1278
1370
  ...resolution,
1279
1371
  shape: "standalone",
1280
1372
  });
1373
+ ensureGuardedScaffold(targetDir);
1281
1374
  fixWebManifestName(targetDir, name, templateName, resolution?.sourceIdentity);
1282
1375
  rewriteNetlifyToml(targetDir, name, "standalone");
1283
1376
  for (const base of ["learnings"]) {
@@ -1562,7 +1655,7 @@ export function detectWorkspace(startDir) {
1562
1655
  }
1563
1656
  export { parseWorkspaceScope };
1564
1657
  /** @internal — exported for E2E tests */
1565
- export { scaffoldWorkspaceRoot as _scaffoldWorkspaceRoot, scaffoldAppTemplate as _scaffoldAppTemplate, scaffoldRequiredPackages as _scaffoldRequiredPackages, postProcessStandalone as _postProcessStandalone, loadCatalog as _loadCatalog, fixPackageJsonName as _fixPackageJsonName, renameGitignore as _renameGitignore, rewriteNetlifyToml as _rewriteNetlifyToml, getCoreDependencyVersion as _getCoreDependencyVersion, getDispatchDependencyVersion as _getDispatchDependencyVersion, getToolkitDependencyVersion as _getToolkitDependencyVersion, getCorePackageVersion as _getCorePackageVersion, getGitHubTemplateRef as _getGitHubTemplateRef, getGitHubTemplateRefCandidates as _getGitHubTemplateRefCandidates, githubTarballUrl as _githubTarballUrl, findLocalTemplateFrom as _findLocalTemplateFrom, workspaceAppNameForTemplateSelection as _workspaceAppNameForTemplateSelection, startShapePromptOptions as _startShapePromptOptions, standaloneTemplatePromptOptions as _standaloneTemplatePromptOptions, parseCommunityTemplateSelection as _parseCommunityTemplateSelection, communityTemplateTrustMessage as _communityTemplateTrustMessage, communityTemplateTarballUrl as _communityTemplateTarballUrl, assertCommunityTemplateRoot as _assertCommunityTemplateRoot, assertSafeCommunityArchiveListing as _assertSafeCommunityArchiveListing, validateCommunityArchive as _validateCommunityArchive, resolveCommunityTemplateSource as _resolveCommunityTemplateSource, discoverCommunityWorkspaceApps as _discoverCommunityWorkspaceApps, normalizeCommunityWorkspaceAppDependencies as _normalizeCommunityWorkspaceAppDependencies, shouldSkipScaffoldEntry as _shouldSkipScaffoldEntry, tarExtractArgs as _tarExtractArgs, downloadGitHubSubdir as _downloadGitHubSubdir, findLocalTemplate as _findLocalTemplate, templateSourceName as _templateSourceName, normalizeTemplateName as _normalizeTemplateName, appTitleForScaffold as _appTitleForScaffold, replacePlaceholders as _replacePlaceholders, rewriteTrackingAppId as _rewriteTrackingAppId, rewriteAgentChatAppId as _rewriteAgentChatAppId, applyScaffoldIdentity as _applyScaffoldIdentity, fixWebManifestName as _fixWebManifestName, copyDir as _copyDir, localTemplateSourceKind as _localTemplateSourceKind, REPO as _REPO, TEMPLATES_DIR as _TEMPLATES_DIR, };
1658
+ export { scaffoldWorkspaceRoot as _scaffoldWorkspaceRoot, ensureGuardedScaffold as _ensureGuardedScaffold, scaffoldAppTemplate as _scaffoldAppTemplate, scaffoldRequiredPackages as _scaffoldRequiredPackages, postProcessStandalone as _postProcessStandalone, loadCatalog as _loadCatalog, fixPackageJsonName as _fixPackageJsonName, renameGitignore as _renameGitignore, rewriteNetlifyToml as _rewriteNetlifyToml, getCoreDependencyVersion as _getCoreDependencyVersion, getDispatchDependencyVersion as _getDispatchDependencyVersion, getToolkitDependencyVersion as _getToolkitDependencyVersion, getCorePackageVersion as _getCorePackageVersion, getGitHubTemplateRef as _getGitHubTemplateRef, getGitHubTemplateRefCandidates as _getGitHubTemplateRefCandidates, githubTarballUrl as _githubTarballUrl, findLocalTemplateFrom as _findLocalTemplateFrom, workspaceAppNameForTemplateSelection as _workspaceAppNameForTemplateSelection, startShapePromptOptions as _startShapePromptOptions, standaloneTemplatePromptOptions as _standaloneTemplatePromptOptions, parseCommunityTemplateSelection as _parseCommunityTemplateSelection, communityTemplateTrustMessage as _communityTemplateTrustMessage, communityTemplateTarballUrl as _communityTemplateTarballUrl, assertCommunityTemplateRoot as _assertCommunityTemplateRoot, assertSafeCommunityArchiveListing as _assertSafeCommunityArchiveListing, validateCommunityArchive as _validateCommunityArchive, resolveCommunityTemplateSource as _resolveCommunityTemplateSource, discoverCommunityWorkspaceApps as _discoverCommunityWorkspaceApps, normalizeCommunityWorkspaceAppDependencies as _normalizeCommunityWorkspaceAppDependencies, shouldSkipScaffoldEntry as _shouldSkipScaffoldEntry, tarExtractArgs as _tarExtractArgs, downloadGitHubSubdir as _downloadGitHubSubdir, findLocalTemplate as _findLocalTemplate, templateSourceName as _templateSourceName, normalizeTemplateName as _normalizeTemplateName, appTitleForScaffold as _appTitleForScaffold, replacePlaceholders as _replacePlaceholders, rewriteTrackingAppId as _rewriteTrackingAppId, rewriteAgentChatAppId as _rewriteAgentChatAppId, applyScaffoldIdentity as _applyScaffoldIdentity, fixWebManifestName as _fixWebManifestName, copyDir as _copyDir, localTemplateSourceKind as _localTemplateSourceKind, REPO as _REPO, TEMPLATES_DIR as _TEMPLATES_DIR, };
1566
1659
  /* ─────────────────────────────────────────────────────────────────────────
1567
1660
  * Download / copy helpers
1568
1661
  * ───────────────────────────────────────────────────────────────────────── */
@@ -1,5 +1,5 @@
1
1
  import { type MigrationManifest } from "../package-lifecycle/index.js";
2
- export type GuardName = "no-drizzle-push" | "no-unscoped-credentials" | "no-unscoped-queries" | "no-env-credentials" | "db-tool-scoping" | "no-env-mutation" | "no-localhost-fallback" | "explicit-collab-access" | "migration-manifest";
2
+ export type GuardName = "no-drizzle-push" | "no-empty-migrations" | "no-unscoped-credentials" | "no-unscoped-queries" | "no-env-credentials" | "db-tool-scoping" | "no-env-mutation" | "no-localhost-fallback" | "explicit-collab-access" | "migration-manifest";
3
3
  export declare const ALL_GUARD_NAMES: GuardName[];
4
4
  export interface DoctorConfig {
5
5
  disabledGuards: string[];
@@ -73,8 +73,8 @@ export declare function checkDisk(root: string, { measureReclaimable }?: {
73
73
  }): DoctorDiskReport;
74
74
  /** Pure escalation rule shared by the CLI (`--strict`) and the `build`
75
75
  * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor
76
- * findings never fail anything on their own only `strict` or
77
- * `failOnBuild` turn findings into a hard failure. */
76
+ * findings fail builds by default; only an explicit `failOnBuild: false`
77
+ * opt-out can keep a build moving, while `strict` always fails. */
78
78
  export declare function shouldFailBuild(hasFindings: boolean, opts: {
79
79
  strict?: boolean;
80
80
  failOnBuild?: boolean;
@@ -104,19 +104,16 @@ export interface DoctorBuildHookOptions {
104
104
  strict?: boolean;
105
105
  }
106
106
  export interface DoctorBuildHookResult {
107
- /** False only when findings are present AND (`strict` was requested OR
108
- * `agent-native.json`'s `doctor.failOnBuild` is true). */
107
+ /** False when findings are present and the project has not explicitly
108
+ * opted out of the build gate. */
109
109
  ok: boolean;
110
110
  report: DoctorReport;
111
111
  }
112
112
  /**
113
113
  * `agent-native build`'s doctor pre-step. Always runs every enabled guard
114
- * and always prints findings (as warnings) to `io.err` — never silent.
115
- * Never causes the build to fail unless `strict` was passed or
116
- * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,
117
- * "Where it runs" — the v1 doctor has zero field mileage against arbitrary
118
- * app layouts, so shipping fail-by-default would risk breaking a first
119
- * deploy on a false positive).
114
+ * and always prints findings to `io.err` — never silent. Findings fail the
115
+ * build by default; only an explicit `doctor.failOnBuild: false` opt-out can
116
+ * keep a build moving, while `--strict` overrides that opt-out.
120
117
  */
121
118
  export declare function runDoctorBuildHook(options: DoctorBuildHookOptions, io?: DoctorIo): Promise<DoctorBuildHookResult>;
122
119
  //# sourceMappingURL=doctor.d.ts.map
@@ -22,11 +22,12 @@
22
22
  */
23
23
  import fs from "node:fs";
24
24
  import path from "node:path";
25
- import { scanDbToolScoping, scanDrizzlePush, scanEnvCredentials, scanEnvMutation, scanExplicitCollabAccess, scanLocalhostFallback, scanUnscopedCredentials, scanUnscopedQueries, } from "../guards/index.js";
25
+ import { scanDbToolScoping, scanDrizzlePush, scanEmptyMigrations, scanEnvCredentials, scanEnvMutation, scanExplicitCollabAccess, scanLocalhostFallback, scanUnscopedCredentials, scanUnscopedQueries, } from "../guards/index.js";
26
26
  import { AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND, scanDeprecatedImports, } from "../package-lifecycle/index.js";
27
27
  import { formatBytes, scanCleanTargets } from "./clean.js";
28
28
  export const ALL_GUARD_NAMES = [
29
29
  "no-drizzle-push",
30
+ "no-empty-migrations",
30
31
  "no-unscoped-credentials",
31
32
  "no-unscoped-queries",
32
33
  "no-env-credentials",
@@ -39,7 +40,7 @@ export const ALL_GUARD_NAMES = [
39
40
  const DEFAULT_DOCTOR_CONFIG = {
40
41
  disabledGuards: [],
41
42
  dbToolScopingDenylist: {},
42
- failOnBuild: false,
43
+ failOnBuild: true,
43
44
  };
44
45
  /**
45
46
  * Reads the optional `"doctor"` key from `<root>/agent-native.json`. All
@@ -62,17 +63,21 @@ export function readDoctorConfig(root) {
62
63
  typeof doctor.dbToolScopingDenylist === "object"
63
64
  ? Object.fromEntries(Object.entries(doctor.dbToolScopingDenylist).filter((entry) => typeof entry[1] === "string"))
64
65
  : {};
65
- const failOnBuild = doctor.failOnBuild === true;
66
+ const failOnBuild = typeof doctor.failOnBuild === "boolean"
67
+ ? doctor.failOnBuild
68
+ : DEFAULT_DOCTOR_CONFIG.failOnBuild;
66
69
  return { disabledGuards, dbToolScopingDenylist, failOnBuild };
67
70
  }
68
- catch {
69
- return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };
71
+ catch (error) {
72
+ throw new Error(`Could not read Doctor configuration from ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
70
73
  }
71
74
  }
72
75
  function runGuard(name, root, config, migrationManifests) {
73
76
  switch (name) {
74
77
  case "no-drizzle-push":
75
78
  return scanDrizzlePush({ root });
79
+ case "no-empty-migrations":
80
+ return scanEmptyMigrations({ root });
76
81
  case "no-unscoped-credentials":
77
82
  return scanUnscopedCredentials({ root });
78
83
  case "no-unscoped-queries":
@@ -157,6 +162,53 @@ export function runDoctorScan(options) {
157
162
  guardsRun: names,
158
163
  };
159
164
  }
165
+ function workspaceDoctorRoots(root) {
166
+ const packagePath = path.join(root, "package.json");
167
+ const appsDir = path.join(root, "apps");
168
+ if (!fs.existsSync(packagePath) || !fs.existsSync(appsDir))
169
+ return null;
170
+ try {
171
+ const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
172
+ if (typeof packageJson?.["agent-native"]?.workspaceCore !== "string") {
173
+ return null;
174
+ }
175
+ }
176
+ catch (error) {
177
+ throw new Error(`Could not read workspace metadata from ${packagePath}: ${error instanceof Error ? error.message : String(error)}`);
178
+ }
179
+ const appRoots = fs
180
+ .readdirSync(appsDir, { withFileTypes: true })
181
+ .filter((entry) => entry.isDirectory())
182
+ .map((entry) => path.join(appsDir, entry.name))
183
+ .filter((appRoot) => fs.existsSync(path.join(appRoot, "package.json")))
184
+ .sort();
185
+ const scanRoots = [...appRoots];
186
+ const sharedRoot = path.join(root, "packages", "shared");
187
+ if (fs.existsSync(path.join(sharedRoot, "package.json"))) {
188
+ scanRoots.push(sharedRoot);
189
+ }
190
+ return { appRoots, scanRoots };
191
+ }
192
+ function prefixWorkspaceFindings(findings, root, appRoot) {
193
+ const prefix = path.relative(root, appRoot).replaceAll("\\", "/");
194
+ return findings.map((finding) => ({
195
+ ...finding,
196
+ file: `${prefix}/${finding.file}`,
197
+ }));
198
+ }
199
+ function runWorkspaceDoctorScan(root, scanRoots, only) {
200
+ const reports = scanRoots.map((scanRoot) => ({
201
+ scanRoot,
202
+ report: runDoctorScan({ root: scanRoot, only }),
203
+ }));
204
+ const guardsRun = Array.from(new Set(reports.flatMap(({ report }) => report.guardsRun)));
205
+ return {
206
+ ok: reports.every(({ report }) => report.ok),
207
+ findings: reports.flatMap(({ scanRoot, report }) => prefixWorkspaceFindings(report.findings, root, scanRoot)),
208
+ warnings: reports.flatMap(({ scanRoot, report }) => prefixWorkspaceFindings(report.warnings, root, scanRoot)),
209
+ guardsRun,
210
+ };
211
+ }
160
212
  /**
161
213
  * Hosted app volumes are ~4.84 GB total, so anything under this is close
162
214
  * enough to a stalled build or a failed write to be worth naming.
@@ -216,8 +268,8 @@ function formatDiskLine(disk) {
216
268
  }
217
269
  /** Pure escalation rule shared by the CLI (`--strict`) and the `build`
218
270
  * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor
219
- * findings never fail anything on their own only `strict` or
220
- * `failOnBuild` turn findings into a hard failure. */
271
+ * findings fail builds by default; only an explicit `failOnBuild: false`
272
+ * opt-out can keep a build moving, while `strict` always fails. */
221
273
  export function shouldFailBuild(hasFindings, opts) {
222
274
  return hasFindings && Boolean(opts.strict || opts.failOnBuild);
223
275
  }
@@ -225,9 +277,12 @@ const defaultIo = {
225
277
  log: (message) => console.log(message),
226
278
  err: (message) => console.error(message),
227
279
  };
228
- function formatDoctorHuman(report, root, disk) {
280
+ function formatDoctorHuman(report, root, disk, workspaceApps) {
229
281
  const lines = [];
230
282
  lines.push(`agent-native doctor: ${root}`);
283
+ if (workspaceApps) {
284
+ lines.push(`Workspace apps scanned: ${workspaceApps.join(", ") || "(none)"}`);
285
+ }
231
286
  lines.push(`Guards run: ${report.guardsRun.join(", ") || "(none)"}`);
232
287
  lines.push(formatDiskLine(disk));
233
288
  if (report.findings.length === 0) {
@@ -293,7 +348,7 @@ export function printDoctorHelp(io = defaultIo) {
293
348
  " agent-native doctor Scan app source for security-critical guard violations",
294
349
  " agent-native doctor --json Machine-readable report: { ok, findings, warnings, guardsRun, disk, strict }",
295
350
  " agent-native doctor --only <guard,guard> Run only the named guard(s)",
296
- " agent-native doctor --strict Escalate findings to a hard failure when used by `agent-native build --strict`",
351
+ " agent-native doctor --strict Keep the build gate explicit when invoked by `agent-native build`",
297
352
  " agent-native doctor --cwd <dir> Run against a project root other than the current directory",
298
353
  " agent-native doctor --disk Also measure what `agent-native clean` would reclaim (scans every build cache)",
299
354
  " agent-native doctor --fix Not implemented in this version",
@@ -307,9 +362,10 @@ export function printDoctorHelp(io = defaultIo) {
307
362
  "`--disk` adds how much of it `agent-native clean` could give back. Disk",
308
363
  "is advisory — it never changes the exit code.",
309
364
  "",
310
- "`agent-native build` runs doctor as a warn-only pre-step by default — it",
311
- "never fails the build unless `agent-native build --strict` is passed or",
312
- 'agent-native.json sets { "doctor": { "failOnBuild": true } }.',
365
+ "`agent-native build` runs doctor before the build and fails on findings",
366
+ 'by default. Set `agent-native.json` to `{ "doctor": {',
367
+ '\"failOnBuild\": false } }` only with a reviewed reason; `--strict`',
368
+ "always keeps the gate enabled.",
313
369
  "",
314
370
  "For dependency-pin health (framework overrides/patches, stale",
315
371
  "@agent-native/* pins), run `agent-native upgrade check` instead.",
@@ -348,7 +404,10 @@ export async function runDoctor(argv, io = defaultIo) {
348
404
  return 2;
349
405
  }
350
406
  }
351
- const report = runDoctorScan({ root, only: opts.only });
407
+ const workspaceRoots = workspaceDoctorRoots(root);
408
+ const report = workspaceRoots === null
409
+ ? runDoctorScan({ root, only: opts.only })
410
+ : runWorkspaceDoctorScan(root, workspaceRoots.scanRoots, opts.only);
352
411
  const disk = checkDisk(root, { measureReclaimable: Boolean(opts.disk) });
353
412
  if (opts.json) {
354
413
  // The machine-readable report always goes to stdout (io.log), whether
@@ -356,10 +415,19 @@ export async function runDoctor(argv, io = defaultIo) {
356
415
  // report.json` in CI always captures the report. Only the usage/
357
416
  // execution error payloads above (bad --cwd, unknown --only) go to
358
417
  // stderr — those are diagnostics for exit code 2, not the report.
359
- io.log(JSON.stringify({ ...report, disk, strict: Boolean(opts.strict) }, null, 2));
418
+ io.log(JSON.stringify({
419
+ ...report,
420
+ ...(workspaceRoots === null
421
+ ? {}
422
+ : {
423
+ workspaceApps: workspaceRoots.appRoots.map((appRoot) => path.relative(root, appRoot).replaceAll("\\", "/")),
424
+ }),
425
+ disk,
426
+ strict: Boolean(opts.strict),
427
+ }, null, 2));
360
428
  }
361
429
  else {
362
- io.log(formatDoctorHuman(report, root, disk));
430
+ io.log(formatDoctorHuman(report, root, disk, workspaceRoots?.appRoots.map((appRoot) => path.relative(root, appRoot).replaceAll("\\", "/"))));
363
431
  if (!report.ok) {
364
432
  io.err("");
365
433
  io.err("agent-native doctor found issues above. Fix them, or add a `// guard:allow-<check> — reason` opt-out with reviewer approval.");
@@ -369,19 +437,19 @@ export async function runDoctor(argv, io = defaultIo) {
369
437
  }
370
438
  /**
371
439
  * `agent-native build`'s doctor pre-step. Always runs every enabled guard
372
- * and always prints findings (as warnings) to `io.err` — never silent.
373
- * Never causes the build to fail unless `strict` was passed or
374
- * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,
375
- * "Where it runs" — the v1 doctor has zero field mileage against arbitrary
376
- * app layouts, so shipping fail-by-default would risk breaking a first
377
- * deploy on a false positive).
440
+ * and always prints findings to `io.err` — never silent. Findings fail the
441
+ * build by default; only an explicit `doctor.failOnBuild: false` opt-out can
442
+ * keep a build moving, while `--strict` overrides that opt-out.
378
443
  */
379
444
  export async function runDoctorBuildHook(options, io = defaultIo) {
380
445
  const root = path.resolve(options.cwd);
381
446
  const config = readDoctorConfig(root);
382
- const report = runDoctorScan({ root });
447
+ const workspaceRoots = workspaceDoctorRoots(root);
448
+ const report = workspaceRoots === null
449
+ ? runDoctorScan({ root })
450
+ : runWorkspaceDoctorScan(root, workspaceRoots.scanRoots);
383
451
  if (report.findings.length > 0) {
384
- io.err(`\n[doctor] ${report.findings.length} finding(s) from \`agent-native doctor\` — run it directly for details. This does not fail the build unless --strict was passed or agent-native.json's doctor.failOnBuild is true.`);
452
+ io.err(`\n[doctor] ${report.findings.length} finding(s) from \`agent-native doctor\` — fix them before the build can continue.`);
385
453
  for (const f of report.findings) {
386
454
  io.err(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);
387
455
  }
@@ -397,7 +465,7 @@ export async function runDoctorBuildHook(options, io = defaultIo) {
397
465
  failOnBuild: config.failOnBuild,
398
466
  });
399
467
  if (fail) {
400
- io.err(`\n[doctor] Failing build: ${options.strict ? "--strict was passed" : "agent-native.json's doctor.failOnBuild is true"}.`);
468
+ io.err(`\n[doctor] Failing build: ${options.strict ? "--strict was passed" : "the doctor.failOnBuild gate is enabled (default: true)"}.`);
401
469
  }
402
470
  return { ok: !fail, report };
403
471
  }
package/dist/cli/index.js CHANGED
@@ -587,10 +587,9 @@ switch (command) {
587
587
  // continuation only runs on success.
588
588
  (async () => {
589
589
  // Doctor pre-step: scans app source for the security-critical guard
590
- // invariants (see `agent-native doctor --help`). Warn-only by
591
- // default prints findings to stderr and always continues. Only
592
- // fails the build when `agent-native build --strict` was passed or
593
- // `agent-native.json` sets `{ "doctor": { "failOnBuild": true } }`.
590
+ // invariants (see `agent-native doctor --help`). Findings fail by
591
+ // default; only an explicit `doctor.failOnBuild: false` opt-out keeps
592
+ // a build moving, while `agent-native build --strict` always fails.
594
593
  try {
595
594
  const { runDoctorBuildHook } = await import("./doctor.js");
596
595
  const hook = await runDoctorBuildHook({
@@ -603,7 +602,8 @@ switch (command) {
603
602
  }
604
603
  }
605
604
  catch (err) {
606
- console.warn(`[doctor] pre-build scan failed to run (continuing): ${err instanceof Error ? err.message : String(err)}`);
605
+ console.error(`[doctor] pre-build scan failed, so the build is blocked: ${err instanceof Error ? err.message : String(err)}`);
606
+ process.exit(1);
607
607
  }
608
608
  if (isReactRouterFramework()) {
609
609
  clearAgentNativeNitroPresetMarker();
@@ -1096,6 +1096,7 @@ Usage:
1096
1096
  Call another agent-native app over A2A
1097
1097
  agent-native script <name> Run an action (deprecated alias for 'action')
1098
1098
  agent-native typecheck Run TypeScript type checking
1099
+ agent-native doctor Scan app/workspace source for guard violations
1099
1100
  agent-native create [name] Scaffold a new agent-native workspace with a
1100
1101
  multi-select template picker. Use --standalone
1101
1102
  for a single-app scaffold, or choose Community
@@ -1,3 +1,4 @@
1
+ import { type ReactNode } from "react";
1
2
  export interface AgentAskPopoverProps {
2
3
  prompt: string;
3
4
  title?: string;
@@ -5,7 +6,8 @@ export interface AgentAskPopoverProps {
5
6
  placeholder?: string;
6
7
  context?: string;
7
8
  className?: string;
9
+ icon?: ReactNode;
8
10
  }
9
11
  /** A low-emphasis entry point for asking the agent without losing the current surface. */
10
- export declare function AgentAskPopover({ prompt, title, label, placeholder, context, className, }: AgentAskPopoverProps): import("react").JSX.Element;
12
+ export declare function AgentAskPopover({ prompt, title, label, placeholder, context, className, icon, }: AgentAskPopoverProps): import("react").JSX.Element;
11
13
  //# sourceMappingURL=AgentAskPopover.d.ts.map
@@ -6,7 +6,7 @@ import { Popover, PopoverContent, PopoverTrigger, } from "./components/ui/popove
6
6
  import { PromptComposer } from "./composer/index.js";
7
7
  import { useT } from "./i18n.js";
8
8
  /** A low-emphasis entry point for asking the agent without losing the current surface. */
9
- export function AgentAskPopover({ prompt, title, label, placeholder, context, className, }) {
9
+ export function AgentAskPopover({ prompt, title, label, placeholder, context, className, icon, }) {
10
10
  const t = useT();
11
11
  const [open, setOpen] = useState(false);
12
12
  const handleSubmit = useCallback((text) => {
@@ -21,7 +21,7 @@ export function AgentAskPopover({ prompt, title, label, placeholder, context, cl
21
21
  });
22
22
  setOpen(false);
23
23
  }, [context]);
24
- return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "outline", size: "sm", className: className ?? "cursor-pointer", children: label ?? t("agentPanel.askAgent", { defaultValue: "Ask the agent" }) }) }), _jsxs(PopoverContent, { align: "end", sideOffset: 8, collisionPadding: 12, className: "z-[260] w-[calc(100vw-32px)] max-w-[420px] p-3", children: [_jsx("p", { className: "px-1 pb-2 text-sm font-semibold text-foreground", children: title ??
24
+ return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: className ?? "cursor-pointer", children: [icon, label ?? t("agentPanel.askAgent", { defaultValue: "Ask the agent" })] }) }), _jsxs(PopoverContent, { align: "end", sideOffset: 8, collisionPadding: 12, className: "z-[260] w-[calc(100vw-32px)] max-w-[420px] p-3", children: [_jsx("p", { className: "px-1 pb-2 text-sm font-semibold text-foreground", children: title ??
25
25
  t("agentPanel.askAgentTitle", { defaultValue: "Ask the agent" }) }), _jsx(PromptComposer, { autoFocus: true, attachmentsEnabled: false, initialText: prompt, initialTextKey: prompt, layoutVariant: "compact", placeholder: placeholder ??
26
26
  t("agentPanel.askAgentPlaceholder", {
27
27
  defaultValue: "Tell the agent what you want to do…",