@agent-native/core 0.146.8 → 0.148.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 (317) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
  3. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -6
  4. package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  5. package/corpus/templates/analytics/DEVELOPING.md +50 -3
  6. package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
  7. package/corpus/templates/analytics/app/i18n/index.ts +14 -29
  8. package/corpus/templates/analytics/app/i18n-data.ts +10 -10
  9. package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
  10. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
  11. package/corpus/templates/analytics/app/routes/status.$slug.tsx +4 -2
  12. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +253 -24
  13. package/corpus/templates/analytics/server/db/schema.ts +23 -0
  14. package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
  15. package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
  16. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
  17. package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
  18. package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
  20. package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
  21. package/corpus/templates/analytics/server/plugins/db.ts +42 -0
  22. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
  23. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -6
  24. package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  25. package/corpus/templates/assets/app/i18n/index.ts +14 -29
  26. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +9 -0
  27. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
  28. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -6
  29. package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  30. package/corpus/templates/brain/app/i18n/index.ts +14 -29
  31. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
  32. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -6
  33. package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  34. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  35. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  36. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  37. package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  38. package/corpus/templates/chat/app/i18n/index.ts +14 -29
  39. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
  40. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -6
  41. package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  42. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
  43. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
  44. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
  45. package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
  46. package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
  47. package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
  48. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +16 -4
  49. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +14 -5
  50. package/corpus/templates/clips/desktop/src/app.tsx +1 -1
  51. package/corpus/templates/clips/package.json +1 -0
  52. package/corpus/templates/clips/react-router.config.ts +7 -0
  53. package/corpus/templates/clips/server/plugins/auth.ts +6 -1
  54. package/corpus/templates/clips/shared/prerendered-public-paths.ts +21 -0
  55. package/corpus/templates/clips/shared/share-meta.ts +8 -3
  56. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
  57. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -6
  58. package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  59. package/corpus/templates/content/app/i18n/index.ts +14 -29
  60. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -6
  61. package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  62. package/corpus/templates/crm/app/i18n/index.ts +14 -29
  63. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
  64. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -6
  65. package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  66. package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
  67. package/corpus/templates/design/actions/import-code.ts +2 -43
  68. package/corpus/templates/design/app/i18n/index.ts +14 -29
  69. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
  70. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -6
  71. package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  72. package/corpus/templates/dispatch/app/chat-first-pages.ts +747 -0
  73. package/corpus/templates/dispatch/app/i18n-data.ts +182 -1
  74. package/corpus/templates/dispatch/app/routes/settings.tsx +62 -1
  75. package/corpus/templates/dispatch/changelog/2026-08-08-chat-first-navigation-keeps-conversations-central-while-open.md +6 -0
  76. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +9 -0
  77. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
  78. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -6
  79. package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  80. package/corpus/templates/factory/AGENTS.md +40 -49
  81. package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
  82. package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
  83. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
  84. package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
  85. package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
  86. package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
  87. package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
  88. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  89. package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
  90. package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
  91. package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
  92. package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
  93. package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
  94. package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
  95. package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
  96. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
  97. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
  98. package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
  99. package/corpus/templates/factory/app/routes/factory.tsx +203 -118
  100. package/corpus/templates/factory/changelog/2026-08-08-scheduler-health-moves-to-settings.md +6 -0
  101. package/corpus/templates/factory/server/db/schema.ts +37 -0
  102. package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
  103. package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
  104. package/corpus/templates/factory/server/triage/audit.ts +79 -0
  105. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
  106. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -6
  107. package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  108. package/corpus/templates/forms/app/i18n/index.ts +14 -29
  109. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
  110. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -6
  111. package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  112. package/corpus/templates/macros/app/i18n/index.ts +14 -29
  113. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
  114. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -6
  115. package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  116. package/corpus/templates/mail/app/i18n/index.ts +14 -29
  117. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +9 -0
  118. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
  119. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -6
  120. package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  121. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
  122. package/corpus/templates/plan/app/i18n/index.ts +14 -29
  123. package/corpus/templates/plan/app/lib/plan-document-title.ts +3 -1
  124. package/corpus/templates/plan/app/root.tsx +1 -0
  125. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
  126. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -6
  127. package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  128. package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
  129. package/corpus/templates/slides/actions/import-code.ts +2 -43
  130. package/corpus/templates/slides/app/i18n/index.ts +14 -29
  131. package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
  132. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +9 -0
  133. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
  134. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -6
  135. package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  136. package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
  137. package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
  138. package/corpus/templates/tasks/app/i18n/index.ts +14 -29
  139. package/dist/agent/engine/ai-sdk-engine.js +2 -1
  140. package/dist/agent/engine/builder-engine.d.ts +11 -1
  141. package/dist/agent/engine/builder-engine.js +11 -4
  142. package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
  143. package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
  144. package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
  145. package/dist/agent/engine/provider-endpoint-validation.js +26 -0
  146. package/dist/agent/engine/provider-env-vars.d.ts +1 -1
  147. package/dist/agent/engine/provider-env-vars.js +1 -1
  148. package/dist/agent/engine/registry.d.ts +8 -6
  149. package/dist/agent/engine/registry.js +37 -24
  150. package/dist/agent/tool-search.d.ts +1 -0
  151. package/dist/agent/tool-search.js +17 -1
  152. package/dist/automations/service.js +4 -10
  153. package/dist/brand-kit/brand-signals.d.ts +13 -0
  154. package/dist/brand-kit/brand-signals.js +15 -0
  155. package/dist/brand-kit/index.d.ts +2 -2
  156. package/dist/brand-kit/index.js +1 -1
  157. package/dist/chat-threads/store.d.ts +2 -0
  158. package/dist/chat-threads/store.js +1 -1
  159. package/dist/cli/agent-plugin.d.ts +5 -2
  160. package/dist/cli/agent-plugin.js +17 -9
  161. package/dist/cli/code-agent-executor.js +25 -5
  162. package/dist/cli/code-agent-mcp-config.d.ts +21 -0
  163. package/dist/cli/code-agent-mcp-config.js +103 -0
  164. package/dist/cli/plan-blocks.d.ts +3 -18
  165. package/dist/cli/plan-blocks.js +2 -95
  166. package/dist/cli/plan-publish-store.d.ts +2 -61
  167. package/dist/cli/plan-publish-store.js +2 -127
  168. package/dist/cli/skills-content/connection.d.ts +1 -1
  169. package/dist/cli/skills-content/connection.js +1 -52
  170. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  171. package/dist/cli/skills-content/visual-recap-skill.js +1 -553
  172. package/dist/client/NewWorkspaceAppFlow.js +4 -1
  173. package/dist/client/agent-chat/index.d.ts +4 -1
  174. package/dist/client/agent-chat/index.js +4 -1
  175. package/dist/client/agent-engine-key.d.ts +14 -4
  176. package/dist/client/agent-engine-key.js +51 -5
  177. package/dist/client/agent-page/AgentTabsPage.d.ts +1 -0
  178. package/dist/client/agent-page/AgentTabsPage.js +4 -3
  179. package/dist/client/agent-provider-catalog.d.ts +20 -0
  180. package/dist/client/agent-provider-catalog.js +100 -0
  181. package/dist/client/app-providers.d.ts +3 -1
  182. package/dist/client/app-providers.js +50 -5
  183. package/dist/client/blocks/index.d.ts +1 -0
  184. package/dist/client/blocks/index.js +1 -0
  185. package/dist/client/chat/run-recovery.js +4 -48
  186. package/dist/client/chat/runtime.js +63 -0
  187. package/dist/client/chat-first/agents-pane.d.ts +2 -0
  188. package/dist/client/chat-first/agents-pane.js +6 -0
  189. package/dist/client/chat-first/app-pane.d.ts +2 -0
  190. package/dist/client/chat-first/app-pane.js +6 -0
  191. package/dist/client/chat-first/apps-rail.d.ts +2 -0
  192. package/dist/client/chat-first/apps-rail.js +103 -0
  193. package/dist/client/chat-first/browser-pane.d.ts +2 -0
  194. package/dist/client/chat-first/browser-pane.js +64 -0
  195. package/dist/client/chat-first/chat-history.d.ts +12 -0
  196. package/dist/client/chat-first/chat-history.js +10 -0
  197. package/dist/client/chat-first/copy.d.ts +2 -0
  198. package/dist/client/chat-first/copy.js +117 -0
  199. package/dist/client/chat-first/index.d.ts +13 -0
  200. package/dist/client/chat-first/index.js +12 -0
  201. package/dist/client/chat-first/primary-nav.d.ts +8 -0
  202. package/dist/client/chat-first/primary-nav.js +6 -0
  203. package/dist/client/chat-first/session-watch-pane.d.ts +2 -0
  204. package/dist/client/chat-first/session-watch-pane.js +9 -0
  205. package/dist/client/chat-first/surface-panel.d.ts +9 -0
  206. package/dist/client/chat-first/surface-panel.js +9 -0
  207. package/dist/client/chat-first/surface-tabs.d.ts +9 -0
  208. package/dist/client/chat-first/surface-tabs.js +74 -0
  209. package/dist/client/chat-first/types.d.ts +74 -0
  210. package/dist/client/chat-first/types.js +1 -0
  211. package/dist/client/chat-first-agent-activity.d.ts +11 -0
  212. package/dist/client/chat-first-agent-activity.js +51 -0
  213. package/dist/client/chat-first-surface-panel-toggle.d.ts +5 -0
  214. package/dist/client/chat-first-surface-panel-toggle.js +6 -0
  215. package/dist/client/chat-first.d.ts +208 -0
  216. package/dist/client/chat-first.js +817 -0
  217. package/dist/client/extensions/ExtensionViewer.js +8 -1
  218. package/dist/client/i18n.d.ts +14 -0
  219. package/dist/client/i18n.js +18 -0
  220. package/dist/client/resources/McpIntegrationDialog.js +3 -2
  221. package/dist/client/resources/McpServerDetail.js +6 -11
  222. package/dist/client/resources/index.d.ts +1 -0
  223. package/dist/client/resources/index.js +1 -0
  224. package/dist/client/resources/use-mcp-servers.d.ts +20 -0
  225. package/dist/client/resources/use-mcp-servers.js +82 -46
  226. package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
  227. package/dist/client/settings/ProviderSetupForm.js +145 -0
  228. package/dist/client/settings/SettingsPanel.js +52 -49
  229. package/dist/client/settings/index.d.ts +3 -0
  230. package/dist/client/settings/index.js +3 -0
  231. package/dist/coding-tools/run-code.d.ts +5 -0
  232. package/dist/coding-tools/run-code.js +196 -36
  233. package/dist/coding-tools/tool-orchestration.d.ts +10 -0
  234. package/dist/coding-tools/tool-orchestration.js +107 -0
  235. package/dist/collab/routes.d.ts +1 -1
  236. package/dist/collab/struct-routes.d.ts +1 -1
  237. package/dist/jobs/background-automation-runner.js +19 -2
  238. package/dist/jobs/frontmatter.d.ts +9 -0
  239. package/dist/jobs/frontmatter.js +16 -0
  240. package/dist/jobs/scheduler-health.d.ts +20 -0
  241. package/dist/jobs/scheduler-health.js +86 -1
  242. package/dist/jobs/scheduler.js +46 -9
  243. package/dist/jobs/tools.d.ts +1 -1
  244. package/dist/jobs/tools.js +2 -7
  245. package/dist/localization/default-messages.d.ts +20 -0
  246. package/dist/localization/default-messages.js +25 -5
  247. package/dist/mcp-client/routes.d.ts +3 -0
  248. package/dist/mcp-client/routes.js +14 -0
  249. package/dist/notifications/routes.d.ts +1 -1
  250. package/dist/observability/routes.d.ts +3 -3
  251. package/dist/onboarding/app-profile.js +1 -1
  252. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  253. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  254. package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
  255. package/dist/secrets/routes.d.ts +6 -6
  256. package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
  257. package/dist/server/agent-chat/run-code-tools.js +3 -1
  258. package/dist/server/agent-chat-plugin.js +6 -6
  259. package/dist/server/agent-engine-api-key-route.js +43 -12
  260. package/dist/server/agents-bundle.d.ts +2 -0
  261. package/dist/server/agents-bundle.js +32 -2
  262. package/dist/server/auth.js +21 -5
  263. package/dist/server/credential-provider.d.ts +8 -2
  264. package/dist/server/credential-provider.js +14 -9
  265. package/dist/server/design-token-utils.d.ts +18 -0
  266. package/dist/server/design-token-utils.js +31 -0
  267. package/dist/server/onboarding-html.js +22 -2
  268. package/dist/server/transcribe-voice.d.ts +1 -1
  269. package/dist/shared/chat-first-app-creation.d.ts +19 -0
  270. package/dist/shared/chat-first-app-creation.js +75 -0
  271. package/dist/shared/document-title.d.ts +7 -0
  272. package/dist/shared/document-title.js +29 -0
  273. package/dist/shared/index.d.ts +2 -0
  274. package/dist/shared/index.js +2 -0
  275. package/dist/styles/chat-history-list.css +16 -0
  276. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  277. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  278. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  279. package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  280. package/dist/templates/chat/app/i18n/index.ts +14 -29
  281. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
  282. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
  283. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
  284. package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  285. package/dist/templates/default/app/i18n/index.ts +14 -29
  286. package/dist/templates/default/react-router.config.ts +18 -0
  287. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
  288. package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  289. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
  290. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
  291. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
  292. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
  293. package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  294. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
  295. package/dist/triggers/dispatcher.js +1 -8
  296. package/docs/content/environment-variables.mdx +39 -38
  297. package/package.json +5 -4
  298. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  299. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  300. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  301. package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  302. package/src/templates/chat/app/i18n/index.ts +14 -29
  303. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
  304. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
  305. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
  306. package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  307. package/src/templates/default/app/i18n/index.ts +14 -29
  308. package/src/templates/default/react-router.config.ts +18 -0
  309. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
  310. package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  311. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
  312. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
  313. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
  314. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
  315. package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  316. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
  317. package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
