@agent-native/core 0.96.0 → 0.97.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 (450) hide show
  1. package/README.md +6 -0
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +39 -0
  4. package/corpus/core/docs/content/audit-log.mdx +2 -1
  5. package/corpus/core/docs/content/automations.mdx +7 -7
  6. package/corpus/core/docs/content/creating-templates.mdx +1 -1
  7. package/corpus/core/docs/content/internationalization.mdx +2 -1
  8. package/corpus/core/docs/content/locales/ar-SA/audit-log.mdx +2 -1
  9. package/corpus/core/docs/content/locales/ar-SA/automations.mdx +7 -7
  10. package/corpus/core/docs/content/locales/ar-SA/getting-started.mdx +7 -1
  11. package/corpus/core/docs/content/locales/ar-SA/internationalization.mdx +1 -1
  12. package/corpus/core/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
  13. package/corpus/core/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
  14. package/corpus/core/docs/content/locales/ar-SA/security.mdx +8 -0
  15. package/corpus/core/docs/content/locales/de-DE/audit-log.mdx +2 -1
  16. package/corpus/core/docs/content/locales/de-DE/automations.mdx +7 -7
  17. package/corpus/core/docs/content/locales/de-DE/getting-started.mdx +7 -1
  18. package/corpus/core/docs/content/locales/de-DE/internationalization.mdx +1 -1
  19. package/corpus/core/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
  20. package/corpus/core/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
  21. package/corpus/core/docs/content/locales/de-DE/security.mdx +8 -0
  22. package/corpus/core/docs/content/locales/es-ES/audit-log.mdx +2 -1
  23. package/corpus/core/docs/content/locales/es-ES/automations.mdx +7 -7
  24. package/corpus/core/docs/content/locales/es-ES/getting-started.mdx +7 -1
  25. package/corpus/core/docs/content/locales/es-ES/internationalization.mdx +1 -1
  26. package/corpus/core/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
  27. package/corpus/core/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
  28. package/corpus/core/docs/content/locales/es-ES/security.mdx +8 -0
  29. package/corpus/core/docs/content/locales/fr-FR/audit-log.mdx +2 -1
  30. package/corpus/core/docs/content/locales/fr-FR/automations.mdx +7 -7
  31. package/corpus/core/docs/content/locales/fr-FR/getting-started.mdx +7 -1
  32. package/corpus/core/docs/content/locales/fr-FR/internationalization.mdx +1 -1
  33. package/corpus/core/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
  34. package/corpus/core/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
  35. package/corpus/core/docs/content/locales/fr-FR/security.mdx +8 -0
  36. package/corpus/core/docs/content/locales/hi-IN/audit-log.mdx +2 -1
  37. package/corpus/core/docs/content/locales/hi-IN/automations.mdx +7 -7
  38. package/corpus/core/docs/content/locales/hi-IN/getting-started.mdx +7 -1
  39. package/corpus/core/docs/content/locales/hi-IN/internationalization.mdx +1 -1
  40. package/corpus/core/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
  41. package/corpus/core/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
  42. package/corpus/core/docs/content/locales/hi-IN/security.mdx +8 -0
  43. package/corpus/core/docs/content/locales/ja-JP/audit-log.mdx +2 -1
  44. package/corpus/core/docs/content/locales/ja-JP/automations.mdx +7 -7
  45. package/corpus/core/docs/content/locales/ja-JP/getting-started.mdx +7 -1
  46. package/corpus/core/docs/content/locales/ja-JP/internationalization.mdx +1 -1
  47. package/corpus/core/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
  48. package/corpus/core/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
  49. package/corpus/core/docs/content/locales/ja-JP/security.mdx +8 -0
  50. package/corpus/core/docs/content/locales/ko-KR/audit-log.mdx +2 -1
  51. package/corpus/core/docs/content/locales/ko-KR/automations.mdx +7 -7
  52. package/corpus/core/docs/content/locales/ko-KR/getting-started.mdx +7 -1
  53. package/corpus/core/docs/content/locales/ko-KR/internationalization.mdx +1 -1
  54. package/corpus/core/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
  55. package/corpus/core/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
  56. package/corpus/core/docs/content/locales/ko-KR/security.mdx +8 -0
  57. package/corpus/core/docs/content/locales/pt-BR/audit-log.mdx +2 -1
  58. package/corpus/core/docs/content/locales/pt-BR/automations.mdx +7 -7
  59. package/corpus/core/docs/content/locales/pt-BR/getting-started.mdx +7 -1
  60. package/corpus/core/docs/content/locales/pt-BR/internationalization.mdx +1 -1
  61. package/corpus/core/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
  62. package/corpus/core/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
  63. package/corpus/core/docs/content/locales/pt-BR/security.mdx +8 -0
  64. package/corpus/core/docs/content/locales/zh-CN/audit-log.mdx +2 -1
  65. package/corpus/core/docs/content/locales/zh-CN/automations.mdx +7 -7
  66. package/corpus/core/docs/content/locales/zh-CN/getting-started.mdx +6 -4
  67. package/corpus/core/docs/content/locales/zh-CN/internationalization.mdx +1 -1
  68. package/corpus/core/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
  69. package/corpus/core/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
  70. package/corpus/core/docs/content/locales/zh-CN/security.mdx +8 -0
  71. package/corpus/core/docs/content/locales/zh-TW/audit-log.mdx +2 -1
  72. package/corpus/core/docs/content/locales/zh-TW/automations.mdx +7 -7
  73. package/corpus/core/docs/content/locales/zh-TW/getting-started.mdx +6 -4
  74. package/corpus/core/docs/content/locales/zh-TW/internationalization.mdx +1 -1
  75. package/corpus/core/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
  76. package/corpus/core/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
  77. package/corpus/core/docs/content/locales/zh-TW/security.mdx +8 -0
  78. package/corpus/core/docs/content/package-lifecycle.mdx +51 -0
  79. package/corpus/core/docs/content/sandbox-adapters.mdx +16 -5
  80. package/corpus/core/package.json +9 -2
  81. package/corpus/core/src/a2a/auth-policy.ts +33 -0
  82. package/corpus/core/src/agent/durable-background.ts +15 -7
  83. package/corpus/core/src/agent/run-store.ts +13 -4
  84. package/corpus/core/src/audit/actions/export-audit-events.ts +162 -0
  85. package/corpus/core/src/audit/store.ts +8 -3
  86. package/corpus/core/src/audit/types.ts +3 -0
  87. package/corpus/core/src/cli/doctor.ts +396 -0
  88. package/corpus/core/src/cli/index.ts +56 -0
  89. package/corpus/core/src/cli/info.ts +3 -3
  90. package/corpus/core/src/cli/package-lifecycle.ts +821 -0
  91. package/corpus/core/src/client/agent-chat-adapter.ts +9 -9
  92. package/corpus/core/src/guards/db-tool-scoping.ts +129 -0
  93. package/corpus/core/src/guards/index.ts +23 -0
  94. package/corpus/core/src/guards/no-drizzle-push.ts +116 -0
  95. package/corpus/core/src/guards/no-env-credentials.ts +229 -0
  96. package/corpus/core/src/guards/no-env-mutation.ts +114 -0
  97. package/corpus/core/src/guards/no-localhost-fallback.ts +124 -0
  98. package/corpus/core/src/guards/no-unscoped-credentials.ts +227 -0
  99. package/corpus/core/src/guards/no-unscoped-queries.ts +834 -0
  100. package/corpus/core/src/guards/scan-utils.ts +105 -0
  101. package/corpus/core/src/guards/types.ts +30 -0
  102. package/corpus/core/src/org/accept-pending.ts +9 -1
  103. package/corpus/core/src/org/migrations.ts +41 -0
  104. package/corpus/core/src/package-lifecycle/index.ts +1 -0
  105. package/corpus/core/src/package-lifecycle/manifest.ts +120 -0
  106. package/corpus/core/src/provider-api/custom-registry.ts +56 -0
  107. package/corpus/core/src/provider-api/index.ts +2 -0
  108. package/corpus/core/src/secrets/storage.ts +47 -27
  109. package/corpus/core/src/server/action-discovery.ts +4 -0
  110. package/corpus/core/src/server/agent-chat-plugin.ts +54 -12
  111. package/corpus/core/src/server/core-routes-plugin.ts +30 -14
  112. package/corpus/core/src/server/csrf.ts +24 -5
  113. package/corpus/core/src/server/framework-request-handler.ts +34 -0
  114. package/corpus/core/src/server/google-realtime-session.ts +1 -36
  115. package/corpus/core/src/server/poll.ts +24 -2
  116. package/corpus/core/src/server/realtime-voice.ts +9 -0
  117. package/corpus/core/src/server/request-origin.ts +63 -0
  118. package/corpus/core/src/server/transcribe-voice.ts +1 -50
  119. package/corpus/core/src/templates/default/package.json +2 -2
  120. package/corpus/core/src/templates/headless/package.json +0 -1
  121. package/corpus/core/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
  122. package/corpus/core/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
  123. package/corpus/core/src/templates/workspace-core/package.json +0 -1
  124. package/corpus/core/src/templates/workspace-root/package.json +0 -1
  125. package/corpus/core/src/triggers/actions.ts +11 -3
  126. package/corpus/core/src/triggers/types.ts +7 -1
  127. package/corpus/templates/analytics/actions/compose-dashboard.ts +65 -37
  128. package/corpus/templates/analytics/actions/mutate-dashboard.ts +73 -24
  129. package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +16 -13
  130. package/corpus/templates/analytics/actions/update-dashboard.ts +53 -42
  131. package/corpus/templates/analytics/changelog/2026-07-10-dashboard-edits-from-the-agent-and-the-ui-at-the-same-time-n.md +6 -0
  132. package/corpus/templates/analytics/changelog/2026-07-10-timed-out-bigquery-jobs-are-now-cancelled-so-they-stop-consu.md +6 -0
  133. package/corpus/templates/analytics/package.json +1 -2
  134. package/corpus/templates/analytics/server/lib/bigquery.ts +3 -2
  135. package/corpus/templates/analytics/server/lib/dashboards-store.ts +154 -11
  136. package/corpus/templates/assets/package.json +1 -2
  137. package/corpus/templates/brain/package.json +1 -2
  138. package/corpus/templates/calendar/package.json +1 -2
  139. package/corpus/templates/chat/package.json +1 -2
  140. package/corpus/templates/clips/changelog/2026-07-10-atomic-view-tracking.md +6 -0
  141. package/corpus/templates/clips/chrome-extension/package.json +3 -2
  142. package/corpus/templates/clips/desktop/package.json +6 -4
  143. package/corpus/templates/clips/desktop/src/lib/recorder.ts +26 -13
  144. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +4 -1
  145. package/corpus/templates/clips/package.json +1 -2
  146. package/corpus/templates/clips/server/db/schema.ts +29 -17
  147. package/corpus/templates/clips/server/plugins/db.ts +8 -0
  148. package/corpus/templates/clips/server/routes/api/view-event.post.ts +260 -105
  149. package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +16 -0
  150. package/corpus/templates/content/AGENTS.md +72 -62
  151. package/corpus/templates/content/actions/_content-database-source-adapters.ts +84 -0
  152. package/corpus/templates/content/actions/_database-source-utils.ts +206 -96
  153. package/corpus/templates/content/actions/_notion-database-source-adapter.ts +216 -0
  154. package/corpus/templates/content/actions/_position-utils.ts +76 -0
  155. package/corpus/templates/content/actions/_property-utils.ts +31 -20
  156. package/corpus/templates/content/actions/add-database-item.ts +52 -39
  157. package/corpus/templates/content/actions/attach-content-database-source.ts +95 -11
  158. package/corpus/templates/content/actions/change-content-database-source-role.ts +24 -1
  159. package/corpus/templates/content/actions/configure-document-property.ts +36 -27
  160. package/corpus/templates/content/actions/create-content-database.ts +40 -30
  161. package/corpus/templates/content/actions/create-document.ts +39 -32
  162. package/corpus/templates/content/actions/duplicate-document-property.ts +37 -28
  163. package/corpus/templates/content/actions/list-notion-database-sources.ts +80 -0
  164. package/corpus/templates/content/actions/move-document.ts +64 -48
  165. package/corpus/templates/content/actions/refresh-content-database-source.ts +42 -3
  166. package/corpus/templates/content/actions/share-local-file-document.ts +36 -27
  167. package/corpus/templates/content/actions/suggest-source-join-key.ts +39 -16
  168. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +89 -23
  169. package/corpus/templates/content/app/components/editor/database/settings.tsx +1 -1
  170. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -1
  171. package/corpus/templates/content/app/i18n/zh-TW.ts +4 -0
  172. package/corpus/templates/content/app/i18n-data.ts +40 -0
  173. package/corpus/templates/content/changelog/2026-07-10-failed-row-creation-and-source-attach-now-show-an-error-inst.md +6 -0
  174. package/corpus/templates/content/changelog/2026-07-10-items-added-at-the-same-time-no-longer-end-up-with-identical.md +6 -0
  175. package/corpus/templates/content/changelog/2026-07-10-notion-databases-can-add-read-only-details-to-content-tables.md +6 -0
  176. package/corpus/templates/content/package.json +1 -2
  177. package/corpus/templates/content/parity/matrix.md +25 -25
  178. package/corpus/templates/content/parity/matrix.ts +1 -0
  179. package/corpus/templates/content/server/routes/api/documents/[id]/move.patch.ts +43 -26
  180. package/corpus/templates/content/shared/api.ts +16 -1
  181. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +8 -4
  182. package/corpus/templates/design/AGENTS.md +12 -2
  183. package/corpus/templates/design/DEVELOPING.md +10 -6
  184. package/corpus/templates/design/actions/apply-visual-edit.ts +191 -6
  185. package/corpus/templates/design/actions/duplicate-design.ts +31 -25
  186. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +5 -1
  187. package/corpus/templates/design/changelog/2026-07-10-duplicating-a-design-can-no-longer-produce-a-copy-with-missi.md +6 -0
  188. package/corpus/templates/design/changelog/2026-07-10-local-visual-edits-can-now-save-safe-leaf-text-class-and.md +6 -0
  189. package/corpus/templates/design/package.json +1 -1
  190. package/corpus/templates/design/shared/local-jsx-visual-edit.ts +388 -0
  191. package/corpus/templates/dispatch/package.json +1 -2
  192. package/corpus/templates/forms/actions/patch-form-fields.ts +82 -44
  193. package/corpus/templates/forms/changelog/2026-07-10-simultaneous-edits-to-different-form-fields-no-longer-overwr.md +6 -0
  194. package/corpus/templates/forms/package.json +1 -2
  195. package/corpus/templates/macros/package.json +1 -2
  196. package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -1
  197. package/corpus/templates/mail/changelog/2026-07-10-fixed-calendar-rsvp-buttons-in-emails-firing-duplicate-respo.md +6 -0
  198. package/corpus/templates/mail/package.json +1 -2
  199. package/corpus/templates/plan/actions/restore-plan-version.ts +126 -96
  200. package/corpus/templates/plan/changelog/2026-07-10-restoring-a-plan-version-can-no-longer-leave-a-plan-half-res.md +6 -0
  201. package/corpus/templates/plan/package.json +1 -2
  202. package/corpus/templates/plan/server/plans.ts +9 -2
  203. package/corpus/templates/slides/actions/list-decks.ts +28 -0
  204. package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +41 -26
  205. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +4 -8
  206. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -4
  207. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -8
  208. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +5 -12
  209. package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +3 -6
  210. package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +3 -6
  211. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +2 -5
  212. package/corpus/templates/slides/app/context/DeckContext.tsx +47 -4
  213. package/corpus/templates/slides/app/pages/DeckEditor.tsx +11 -30
  214. package/corpus/templates/slides/app/pages/Index.tsx +2 -3
  215. package/corpus/templates/slides/app/root.tsx +0 -5
  216. package/corpus/templates/slides/changelog/2026-07-10-deck-lists-load-much-faster-and-no-longer-re-download-slide-.md +6 -0
  217. package/corpus/templates/slides/package.json +1 -2
  218. package/dist/a2a/auth-policy.d.ts +19 -0
  219. package/dist/a2a/auth-policy.d.ts.map +1 -1
  220. package/dist/a2a/auth-policy.js +32 -0
  221. package/dist/a2a/auth-policy.js.map +1 -1
  222. package/dist/agent/durable-background.d.ts +8 -5
  223. package/dist/agent/durable-background.d.ts.map +1 -1
  224. package/dist/agent/durable-background.js +15 -8
  225. package/dist/agent/durable-background.js.map +1 -1
  226. package/dist/agent/run-store.d.ts.map +1 -1
  227. package/dist/agent/run-store.js +9 -4
  228. package/dist/agent/run-store.js.map +1 -1
  229. package/dist/audit/actions/export-audit-events.d.ts +27 -0
  230. package/dist/audit/actions/export-audit-events.d.ts.map +1 -0
  231. package/dist/audit/actions/export-audit-events.js +144 -0
  232. package/dist/audit/actions/export-audit-events.js.map +1 -0
  233. package/dist/audit/store.d.ts +1 -0
  234. package/dist/audit/store.d.ts.map +1 -1
  235. package/dist/audit/store.js +8 -3
  236. package/dist/audit/store.js.map +1 -1
  237. package/dist/audit/types.d.ts +3 -0
  238. package/dist/audit/types.d.ts.map +1 -1
  239. package/dist/audit/types.js.map +1 -1
  240. package/dist/cli/doctor.d.ts +83 -0
  241. package/dist/cli/doctor.d.ts.map +1 -0
  242. package/dist/cli/doctor.js +277 -0
  243. package/dist/cli/doctor.js.map +1 -0
  244. package/dist/cli/index.js +50 -0
  245. package/dist/cli/index.js.map +1 -1
  246. package/dist/cli/info.js +3 -3
  247. package/dist/cli/info.js.map +1 -1
  248. package/dist/cli/package-lifecycle.d.ts +50 -0
  249. package/dist/cli/package-lifecycle.d.ts.map +1 -0
  250. package/dist/cli/package-lifecycle.js +560 -0
  251. package/dist/cli/package-lifecycle.js.map +1 -0
  252. package/dist/client/agent-chat-adapter.js +7 -3
  253. package/dist/client/agent-chat-adapter.js.map +1 -1
  254. package/dist/collab/struct-routes.d.ts +1 -1
  255. package/dist/guards/db-tool-scoping.d.ts +38 -0
  256. package/dist/guards/db-tool-scoping.d.ts.map +1 -0
  257. package/dist/guards/db-tool-scoping.js +114 -0
  258. package/dist/guards/db-tool-scoping.js.map +1 -0
  259. package/dist/guards/index.d.ts +23 -0
  260. package/dist/guards/index.d.ts.map +1 -0
  261. package/dist/guards/index.js +19 -0
  262. package/dist/guards/index.js.map +1 -0
  263. package/dist/guards/no-drizzle-push.d.ts +14 -0
  264. package/dist/guards/no-drizzle-push.d.ts.map +1 -0
  265. package/dist/guards/no-drizzle-push.js +97 -0
  266. package/dist/guards/no-drizzle-push.js.map +1 -0
  267. package/dist/guards/no-env-credentials.d.ts +36 -0
  268. package/dist/guards/no-env-credentials.d.ts.map +1 -0
  269. package/dist/guards/no-env-credentials.js +204 -0
  270. package/dist/guards/no-env-credentials.js.map +1 -0
  271. package/dist/guards/no-env-mutation.d.ts +23 -0
  272. package/dist/guards/no-env-mutation.d.ts.map +1 -0
  273. package/dist/guards/no-env-mutation.js +90 -0
  274. package/dist/guards/no-env-mutation.js.map +1 -0
  275. package/dist/guards/no-localhost-fallback.d.ts +30 -0
  276. package/dist/guards/no-localhost-fallback.d.ts.map +1 -0
  277. package/dist/guards/no-localhost-fallback.js +105 -0
  278. package/dist/guards/no-localhost-fallback.js.map +1 -0
  279. package/dist/guards/no-unscoped-credentials.d.ts +28 -0
  280. package/dist/guards/no-unscoped-credentials.d.ts.map +1 -0
  281. package/dist/guards/no-unscoped-credentials.js +199 -0
  282. package/dist/guards/no-unscoped-credentials.js.map +1 -0
  283. package/dist/guards/no-unscoped-queries.d.ts +32 -0
  284. package/dist/guards/no-unscoped-queries.d.ts.map +1 -0
  285. package/dist/guards/no-unscoped-queries.js +720 -0
  286. package/dist/guards/no-unscoped-queries.js.map +1 -0
  287. package/dist/guards/scan-utils.d.ts +28 -0
  288. package/dist/guards/scan-utils.d.ts.map +1 -0
  289. package/dist/guards/scan-utils.js +92 -0
  290. package/dist/guards/scan-utils.js.map +1 -0
  291. package/dist/guards/types.d.ts +28 -0
  292. package/dist/guards/types.d.ts.map +1 -0
  293. package/dist/guards/types.js +11 -0
  294. package/dist/guards/types.js.map +1 -0
  295. package/dist/org/accept-pending.d.ts.map +1 -1
  296. package/dist/org/accept-pending.js +9 -1
  297. package/dist/org/accept-pending.js.map +1 -1
  298. package/dist/org/migrations.d.ts +7 -2
  299. package/dist/org/migrations.d.ts.map +1 -1
  300. package/dist/org/migrations.js +41 -0
  301. package/dist/org/migrations.js.map +1 -1
  302. package/dist/package-lifecycle/index.d.ts +2 -0
  303. package/dist/package-lifecycle/index.d.ts.map +1 -0
  304. package/dist/package-lifecycle/index.js +2 -0
  305. package/dist/package-lifecycle/index.js.map +1 -0
  306. package/dist/package-lifecycle/manifest.d.ts +24 -0
  307. package/dist/package-lifecycle/manifest.d.ts.map +1 -0
  308. package/dist/package-lifecycle/manifest.js +81 -0
  309. package/dist/package-lifecycle/manifest.js.map +1 -0
  310. package/dist/progress/routes.d.ts +1 -1
  311. package/dist/provider-api/custom-registry.d.ts +32 -1
  312. package/dist/provider-api/custom-registry.d.ts.map +1 -1
  313. package/dist/provider-api/custom-registry.js +41 -1
  314. package/dist/provider-api/custom-registry.js.map +1 -1
  315. package/dist/provider-api/index.d.ts +1 -1
  316. package/dist/provider-api/index.d.ts.map +1 -1
  317. package/dist/provider-api/index.js +1 -1
  318. package/dist/provider-api/index.js.map +1 -1
  319. package/dist/secrets/storage.d.ts.map +1 -1
  320. package/dist/secrets/storage.js +45 -27
  321. package/dist/secrets/storage.js.map +1 -1
  322. package/dist/server/action-discovery.d.ts.map +1 -1
  323. package/dist/server/action-discovery.js +4 -0
  324. package/dist/server/action-discovery.js.map +1 -1
  325. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  326. package/dist/server/agent-chat-plugin.js +47 -13
  327. package/dist/server/agent-chat-plugin.js.map +1 -1
  328. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  329. package/dist/server/core-routes-plugin.js +23 -12
  330. package/dist/server/core-routes-plugin.js.map +1 -1
  331. package/dist/server/csrf.d.ts.map +1 -1
  332. package/dist/server/csrf.js +18 -5
  333. package/dist/server/csrf.js.map +1 -1
  334. package/dist/server/framework-request-handler.d.ts.map +1 -1
  335. package/dist/server/framework-request-handler.js +34 -0
  336. package/dist/server/framework-request-handler.js.map +1 -1
  337. package/dist/server/google-realtime-session.d.ts.map +1 -1
  338. package/dist/server/google-realtime-session.js +2 -34
  339. package/dist/server/google-realtime-session.js.map +1 -1
  340. package/dist/server/poll.d.ts.map +1 -1
  341. package/dist/server/poll.js +24 -2
  342. package/dist/server/poll.js.map +1 -1
  343. package/dist/server/realtime-voice.d.ts.map +1 -1
  344. package/dist/server/realtime-voice.js +9 -0
  345. package/dist/server/realtime-voice.js.map +1 -1
  346. package/dist/server/request-origin.d.ts +10 -0
  347. package/dist/server/request-origin.d.ts.map +1 -0
  348. package/dist/server/request-origin.js +60 -0
  349. package/dist/server/request-origin.js.map +1 -0
  350. package/dist/server/transcribe-voice.d.ts.map +1 -1
  351. package/dist/server/transcribe-voice.js +2 -48
  352. package/dist/server/transcribe-voice.js.map +1 -1
  353. package/dist/templates/default/package.json +2 -2
  354. package/dist/templates/headless/package.json +0 -1
  355. package/dist/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
  356. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
  357. package/dist/templates/workspace-core/package.json +0 -1
  358. package/dist/templates/workspace-root/package.json +0 -1
  359. package/dist/triggers/actions.d.ts.map +1 -1
  360. package/dist/triggers/actions.js +8 -3
  361. package/dist/triggers/actions.js.map +1 -1
  362. package/dist/triggers/types.d.ts +7 -1
  363. package/dist/triggers/types.d.ts.map +1 -1
  364. package/dist/triggers/types.js.map +1 -1
  365. package/docs/content/audit-log.mdx +2 -1
  366. package/docs/content/automations.mdx +7 -7
  367. package/docs/content/creating-templates.mdx +1 -1
  368. package/docs/content/internationalization.mdx +2 -1
  369. package/docs/content/locales/ar-SA/audit-log.mdx +2 -1
  370. package/docs/content/locales/ar-SA/automations.mdx +7 -7
  371. package/docs/content/locales/ar-SA/getting-started.mdx +7 -1
  372. package/docs/content/locales/ar-SA/internationalization.mdx +1 -1
  373. package/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
  374. package/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
  375. package/docs/content/locales/ar-SA/security.mdx +8 -0
  376. package/docs/content/locales/de-DE/audit-log.mdx +2 -1
  377. package/docs/content/locales/de-DE/automations.mdx +7 -7
  378. package/docs/content/locales/de-DE/getting-started.mdx +7 -1
  379. package/docs/content/locales/de-DE/internationalization.mdx +1 -1
  380. package/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
  381. package/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
  382. package/docs/content/locales/de-DE/security.mdx +8 -0
  383. package/docs/content/locales/es-ES/audit-log.mdx +2 -1
  384. package/docs/content/locales/es-ES/automations.mdx +7 -7
  385. package/docs/content/locales/es-ES/getting-started.mdx +7 -1
  386. package/docs/content/locales/es-ES/internationalization.mdx +1 -1
  387. package/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
  388. package/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
  389. package/docs/content/locales/es-ES/security.mdx +8 -0
  390. package/docs/content/locales/fr-FR/audit-log.mdx +2 -1
  391. package/docs/content/locales/fr-FR/automations.mdx +7 -7
  392. package/docs/content/locales/fr-FR/getting-started.mdx +7 -1
  393. package/docs/content/locales/fr-FR/internationalization.mdx +1 -1
  394. package/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
  395. package/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
  396. package/docs/content/locales/fr-FR/security.mdx +8 -0
  397. package/docs/content/locales/hi-IN/audit-log.mdx +2 -1
  398. package/docs/content/locales/hi-IN/automations.mdx +7 -7
  399. package/docs/content/locales/hi-IN/getting-started.mdx +7 -1
  400. package/docs/content/locales/hi-IN/internationalization.mdx +1 -1
  401. package/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
  402. package/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
  403. package/docs/content/locales/hi-IN/security.mdx +8 -0
  404. package/docs/content/locales/ja-JP/audit-log.mdx +2 -1
  405. package/docs/content/locales/ja-JP/automations.mdx +7 -7
  406. package/docs/content/locales/ja-JP/getting-started.mdx +7 -1
  407. package/docs/content/locales/ja-JP/internationalization.mdx +1 -1
  408. package/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
  409. package/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
  410. package/docs/content/locales/ja-JP/security.mdx +8 -0
  411. package/docs/content/locales/ko-KR/audit-log.mdx +2 -1
  412. package/docs/content/locales/ko-KR/automations.mdx +7 -7
  413. package/docs/content/locales/ko-KR/getting-started.mdx +7 -1
  414. package/docs/content/locales/ko-KR/internationalization.mdx +1 -1
  415. package/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
  416. package/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
  417. package/docs/content/locales/ko-KR/security.mdx +8 -0
  418. package/docs/content/locales/pt-BR/audit-log.mdx +2 -1
  419. package/docs/content/locales/pt-BR/automations.mdx +7 -7
  420. package/docs/content/locales/pt-BR/getting-started.mdx +7 -1
  421. package/docs/content/locales/pt-BR/internationalization.mdx +1 -1
  422. package/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
  423. package/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
  424. package/docs/content/locales/pt-BR/security.mdx +8 -0
  425. package/docs/content/locales/zh-CN/audit-log.mdx +2 -1
  426. package/docs/content/locales/zh-CN/automations.mdx +7 -7
  427. package/docs/content/locales/zh-CN/getting-started.mdx +6 -4
  428. package/docs/content/locales/zh-CN/internationalization.mdx +1 -1
  429. package/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
  430. package/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
  431. package/docs/content/locales/zh-CN/security.mdx +8 -0
  432. package/docs/content/locales/zh-TW/audit-log.mdx +2 -1
  433. package/docs/content/locales/zh-TW/automations.mdx +7 -7
  434. package/docs/content/locales/zh-TW/getting-started.mdx +6 -4
  435. package/docs/content/locales/zh-TW/internationalization.mdx +1 -1
  436. package/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
  437. package/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
  438. package/docs/content/locales/zh-TW/security.mdx +8 -0
  439. package/docs/content/package-lifecycle.mdx +51 -0
  440. package/docs/content/sandbox-adapters.mdx +16 -5
  441. package/package.json +10 -3
  442. package/src/templates/default/package.json +2 -2
  443. package/src/templates/headless/package.json +0 -1
  444. package/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
  445. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
  446. package/src/templates/workspace-core/package.json +0 -1
  447. package/src/templates/workspace-root/package.json +0 -1
  448. package/corpus/templates/slides/app/components/ui/toast.tsx +0 -1
  449. package/corpus/templates/slides/app/components/ui/toaster.tsx +0 -1
  450. package/corpus/templates/slides/app/hooks/use-toast.ts +0 -1
