@agent-native/core 0.132.2 → 0.133.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 (436) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +161 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/correlation.ts +11 -1
  5. package/corpus/core/src/a2a/types.ts +11 -3
  6. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +33 -46
  7. package/corpus/core/src/agent/engine/builder-engine.ts +22 -10
  8. package/corpus/core/src/agent/engine/error-detail.ts +184 -3
  9. package/corpus/core/src/agent/engine/failure-taxonomy.ts +123 -0
  10. package/corpus/core/src/agent/engine/index.ts +8 -0
  11. package/corpus/core/src/agent/engine/registry.ts +92 -8
  12. package/corpus/core/src/agent/engine/translate-ai-sdk.ts +17 -2
  13. package/corpus/core/src/agent/production-agent.ts +13 -33
  14. package/corpus/core/src/agent/run-loop-with-resume.ts +1 -1
  15. package/corpus/core/src/agent/run-manager.ts +43 -14
  16. package/corpus/core/src/agent/run-store.ts +30 -3
  17. package/corpus/core/src/agent/thread-data-builder.ts +36 -4
  18. package/corpus/core/src/cli/templates-meta.ts +13 -0
  19. package/corpus/core/src/cli/workspace-dev.ts +1 -0
  20. package/corpus/core/src/client/error-format.ts +12 -0
  21. package/corpus/core/src/credentials/index.ts +51 -12
  22. package/corpus/core/src/extensions/url-safety.ts +46 -12
  23. package/corpus/core/src/integrations/adapters/slack.ts +32 -10
  24. package/corpus/core/src/integrations/google-docs-poller.ts +12 -1
  25. package/corpus/core/src/integrations/installations-store.ts +30 -0
  26. package/corpus/core/src/integrations/plugin.ts +5 -5
  27. package/corpus/core/src/integrations/types.ts +7 -0
  28. package/corpus/core/src/integrations/webhook-handler.ts +24 -1
  29. package/corpus/core/src/jobs/background-automation-runner.ts +38 -1
  30. package/corpus/core/src/provider-api/index.ts +8 -2
  31. package/corpus/core/src/scripts/call-agent.ts +6 -0
  32. package/corpus/core/src/server/agent-chat-plugin.ts +30 -9
  33. package/corpus/core/src/server/agent-discovery.ts +2 -0
  34. package/corpus/core/src/server/builder-design-systems.ts +21 -0
  35. package/corpus/core/src/server/credential-provider.ts +51 -12
  36. package/corpus/core/src/server/index.ts +1 -0
  37. package/corpus/core/src/server/onboarding-html.ts +37 -2
  38. package/corpus/core/src/shared/reasoning-effort.ts +1 -1
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  40. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +6 -2
  41. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +39 -19
  42. package/corpus/templates/assets/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  43. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +30 -3
  44. package/corpus/templates/brain/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  45. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
  46. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +54 -25
  47. package/corpus/templates/calendar/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  48. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  49. package/corpus/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  50. package/corpus/templates/clips/app/components/library/library-layout.tsx +37 -21
  51. package/corpus/templates/clips/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  52. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +1 -1
  53. package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +1 -1
  54. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +34 -17
  55. package/corpus/templates/content/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  56. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -2
  57. package/corpus/templates/design/actions/create-design-system.ts +1 -0
  58. package/corpus/templates/design/actions/set-default-design-system.ts +34 -26
  59. package/corpus/templates/design/app/components/layout/Sidebar.tsx +21 -4
  60. package/corpus/templates/design/app/i18n-data.ts +39 -0
  61. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +229 -12
  62. package/corpus/templates/design/app/pages/DesignSystems.tsx +10 -4
  63. package/corpus/templates/design/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  64. package/corpus/templates/design/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
  65. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +19 -4
  66. package/corpus/templates/dispatch/AGENTS.md +4 -0
  67. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +562 -0
  68. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +198 -0
  69. package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +115 -0
  70. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +182 -0
  71. package/corpus/templates/factory/.agents/skills/capture-learnings/SKILL.md +89 -0
  72. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +221 -0
  73. package/corpus/templates/factory/.agents/skills/customizing-agent-native/SKILL.md +220 -0
  74. package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +263 -0
  75. package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +52 -0
  76. package/corpus/templates/factory/.agents/skills/feature-flags/SKILL.md +169 -0
  77. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +174 -0
  78. package/corpus/templates/factory/.agents/skills/real-time-sync/SKILL.md +232 -0
  79. package/corpus/templates/factory/.agents/skills/security/SKILL.md +324 -0
  80. package/corpus/templates/factory/.agents/skills/self-modifying-code/SKILL.md +119 -0
  81. package/corpus/templates/factory/.agents/skills/shadcn-ui/SKILL.md +123 -0
  82. package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +232 -0
  83. package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +178 -0
  84. package/corpus/templates/factory/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
  85. package/corpus/templates/factory/.env.example +24 -0
  86. package/corpus/templates/factory/.ignore +0 -0
  87. package/corpus/templates/factory/.oxfmtrc.json +8 -0
  88. package/corpus/templates/factory/AGENTS.md +90 -0
  89. package/corpus/templates/factory/CHANGELOG.md +10 -0
  90. package/corpus/templates/factory/DEVELOPING.md +185 -0
  91. package/corpus/templates/factory/README.md +64 -0
  92. package/corpus/templates/factory/_gitignore +42 -0
  93. package/corpus/templates/factory/actions/add-factory-comment.ts +55 -0
  94. package/corpus/templates/factory/actions/approve-factory-item.ts +214 -0
  95. package/corpus/templates/factory/actions/babysit-pull-request.ts +126 -0
  96. package/corpus/templates/factory/actions/evaluate-triage-item.ts +172 -0
  97. package/corpus/templates/factory/actions/get-factory-graph.ts +62 -0
  98. package/corpus/templates/factory/actions/get-triage-config.ts +42 -0
  99. package/corpus/templates/factory/actions/get-triage-item.ts +74 -0
  100. package/corpus/templates/factory/actions/hello.ts +13 -0
  101. package/corpus/templates/factory/actions/ingest-github-observation.ts +100 -0
  102. package/corpus/templates/factory/actions/list-factories.ts +40 -0
  103. package/corpus/templates/factory/actions/list-factory-comments.ts +40 -0
  104. package/corpus/templates/factory/actions/list-triage-items.ts +85 -0
  105. package/corpus/templates/factory/actions/list-triage-rules.ts +44 -0
  106. package/corpus/templates/factory/actions/navigate.ts +41 -0
  107. package/corpus/templates/factory/actions/poll-slack-channel.ts +118 -0
  108. package/corpus/templates/factory/actions/reconcile-triage-run.ts +179 -0
  109. package/corpus/templates/factory/actions/record-triage-feedback.ts +58 -0
  110. package/corpus/templates/factory/actions/run.ts +2 -0
  111. package/corpus/templates/factory/actions/save-factory-graph.ts +129 -0
  112. package/corpus/templates/factory/actions/save-triage-config.ts +67 -0
  113. package/corpus/templates/factory/actions/save-triage-rule.ts +89 -0
  114. package/corpus/templates/factory/actions/suggest-factory-rules.ts +70 -0
  115. package/corpus/templates/factory/actions/view-screen.ts +73 -0
  116. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +441 -0
  117. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +388 -0
  118. package/corpus/templates/factory/app/components/layout/Header.tsx +60 -0
  119. package/corpus/templates/factory/app/components/layout/Layout.tsx +190 -0
  120. package/corpus/templates/factory/app/components/layout/Sidebar.tsx +538 -0
  121. package/corpus/templates/factory/app/components/triage/triage-status-pill.tsx +28 -0
  122. package/corpus/templates/factory/app/components/ui/button.tsx +1 -0
  123. package/corpus/templates/factory/app/components/ui/card.tsx +1 -0
  124. package/corpus/templates/factory/app/components/ui/dropdown-menu.tsx +1 -0
  125. package/corpus/templates/factory/app/components/ui/input.tsx +1 -0
  126. package/corpus/templates/factory/app/components/ui/label.tsx +1 -0
  127. package/corpus/templates/factory/app/components/ui/sheet.tsx +1 -0
  128. package/corpus/templates/factory/app/components/ui/textarea.tsx +1 -0
  129. package/corpus/templates/factory/app/components/ui/toolkit-provider.tsx +17 -0
  130. package/corpus/templates/factory/app/components/ui/tooltip.tsx +1 -0
  131. package/corpus/templates/factory/app/design-system.ts +3 -0
  132. package/corpus/templates/factory/app/entry.client.tsx +22 -0
  133. package/corpus/templates/factory/app/entry.server.tsx +10 -0
  134. package/corpus/templates/factory/app/global.css +93 -0
  135. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +113 -0
  136. package/corpus/templates/factory/app/i18n/en-US.ts +211 -0
  137. package/corpus/templates/factory/app/i18n/index.ts +34 -0
  138. package/corpus/templates/factory/app/i18n-data.ts +556 -0
  139. package/corpus/templates/factory/app/lib/agent-page.tsx +49 -0
  140. package/corpus/templates/factory/app/lib/app-config.ts +11 -0
  141. package/corpus/templates/factory/app/lib/tab-id.ts +1 -0
  142. package/corpus/templates/factory/app/lib/utils.ts +1 -0
  143. package/corpus/templates/factory/app/root.tsx +175 -0
  144. package/corpus/templates/factory/app/routes/_index.tsx +94 -0
  145. package/corpus/templates/factory/app/routes/agent.tsx +24 -0
  146. package/corpus/templates/factory/app/routes/chat.$threadId.tsx +1 -0
  147. package/corpus/templates/factory/app/routes/database.tsx +17 -0
  148. package/corpus/templates/factory/app/routes/extensions.$id.$slug.tsx +2 -0
  149. package/corpus/templates/factory/app/routes/extensions.$id.tsx +11 -0
  150. package/corpus/templates/factory/app/routes/extensions._index.tsx +11 -0
  151. package/corpus/templates/factory/app/routes/extensions.tsx +5 -0
  152. package/corpus/templates/factory/app/routes/factory.tsx +1003 -0
  153. package/corpus/templates/factory/app/routes/observability.tsx +19 -0
  154. package/corpus/templates/factory/app/routes/settings.tsx +89 -0
  155. package/corpus/templates/factory/app/routes/team.tsx +11 -0
  156. package/corpus/templates/factory/app/routes.ts +4 -0
  157. package/corpus/templates/factory/app/vite-env.d.ts +6 -0
  158. package/corpus/templates/factory/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  159. package/corpus/templates/factory/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  160. package/corpus/templates/factory/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
  161. package/corpus/templates/factory/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  162. package/corpus/templates/factory/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  163. package/corpus/templates/factory/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  164. package/corpus/templates/factory/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
  165. package/corpus/templates/factory/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  166. package/corpus/templates/factory/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
  167. package/corpus/templates/factory/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  168. package/corpus/templates/factory/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
  169. package/corpus/templates/factory/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  170. package/corpus/templates/factory/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  171. package/corpus/templates/factory/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  172. package/corpus/templates/factory/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  173. package/corpus/templates/factory/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  174. package/corpus/templates/factory/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  175. package/corpus/templates/factory/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  176. package/corpus/templates/factory/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  177. package/corpus/templates/factory/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  178. package/corpus/templates/factory/changelog/2026-07-29-sidebar-footers-now-keep-feedback-search-and-collapse-togeth.md +6 -0
  179. package/corpus/templates/factory/changelog/2026-07-31-added-an-inspectable-observe-only-factory-queue-for-slack-.md +6 -0
  180. package/corpus/templates/factory/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  181. package/corpus/templates/factory/components.json +20 -0
  182. package/corpus/templates/factory/data/sync-config.json +1 -0
  183. package/corpus/templates/factory/learnings.defaults.md +5 -0
  184. package/corpus/templates/factory/netlify.toml +10 -0
  185. package/corpus/templates/factory/package.json +105 -0
  186. package/corpus/templates/factory/public/agent-native-icon-dark.svg +10 -0
  187. package/corpus/templates/factory/public/agent-native-icon-light.svg +10 -0
  188. package/corpus/templates/factory/public/agent-native-logo-dark.svg +21 -0
  189. package/corpus/templates/factory/public/agent-native-logo-light.svg +21 -0
  190. package/corpus/templates/factory/public/favicon.svg +1 -0
  191. package/corpus/templates/factory/public/icon-180.svg +1 -0
  192. package/corpus/templates/factory/public/icon-192.svg +1 -0
  193. package/corpus/templates/factory/public/icon-512.svg +1 -0
  194. package/corpus/templates/factory/public/manifest.json +21 -0
  195. package/corpus/templates/factory/react-router.config.ts +7 -0
  196. package/corpus/templates/factory/server/connectors/credentials.ts +129 -0
  197. package/corpus/templates/factory/server/connectors/slack.ts +129 -0
  198. package/corpus/templates/factory/server/db/index.ts +6 -0
  199. package/corpus/templates/factory/server/db/schema.ts +193 -0
  200. package/corpus/templates/factory/server/factory-graph/contracts.ts +212 -0
  201. package/corpus/templates/factory/server/factory-graph/store.ts +121 -0
  202. package/corpus/templates/factory/server/lib/require-workspace-member.ts +55 -0
  203. package/corpus/templates/factory/server/middleware/auth.ts +15 -0
  204. package/corpus/templates/factory/server/plugins/agent-chat.ts +58 -0
  205. package/corpus/templates/factory/server/plugins/auth.ts +14 -0
  206. package/corpus/templates/factory/server/plugins/factory-migrations.ts +247 -0
  207. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +116 -0
  208. package/corpus/templates/factory/server/plugins/integrations.ts +46 -0
  209. package/corpus/templates/factory/server/routes/[...page].get.ts +5 -0
  210. package/corpus/templates/factory/server/routes/_agent-native/factory/builder-callback.post.ts +116 -0
  211. package/corpus/templates/factory/server/triage/ai-services-git.ts +197 -0
  212. package/corpus/templates/factory/server/triage/builder-executor.ts +118 -0
  213. package/corpus/templates/factory/server/triage/contracts.ts +164 -0
  214. package/corpus/templates/factory/server/triage/github-ingestion.ts +35 -0
  215. package/corpus/templates/factory/server/triage/guards.ts +121 -0
  216. package/corpus/templates/factory/server/triage/ids.ts +27 -0
  217. package/corpus/templates/factory/server/triage/pr-babysit.ts +100 -0
  218. package/corpus/templates/factory/server/triage/pr-monitor.ts +220 -0
  219. package/corpus/templates/factory/server/triage/slack-client.ts +55 -0
  220. package/corpus/templates/factory/server/triage/slack-poller.ts +152 -0
  221. package/corpus/templates/factory/ssr-entry.ts +15 -0
  222. package/corpus/templates/factory/tsconfig.json +21 -0
  223. package/corpus/templates/factory/vite.config.ts +19 -0
  224. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +55 -5
  225. package/corpus/templates/forms/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  226. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +6 -2
  227. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +21 -6
  228. package/corpus/templates/plan/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  229. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +12 -0
  230. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -0
  231. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +11 -0
  232. package/corpus/templates/slides/AGENTS.md +5 -6
  233. package/corpus/templates/slides/actions/_await-fit-check.ts +20 -10
  234. package/corpus/templates/slides/actions/add-slide.ts +17 -4
  235. package/corpus/templates/slides/actions/create-design-system.ts +16 -4
  236. package/corpus/templates/slides/actions/delete-design-system.ts +18 -2
  237. package/corpus/templates/slides/actions/get-layout-overflows.ts +88 -0
  238. package/corpus/templates/slides/actions/import-file.ts +1 -0
  239. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +8 -0
  240. package/corpus/templates/slides/actions/patch-deck.ts +48 -16
  241. package/corpus/templates/slides/actions/set-default-design-system.ts +49 -19
  242. package/corpus/templates/slides/actions/update-slide.ts +13 -3
  243. package/corpus/templates/slides/actions/view-screen.ts +87 -10
  244. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +155 -28
  245. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +21 -17
  246. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +849 -341
  247. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +102 -2
  248. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +13 -16
  249. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +60 -12
  250. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +11 -1
  251. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +66 -19
  252. package/corpus/templates/slides/app/i18n/en-US.ts +23 -0
  253. package/corpus/templates/slides/app/lib/normalize-slide-padding.ts +8 -15
  254. package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -3
  255. package/corpus/templates/slides/app/pages/DesignSystems.tsx +4 -3
  256. package/corpus/templates/slides/app/pages/Index.tsx +1 -1
  257. package/corpus/templates/slides/changelog/2026-07-31-design-system-details-now-show-their-source-and-indexing-sta.md +6 -0
  258. package/corpus/templates/slides/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
  259. package/corpus/templates/slides/changelog/2026-07-31-design-system-setup-keeps-focus-rings-visible-and-uses-a-sim.md +6 -0
  260. package/corpus/templates/slides/changelog/2026-07-31-skip-prompt-is-now-available-in-the-new-deck-prompt-header.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-07-31-slides-now-detect-real-text-and-box-overflow-across-the-deck.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  263. package/corpus/templates/slides/server/handlers/design-systems.ts +1 -0
  264. package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +1 -0
  265. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +23 -4
  266. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
  267. package/corpus/templates/slides/server/plugins/creative-context.ts +16 -3
  268. package/corpus/templates/slides/server/workspace-defaults.ts +5 -1
  269. package/corpus/templates/slides/shared/slide-fit.ts +26 -0
  270. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +30 -3
  271. package/corpus/templates/tasks/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  272. package/dist/a2a/correlation.d.ts +4 -1
  273. package/dist/a2a/correlation.d.ts.map +1 -1
  274. package/dist/a2a/correlation.js +8 -1
  275. package/dist/a2a/correlation.js.map +1 -1
  276. package/dist/a2a/types.d.ts +11 -3
  277. package/dist/a2a/types.d.ts.map +1 -1
  278. package/dist/a2a/types.js.map +1 -1
  279. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  280. package/dist/agent/engine/ai-sdk-engine.js +27 -41
  281. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  282. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  283. package/dist/agent/engine/builder-engine.js +18 -8
  284. package/dist/agent/engine/builder-engine.js.map +1 -1
  285. package/dist/agent/engine/error-detail.d.ts +61 -0
  286. package/dist/agent/engine/error-detail.d.ts.map +1 -1
  287. package/dist/agent/engine/error-detail.js +145 -3
  288. package/dist/agent/engine/error-detail.js.map +1 -1
  289. package/dist/agent/engine/failure-taxonomy.d.ts +24 -0
  290. package/dist/agent/engine/failure-taxonomy.d.ts.map +1 -0
  291. package/dist/agent/engine/failure-taxonomy.js +88 -0
  292. package/dist/agent/engine/failure-taxonomy.js.map +1 -0
  293. package/dist/agent/engine/index.d.ts +2 -1
  294. package/dist/agent/engine/index.d.ts.map +1 -1
  295. package/dist/agent/engine/index.js +2 -1
  296. package/dist/agent/engine/index.js.map +1 -1
  297. package/dist/agent/engine/registry.d.ts +16 -0
  298. package/dist/agent/engine/registry.d.ts.map +1 -1
  299. package/dist/agent/engine/registry.js +71 -6
  300. package/dist/agent/engine/registry.js.map +1 -1
  301. package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
  302. package/dist/agent/engine/translate-ai-sdk.js +14 -2
  303. package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
  304. package/dist/agent/production-agent.d.ts.map +1 -1
  305. package/dist/agent/production-agent.js +13 -24
  306. package/dist/agent/production-agent.js.map +1 -1
  307. package/dist/agent/run-loop-with-resume.js +1 -1
  308. package/dist/agent/run-loop-with-resume.js.map +1 -1
  309. package/dist/agent/run-manager.d.ts.map +1 -1
  310. package/dist/agent/run-manager.js +39 -10
  311. package/dist/agent/run-manager.js.map +1 -1
  312. package/dist/agent/run-store.d.ts +10 -0
  313. package/dist/agent/run-store.d.ts.map +1 -1
  314. package/dist/agent/run-store.js +20 -3
  315. package/dist/agent/run-store.js.map +1 -1
  316. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  317. package/dist/agent/thread-data-builder.js +28 -4
  318. package/dist/agent/thread-data-builder.js.map +1 -1
  319. package/dist/cli/templates-meta.d.ts.map +1 -1
  320. package/dist/cli/templates-meta.js +13 -0
  321. package/dist/cli/templates-meta.js.map +1 -1
  322. package/dist/cli/workspace-dev.d.ts.map +1 -1
  323. package/dist/cli/workspace-dev.js +1 -0
  324. package/dist/cli/workspace-dev.js.map +1 -1
  325. package/dist/client/error-format.d.ts.map +1 -1
  326. package/dist/client/error-format.js +10 -0
  327. package/dist/client/error-format.js.map +1 -1
  328. package/dist/collab/awareness.d.ts +2 -2
  329. package/dist/collab/awareness.d.ts.map +1 -1
  330. package/dist/credentials/index.d.ts +9 -2
  331. package/dist/credentials/index.d.ts.map +1 -1
  332. package/dist/credentials/index.js +50 -8
  333. package/dist/credentials/index.js.map +1 -1
  334. package/dist/extensions/url-safety.d.ts.map +1 -1
  335. package/dist/extensions/url-safety.js +38 -12
  336. package/dist/extensions/url-safety.js.map +1 -1
  337. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  338. package/dist/integrations/adapters/slack.js +25 -8
  339. package/dist/integrations/adapters/slack.js.map +1 -1
  340. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  341. package/dist/integrations/google-docs-poller.js +13 -1
  342. package/dist/integrations/google-docs-poller.js.map +1 -1
  343. package/dist/integrations/installations-store.d.ts +10 -0
  344. package/dist/integrations/installations-store.d.ts.map +1 -1
  345. package/dist/integrations/installations-store.js +24 -0
  346. package/dist/integrations/installations-store.js.map +1 -1
  347. package/dist/integrations/plugin.d.ts.map +1 -1
  348. package/dist/integrations/plugin.js +6 -5
  349. package/dist/integrations/plugin.js.map +1 -1
  350. package/dist/integrations/types.d.ts +7 -0
  351. package/dist/integrations/types.d.ts.map +1 -1
  352. package/dist/integrations/types.js.map +1 -1
  353. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  354. package/dist/integrations/webhook-handler.js +16 -1
  355. package/dist/integrations/webhook-handler.js.map +1 -1
  356. package/dist/jobs/background-automation-runner.d.ts.map +1 -1
  357. package/dist/jobs/background-automation-runner.js +35 -2
  358. package/dist/jobs/background-automation-runner.js.map +1 -1
  359. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  360. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  361. package/dist/notifications/routes.d.ts +3 -3
  362. package/dist/observability/routes.d.ts +3 -3
  363. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  364. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  365. package/dist/provider-api/index.js +7 -3
  366. package/dist/provider-api/index.js.map +1 -1
  367. package/dist/scripts/call-agent.d.ts.map +1 -1
  368. package/dist/scripts/call-agent.js +6 -1
  369. package/dist/scripts/call-agent.js.map +1 -1
  370. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  371. package/dist/server/agent-chat-plugin.js +25 -7
  372. package/dist/server/agent-chat-plugin.js.map +1 -1
  373. package/dist/server/agent-discovery.d.ts +2 -0
  374. package/dist/server/agent-discovery.d.ts.map +1 -1
  375. package/dist/server/agent-discovery.js.map +1 -1
  376. package/dist/server/builder-design-systems.d.ts +4 -1
  377. package/dist/server/builder-design-systems.d.ts.map +1 -1
  378. package/dist/server/builder-design-systems.js +11 -1
  379. package/dist/server/builder-design-systems.js.map +1 -1
  380. package/dist/server/credential-provider.d.ts.map +1 -1
  381. package/dist/server/credential-provider.js +49 -12
  382. package/dist/server/credential-provider.js.map +1 -1
  383. package/dist/server/index.d.ts +1 -1
  384. package/dist/server/index.d.ts.map +1 -1
  385. package/dist/server/index.js.map +1 -1
  386. package/dist/server/onboarding-html.d.ts.map +1 -1
  387. package/dist/server/onboarding-html.js +37 -2
  388. package/dist/server/onboarding-html.js.map +1 -1
  389. package/dist/server/transcribe-voice.d.ts +1 -1
  390. package/dist/shared/reasoning-effort.d.ts +1 -0
  391. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  392. package/dist/shared/reasoning-effort.js +1 -1
  393. package/dist/shared/reasoning-effort.js.map +1 -1
  394. package/dist/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  395. package/dist/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  396. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  397. package/package.json +1 -1
  398. package/src/a2a/correlation.ts +11 -1
  399. package/src/a2a/types.ts +11 -3
  400. package/src/agent/engine/ai-sdk-engine.ts +33 -46
  401. package/src/agent/engine/builder-engine.ts +22 -10
  402. package/src/agent/engine/error-detail.ts +184 -3
  403. package/src/agent/engine/failure-taxonomy.ts +123 -0
  404. package/src/agent/engine/index.ts +8 -0
  405. package/src/agent/engine/registry.ts +92 -8
  406. package/src/agent/engine/translate-ai-sdk.ts +17 -2
  407. package/src/agent/production-agent.ts +13 -33
  408. package/src/agent/run-loop-with-resume.ts +1 -1
  409. package/src/agent/run-manager.ts +43 -14
  410. package/src/agent/run-store.ts +30 -3
  411. package/src/agent/thread-data-builder.ts +36 -4
  412. package/src/cli/templates-meta.ts +13 -0
  413. package/src/cli/workspace-dev.ts +1 -0
  414. package/src/client/error-format.ts +12 -0
  415. package/src/credentials/index.ts +51 -12
  416. package/src/extensions/url-safety.ts +46 -12
  417. package/src/integrations/adapters/slack.ts +32 -10
  418. package/src/integrations/google-docs-poller.ts +12 -1
  419. package/src/integrations/installations-store.ts +30 -0
  420. package/src/integrations/plugin.ts +5 -5
  421. package/src/integrations/types.ts +7 -0
  422. package/src/integrations/webhook-handler.ts +24 -1
  423. package/src/jobs/background-automation-runner.ts +38 -1
  424. package/src/provider-api/index.ts +8 -2
  425. package/src/scripts/call-agent.ts +6 -0
  426. package/src/server/agent-chat-plugin.ts +30 -9
  427. package/src/server/agent-discovery.ts +2 -0
  428. package/src/server/builder-design-systems.ts +21 -0
  429. package/src/server/credential-provider.ts +51 -12
  430. package/src/server/index.ts +1 -0
  431. package/src/server/onboarding-html.ts +37 -2
  432. package/src/shared/reasoning-effort.ts +1 -1
  433. package/src/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  434. package/src/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  435. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  436. package/corpus/templates/clips/desktop/src/lib/media-device-selection.ts +0 -157