@@ -13,6 +13,7 @@ import {
13
13
  requireWorkspaceMember,
14
14
  workspaceMemberIdentityFromContext,
15
15
  } from "../server/lib/require-workspace-member.js";
16
+ import { recordFactoryAudit } from "../server/triage/audit.js";
16
17
 
17
18
  export default defineAction({
18
19
  description:
@@ -21,7 +22,7 @@ export default defineAction({
21
22
  http: { method: "GET" },
22
23
  readOnly: true,
23
24
  run: async ({ itemId }, context) => {
24
- const { orgId } = await requireWorkspaceMember(
25
+ const { userEmail, orgId } = await requireWorkspaceMember(
25
26
  workspaceMemberIdentityFromContext(context),
26
27
  );
27
28
  const db = getDb();
@@ -55,6 +56,28 @@ export default defineAction({
55
56
  .where(and(eq(triageRuns.itemId, itemId), eq(triageRuns.orgId, orgId)))
56
57
  .orderBy(asc(triageRuns.startedAt));
57
58
 
59
+ const matchingFeedback = feedback.filter((entry) =>
60
+ decisions.some((decision) => decision.id === entry.decisionId),
61
+ );
62
+ await recordFactoryAudit(
63
+ context,
64
+ { userEmail, orgId },
65
+ {
66
+ action: "get-triage-item",
67
+ kind: "read",
68
+ itemId,
69
+ source: item.source,
70
+ sourceUrl: item.sourceUrl,
71
+ summary: `Inspected ${item.title}`,
72
+ details: {
73
+ decisionCount: decisions.length,
74
+ feedbackCount: matchingFeedback.length,
75
+ runCount: runs.length,
76
+ coverage: item.coverage,
77
+ },
78
+ },
79
+ );
80
+
58
81
  return {
59
82
  ...item,
60
83
  decisions: decisions.map((decision) => ({
@@ -65,9 +88,7 @@ export default defineAction({
65
88
  mode: decision.mode,
66
89
  createdAt: decision.createdAt,
67
90
  })),
68
- feedback: feedback.filter((entry) =>
69
- decisions.some((decision) => decision.id === entry.decisionId),
70
- ),
91
+ feedback: matchingFeedback,
71
92
  runs,
72
93
  };
73
94
  },
@@ -16,6 +16,7 @@ import {
16
16
  workspaceMemberIdentityFromContext,
17
17
  } from "../server/lib/require-workspace-member.js";
18
18
  import { createAiServicesGitReadClient } from "../server/triage/ai-services-git.js";
19
+ import { recordFactoryAudit } from "../server/triage/audit.js";
19
20
  import { createGitHubClient } from "../server/triage/github-client.js";
20
21
  import { stableId } from "../server/triage/ids.js";
21
22
  import {
@@ -231,6 +232,34 @@ export default defineAction({
231
232
  factoryTriggered,
232
233
  });
233
234
 
235
+ await recordFactoryAudit(
236
+ context,
237
+ { userEmail, orgId },
238
+ {
239
+ action: "govern-agent-native-pull-request",
240
+ kind: "governance",
241
+ status: governance.autoApprove ? "success" : "skipped",
242
+ itemId: itemId ?? null,
243
+ source: "github",
244
+ sourceUrl: pullRequest.htmlUrl,
245
+ summary: governance.reason,
246
+ details: {
247
+ repo,
248
+ pullRequestNumber,
249
+ clearBug,
250
+ productUxImplications,
251
+ internalBuilderMember: internalMember.isMember,
252
+ factoryTriggered,
253
+ checksPassed,
254
+ reviewFeedbackHandled,
255
+ autoApprove: governance.autoApprove,
256
+ autoMerge: governance.autoMerge,
257
+ ownerOwnedArea: governance.ownerOwnedArea ?? null,
258
+ guardResults: governance.guardResults,
259
+ },
260
+ },
261
+ );
262
+
234
263
  if (itemId) {
235
264
  const item = (
236
265
  await getDb()
@@ -338,6 +367,19 @@ export default defineAction({
338
367
  }
339
368
 
340
369
  if (!governance.autoMerge) {
370
+ await recordFactoryAudit(
371
+ context,
372
+ { userEmail, orgId },
373
+ {
374
+ action: "govern-agent-native-pull-request",
375
+ kind: "external_action",
376
+ itemId: itemId ?? null,
377
+ source: "github",
378
+ sourceUrl: approvalUrl,
379
+ summary: "Approved the pull request after governance checks passed.",
380
+ details: { repo, pullRequestNumber, approvalUrl },
381
+ },
382
+ );
341
383
  return {
342
384
  ok: true,
343
385
  action: "approved",
@@ -374,6 +416,19 @@ export default defineAction({
374
416
  })
375
417
  .where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
376
418
  }
419
+ await recordFactoryAudit(
420
+ context,
421
+ { userEmail, orgId },
422
+ {
423
+ action: "govern-agent-native-pull-request",
424
+ kind: "external_action",
425
+ itemId: itemId ?? null,
426
+ source: "github",
427
+ sourceUrl: pullRequest.htmlUrl,
428
+ summary: "Merged the pull request after governance checks passed.",
429
+ details: { repo, pullRequestNumber, approvalUrl, mergeSha: merge.sha },
430
+ },
431
+ );
377
432
  return {
378
433
  ok: true,
379
434
  action: "merged",
@@ -7,6 +7,7 @@ import {
7
7
  requireWorkspaceMember,
8
8
  workspaceMemberIdentityFromContext,
9
9
  } from "../server/lib/require-workspace-member.js";
10
+ import { recordFactoryAudit } from "../server/triage/audit.js";
10
11
  import { pullRequestSnapshotToEnvelope } from "../server/triage/github-ingestion.js";
11
12
  import { itemDedupeKey } from "../server/triage/ids.js";
12
13
  import type {
@@ -90,6 +91,26 @@ export default defineAction({
90
91
  },
91
92
  });
92
93
 
94
+ await recordFactoryAudit(
95
+ context,
96
+ { userEmail, orgId },
97
+ {
98
+ action: "ingest-github-observation",
99
+ kind: "observed",
100
+ itemId: id,
101
+ source: envelope.source,
102
+ sourceUrl: envelope.sourceUrl,
103
+ summary: envelope.title,
104
+ details: {
105
+ repository: envelope.repository,
106
+ pullRequestNumber: envelope.pullRequestNumber,
107
+ coverage: envelope.coverage,
108
+ reviewCount: input.reviews.length,
109
+ checkCount: input.checks.length,
110
+ },
111
+ },
112
+ );
113
+
93
114
  return {
94
115
  ok: true,
95
116
  id,
@@ -0,0 +1,118 @@
1
+ import { defineAction } from "@agent-native/core/action";
2
+ import {
3
+ listAutomationDefinitions,
4
+ listAutomationRuns,
5
+ } from "@agent-native/core/triggers";
6
+ import { and, desc, eq, inArray } from "drizzle-orm";
7
+ import { z } from "zod";
8
+
9
+ import { getDb } from "../server/db/index.js";
10
+ import { factoryAuditEvents } from "../server/db/schema.js";
11
+ import {
12
+ requireWorkspaceMember,
13
+ workspaceMemberIdentityFromContext,
14
+ } from "../server/lib/require-workspace-member.js";
15
+
16
+ export default defineAction({
17
+ description:
18
+ "List recent Factory automation runs with the bounded source observations, decisions, and external actions recorded for each run.",
19
+ agentTool: false,
20
+ schema: z.object({
21
+ factoryId: z.string().trim().min(1).optional(),
22
+ automation: z.string().trim().min(1).optional(),
23
+ limit: z.coerce.number().int().min(1).max(50).default(20),
24
+ }),
25
+ http: { method: "GET" },
26
+ readOnly: true,
27
+ run: async ({ automation, limit }, context) => {
28
+ const { userEmail, orgId } = await requireWorkspaceMember(
29
+ workspaceMemberIdentityFromContext(context),
30
+ );
31
+ const definitions = await listAutomationDefinitions(
32
+ { userEmail, orgId, appId: "factory" },
33
+ "organization",
34
+ );
35
+ const factoryDefinitions = definitions.filter(
36
+ ({ meta, name }) =>
37
+ meta.domain === "factory" && (!automation || name === automation),
38
+ );
39
+ const runGroups = await Promise.all(
40
+ factoryDefinitions.map(async ({ name, resource }) =>
41
+ listAutomationRuns({
42
+ owners: [resource.owner],
43
+ automation: name,
44
+ appId: "factory",
45
+ limit,
46
+ }),
47
+ ),
48
+ );
49
+ const runs = runGroups.flat().sort((a, b) => b.startedAt - a.startedAt);
50
+ const boundedRuns = runs.slice(0, limit);
51
+ const runIds = boundedRuns
52
+ .map((run) => run.runId)
53
+ .filter((runId): runId is string => Boolean(runId));
54
+
55
+ const db = getDb();
56
+ const events = runIds.length
57
+ ? await db
58
+ .select()
59
+ .from(factoryAuditEvents)
60
+ .where(
61
+ and(
62
+ eq(factoryAuditEvents.orgId, orgId),
63
+ inArray(factoryAuditEvents.automationRunId, runIds),
64
+ ),
65
+ )
66
+ .orderBy(desc(factoryAuditEvents.createdAt))
67
+ : [];
68
+ const eventsByRun = new Map<string, typeof events>();
69
+ for (const event of events) {
70
+ if (!event.automationRunId) continue;
71
+ const current = eventsByRun.get(event.automationRunId) ?? [];
72
+ current.push(event);
73
+ eventsByRun.set(event.automationRunId, current);
74
+ }
75
+
76
+ return {
77
+ runs: boundedRuns.map((run) => ({
78
+ id: run.id,
79
+ automation: run.automation,
80
+ runId: run.runId,
81
+ threadId: run.threadId,
82
+ status: run.status,
83
+ startedAt: run.startedAt,
84
+ finishedAt: run.finishedAt,
85
+ error: run.error,
86
+ events: (eventsByRun.get(run.runId ?? "") ?? []).map((event) => ({
87
+ id: event.id,
88
+ automationRunId: event.automationRunId,
89
+ automationThreadId: event.automationThreadId,
90
+ automationName: event.automationName,
91
+ itemId: event.itemId,
92
+ source: event.source,
93
+ sourceUrl: event.sourceUrl,
94
+ action: event.action,
95
+ kind: event.kind,
96
+ status: event.status,
97
+ summary: event.summary,
98
+ details: parseDetails(event.detailsJson),
99
+ createdAt: event.createdAt,
100
+ })),
101
+ })),
102
+ count: boundedRuns.length,
103
+ };
104
+ },
105
+ });
106
+
107
+ function parseDetails(value: string): Record<string, unknown> {
108
+ let parsed: unknown;
109
+ try {
110
+ parsed = JSON.parse(value);
111
+ } catch {
112
+ throw new Error("Factory audit details are unreadable.");
113
+ }
114
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
115
+ throw new Error("Factory audit details are unreadable.");
116
+ }
117
+ return parsed as Record<string, unknown>;
118
+ }
@@ -22,7 +22,7 @@ export default defineAction({
22
22
  workspaceMemberIdentityFromContext(context),
23
23
  );
24
24
  const definitions = await listAutomationDefinitions(
25
- { userEmail, orgId },
25
+ { userEmail, orgId, appId: "factory" },
26
26
  "organization",
27
27
  );
28
28
  return Promise.all(
@@ -45,6 +45,7 @@ export default defineAction({
45
45
  runs: await listAutomationRuns({
46
46
  owners: [resource.owner],
47
47
  automation: name,
48
+ appId: "factory",
48
49
  limit: 20,
49
50
  }),
50
51
  })),
@@ -8,6 +8,7 @@ import {
8
8
  requireWorkspaceMember,
9
9
  workspaceMemberIdentityFromContext,
10
10
  } from "../server/lib/require-workspace-member.js";
11
+ import { recordFactoryAudit } from "../server/triage/audit.js";
11
12
  import {
12
13
  triageItemStatusSchema,
13
14
  triageSourceSchema,
@@ -24,7 +25,7 @@ export default defineAction({
24
25
  http: { method: "GET" },
25
26
  readOnly: true,
26
27
  run: async ({ status, source, limit }, context) => {
27
- const { orgId } = await requireWorkspaceMember(
28
+ const { userEmail, orgId } = await requireWorkspaceMember(
28
29
  workspaceMemberIdentityFromContext(context),
29
30
  );
30
31
  const db = getDb();
@@ -54,7 +55,7 @@ export default defineAction({
54
55
  }
55
56
  }
56
57
 
57
- return items.map((item) => {
58
+ const listedItems = items.map((item) => {
58
59
  const latestDecision = latestByItem.get(item.id);
59
60
  return {
60
61
  id: item.id,
@@ -86,5 +87,26 @@ export default defineAction({
86
87
  : null,
87
88
  };
88
89
  });
90
+
91
+ for (const item of listedItems) {
92
+ await recordFactoryAudit(
93
+ context,
94
+ { userEmail, orgId },
95
+ {
96
+ action: "list-triage-items",
97
+ kind: "read",
98
+ itemId: item.itemId,
99
+ source: item.source,
100
+ sourceUrl: item.sourceUrl,
101
+ summary: item.title,
102
+ details: {
103
+ status: item.status,
104
+ coverage: item.coverage,
105
+ decision: item.latestDecision?.outcome ?? null,
106
+ },
107
+ },
108
+ );
109
+ }
110
+ return listedItems;
89
111
  },
90
112
  });
@@ -9,6 +9,7 @@ import {
9
9
  requireWorkspaceMember,
10
10
  workspaceMemberIdentityFromContext,
11
11
  } from "../server/lib/require-workspace-member.js";
12
+ import { recordFactoryAudit } from "../server/triage/audit.js";
12
13
  import { createGitHubClient } from "../server/triage/github-client.js";
13
14
  import { itemDedupeKey } from "../server/triage/ids.js";
14
15
  import { mergeTriageMetadata } from "../server/triage/metadata.js";
@@ -193,6 +194,65 @@ export default defineAction({
193
194
  }
194
195
  });
195
196
 
197
+ if (issues.length === 0 && pullRequests.length === 0) {
198
+ await recordFactoryAudit(
199
+ context,
200
+ { userEmail, orgId },
201
+ {
202
+ action: "poll-github-sources",
203
+ kind: "observed",
204
+ source: "github",
205
+ summary: "No open GitHub issues or pull requests were observed.",
206
+ details: { repository: repositoryName },
207
+ },
208
+ );
209
+ } else {
210
+ for (const issue of issues) {
211
+ await recordFactoryAudit(
212
+ context,
213
+ { userEmail, orgId },
214
+ {
215
+ action: "poll-github-sources",
216
+ kind: "observed",
217
+ itemId: itemDedupeKey(
218
+ {
219
+ source: "github_issue",
220
+ externalId: `${repositoryName}#${issue.number}`,
221
+ },
222
+ orgId,
223
+ ),
224
+ source: "github_issue",
225
+ sourceUrl: issue.htmlUrl,
226
+ summary: issue.title,
227
+ details: { repository: repositoryName, number: issue.number },
228
+ },
229
+ );
230
+ }
231
+ for (const pullRequest of pullRequests) {
232
+ await recordFactoryAudit(
233
+ context,
234
+ { userEmail, orgId },
235
+ {
236
+ action: "poll-github-sources",
237
+ kind: "observed",
238
+ itemId: itemDedupeKey(
239
+ {
240
+ source: "github",
241
+ externalId: `${repositoryName}#${pullRequest.number}`,
242
+ repository: repositoryName,
243
+ pullRequestNumber: pullRequest.number,
244
+ },
245
+ orgId,
246
+ ),
247
+ source: "github",
248
+ sourceUrl: pullRequest.htmlUrl,
249
+ summary: pullRequest.title,
250
+ details: { repository: repositoryName, number: pullRequest.number },
251
+ },
252
+ );
253
+ }
254
+ }
255
+
196
256
  return {
197
257
  ok: true,
198
258
  repository: repositoryName,
@@ -9,6 +9,7 @@ import {
9
9
  requireWorkspaceMember,
10
10
  workspaceMemberIdentityFromContext,
11
11
  } from "../server/lib/require-workspace-member.js";
12
+ import { recordFactoryAudit } from "../server/triage/audit.js";
12
13
  import { itemDedupeKey } from "../server/triage/ids.js";
13
14
  import { mergeTriageMetadata } from "../server/triage/metadata.js";
14
15
  import { createSentryClient } from "../server/triage/sentry-client.js";
@@ -151,6 +152,44 @@ export default defineAction({
151
152
  .where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)));
152
153
  });
153
154
 
155
+ if (observedIssues.length === 0) {
156
+ await recordFactoryAudit(
157
+ context,
158
+ { userEmail, orgId },
159
+ {
160
+ action: "poll-sentry-errors",
161
+ kind: "observed",
162
+ source: "sentry",
163
+ summary: "No unresolved Sentry errors were observed.",
164
+ details: { sentryOrgSlug: config.sentryOrgSlug },
165
+ },
166
+ );
167
+ } else {
168
+ for (const issue of observedIssues) {
169
+ await recordFactoryAudit(
170
+ context,
171
+ { userEmail, orgId },
172
+ {
173
+ action: "poll-sentry-errors",
174
+ kind: "observed",
175
+ itemId: itemDedupeKey(
176
+ { source: "sentry", externalId: issue.id },
177
+ orgId,
178
+ ),
179
+ source: "sentry",
180
+ sourceUrl: issue.permalink,
181
+ summary: issue.title,
182
+ details: {
183
+ shortId: issue.shortId,
184
+ level: issue.level,
185
+ count: issue.count,
186
+ projectSlug: issue.projectSlug,
187
+ },
188
+ },
189
+ );
190
+ }
191
+ }
192
+
154
193
  return {
155
194
  ok: true,
156
195
  observed: observedIssues.length,
@@ -4,10 +4,12 @@ import { z } from "zod";
4
4
 
5
5
  import { getDb } from "../server/db/index.js";
6
6
  import { triageConfig, triageItems } from "../server/db/schema.js";
7
+ import { requireFactoryAutomation } from "../server/lib/require-factory-automation.js";
7
8
  import {
8
9
  requireWorkspaceMember,
9
10
  workspaceMemberIdentityFromContext,
10
11
  } from "../server/lib/require-workspace-member.js";
12
+ import { recordFactoryAudit } from "../server/triage/audit.js";
11
13
  import { itemDedupeKey } from "../server/triage/ids.js";
12
14
  import { pollSlackChannel } from "../server/triage/slack-poller.js";
13
15
 
@@ -17,11 +19,16 @@ export default defineAction({
17
19
  schema: z.object({
18
20
  channelId: z.string().trim().min(1).max(128).optional(),
19
21
  }),
20
- http: { method: "POST" },
22
+ http: false,
21
23
  run: async ({ channelId: requestedChannelId }, context) => {
22
24
  const { userEmail, orgId } = await requireWorkspaceMember(
23
25
  workspaceMemberIdentityFromContext(context),
24
26
  );
27
+ await requireFactoryAutomation(
28
+ context,
29
+ { userEmail, orgId },
30
+ "sourcePolling",
31
+ );
25
32
  const db = getDb();
26
33
  const config = (
27
34
  await db
@@ -106,6 +113,43 @@ export default defineAction({
106
113
  }
107
114
  });
108
115
 
116
+ if (result.envelopes.length === 0) {
117
+ await recordFactoryAudit(
118
+ context,
119
+ { userEmail, orgId },
120
+ {
121
+ action: "poll-slack-channel",
122
+ kind: "observed",
123
+ source: "slack",
124
+ summary: "No new Slack feedback was observed.",
125
+ details: {
126
+ channelId,
127
+ coverage: result.hasMore ? "partial" : "complete",
128
+ },
129
+ },
130
+ );
131
+ } else {
132
+ for (const envelope of result.envelopes) {
133
+ await recordFactoryAudit(
134
+ context,
135
+ { userEmail, orgId },
136
+ {
137
+ action: "poll-slack-channel",
138
+ kind: "observed",
139
+ itemId: itemDedupeKey(envelope, orgId),
140
+ source: envelope.source,
141
+ sourceUrl: envelope.sourceUrl ?? null,
142
+ summary: envelope.summary ?? envelope.title,
143
+ details: {
144
+ channelId,
145
+ threadTs: envelope.threadTs ?? null,
146
+ coverage: envelope.coverage,
147
+ },
148
+ },
149
+ );
150
+ }
151
+ }
152
+
109
153
  return {
110
154
  ok: true,
111
155
  source: "slack",
@@ -24,7 +24,7 @@ export default defineAction({
24
24
  workspaceMemberIdentityFromContext(context),
25
25
  );
26
26
  const definitions = await listAutomationDefinitions(
27
- { userEmail, orgId },
27
+ { userEmail, orgId, appId: "factory" },
28
28
  "organization",
29
29
  );
30
30
  const definition = definitions.find(
@@ -32,7 +32,7 @@ export default defineAction({
32
32
  workspaceMemberIdentityFromContext(context),
33
33
  );
34
34
  const definitions = await listAutomationDefinitions(
35
- { userEmail, orgId },
35
+ { userEmail, orgId, appId: "factory" },
36
36
  "organization",
37
37
  );
38
38
  const definition = definitions.find(
@@ -46,7 +46,7 @@ export default defineAction({
46
46
  );
47
47
  }
48
48
  const updated = await updateAutomation(
49
- { userEmail, orgId },
49
+ { userEmail, orgId, appId: "factory" },
50
50
  {
51
51
  name: definition.name,
52
52
  scope: "organization",
@@ -14,6 +14,7 @@ import {
14
14
  requireWorkspaceMember,
15
15
  workspaceMemberIdentityFromContext,
16
16
  } from "../server/lib/require-workspace-member.js";
17
+ import { recordFactoryAudit } from "../server/triage/audit.js";
17
18
  import { startBuilderRun } from "../server/triage/builder-executor.js";
18
19
  import { stableId } from "../server/triage/ids.js";
19
20
  import {
@@ -182,6 +183,26 @@ export default defineAction({
182
183
  : reason,
183
184
  guardResults,
184
185
  });
186
+ await recordFactoryAudit(
187
+ context,
188
+ { userEmail, orgId },
189
+ {
190
+ action: "start-builder-for-item",
191
+ kind: "decision",
192
+ itemId,
193
+ source: item.source,
194
+ sourceUrl: item.sourceUrl,
195
+ status: blocked ? "skipped" : "success",
196
+ summary: blocked ? "Factory kept this item for manual review." : reason,
197
+ details: {
198
+ decisionId,
199
+ clearBug,
200
+ productUxImplications,
201
+ ownerOwnedArea: ownerOwnedArea ?? null,
202
+ guardResults,
203
+ },
204
+ },
205
+ );
185
206
  if (blocked) {
186
207
  await db
187
208
  .update(triageItems)
@@ -332,6 +353,19 @@ export default defineAction({
332
353
  updatedAt: new Date().toISOString(),
333
354
  })
334
355
  .where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
356
+ await recordFactoryAudit(
357
+ context,
358
+ { userEmail, orgId },
359
+ {
360
+ action: "start-builder-for-item",
361
+ kind: "external_action",
362
+ itemId,
363
+ source: item.source,
364
+ sourceUrl: item.sourceUrl,
365
+ summary: "Tagged Builder in the Slack thread and requested a PR.",
366
+ details: { provider: "bot-tag", runId },
367
+ },
368
+ );
335
369
  return {
336
370
  ok: true,
337
371
  started: true,
@@ -385,6 +419,23 @@ export default defineAction({
385
419
  updatedAt: new Date().toISOString(),
386
420
  })
387
421
  .where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
422
+ await recordFactoryAudit(
423
+ context,
424
+ { userEmail, orgId },
425
+ {
426
+ action: "start-builder-for-item",
427
+ kind: "external_action",
428
+ itemId,
429
+ source: item.source,
430
+ sourceUrl: item.sourceUrl,
431
+ summary: "Submitted the clear bug to Builder.",
432
+ details: {
433
+ provider: "builder-http",
434
+ runId,
435
+ providerTaskId: result.providerTaskId ?? null,
436
+ },
437
+ },
438
+ );
388
439
  return {
389
440
  ok: true,
390
441
  started: true,