@@ -0,0 +1,277 @@
1
+ /**
2
+ * `agent-native doctor` — scan an app's source tree for the security-
3
+ * critical code-safety invariants this monorepo already enforces on
4
+ * itself via `scripts/guard-*.mjs` (see
5
+ * `advisor-plans/reports/005-doctor-design.md` for the full design and
6
+ * `advisor-plans/015-doctor-v1-implementation.md` for the implementation
7
+ * plan). v1 ships 7 of those guards, ported to work against a single
8
+ * generated app root instead of this monorepo's multi-template layout —
9
+ * see `../guards/index.ts`.
10
+ *
11
+ * This is a NEW top-level command, deliberately kept separate from the two
12
+ * existing "doctor" precedents in this CLI:
13
+ * - `agent-native upgrade check` (`upgrade.ts`) — dependency-pin health.
14
+ * - `agent-native recap doctor` (`recap.ts`) — PR Visual Recap config health.
15
+ * Each diagnoses a different domain; none are folded into a shared
16
+ * mega-doctor (see report 005, "Relationship to upgrade doctor and recap
17
+ * doctor").
18
+ *
19
+ * `--fix` is reserved, not implemented in v1 — it prints a message and
20
+ * exits 2 rather than silently no-op, so a future implementation doesn't
21
+ * collide with a script already passing the flag.
22
+ */
23
+ import fs from "node:fs";
24
+ import path from "node:path";
25
+ import { scanDbToolScoping, scanDrizzlePush, scanEnvCredentials, scanEnvMutation, scanLocalhostFallback, scanUnscopedCredentials, scanUnscopedQueries, } from "../guards/index.js";
26
+ export const ALL_GUARD_NAMES = [
27
+ "no-drizzle-push",
28
+ "no-unscoped-credentials",
29
+ "no-unscoped-queries",
30
+ "no-env-credentials",
31
+ "db-tool-scoping",
32
+ "no-env-mutation",
33
+ "no-localhost-fallback",
34
+ ];
35
+ const DEFAULT_DOCTOR_CONFIG = {
36
+ disabledGuards: [],
37
+ dbToolScopingDenylist: {},
38
+ failOnBuild: false,
39
+ };
40
+ /**
41
+ * Reads the optional `"doctor"` key from `<root>/agent-native.json`. All
42
+ * fields are optional with sane empty defaults — an app needs zero config
43
+ * to run `agent-native doctor` with every v1 guard enabled.
44
+ */
45
+ export function readDoctorConfig(root) {
46
+ const manifestPath = path.join(root, "agent-native.json");
47
+ if (!fs.existsSync(manifestPath)) {
48
+ return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };
49
+ }
50
+ try {
51
+ const raw = fs.readFileSync(manifestPath, "utf-8");
52
+ const parsed = JSON.parse(raw);
53
+ const doctor = parsed.doctor ?? {};
54
+ const disabledGuards = Array.isArray(doctor.disabledGuards)
55
+ ? doctor.disabledGuards.filter((v) => typeof v === "string")
56
+ : [];
57
+ const dbToolScopingDenylist = doctor.dbToolScopingDenylist &&
58
+ typeof doctor.dbToolScopingDenylist === "object"
59
+ ? Object.fromEntries(Object.entries(doctor.dbToolScopingDenylist).filter((entry) => typeof entry[1] === "string"))
60
+ : {};
61
+ const failOnBuild = doctor.failOnBuild === true;
62
+ return { disabledGuards, dbToolScopingDenylist, failOnBuild };
63
+ }
64
+ catch {
65
+ return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };
66
+ }
67
+ }
68
+ function runGuard(name, root, config) {
69
+ switch (name) {
70
+ case "no-drizzle-push":
71
+ return scanDrizzlePush({ root });
72
+ case "no-unscoped-credentials":
73
+ return scanUnscopedCredentials({ root });
74
+ case "no-unscoped-queries":
75
+ return scanUnscopedQueries({ root, extraExemptPaths: [] });
76
+ case "no-env-credentials":
77
+ return scanEnvCredentials({ root });
78
+ case "db-tool-scoping":
79
+ return scanDbToolScoping({
80
+ root,
81
+ denylist: config.dbToolScopingDenylist,
82
+ });
83
+ case "no-env-mutation":
84
+ return scanEnvMutation({ root });
85
+ case "no-localhost-fallback":
86
+ return scanLocalhostFallback({ root, extraExemptPaths: [] });
87
+ }
88
+ }
89
+ /** Pure scan orchestrator: runs the selected guards against `root` and
90
+ * returns a flat report. No I/O beyond reading `agent-native.json` and the
91
+ * app source tree — no printing, no process.exit. */
92
+ export function runDoctorScan(options) {
93
+ const root = options.root;
94
+ const config = readDoctorConfig(root);
95
+ let names;
96
+ if (options.only && options.only.length > 0) {
97
+ const knownOnly = options.only.filter((n) => ALL_GUARD_NAMES.includes(n));
98
+ names = knownOnly;
99
+ }
100
+ else {
101
+ names = ALL_GUARD_NAMES.filter((n) => !config.disabledGuards.includes(n));
102
+ }
103
+ const findings = [];
104
+ for (const name of names) {
105
+ const result = runGuard(name, root, config);
106
+ for (const f of result.findings) {
107
+ findings.push({
108
+ guard: name,
109
+ file: f.file,
110
+ line: f.line,
111
+ message: f.message,
112
+ });
113
+ }
114
+ }
115
+ return { ok: findings.length === 0, findings, guardsRun: names };
116
+ }
117
+ /** Pure escalation rule shared by the CLI (`--strict`) and the `build`
118
+ * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor
119
+ * findings never fail anything on their own — only `strict` or
120
+ * `failOnBuild` turn findings into a hard failure. */
121
+ export function shouldFailBuild(hasFindings, opts) {
122
+ return hasFindings && Boolean(opts.strict || opts.failOnBuild);
123
+ }
124
+ const defaultIo = {
125
+ log: (message) => console.log(message),
126
+ err: (message) => console.error(message),
127
+ };
128
+ function formatDoctorHuman(report, root) {
129
+ const lines = [];
130
+ lines.push(`agent-native doctor: ${root}`);
131
+ lines.push(`Guards run: ${report.guardsRun.join(", ") || "(none)"}`);
132
+ if (report.findings.length === 0) {
133
+ lines.push("Clean — no findings.");
134
+ }
135
+ else {
136
+ lines.push(`${report.findings.length} finding(s):`);
137
+ for (const f of report.findings) {
138
+ lines.push(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);
139
+ }
140
+ }
141
+ return lines.join("\n");
142
+ }
143
+ export function parseDoctorArgs(argv) {
144
+ const opts = {};
145
+ for (let i = 0; i < argv.length; i++) {
146
+ const arg = argv[i];
147
+ if (arg === "--help" || arg === "-h") {
148
+ opts.help = true;
149
+ }
150
+ else if (arg === "--json") {
151
+ opts.json = true;
152
+ }
153
+ else if (arg === "--strict") {
154
+ opts.strict = true;
155
+ }
156
+ else if (arg === "--fix") {
157
+ opts.fix = true;
158
+ }
159
+ else if (arg === "--cwd" && argv[i + 1] !== undefined) {
160
+ opts.cwd = argv[++i];
161
+ }
162
+ else if (arg.startsWith("--cwd=")) {
163
+ opts.cwd = arg.slice("--cwd=".length);
164
+ }
165
+ else if (arg === "--only" && argv[i + 1] !== undefined) {
166
+ opts.only = splitGuardList(argv[++i]);
167
+ }
168
+ else if (arg.startsWith("--only=")) {
169
+ opts.only = splitGuardList(arg.slice("--only=".length));
170
+ }
171
+ }
172
+ return opts;
173
+ }
174
+ function splitGuardList(value) {
175
+ return value
176
+ .split(",")
177
+ .map((s) => s.trim())
178
+ .filter((s) => s.length > 0);
179
+ }
180
+ export function printDoctorHelp(io = defaultIo) {
181
+ io.log([
182
+ "Usage:",
183
+ " agent-native doctor Scan app source for security-critical guard violations",
184
+ " agent-native doctor --json Machine-readable report: { ok, findings, guardsRun }",
185
+ " agent-native doctor --only <guard,guard> Run only the named guard(s)",
186
+ " agent-native doctor --strict Escalate findings to a hard failure when used by `agent-native build --strict`",
187
+ " agent-native doctor --cwd <dir> Run against a project root other than the current directory",
188
+ " agent-native doctor --fix Not implemented in this version",
189
+ " agent-native doctor --help Show this help",
190
+ "",
191
+ `Guards: ${ALL_GUARD_NAMES.join(", ")}`,
192
+ "",
193
+ "Exit codes: 0 clean, 1 findings present, 2 usage/execution error.",
194
+ "",
195
+ "`agent-native build` runs doctor as a warn-only pre-step by default — it",
196
+ "never fails the build unless `agent-native build --strict` is passed or",
197
+ 'agent-native.json sets { "doctor": { "failOnBuild": true } }.',
198
+ "",
199
+ "For dependency-pin health (framework overrides/patches, stale",
200
+ "@agent-native/* pins), run `agent-native upgrade check` instead.",
201
+ ].join("\n"));
202
+ }
203
+ /** `agent-native doctor` CLI entrypoint. Returns the process exit code —
204
+ * callers are responsible for calling `process.exit(code)`. */
205
+ export async function runDoctor(argv, io = defaultIo) {
206
+ const opts = parseDoctorArgs(argv);
207
+ if (opts.help) {
208
+ printDoctorHelp(io);
209
+ return 0;
210
+ }
211
+ if (opts.fix) {
212
+ io.err("agent-native doctor --fix is not implemented in this version. Fix findings manually and re-run `agent-native doctor`.");
213
+ return 2;
214
+ }
215
+ const root = path.resolve(opts.cwd ?? process.cwd());
216
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
217
+ const message = `--cwd path does not exist or is not a directory: ${root}`;
218
+ if (opts.json)
219
+ io.err(JSON.stringify({ ok: false, message }, null, 2));
220
+ else
221
+ io.err(message);
222
+ return 2;
223
+ }
224
+ if (opts.only) {
225
+ const unknown = opts.only.filter((n) => !ALL_GUARD_NAMES.includes(n));
226
+ if (unknown.length > 0) {
227
+ const message = `Unknown guard name(s) in --only: ${unknown.join(", ")}. Known guards: ${ALL_GUARD_NAMES.join(", ")}`;
228
+ if (opts.json)
229
+ io.err(JSON.stringify({ ok: false, message }, null, 2));
230
+ else
231
+ io.err(message);
232
+ return 2;
233
+ }
234
+ }
235
+ const report = runDoctorScan({ root, only: opts.only });
236
+ if (opts.json) {
237
+ const sink = report.ok ? io.log : io.err;
238
+ sink(JSON.stringify({ ...report, strict: Boolean(opts.strict) }, null, 2));
239
+ }
240
+ else {
241
+ io.log(formatDoctorHuman(report, root));
242
+ if (!report.ok) {
243
+ io.err("");
244
+ io.err("agent-native doctor found issues above. Fix them, or add a `// guard:allow-<check> — reason` opt-out with reviewer approval.");
245
+ }
246
+ }
247
+ return report.ok ? 0 : 1;
248
+ }
249
+ /**
250
+ * `agent-native build`'s doctor pre-step. Always runs every enabled guard
251
+ * and always prints findings (as warnings) to `io.err` — never silent.
252
+ * Never causes the build to fail unless `strict` was passed or
253
+ * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,
254
+ * "Where it runs" — the v1 doctor has zero field mileage against arbitrary
255
+ * app layouts, so shipping fail-by-default would risk breaking a first
256
+ * deploy on a false positive).
257
+ */
258
+ export async function runDoctorBuildHook(options, io = defaultIo) {
259
+ const root = path.resolve(options.cwd);
260
+ const config = readDoctorConfig(root);
261
+ const report = runDoctorScan({ root });
262
+ if (report.findings.length > 0) {
263
+ 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.`);
264
+ for (const f of report.findings) {
265
+ io.err(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);
266
+ }
267
+ }
268
+ const fail = shouldFailBuild(report.findings.length > 0, {
269
+ strict: options.strict,
270
+ failOnBuild: config.failOnBuild,
271
+ });
272
+ if (fail) {
273
+ io.err(`\n[doctor] Failing build: ${options.strict ? "--strict was passed" : "agent-native.json's doctor.failOnBuild is true"}.`);
274
+ }
275
+ return { ok: !fail, report };
276
+ }
277
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `agent-native doctor` — scan an app's source tree for the security-\n * critical code-safety invariants this monorepo already enforces on\n * itself via `scripts/guard-*.mjs` (see\n * `advisor-plans/reports/005-doctor-design.md` for the full design and\n * `advisor-plans/015-doctor-v1-implementation.md` for the implementation\n * plan). v1 ships 7 of those guards, ported to work against a single\n * generated app root instead of this monorepo's multi-template layout —\n * see `../guards/index.ts`.\n *\n * This is a NEW top-level command, deliberately kept separate from the two\n * existing \"doctor\" precedents in this CLI:\n * - `agent-native upgrade check` (`upgrade.ts`) — dependency-pin health.\n * - `agent-native recap doctor` (`recap.ts`) — PR Visual Recap config health.\n * Each diagnoses a different domain; none are folded into a shared\n * mega-doctor (see report 005, \"Relationship to upgrade doctor and recap\n * doctor\").\n *\n * `--fix` is reserved, not implemented in v1 — it prints a message and\n * exits 2 rather than silently no-op, so a future implementation doesn't\n * collide with a script already passing the flag.\n */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n scanDbToolScoping,\n scanDrizzlePush,\n scanEnvCredentials,\n scanEnvMutation,\n scanLocalhostFallback,\n scanUnscopedCredentials,\n scanUnscopedQueries,\n} from \"../guards/index.js\";\nimport type { GuardResult } from \"../guards/index.js\";\n\nexport type GuardName =\n | \"no-drizzle-push\"\n | \"no-unscoped-credentials\"\n | \"no-unscoped-queries\"\n | \"no-env-credentials\"\n | \"db-tool-scoping\"\n | \"no-env-mutation\"\n | \"no-localhost-fallback\";\n\nexport const ALL_GUARD_NAMES: GuardName[] = [\n \"no-drizzle-push\",\n \"no-unscoped-credentials\",\n \"no-unscoped-queries\",\n \"no-env-credentials\",\n \"db-tool-scoping\",\n \"no-env-mutation\",\n \"no-localhost-fallback\",\n];\n\nexport interface DoctorConfig {\n disabledGuards: string[];\n dbToolScopingDenylist: Record<string, string>;\n failOnBuild: boolean;\n}\n\nconst DEFAULT_DOCTOR_CONFIG: DoctorConfig = {\n disabledGuards: [],\n dbToolScopingDenylist: {},\n failOnBuild: false,\n};\n\nexport interface DoctorFinding {\n guard: string;\n file: string;\n line: number;\n message: string;\n}\n\nexport interface DoctorReport {\n ok: boolean;\n findings: DoctorFinding[];\n guardsRun: string[];\n}\n\n/**\n * Reads the optional `\"doctor\"` key from `<root>/agent-native.json`. All\n * fields are optional with sane empty defaults — an app needs zero config\n * to run `agent-native doctor` with every v1 guard enabled.\n */\nexport function readDoctorConfig(root: string): DoctorConfig {\n const manifestPath = path.join(root, \"agent-native.json\");\n if (!fs.existsSync(manifestPath)) {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n try {\n const raw = fs.readFileSync(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { doctor?: Record<string, unknown> };\n const doctor = parsed.doctor ?? {};\n const disabledGuards = Array.isArray(doctor.disabledGuards)\n ? doctor.disabledGuards.filter((v): v is string => typeof v === \"string\")\n : [];\n const dbToolScopingDenylist =\n doctor.dbToolScopingDenylist &&\n typeof doctor.dbToolScopingDenylist === \"object\"\n ? (Object.fromEntries(\n Object.entries(\n doctor.dbToolScopingDenylist as Record<string, unknown>,\n ).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === \"string\",\n ),\n ) as Record<string, string>)\n : {};\n const failOnBuild = doctor.failOnBuild === true;\n return { disabledGuards, dbToolScopingDenylist, failOnBuild };\n } catch {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n}\n\nfunction runGuard(\n name: GuardName,\n root: string,\n config: DoctorConfig,\n): GuardResult {\n switch (name) {\n case \"no-drizzle-push\":\n return scanDrizzlePush({ root });\n case \"no-unscoped-credentials\":\n return scanUnscopedCredentials({ root });\n case \"no-unscoped-queries\":\n return scanUnscopedQueries({ root, extraExemptPaths: [] });\n case \"no-env-credentials\":\n return scanEnvCredentials({ root });\n case \"db-tool-scoping\":\n return scanDbToolScoping({\n root,\n denylist: config.dbToolScopingDenylist,\n });\n case \"no-env-mutation\":\n return scanEnvMutation({ root });\n case \"no-localhost-fallback\":\n return scanLocalhostFallback({ root, extraExemptPaths: [] });\n }\n}\n\nexport interface RunDoctorScanOptions {\n root: string;\n /** Restrict to these guard names. When omitted, runs every guard not\n * listed in `agent-native.json`'s `doctor.disabledGuards`. Unknown names\n * are silently ignored here — the CLI layer (`runDoctor`) validates\n * `--only` and reports a usage error before calling this. */\n only?: string[];\n}\n\n/** Pure scan orchestrator: runs the selected guards against `root` and\n * returns a flat report. No I/O beyond reading `agent-native.json` and the\n * app source tree — no printing, no process.exit. */\nexport function runDoctorScan(options: RunDoctorScanOptions): DoctorReport {\n const root = options.root;\n const config = readDoctorConfig(root);\n\n let names: GuardName[];\n if (options.only && options.only.length > 0) {\n const knownOnly = options.only.filter((n): n is GuardName =>\n (ALL_GUARD_NAMES as string[]).includes(n),\n );\n names = knownOnly;\n } else {\n names = ALL_GUARD_NAMES.filter((n) => !config.disabledGuards.includes(n));\n }\n\n const findings: DoctorFinding[] = [];\n for (const name of names) {\n const result = runGuard(name, root, config);\n for (const f of result.findings) {\n findings.push({\n guard: name,\n file: f.file,\n line: f.line,\n message: f.message,\n });\n }\n }\n\n return { ok: findings.length === 0, findings, guardsRun: names };\n}\n\n/** Pure escalation rule shared by the CLI (`--strict`) and the `build`\n * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor\n * findings never fail anything on their own — only `strict` or\n * `failOnBuild` turn findings into a hard failure. */\nexport function shouldFailBuild(\n hasFindings: boolean,\n opts: { strict?: boolean; failOnBuild?: boolean },\n): boolean {\n return hasFindings && Boolean(opts.strict || opts.failOnBuild);\n}\n\nexport interface DoctorIo {\n log: (message: string) => void;\n err: (message: string) => void;\n}\n\nconst defaultIo: DoctorIo = {\n log: (message) => console.log(message),\n err: (message) => console.error(message),\n};\n\nfunction formatDoctorHuman(report: DoctorReport, root: string): string {\n const lines: string[] = [];\n lines.push(`agent-native doctor: ${root}`);\n lines.push(`Guards run: ${report.guardsRun.join(\", \") || \"(none)\"}`);\n if (report.findings.length === 0) {\n lines.push(\"Clean — no findings.\");\n } else {\n lines.push(`${report.findings.length} finding(s):`);\n for (const f of report.findings) {\n lines.push(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nexport interface DoctorCliOptions {\n json?: boolean;\n cwd?: string;\n only?: string[];\n strict?: boolean;\n help?: boolean;\n fix?: boolean;\n}\n\nexport function parseDoctorArgs(argv: string[]): DoctorCliOptions {\n const opts: DoctorCliOptions = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--help\" || arg === \"-h\") {\n opts.help = true;\n } else if (arg === \"--json\") {\n opts.json = true;\n } else if (arg === \"--strict\") {\n opts.strict = true;\n } else if (arg === \"--fix\") {\n opts.fix = true;\n } else if (arg === \"--cwd\" && argv[i + 1] !== undefined) {\n opts.cwd = argv[++i];\n } else if (arg.startsWith(\"--cwd=\")) {\n opts.cwd = arg.slice(\"--cwd=\".length);\n } else if (arg === \"--only\" && argv[i + 1] !== undefined) {\n opts.only = splitGuardList(argv[++i]);\n } else if (arg.startsWith(\"--only=\")) {\n opts.only = splitGuardList(arg.slice(\"--only=\".length));\n }\n }\n return opts;\n}\n\nfunction splitGuardList(value: string): string[] {\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nexport function printDoctorHelp(io: Pick<DoctorIo, \"log\"> = defaultIo): void {\n io.log(\n [\n \"Usage:\",\n \" agent-native doctor Scan app source for security-critical guard violations\",\n \" agent-native doctor --json Machine-readable report: { ok, findings, guardsRun }\",\n \" agent-native doctor --only <guard,guard> Run only the named guard(s)\",\n \" agent-native doctor --strict Escalate findings to a hard failure when used by `agent-native build --strict`\",\n \" agent-native doctor --cwd <dir> Run against a project root other than the current directory\",\n \" agent-native doctor --fix Not implemented in this version\",\n \" agent-native doctor --help Show this help\",\n \"\",\n `Guards: ${ALL_GUARD_NAMES.join(\", \")}`,\n \"\",\n \"Exit codes: 0 clean, 1 findings present, 2 usage/execution error.\",\n \"\",\n \"`agent-native build` runs doctor as a warn-only pre-step by default — it\",\n \"never fails the build unless `agent-native build --strict` is passed or\",\n 'agent-native.json sets { \"doctor\": { \"failOnBuild\": true } }.',\n \"\",\n \"For dependency-pin health (framework overrides/patches, stale\",\n \"@agent-native/* pins), run `agent-native upgrade check` instead.\",\n ].join(\"\\n\"),\n );\n}\n\n/** `agent-native doctor` CLI entrypoint. Returns the process exit code —\n * callers are responsible for calling `process.exit(code)`. */\nexport async function runDoctor(\n argv: string[],\n io: DoctorIo = defaultIo,\n): Promise<number> {\n const opts = parseDoctorArgs(argv);\n\n if (opts.help) {\n printDoctorHelp(io);\n return 0;\n }\n\n if (opts.fix) {\n io.err(\n \"agent-native doctor --fix is not implemented in this version. Fix findings manually and re-run `agent-native doctor`.\",\n );\n return 2;\n }\n\n const root = path.resolve(opts.cwd ?? process.cwd());\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n const message = `--cwd path does not exist or is not a directory: ${root}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n\n if (opts.only) {\n const unknown = opts.only.filter(\n (n) => !(ALL_GUARD_NAMES as string[]).includes(n),\n );\n if (unknown.length > 0) {\n const message = `Unknown guard name(s) in --only: ${unknown.join(\", \")}. Known guards: ${ALL_GUARD_NAMES.join(\", \")}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n }\n\n const report = runDoctorScan({ root, only: opts.only });\n\n if (opts.json) {\n const sink = report.ok ? io.log : io.err;\n sink(JSON.stringify({ ...report, strict: Boolean(opts.strict) }, null, 2));\n } else {\n io.log(formatDoctorHuman(report, root));\n if (!report.ok) {\n io.err(\"\");\n io.err(\n \"agent-native doctor found issues above. Fix them, or add a `// guard:allow-<check> — reason` opt-out with reviewer approval.\",\n );\n }\n }\n\n return report.ok ? 0 : 1;\n}\n\nexport interface DoctorBuildHookOptions {\n cwd: string;\n /** Set when the caller passed `agent-native build --strict`. */\n strict?: boolean;\n}\n\nexport interface DoctorBuildHookResult {\n /** False only when findings are present AND (`strict` was requested OR\n * `agent-native.json`'s `doctor.failOnBuild` is true). */\n ok: boolean;\n report: DoctorReport;\n}\n\n/**\n * `agent-native build`'s doctor pre-step. Always runs every enabled guard\n * and always prints findings (as warnings) to `io.err` — never silent.\n * Never causes the build to fail unless `strict` was passed or\n * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,\n * \"Where it runs\" — the v1 doctor has zero field mileage against arbitrary\n * app layouts, so shipping fail-by-default would risk breaking a first\n * deploy on a false positive).\n */\nexport async function runDoctorBuildHook(\n options: DoctorBuildHookOptions,\n io: DoctorIo = defaultIo,\n): Promise<DoctorBuildHookResult> {\n const root = path.resolve(options.cwd);\n const config = readDoctorConfig(root);\n const report = runDoctorScan({ root });\n\n if (report.findings.length > 0) {\n io.err(\n `\\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.`,\n );\n for (const f of report.findings) {\n io.err(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n\n const fail = shouldFailBuild(report.findings.length > 0, {\n strict: options.strict,\n failOnBuild: config.failOnBuild,\n });\n if (fail) {\n io.err(\n `\\n[doctor] Failing build: ${options.strict ? \"--strict was passed\" : \"agent-native.json's doctor.failOnBuild is true\"}.`,\n );\n }\n\n return { ok: !fail, report };\n}\n"]}
package/dist/cli/index.js CHANGED
@@ -491,6 +491,25 @@ switch (command) {
491
491
  // child exits non-zero, runBuildStep calls process.exit itself; the
492
492
  // continuation only runs on success.
493
493
  (async () => {
494
+ // Doctor pre-step: scans app source for the security-critical guard
495
+ // invariants (see `agent-native doctor --help`). Warn-only by
496
+ // default — prints findings to stderr and always continues. Only
497
+ // fails the build when `agent-native build --strict` was passed or
498
+ // `agent-native.json` sets `{ "doctor": { "failOnBuild": true } }`.
499
+ try {
500
+ const { runDoctorBuildHook } = await import("./doctor.js");
501
+ const hook = await runDoctorBuildHook({
502
+ cwd: process.cwd(),
503
+ strict: args.includes("--strict"),
504
+ });
505
+ if (!hook.ok) {
506
+ console.error("\nBuild aborted by `agent-native doctor` (see findings above).");
507
+ process.exit(1);
508
+ }
509
+ }
510
+ catch (err) {
511
+ console.warn(`[doctor] pre-build scan failed to run (continuing): ${err instanceof Error ? err.message : String(err)}`);
512
+ }
494
513
  if (isReactRouterFramework()) {
495
514
  validateReactRouterBuildDependencies();
496
515
  const rr = findReactRouterBin();
@@ -660,6 +679,21 @@ switch (command) {
660
679
  });
661
680
  break;
662
681
  }
682
+ case "doctor": {
683
+ // Scan app source for security-critical guard invariants (see
684
+ // `agent-native doctor --help`). For dependency-pin health, see
685
+ // `agent-native upgrade check` instead.
686
+ import("./doctor.js")
687
+ .then(async (m) => {
688
+ const code = await m.runDoctor(args);
689
+ process.exit(code);
690
+ })
691
+ .catch((err) => {
692
+ console.error(err?.message ?? err);
693
+ process.exit(1);
694
+ });
695
+ break;
696
+ }
663
697
  case "code": {
664
698
  import("./code.js")
665
699
  .then((m) => m.runCode(args))
@@ -838,6 +872,18 @@ switch (command) {
838
872
  });
839
873
  break;
840
874
  }
875
+ case "package": {
876
+ import("./package-lifecycle.js")
877
+ .then(async (m) => {
878
+ const code = await m.runPackageLifecycle(args);
879
+ process.exit(code);
880
+ })
881
+ .catch((err) => {
882
+ console.error(err?.message ?? err);
883
+ process.exit(1);
884
+ });
885
+ break;
886
+ }
841
887
  case "audit-agent-web": {
842
888
  import("./audit-agent-web.js")
843
889
  .then((m) => m.runAuditAgentWeb(args))
@@ -962,6 +1008,10 @@ Usage:
962
1008
  Pass a URL instead of a name for a generic
963
1009
  research-and-integrate blueprint. --list to
964
1010
  browse available blueprints.
1011
+ agent-native package <cmd> <package>
1012
+ Manifest package lifecycle: inspect | add | eject.
1013
+ add/eject are dry-run unless --apply; --json emits
1014
+ a machine-readable compatibility/change report.
965
1015
  agent-native changelog <cmd> Author the app's user-facing changelog.
966
1016
  cmds: add "<summary>" [--type added|fixed|...] |
967
1017
  release | list. Pending entries live in