@@ -0,0 +1,129 @@
1
+ export type Workspace = "primary" | "secondary";
2
+
3
+ export type SlackTokenResolver = (workspace: Workspace) => Promise<string>;
4
+
5
+ export interface SlackMessage {
6
+ type: string;
7
+ user?: string;
8
+ bot_id?: string;
9
+ username?: string;
10
+ text: string;
11
+ ts: string;
12
+ thread_ts?: string;
13
+ reply_count?: number;
14
+ permalink?: string;
15
+ }
16
+
17
+ export interface SlackTeamInfo {
18
+ id: string;
19
+ name: string;
20
+ domain: string;
21
+ }
22
+
23
+ export interface ChannelHistoryResult {
24
+ messages: SlackMessage[];
25
+ has_more: boolean;
26
+ next_cursor?: string;
27
+ }
28
+
29
+ const cache = new Map<string, { value: unknown; expiresAt: number }>();
30
+ const cacheTtlMs = 120_000;
31
+
32
+ async function getToken(
33
+ workspace: Workspace,
34
+ tokenResolver?: SlackTokenResolver,
35
+ ): Promise<string> {
36
+ if (tokenResolver) return tokenResolver(workspace);
37
+ throw new Error(
38
+ `A workspace Slack credential resolver is required for the ${workspace} connection.`,
39
+ );
40
+ }
41
+
42
+ async function slackApi<T>(
43
+ workspace: Workspace,
44
+ method: string,
45
+ params: Record<string, string> | undefined,
46
+ tokenResolver?: SlackTokenResolver,
47
+ ): Promise<T> {
48
+ const cacheKey = `${workspace}:${method}:${JSON.stringify(params ?? {})}`;
49
+ const cached = cache.get(cacheKey);
50
+ if (cached && cached.expiresAt > Date.now()) return cached.value as T;
51
+ const token = await getToken(workspace, tokenResolver);
52
+ const url = new URL(`https://slack.com/api/${method}`);
53
+ for (const [key, value] of Object.entries(params ?? {}))
54
+ url.searchParams.set(key, value);
55
+ const response = await fetch(url, {
56
+ headers: { Authorization: `Bearer ${token}` },
57
+ });
58
+ if (!response.ok)
59
+ throw new Error(
60
+ `Slack API error ${response.status}: ${await response.text()}`,
61
+ );
62
+ const data = (await response.json()) as T & { ok?: boolean; error?: string };
63
+ if (data.ok === false)
64
+ throw new Error(`Slack API error: ${data.error ?? "unknown_error"}`);
65
+ cache.set(cacheKey, { value: data, expiresAt: Date.now() + cacheTtlMs });
66
+ return data;
67
+ }
68
+
69
+ export async function getChannelHistory(
70
+ workspace: Workspace,
71
+ channelId: string,
72
+ limit = 100,
73
+ cursor?: string,
74
+ tokenResolver?: SlackTokenResolver,
75
+ ): Promise<ChannelHistoryResult> {
76
+ const params: Record<string, string> = {
77
+ channel: channelId,
78
+ limit: String(Math.min(limit, 200)),
79
+ };
80
+ if (cursor) params.latest = cursor;
81
+ try {
82
+ const data = await slackApi<{
83
+ messages?: SlackMessage[];
84
+ has_more?: boolean;
85
+ }>(workspace, "conversations.history", params, tokenResolver);
86
+ const messages = data.messages ?? [];
87
+ return {
88
+ messages,
89
+ has_more: Boolean(data.has_more),
90
+ next_cursor: messages[messages.length - 1]?.ts,
91
+ };
92
+ } catch (error) {
93
+ if (!String(error).includes("not_in_channel")) throw error;
94
+ const token = await getToken(workspace, tokenResolver);
95
+ const joined = await fetch("https://slack.com/api/conversations.join", {
96
+ method: "POST",
97
+ headers: {
98
+ Authorization: `Bearer ${token}`,
99
+ "Content-Type": "application/json",
100
+ },
101
+ body: JSON.stringify({ channel: channelId }),
102
+ });
103
+ const joinedData = (await joined.json()) as { ok?: boolean };
104
+ if (!joinedData.ok) throw error;
105
+ const data = await slackApi<{
106
+ messages?: SlackMessage[];
107
+ has_more?: boolean;
108
+ }>(workspace, "conversations.history", params, tokenResolver);
109
+ const messages = data.messages ?? [];
110
+ return {
111
+ messages,
112
+ has_more: Boolean(data.has_more),
113
+ next_cursor: messages[messages.length - 1]?.ts,
114
+ };
115
+ }
116
+ }
117
+
118
+ export async function getTeamInfo(
119
+ workspace: Workspace,
120
+ tokenResolver?: SlackTokenResolver,
121
+ ): Promise<SlackTeamInfo> {
122
+ const data = await slackApi<{ team?: SlackTeamInfo; team_id?: string }>(
123
+ workspace,
124
+ "team.info",
125
+ undefined,
126
+ tokenResolver,
127
+ );
128
+ return data.team ?? { id: data.team_id ?? "", name: workspace, domain: "" };
129
+ }
@@ -0,0 +1,6 @@
1
+ import { createGetDb } from "@agent-native/core/db";
2
+
3
+ import * as schema from "./schema.js";
4
+
5
+ export const getDb = createGetDb(schema);
6
+ export { schema };
@@ -0,0 +1,193 @@
1
+ import {
2
+ index,
3
+ integer,
4
+ now,
5
+ table,
6
+ text,
7
+ uniqueIndex,
8
+ } from "@agent-native/core/db/schema";
9
+
10
+ export const triageItems = table(
11
+ "factory_items",
12
+ {
13
+ id: text("id").primaryKey(),
14
+ source: text("source").notNull(),
15
+ externalId: text("external_id").notNull(),
16
+ sourceUrl: text("source_url"),
17
+ title: text("title").notNull(),
18
+ summary: text("summary"),
19
+ status: text("status").notNull().default("received"),
20
+ risk: text("risk").notNull().default("unknown"),
21
+ channelId: text("channel_id"),
22
+ threadTs: text("thread_ts"),
23
+ repository: text("repository"),
24
+ pullRequestNumber: integer("pull_request_number"),
25
+ headSha: text("head_sha"),
26
+ coverage: text("coverage").notNull().default("unknown"),
27
+ dedupeKey: text("dedupe_key").notNull(),
28
+ metadataJson: text("metadata_json").notNull().default("{}"),
29
+ lastSeenAt: text("last_seen_at"),
30
+ createdAt: text("created_at").notNull().default(now()),
31
+ updatedAt: text("updated_at").notNull().default(now()),
32
+ ownerEmail: text("owner_email").notNull(),
33
+ orgId: text("org_id"),
34
+ },
35
+ (item) => ({
36
+ orgDedupeUnique: uniqueIndex("factory_items_org_dedupe_idx").on(
37
+ item.orgId,
38
+ item.dedupeKey,
39
+ ),
40
+ orgStatusIdx: index("factory_items_org_status_idx").on(
41
+ item.orgId,
42
+ item.status,
43
+ item.updatedAt,
44
+ ),
45
+ }),
46
+ );
47
+
48
+ export const triageRules = table("factory_rules", {
49
+ id: text("id").primaryKey(),
50
+ name: text("name").notNull(),
51
+ description: text("description").notNull(),
52
+ promptText: text("prompt_text").notNull(),
53
+ mode: text("mode").notNull().default("shadow"),
54
+ enabled: integer("enabled").notNull().default(1),
55
+ guardsJson: text("guards_json").notNull().default("{}"),
56
+ promptVersion: integer("prompt_version").notNull().default(1),
57
+ createdAt: text("created_at").notNull().default(now()),
58
+ updatedAt: text("updated_at").notNull().default(now()),
59
+ ownerEmail: text("owner_email").notNull(),
60
+ orgId: text("org_id"),
61
+ });
62
+
63
+ export const triageDecisions = table("factory_decisions", {
64
+ id: text("id").primaryKey(),
65
+ itemId: text("item_id").notNull(),
66
+ ruleId: text("rule_id"),
67
+ mode: text("mode").notNull().default("shadow"),
68
+ outcome: text("outcome").notNull(),
69
+ reason: text("reason").notNull(),
70
+ guardResultsJson: text("guard_results_json").notNull().default("[]"),
71
+ model: text("model"),
72
+ promptVersion: integer("prompt_version"),
73
+ createdAt: text("created_at").notNull().default(now()),
74
+ ownerEmail: text("owner_email").notNull(),
75
+ orgId: text("org_id"),
76
+ });
77
+
78
+ export const triageRuns = table("factory_runs", {
79
+ id: text("id").primaryKey(),
80
+ itemId: text("item_id").notNull(),
81
+ source: text("source").notNull(),
82
+ provider: text("provider"),
83
+ providerTaskId: text("provider_task_id"),
84
+ dedupeKey: text("dedupe_key"),
85
+ approvalEmail: text("approval_email"),
86
+ status: text("status").notNull().default("received"),
87
+ progressLogJson: text("progress_log_json").notNull().default("[]"),
88
+ dispatchAttempts: integer("dispatch_attempts").notNull().default(0),
89
+ needsContinuation: integer("needs_continuation").notNull().default(0),
90
+ startedAt: text("started_at").notNull().default(now()),
91
+ heartbeatAt: text("heartbeat_at"),
92
+ completedAt: text("completed_at"),
93
+ error: text("error"),
94
+ ownerEmail: text("owner_email").notNull(),
95
+ orgId: text("org_id"),
96
+ });
97
+
98
+ export const triageFeedback = table("factory_feedback", {
99
+ id: text("id").primaryKey(),
100
+ decisionId: text("decision_id").notNull(),
101
+ verdict: text("verdict").notNull(),
102
+ note: text("note"),
103
+ createdAt: text("created_at").notNull().default(now()),
104
+ ownerEmail: text("owner_email").notNull(),
105
+ orgId: text("org_id"),
106
+ });
107
+
108
+ export const triageConfig = table("factory_config", {
109
+ id: text("id").primaryKey(),
110
+ slackWorkspace: text("slack_workspace").notNull().default("primary"),
111
+ slackChannelId: text("slack_channel_id"),
112
+ slackChannelName: text("slack_channel_name"),
113
+ pollingEnabled: integer("polling_enabled").notNull().default(0),
114
+ lastSlackTs: text("last_slack_ts"),
115
+ slackHistoryCursor: text("slack_history_cursor"),
116
+ repository: text("repository"),
117
+ createdAt: text("created_at").notNull().default(now()),
118
+ updatedAt: text("updated_at").notNull().default(now()),
119
+ ownerEmail: text("owner_email").notNull(),
120
+ orgId: text("org_id"),
121
+ });
122
+
123
+ export const factoryDefinitions = table(
124
+ "factory_definitions",
125
+ {
126
+ id: text("id").primaryKey(),
127
+ name: text("name").notNull(),
128
+ description: text("description").notNull().default(""),
129
+ prompt: text("prompt").notNull().default(""),
130
+ graphVersion: integer("graph_version").notNull().default(1),
131
+ graphJson: text("graph_json").notNull().default("{}"),
132
+ createdAt: text("created_at").notNull().default(now()),
133
+ updatedAt: text("updated_at").notNull().default(now()),
134
+ ownerEmail: text("owner_email").notNull(),
135
+ orgId: text("org_id"),
136
+ },
137
+ (factory) => ({
138
+ orgUpdatedIdx: index("factory_definitions_org_updated_idx").on(
139
+ factory.orgId,
140
+ factory.updatedAt,
141
+ ),
142
+ }),
143
+ );
144
+
145
+ export const factoryGraphVersions = table(
146
+ "factory_graph_versions",
147
+ {
148
+ id: text("id").primaryKey(),
149
+ factoryId: text("factory_id").notNull(),
150
+ version: integer("version").notNull(),
151
+ graphJson: text("graph_json").notNull(),
152
+ source: text("source").notNull().default("manual"),
153
+ changeSummary: text("change_summary").notNull().default(""),
154
+ createdAt: text("created_at").notNull().default(now()),
155
+ createdBy: text("created_by").notNull(),
156
+ ownerEmail: text("owner_email").notNull(),
157
+ orgId: text("org_id"),
158
+ },
159
+ (version) => ({
160
+ factoryVersionUnique: uniqueIndex("factory_graph_versions_unique_idx").on(
161
+ version.orgId,
162
+ version.factoryId,
163
+ version.version,
164
+ ),
165
+ factoryCreatedIdx: index("factory_graph_versions_created_idx").on(
166
+ version.orgId,
167
+ version.factoryId,
168
+ version.createdAt,
169
+ ),
170
+ }),
171
+ );
172
+
173
+ export const factoryComments = table(
174
+ "factory_comments",
175
+ {
176
+ id: text("id").primaryKey(),
177
+ factoryId: text("factory_id").notNull(),
178
+ graphVersion: integer("graph_version").notNull(),
179
+ targetType: text("target_type").notNull().default("canvas"),
180
+ targetId: text("target_id"),
181
+ body: text("body").notNull(),
182
+ createdAt: text("created_at").notNull().default(now()),
183
+ ownerEmail: text("owner_email").notNull(),
184
+ orgId: text("org_id"),
185
+ },
186
+ (comment) => ({
187
+ factoryCreatedIdx: index("factory_comments_created_idx").on(
188
+ comment.orgId,
189
+ comment.factoryId,
190
+ comment.createdAt,
191
+ ),
192
+ }),
193
+ );
@@ -0,0 +1,212 @@
1
+ import { z } from "zod";
2
+
3
+ export const factoryNodeKindSchema = z.enum([
4
+ "source",
5
+ "transform",
6
+ "decision",
7
+ "gate",
8
+ "agent",
9
+ "system",
10
+ "terminal",
11
+ ]);
12
+ export type FactoryNodeKind = z.infer<typeof factoryNodeKindSchema>;
13
+
14
+ export const factoryProviderSchema = z.enum([
15
+ "slack",
16
+ "github",
17
+ "builder",
18
+ "claude",
19
+ "codex",
20
+ "human",
21
+ "factory",
22
+ ]);
23
+ export type FactoryProvider = z.infer<typeof factoryProviderSchema>;
24
+
25
+ export const factoryGraphNodeSchema = z.object({
26
+ id: z.string().min(1).max(120),
27
+ label: z.string().trim().min(1).max(120),
28
+ description: z.string().trim().max(500).default(""),
29
+ kind: factoryNodeKindSchema,
30
+ provider: factoryProviderSchema.optional(),
31
+ agent: z.string().trim().max(120).optional(),
32
+ metricsKey: z.string().trim().max(120).optional(),
33
+ position: z.object({
34
+ x: z.number().finite().min(0).max(4000),
35
+ y: z.number().finite().min(0).max(2400),
36
+ }),
37
+ });
38
+ export type FactoryGraphNode = z.infer<typeof factoryGraphNodeSchema>;
39
+
40
+ export const factoryGraphEdgeSchema = z.object({
41
+ id: z.string().min(1).max(120),
42
+ source: z.string().min(1).max(120),
43
+ target: z.string().min(1).max(120),
44
+ label: z.string().trim().max(160).default(""),
45
+ condition: z.string().trim().max(500).default(""),
46
+ });
47
+ export type FactoryGraphEdge = z.infer<typeof factoryGraphEdgeSchema>;
48
+
49
+ export const factoryGraphSchema = z.object({
50
+ version: z.number().int().positive(),
51
+ name: z.string().trim().min(1).max(120),
52
+ description: z.string().trim().max(500).default(""),
53
+ executionMode: z.literal("blueprint").default("blueprint"),
54
+ nodes: z.array(factoryGraphNodeSchema).max(100),
55
+ edges: z.array(factoryGraphEdgeSchema).max(200),
56
+ });
57
+ export type FactoryGraph = z.infer<typeof factoryGraphSchema>;
58
+
59
+ export function normalizeFactoryGraph(value: unknown): FactoryGraph {
60
+ const graph = factoryGraphSchema.parse(value);
61
+ const nodeIds = new Set<string>();
62
+ for (const node of graph.nodes) {
63
+ if (nodeIds.has(node.id)) {
64
+ throw new Error(`Factory graph contains duplicate node id: ${node.id}`);
65
+ }
66
+ nodeIds.add(node.id);
67
+ }
68
+
69
+ const edgeIds = new Set<string>();
70
+ for (const edge of graph.edges) {
71
+ if (edgeIds.has(edge.id)) {
72
+ throw new Error(`Factory graph contains duplicate edge id: ${edge.id}`);
73
+ }
74
+ if (!nodeIds.has(edge.source) || !nodeIds.has(edge.target)) {
75
+ throw new Error(
76
+ `Factory graph edge ${edge.id} references a missing node.`,
77
+ );
78
+ }
79
+ if (edge.source === edge.target) {
80
+ throw new Error(`Factory graph edge ${edge.id} cannot self-reference.`);
81
+ }
82
+ edgeIds.add(edge.id);
83
+ }
84
+
85
+ return {
86
+ ...graph,
87
+ nodes: graph.nodes.map((node) => ({ ...node })),
88
+ edges: graph.edges.map((edge) => ({ ...edge })),
89
+ };
90
+ }
91
+
92
+ export function defaultFactoryGraph(): FactoryGraph {
93
+ return {
94
+ version: 1,
95
+ name: "Product feedback to shipped change",
96
+ description:
97
+ "Observe product signals, classify them safely, and keep a human in the loop before work starts.",
98
+ executionMode: "blueprint",
99
+ nodes: [
100
+ {
101
+ id: "slack-feedback",
102
+ label: "Product feedback",
103
+ description: "Watch the configured feedback channel.",
104
+ kind: "source",
105
+ provider: "slack",
106
+ metricsKey: "slack",
107
+ position: { x: 48, y: 170 },
108
+ },
109
+ {
110
+ id: "github-evidence",
111
+ label: "Pull request evidence",
112
+ description: "Read PR metadata, checks, and review state.",
113
+ kind: "source",
114
+ provider: "github",
115
+ metricsKey: "github",
116
+ position: { x: 48, y: 420 },
117
+ },
118
+ {
119
+ id: "normalize-context",
120
+ label: "Normalize context",
121
+ description: "Deduplicate and preserve source links and coverage.",
122
+ kind: "transform",
123
+ provider: "factory",
124
+ metricsKey: "items",
125
+ position: { x: 310, y: 290 },
126
+ },
127
+ {
128
+ id: "ai-triage",
129
+ label: "Enabled rules (parallel)",
130
+ description:
131
+ "Evaluate each enabled rule against the same evidence with structured guards.",
132
+ kind: "decision",
133
+ provider: "factory",
134
+ agent: "Factory agent",
135
+ metricsKey: "decisions",
136
+ position: { x: 570, y: 290 },
137
+ },
138
+ {
139
+ id: "human-gate",
140
+ label: "Human review",
141
+ description: "Review shadow decisions and approve a bounded run.",
142
+ kind: "gate",
143
+ provider: "human",
144
+ metricsKey: "needs_manual",
145
+ position: { x: 830, y: 155 },
146
+ },
147
+ {
148
+ id: "builder-agent",
149
+ label: "Approved coding run",
150
+ description: "Start approved work through the configured executor.",
151
+ kind: "agent",
152
+ provider: "builder",
153
+ agent: "Builder",
154
+ metricsKey: "runs",
155
+ position: { x: 830, y: 420 },
156
+ },
157
+ {
158
+ id: "shipped-change",
159
+ label: "PR and delivery",
160
+ description: "Reconcile callbacks and preserve the terminal outcome.",
161
+ kind: "terminal",
162
+ provider: "github",
163
+ metricsKey: "completed",
164
+ position: { x: 1090, y: 420 },
165
+ },
166
+ ],
167
+ edges: [
168
+ {
169
+ id: "slack-to-normalize",
170
+ source: "slack-feedback",
171
+ target: "normalize-context",
172
+ label: "feedback",
173
+ condition: "",
174
+ },
175
+ {
176
+ id: "github-to-normalize",
177
+ source: "github-evidence",
178
+ target: "normalize-context",
179
+ label: "evidence",
180
+ condition: "",
181
+ },
182
+ {
183
+ id: "normalize-to-triage",
184
+ source: "normalize-context",
185
+ target: "ai-triage",
186
+ label: "complete or partial context",
187
+ condition: "",
188
+ },
189
+ {
190
+ id: "triage-to-human",
191
+ source: "ai-triage",
192
+ target: "human-gate",
193
+ label: "shadow decision",
194
+ condition: "always review until a rule is explicitly promoted",
195
+ },
196
+ {
197
+ id: "human-to-agent",
198
+ source: "human-gate",
199
+ target: "builder-agent",
200
+ label: "approved proposal",
201
+ condition: "guard checks pass and a person approves",
202
+ },
203
+ {
204
+ id: "agent-to-shipped",
205
+ source: "builder-agent",
206
+ target: "shipped-change",
207
+ label: "callback and reconciliation",
208
+ condition: "",
209
+ },
210
+ ],
211
+ };
212
+ }
@@ -0,0 +1,121 @@
1
+ import { and, count, desc, eq, type SQL } from "drizzle-orm";
2
+
3
+ import { getDb } from "../db/index.js";
4
+ import {
5
+ factoryDefinitions,
6
+ triageDecisions,
7
+ triageItems,
8
+ triageRuns,
9
+ } from "../db/schema.js";
10
+ import {
11
+ defaultFactoryGraph,
12
+ normalizeFactoryGraph,
13
+ type FactoryGraph,
14
+ } from "./contracts.js";
15
+
16
+ export const DEFAULT_FACTORY_ID = "product-feedback";
17
+
18
+ export interface FactoryMetricSummary {
19
+ totalItems: number;
20
+ slackItems: number;
21
+ githubItems: number;
22
+ decisions: number;
23
+ manualItems: number;
24
+ runs: number;
25
+ completedRuns: number;
26
+ }
27
+
28
+ export function parseFactoryGraph(value: string): FactoryGraph {
29
+ try {
30
+ return normalizeFactoryGraph(JSON.parse(value));
31
+ } catch (error) {
32
+ throw new Error(
33
+ `Factory graph is unreadable: ${error instanceof Error ? error.message : String(error)}`,
34
+ );
35
+ }
36
+ }
37
+
38
+ export async function listFactoryDefinitions(orgId: string) {
39
+ return getDb()
40
+ .select({
41
+ id: factoryDefinitions.id,
42
+ name: factoryDefinitions.name,
43
+ description: factoryDefinitions.description,
44
+ prompt: factoryDefinitions.prompt,
45
+ graphVersion: factoryDefinitions.graphVersion,
46
+ updatedAt: factoryDefinitions.updatedAt,
47
+ })
48
+ .from(factoryDefinitions)
49
+ .where(eq(factoryDefinitions.orgId, orgId))
50
+ .orderBy(desc(factoryDefinitions.updatedAt));
51
+ }
52
+
53
+ export async function readFactoryDefinition(orgId: string, factoryId: string) {
54
+ return (
55
+ await getDb()
56
+ .select()
57
+ .from(factoryDefinitions)
58
+ .where(eq(factoryDefinitions.id, factoryId))
59
+ .limit(1)
60
+ ).find((row) => row.orgId === orgId);
61
+ }
62
+
63
+ export async function readFactoryMetrics(
64
+ orgId: string,
65
+ ): Promise<FactoryMetricSummary> {
66
+ const db = getDb();
67
+ const [
68
+ totalItems,
69
+ slackItems,
70
+ githubItems,
71
+ decisions,
72
+ manualItems,
73
+ runs,
74
+ completedRuns,
75
+ ] = await Promise.all([
76
+ countRows(triageItems, orgId),
77
+ countRows(triageItems, orgId, eq(triageItems.source, "slack")),
78
+ countRows(triageItems, orgId, eq(triageItems.source, "github")),
79
+ countRows(triageDecisions, orgId),
80
+ countRows(triageItems, orgId, eq(triageItems.status, "needs_manual")),
81
+ countRows(triageRuns, orgId),
82
+ countRows(triageRuns, orgId, eq(triageRuns.status, "completed")),
83
+ ]);
84
+
85
+ return {
86
+ totalItems,
87
+ slackItems,
88
+ githubItems,
89
+ decisions,
90
+ manualItems,
91
+ runs,
92
+ completedRuns,
93
+ };
94
+ }
95
+
96
+ async function countRows(
97
+ table: typeof triageItems | typeof triageDecisions | typeof triageRuns,
98
+ orgId: string,
99
+ extra?: SQL,
100
+ ) {
101
+ const where = extra
102
+ ? and(eq(table.orgId, orgId), extra)
103
+ : eq(table.orgId, orgId);
104
+ const row = (
105
+ await getDb().select({ value: count() }).from(table).where(where)
106
+ )[0];
107
+ return Number(row?.value ?? 0);
108
+ }
109
+
110
+ export function defaultFactoryDefinition() {
111
+ return {
112
+ id: DEFAULT_FACTORY_ID,
113
+ name: "Product feedback to shipped change",
114
+ description: defaultFactoryGraph().description,
115
+ prompt:
116
+ "Observe product feedback and pull-request evidence, classify it in shadow mode, and keep a person in the loop before coding work starts.",
117
+ graphVersion: 1,
118
+ graph: defaultFactoryGraph(),
119
+ virtual: true,
120
+ } as const;
121
+ }