@agent-native/core 0.7.19 → 0.7.21

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 (263) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/builder-engine.js +45 -2
  4. package/dist/agent/engine/builder-engine.js.map +1 -1
  5. package/dist/agent/loop-settings.d.ts +37 -0
  6. package/dist/agent/loop-settings.d.ts.map +1 -0
  7. package/dist/agent/loop-settings.js +127 -0
  8. package/dist/agent/loop-settings.js.map +1 -0
  9. package/dist/agent/production-agent.d.ts +8 -0
  10. package/dist/agent/production-agent.d.ts.map +1 -1
  11. package/dist/agent/production-agent.js +268 -29
  12. package/dist/agent/production-agent.js.map +1 -1
  13. package/dist/agent/run-manager.d.ts.map +1 -1
  14. package/dist/agent/run-manager.js +76 -3
  15. package/dist/agent/run-manager.js.map +1 -1
  16. package/dist/agent/run-store.d.ts +1 -1
  17. package/dist/agent/run-store.d.ts.map +1 -1
  18. package/dist/agent/run-store.js +65 -2
  19. package/dist/agent/run-store.js.map +1 -1
  20. package/dist/agent/thread-data-builder.d.ts +3 -0
  21. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  22. package/dist/agent/thread-data-builder.js +52 -10
  23. package/dist/agent/thread-data-builder.js.map +1 -1
  24. package/dist/agent/tool-search.d.ts +37 -0
  25. package/dist/agent/tool-search.d.ts.map +1 -0
  26. package/dist/agent/tool-search.js +201 -0
  27. package/dist/agent/tool-search.js.map +1 -0
  28. package/dist/agent/types.d.ts +8 -1
  29. package/dist/agent/types.d.ts.map +1 -1
  30. package/dist/agent/types.js.map +1 -1
  31. package/dist/cli/create.d.ts.map +1 -1
  32. package/dist/cli/create.js +44 -9
  33. package/dist/cli/create.js.map +1 -1
  34. package/dist/cli/workspacify.d.ts +2 -0
  35. package/dist/cli/workspacify.d.ts.map +1 -1
  36. package/dist/cli/workspacify.js +34 -1
  37. package/dist/cli/workspacify.js.map +1 -1
  38. package/dist/client/AssistantChat.d.ts.map +1 -1
  39. package/dist/client/AssistantChat.js +277 -18
  40. package/dist/client/AssistantChat.js.map +1 -1
  41. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  42. package/dist/client/ConnectBuilderCard.js +1 -1
  43. package/dist/client/ConnectBuilderCard.js.map +1 -1
  44. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  45. package/dist/client/MultiTabAssistantChat.js +14 -6
  46. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  47. package/dist/client/NewWorkspaceAppFlow.d.ts +14 -0
  48. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -0
  49. package/dist/client/NewWorkspaceAppFlow.js +198 -0
  50. package/dist/client/NewWorkspaceAppFlow.js.map +1 -0
  51. package/dist/client/PoweredByBadge.d.ts +10 -1
  52. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  53. package/dist/client/PoweredByBadge.js +120 -8
  54. package/dist/client/PoweredByBadge.js.map +1 -1
  55. package/dist/client/agent-chat-adapter.d.ts +3 -5
  56. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  57. package/dist/client/agent-chat-adapter.js +26 -19
  58. package/dist/client/agent-chat-adapter.js.map +1 -1
  59. package/dist/client/agent-chat.d.ts.map +1 -1
  60. package/dist/client/agent-chat.js +15 -3
  61. package/dist/client/agent-chat.js.map +1 -1
  62. package/dist/client/analytics.d.ts +1 -1
  63. package/dist/client/analytics.d.ts.map +1 -1
  64. package/dist/client/analytics.js +141 -1
  65. package/dist/client/analytics.js.map +1 -1
  66. package/dist/client/builder-frame.d.ts +10 -0
  67. package/dist/client/builder-frame.d.ts.map +1 -0
  68. package/dist/client/builder-frame.js +94 -0
  69. package/dist/client/builder-frame.js.map +1 -0
  70. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  71. package/dist/client/composer/MentionPopover.js +5 -1
  72. package/dist/client/composer/MentionPopover.js.map +1 -1
  73. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  74. package/dist/client/composer/TiptapComposer.js +11 -6
  75. package/dist/client/composer/TiptapComposer.js.map +1 -1
  76. package/dist/client/error-format.d.ts +20 -1
  77. package/dist/client/error-format.d.ts.map +1 -1
  78. package/dist/client/error-format.js +53 -5
  79. package/dist/client/error-format.js.map +1 -1
  80. package/dist/client/index.d.ts +3 -1
  81. package/dist/client/index.d.ts.map +1 -1
  82. package/dist/client/index.js +3 -1
  83. package/dist/client/index.js.map +1 -1
  84. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  85. package/dist/client/notifications/NotificationsBell.js +28 -1
  86. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  87. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  88. package/dist/client/onboarding/OnboardingPanel.js +88 -6
  89. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  90. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  91. package/dist/client/settings/SettingsPanel.js +145 -9
  92. package/dist/client/settings/SettingsPanel.js.map +1 -1
  93. package/dist/client/settings/useBuilderStatus.d.ts +13 -0
  94. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  95. package/dist/client/settings/useBuilderStatus.js +50 -9
  96. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  97. package/dist/client/sse-event-processor.d.ts +3 -0
  98. package/dist/client/sse-event-processor.d.ts.map +1 -1
  99. package/dist/client/sse-event-processor.js +88 -7
  100. package/dist/client/sse-event-processor.js.map +1 -1
  101. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  102. package/dist/client/tools/ToolsListPage.js +16 -1
  103. package/dist/client/tools/ToolsListPage.js.map +1 -1
  104. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
  105. package/dist/client/tools/ToolsSidebarSection.js +63 -8
  106. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  107. package/dist/client/tools/tool-order.d.ts +7 -0
  108. package/dist/client/tools/tool-order.d.ts.map +1 -0
  109. package/dist/client/tools/tool-order.js +47 -0
  110. package/dist/client/tools/tool-order.js.map +1 -0
  111. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  112. package/dist/client/transcription/BuilderTranscriptionCta.js +71 -6
  113. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  114. package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
  115. package/dist/client/use-send-to-agent-chat.js +11 -3
  116. package/dist/client/use-send-to-agent-chat.js.map +1 -1
  117. package/dist/client/useProductionAgent.d.ts.map +1 -1
  118. package/dist/client/useProductionAgent.js +1 -1
  119. package/dist/client/useProductionAgent.js.map +1 -1
  120. package/dist/db/client.d.ts.map +1 -1
  121. package/dist/db/client.js +5 -1
  122. package/dist/db/client.js.map +1 -1
  123. package/dist/deploy/build.d.ts +1 -0
  124. package/dist/deploy/build.d.ts.map +1 -1
  125. package/dist/deploy/build.js +4 -1
  126. package/dist/deploy/build.js.map +1 -1
  127. package/dist/oauth-tokens/index.d.ts +1 -1
  128. package/dist/oauth-tokens/index.d.ts.map +1 -1
  129. package/dist/oauth-tokens/index.js +1 -1
  130. package/dist/oauth-tokens/index.js.map +1 -1
  131. package/dist/oauth-tokens/store.d.ts.map +1 -1
  132. package/dist/oauth-tokens/store.js +6 -0
  133. package/dist/oauth-tokens/store.js.map +1 -1
  134. package/dist/observability/store.d.ts.map +1 -1
  135. package/dist/observability/store.js +19 -19
  136. package/dist/observability/store.js.map +1 -1
  137. package/dist/onboarding/default-steps.d.ts.map +1 -1
  138. package/dist/onboarding/default-steps.js +95 -61
  139. package/dist/onboarding/default-steps.js.map +1 -1
  140. package/dist/onboarding/plugin.d.ts.map +1 -1
  141. package/dist/onboarding/plugin.js +17 -8
  142. package/dist/onboarding/plugin.js.map +1 -1
  143. package/dist/org/migrations.js +2 -2
  144. package/dist/org/migrations.js.map +1 -1
  145. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  146. package/dist/scripts/agent-engines/list-agent-engines.js +2 -3
  147. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  148. package/dist/scripts/db/exec.d.ts +2 -1
  149. package/dist/scripts/db/exec.d.ts.map +1 -1
  150. package/dist/scripts/db/exec.js +264 -61
  151. package/dist/scripts/db/exec.js.map +1 -1
  152. package/dist/scripts/db/schema.d.ts.map +1 -1
  153. package/dist/scripts/db/schema.js +16 -4
  154. package/dist/scripts/db/schema.js.map +1 -1
  155. package/dist/scripts/dev/index.d.ts.map +1 -1
  156. package/dist/scripts/dev/index.js +36 -11
  157. package/dist/scripts/dev/index.js.map +1 -1
  158. package/dist/scripts/manage-agent-loop-settings.d.ts +7 -0
  159. package/dist/scripts/manage-agent-loop-settings.d.ts.map +1 -0
  160. package/dist/scripts/manage-agent-loop-settings.js +63 -0
  161. package/dist/scripts/manage-agent-loop-settings.js.map +1 -0
  162. package/dist/scripts/runner.d.ts.map +1 -1
  163. package/dist/scripts/runner.js +11 -0
  164. package/dist/scripts/runner.js.map +1 -1
  165. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  166. package/dist/server/agent-chat-plugin.js +60 -18
  167. package/dist/server/agent-chat-plugin.js.map +1 -1
  168. package/dist/server/app-url.d.ts +5 -4
  169. package/dist/server/app-url.d.ts.map +1 -1
  170. package/dist/server/app-url.js +8 -4
  171. package/dist/server/app-url.js.map +1 -1
  172. package/dist/server/auth.d.ts +8 -0
  173. package/dist/server/auth.d.ts.map +1 -1
  174. package/dist/server/auth.js +82 -29
  175. package/dist/server/auth.js.map +1 -1
  176. package/dist/server/better-auth-instance.d.ts.map +1 -1
  177. package/dist/server/better-auth-instance.js +16 -5
  178. package/dist/server/better-auth-instance.js.map +1 -1
  179. package/dist/server/builder-browser.d.ts +12 -0
  180. package/dist/server/builder-browser.d.ts.map +1 -1
  181. package/dist/server/builder-browser.js +36 -4
  182. package/dist/server/builder-browser.js.map +1 -1
  183. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  184. package/dist/server/core-routes-plugin.js +350 -53
  185. package/dist/server/core-routes-plugin.js.map +1 -1
  186. package/dist/server/credential-provider.d.ts +21 -3
  187. package/dist/server/credential-provider.d.ts.map +1 -1
  188. package/dist/server/credential-provider.js +51 -21
  189. package/dist/server/credential-provider.js.map +1 -1
  190. package/dist/server/google-oauth.d.ts +3 -0
  191. package/dist/server/google-oauth.d.ts.map +1 -1
  192. package/dist/server/google-oauth.js +27 -3
  193. package/dist/server/google-oauth.js.map +1 -1
  194. package/dist/server/index.d.ts +4 -3
  195. package/dist/server/index.d.ts.map +1 -1
  196. package/dist/server/index.js +4 -3
  197. package/dist/server/index.js.map +1 -1
  198. package/dist/server/onboarding-html.js +2 -2
  199. package/dist/server/onboarding-html.js.map +1 -1
  200. package/dist/server/schema-prompt.d.ts.map +1 -1
  201. package/dist/server/schema-prompt.js +2 -1
  202. package/dist/server/schema-prompt.js.map +1 -1
  203. package/dist/server/security-headers.d.ts +3 -0
  204. package/dist/server/security-headers.d.ts.map +1 -1
  205. package/dist/server/security-headers.js +7 -1
  206. package/dist/server/security-headers.js.map +1 -1
  207. package/dist/server/ssr-handler.d.ts.map +1 -1
  208. package/dist/server/ssr-handler.js +31 -6
  209. package/dist/server/ssr-handler.js.map +1 -1
  210. package/dist/templates/default/_gitignore +5 -1
  211. package/dist/templates/default/app/root.tsx +1 -0
  212. package/dist/templates/default/public/favicon.svg +3 -3
  213. package/dist/templates/default/public/icon-180.svg +3 -3
  214. package/dist/templates/default/public/icon-192.svg +3 -3
  215. package/dist/templates/default/public/icon-512.svg +3 -3
  216. package/dist/templates/workspace-core/AGENTS.md +23 -7
  217. package/dist/templates/workspace-core/package.json +2 -1
  218. package/dist/templates/workspace-core/src/credentials.ts +22 -11
  219. package/dist/templates/workspace-root/.env.example +7 -0
  220. package/dist/templates/workspace-root/README.md +6 -3
  221. package/dist/templates/workspace-root/_gitignore +3 -0
  222. package/dist/templates/workspace-root/package.json +3 -1
  223. package/dist/templates/workspace-root/scripts/workspace-dev.ts +375 -0
  224. package/dist/tools/actions.d.ts.map +1 -1
  225. package/dist/tools/actions.js +2 -0
  226. package/dist/tools/actions.js.map +1 -1
  227. package/dist/tools/html-shell.d.ts.map +1 -1
  228. package/dist/tools/html-shell.js +13 -1
  229. package/dist/tools/html-shell.js.map +1 -1
  230. package/dist/tools/store.d.ts.map +1 -1
  231. package/dist/tools/store.js +10 -10
  232. package/dist/tools/store.js.map +1 -1
  233. package/dist/tracking/providers.d.ts +1 -0
  234. package/dist/tracking/providers.d.ts.map +1 -1
  235. package/dist/tracking/providers.js +72 -0
  236. package/dist/tracking/providers.js.map +1 -1
  237. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  238. package/dist/vite/action-types-plugin.js +106 -9
  239. package/dist/vite/action-types-plugin.js.map +1 -1
  240. package/dist/vite/client.d.ts.map +1 -1
  241. package/dist/vite/client.js +62 -1
  242. package/dist/vite/client.js.map +1 -1
  243. package/docs/content/authentication.md +17 -13
  244. package/docs/content/deployment.md +11 -11
  245. package/docs/content/mcp-clients.md +2 -2
  246. package/docs/content/onboarding.md +32 -30
  247. package/docs/content/security.md +1 -1
  248. package/docs/content/tools.md +4 -0
  249. package/package.json +2 -2
  250. package/src/templates/default/_gitignore +5 -1
  251. package/src/templates/default/app/root.tsx +1 -0
  252. package/src/templates/default/public/favicon.svg +3 -3
  253. package/src/templates/default/public/icon-180.svg +3 -3
  254. package/src/templates/default/public/icon-192.svg +3 -3
  255. package/src/templates/default/public/icon-512.svg +3 -3
  256. package/src/templates/workspace-core/AGENTS.md +23 -7
  257. package/src/templates/workspace-core/package.json +2 -1
  258. package/src/templates/workspace-core/src/credentials.ts +22 -11
  259. package/src/templates/workspace-root/.env.example +7 -0
  260. package/src/templates/workspace-root/README.md +6 -3
  261. package/src/templates/workspace-root/_gitignore +3 -0
  262. package/src/templates/workspace-root/package.json +3 -1
  263. package/src/templates/workspace-root/scripts/workspace-dev.ts +375 -0
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/tools/store.ts"],"names":[],"mappings":"AAuCA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiCvD;AA4DD,wBAAgB,sBAAsB,SASrC;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC1C;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAOpD;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAIjE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA2BvE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC3C;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAczB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe7D"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/tools/store.ts"],"names":[],"mappings":"AAuCA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CvD;AA4DD,wBAAgB,sBAAsB,SASrC;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC1C;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAOpD;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAIjE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA2BvE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC3C;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAczB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe7D"}
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { eq } from "drizzle-orm";
3
- import { getDbExec, isPostgres } from "../db/client.js";
3
+ import { getDbExec, isPostgres, retryOnDdlRace } from "../db/client.js";
4
4
  import { createGetDb } from "../db/create-get-db.js";
5
5
  import { accessFilter, assertAccess, resolveAccess, } from "../sharing/access.js";
6
6
  import { getRequestUserEmail, getRequestOrgId, } from "../server/request-context.js";
@@ -13,23 +13,23 @@ export async function ensureToolsTables() {
13
13
  _initPromise = (async () => {
14
14
  const client = getDbExec();
15
15
  const pg = isPostgres();
16
- await client.execute(pg ? TOOLS_CREATE_SQL_PG : TOOLS_CREATE_SQL);
17
- await client.execute(pg ? TOOL_SHARES_CREATE_SQL_PG : TOOL_SHARES_CREATE_SQL);
18
- await client.execute(pg ? TOOL_DATA_CREATE_SQL_PG : TOOL_DATA_CREATE_SQL);
16
+ await retryOnDdlRace(() => client.execute(pg ? TOOLS_CREATE_SQL_PG : TOOLS_CREATE_SQL));
17
+ await retryOnDdlRace(() => client.execute(pg ? TOOL_SHARES_CREATE_SQL_PG : TOOL_SHARES_CREATE_SQL));
18
+ await retryOnDdlRace(() => client.execute(pg ? TOOL_DATA_CREATE_SQL_PG : TOOL_DATA_CREATE_SQL));
19
19
  await ensureToolDataItemId(client, pg);
20
20
  await ensureToolDataScope(client, pg);
21
21
  await client.execute(pg ? TOOL_DATA_DROP_OLD_INDEX_SQL_PG : TOOL_DATA_DROP_OLD_INDEX_SQL);
22
- await client.execute(pg ? TOOL_DATA_ITEM_INDEX_SQL_PG : TOOL_DATA_ITEM_INDEX_SQL);
23
- await client.execute(TOOLS_OWNER_INDEX_SQL);
24
- await client.execute(TOOLS_ORG_INDEX_SQL);
25
- await client.execute(TOOL_SHARES_RESOURCE_INDEX_SQL);
22
+ await retryOnDdlRace(() => client.execute(pg ? TOOL_DATA_ITEM_INDEX_SQL_PG : TOOL_DATA_ITEM_INDEX_SQL));
23
+ await retryOnDdlRace(() => client.execute(TOOLS_OWNER_INDEX_SQL));
24
+ await retryOnDdlRace(() => client.execute(TOOLS_ORG_INDEX_SQL));
25
+ await retryOnDdlRace(() => client.execute(TOOL_SHARES_RESOURCE_INDEX_SQL));
26
26
  // tool_consents was introduced for an audit-C1 per-viewer consent
27
27
  // gate that we removed once we settled on intra-org trust as the
28
28
  // baseline. The table is kept (additive — never drop) so deploys
29
29
  // that already created it stay healthy; the runtime consent code
30
30
  // is gone. Idempotent CREATE IF NOT EXISTS for fresh schemas.
31
- await client.execute(pg ? TOOL_CONSENTS_CREATE_SQL_PG : TOOL_CONSENTS_CREATE_SQL);
32
- await client.execute(TOOL_CONSENTS_VIEWER_INDEX_SQL);
31
+ await retryOnDdlRace(() => client.execute(pg ? TOOL_CONSENTS_CREATE_SQL_PG : TOOL_CONSENTS_CREATE_SQL));
32
+ await retryOnDdlRace(() => client.execute(TOOL_CONSENTS_VIEWER_INDEX_SQL));
33
33
  })();
34
34
  }
35
35
  return _initPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/tools/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { getDbExec, isPostgres } from \"../db/client.js\";\nimport { createGetDb } from \"../db/create-get-db.js\";\nimport {\n accessFilter,\n assertAccess,\n resolveAccess,\n} from \"../sharing/access.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { registerShareableResource } from \"../sharing/registry.js\";\nimport {\n tools,\n toolShares,\n TOOLS_CREATE_SQL,\n TOOLS_CREATE_SQL_PG,\n TOOL_SHARES_CREATE_SQL,\n TOOL_SHARES_CREATE_SQL_PG,\n TOOL_DATA_CREATE_SQL,\n TOOL_DATA_CREATE_SQL_PG,\n TOOL_DATA_ITEM_INDEX_SQL,\n TOOL_DATA_ITEM_INDEX_SQL_PG,\n TOOL_DATA_DROP_OLD_INDEX_SQL,\n TOOL_DATA_DROP_OLD_INDEX_SQL_PG,\n TOOLS_OWNER_INDEX_SQL,\n TOOLS_ORG_INDEX_SQL,\n TOOL_SHARES_RESOURCE_INDEX_SQL,\n TOOL_CONSENTS_CREATE_SQL,\n TOOL_CONSENTS_CREATE_SQL_PG,\n TOOL_CONSENTS_VIEWER_INDEX_SQL,\n} from \"./schema.js\";\n\nconst getDb = createGetDb({ tools, toolShares });\n\nlet _initPromise: Promise<void> | undefined;\n\nexport async function ensureToolsTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const pg = isPostgres();\n await client.execute(pg ? TOOLS_CREATE_SQL_PG : TOOLS_CREATE_SQL);\n await client.execute(\n pg ? TOOL_SHARES_CREATE_SQL_PG : TOOL_SHARES_CREATE_SQL,\n );\n await client.execute(pg ? TOOL_DATA_CREATE_SQL_PG : TOOL_DATA_CREATE_SQL);\n await ensureToolDataItemId(client, pg);\n await ensureToolDataScope(client, pg);\n await client.execute(\n pg ? TOOL_DATA_DROP_OLD_INDEX_SQL_PG : TOOL_DATA_DROP_OLD_INDEX_SQL,\n );\n await client.execute(\n pg ? TOOL_DATA_ITEM_INDEX_SQL_PG : TOOL_DATA_ITEM_INDEX_SQL,\n );\n await client.execute(TOOLS_OWNER_INDEX_SQL);\n await client.execute(TOOLS_ORG_INDEX_SQL);\n await client.execute(TOOL_SHARES_RESOURCE_INDEX_SQL);\n // tool_consents was introduced for an audit-C1 per-viewer consent\n // gate that we removed once we settled on intra-org trust as the\n // baseline. The table is kept (additive — never drop) so deploys\n // that already created it stay healthy; the runtime consent code\n // is gone. Idempotent CREATE IF NOT EXISTS for fresh schemas.\n await client.execute(\n pg ? TOOL_CONSENTS_CREATE_SQL_PG : TOOL_CONSENTS_CREATE_SQL,\n );\n await client.execute(TOOL_CONSENTS_VIEWER_INDEX_SQL);\n })();\n }\n return _initPromise;\n}\n\nasync function ensureToolDataItemId(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n if (pg) {\n await client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS item_id TEXT`,\n );\n return;\n }\n\n // Keep this additive: legacy rows with item_id=id are still read correctly\n // through COALESCE(item_id, id), so SQLite never needs a table rebuild here.\n try {\n await client.execute(`ALTER TABLE tool_data ADD COLUMN item_id TEXT`);\n } catch (err: any) {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n ) {\n throw err;\n }\n }\n}\n\nasync function ensureToolDataScope(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const addCol = (name: string, def: string) => {\n if (pg) {\n return client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS ${name} ${def}`,\n );\n }\n return client\n .execute(`ALTER TABLE tool_data ADD COLUMN ${name} ${def}`)\n .catch((err: any) => {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n )\n throw err;\n });\n };\n await addCol(\"scope\", \"TEXT NOT NULL DEFAULT 'user'\");\n await addCol(\"org_id\", \"TEXT\");\n await addCol(\"scope_key\", \"TEXT NOT NULL DEFAULT 'local@localhost'\");\n // One-time backfill migration: replaces the dev-mode DEFAULT scope_key\n // with each row's real owner_email. Not a per-request fallback.\n await client.execute(\n // guard:allow-localhost-fallback — one-time backfill migration replacing dev-mode default scope_key with the row's real owner_email\n `UPDATE tool_data SET scope_key = owner_email WHERE scope_key = 'local@localhost' AND owner_email != 'local@localhost'`,\n );\n}\n\nexport function registerToolsShareable() {\n registerShareableResource({\n type: \"tool\",\n resourceTable: tools,\n sharesTable: toolShares,\n displayName: \"Tool\",\n titleColumn: \"name\",\n getDb: () => getDb(),\n });\n}\n\nexport interface ToolRow {\n id: string;\n name: string;\n description: string;\n content: string;\n icon: string | null;\n createdAt: string;\n updatedAt: string;\n ownerEmail: string;\n orgId: string | null;\n visibility: \"private\" | \"org\" | \"public\";\n}\n\nexport async function listTools(): Promise<ToolRow[]> {\n await ensureToolsTables();\n const db = getDb();\n return db\n .select()\n .from(tools)\n .where(accessFilter(tools, toolShares)) as Promise<ToolRow[]>;\n}\n\nexport async function getTool(id: string): Promise<ToolRow | null> {\n await ensureToolsTables();\n const access = await resolveAccess(\"tool\", id);\n return (access?.resource as ToolRow | undefined) ?? null;\n}\n\nexport interface CreateToolData {\n name: string;\n description?: string;\n content?: string;\n icon?: string;\n}\n\nexport async function createTool(data: CreateToolData): Promise<ToolRow> {\n await ensureToolsTables();\n const db = getDb();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const orgId = getRequestOrgId();\n const id = randomUUID();\n const now = new Date().toISOString();\n const row: ToolRow = {\n id,\n name: data.name,\n description: data.description ?? \"\",\n content: data.content ?? \"\",\n icon: data.icon ?? null,\n createdAt: now,\n updatedAt: now,\n ownerEmail: userEmail,\n orgId: orgId ?? null,\n // Default to org-visibility when the user has an active organization so\n // teammates see the tool in their sidebar — matching how analytics\n // dashboards/analyses are scoped (`templates/analytics/server/lib/\n // dashboards-store.ts:356`). Solo users (no org) get the private\n // default. Owners can still flip back to private via update-tool.\n visibility: orgId ? \"org\" : \"private\",\n };\n await db.insert(tools).values(row);\n return row;\n}\n\nexport interface UpdateToolData {\n name?: string;\n description?: string;\n icon?: string;\n visibility?: \"private\" | \"org\" | \"public\";\n}\n\nexport async function updateTool(\n id: string,\n data: UpdateToolData,\n): Promise<ToolRow | null> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"editor\");\n const db = getDb();\n const updates: Record<string, unknown> = {\n updatedAt: new Date().toISOString(),\n };\n if (data.name !== undefined) updates.name = data.name;\n if (data.description !== undefined) updates.description = data.description;\n if (data.icon !== undefined) updates.icon = data.icon;\n if (data.visibility !== undefined) updates.visibility = data.visibility;\n await db.update(tools).set(updates).where(eq(tools.id, id));\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n return (rows[0] as ToolRow) ?? null;\n}\n\nexport interface UpdateToolContentOpts {\n content?: string;\n patches?: Array<{ find: string; replace: string }>;\n}\n\nexport async function updateToolContent(\n id: string,\n opts: UpdateToolContentOpts,\n): Promise<ToolRow | null> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"editor\");\n const db = getDb();\n\n let newContent: string;\n if (opts.content !== undefined) {\n newContent = opts.content;\n } else if (opts.patches) {\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n if (!rows[0]) return null;\n newContent = (rows[0] as ToolRow).content;\n for (const patch of opts.patches) {\n newContent = newContent.replace(patch.find, patch.replace);\n }\n } else {\n return null;\n }\n\n await db\n .update(tools)\n .set({ content: newContent, updatedAt: new Date().toISOString() })\n .where(eq(tools.id, id));\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n return (rows[0] as ToolRow) ?? null;\n}\n\nexport async function deleteTool(id: string): Promise<boolean> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"admin\");\n const db = getDb();\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n if (!rows[0]) return false;\n await db.delete(toolShares).where(eq(toolShares.resourceId, id));\n await getDbExec().execute({\n sql: `DELETE FROM tool_data WHERE tool_id = ?`,\n args: [id],\n });\n const { cascadeDeleteToolSlots } = await import(\"./slots/store.js\");\n await cascadeDeleteToolSlots(id);\n await db.delete(tools).where(eq(tools.id, id));\n return true;\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/tools/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { getDbExec, isPostgres, retryOnDdlRace } from \"../db/client.js\";\nimport { createGetDb } from \"../db/create-get-db.js\";\nimport {\n accessFilter,\n assertAccess,\n resolveAccess,\n} from \"../sharing/access.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { registerShareableResource } from \"../sharing/registry.js\";\nimport {\n tools,\n toolShares,\n TOOLS_CREATE_SQL,\n TOOLS_CREATE_SQL_PG,\n TOOL_SHARES_CREATE_SQL,\n TOOL_SHARES_CREATE_SQL_PG,\n TOOL_DATA_CREATE_SQL,\n TOOL_DATA_CREATE_SQL_PG,\n TOOL_DATA_ITEM_INDEX_SQL,\n TOOL_DATA_ITEM_INDEX_SQL_PG,\n TOOL_DATA_DROP_OLD_INDEX_SQL,\n TOOL_DATA_DROP_OLD_INDEX_SQL_PG,\n TOOLS_OWNER_INDEX_SQL,\n TOOLS_ORG_INDEX_SQL,\n TOOL_SHARES_RESOURCE_INDEX_SQL,\n TOOL_CONSENTS_CREATE_SQL,\n TOOL_CONSENTS_CREATE_SQL_PG,\n TOOL_CONSENTS_VIEWER_INDEX_SQL,\n} from \"./schema.js\";\n\nconst getDb = createGetDb({ tools, toolShares });\n\nlet _initPromise: Promise<void> | undefined;\n\nexport async function ensureToolsTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const pg = isPostgres();\n await retryOnDdlRace(() =>\n client.execute(pg ? TOOLS_CREATE_SQL_PG : TOOLS_CREATE_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(pg ? TOOL_SHARES_CREATE_SQL_PG : TOOL_SHARES_CREATE_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(pg ? TOOL_DATA_CREATE_SQL_PG : TOOL_DATA_CREATE_SQL),\n );\n await ensureToolDataItemId(client, pg);\n await ensureToolDataScope(client, pg);\n await client.execute(\n pg ? TOOL_DATA_DROP_OLD_INDEX_SQL_PG : TOOL_DATA_DROP_OLD_INDEX_SQL,\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? TOOL_DATA_ITEM_INDEX_SQL_PG : TOOL_DATA_ITEM_INDEX_SQL,\n ),\n );\n await retryOnDdlRace(() => client.execute(TOOLS_OWNER_INDEX_SQL));\n await retryOnDdlRace(() => client.execute(TOOLS_ORG_INDEX_SQL));\n await retryOnDdlRace(() =>\n client.execute(TOOL_SHARES_RESOURCE_INDEX_SQL),\n );\n // tool_consents was introduced for an audit-C1 per-viewer consent\n // gate that we removed once we settled on intra-org trust as the\n // baseline. The table is kept (additive — never drop) so deploys\n // that already created it stay healthy; the runtime consent code\n // is gone. Idempotent CREATE IF NOT EXISTS for fresh schemas.\n await retryOnDdlRace(() =>\n client.execute(\n pg ? TOOL_CONSENTS_CREATE_SQL_PG : TOOL_CONSENTS_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(TOOL_CONSENTS_VIEWER_INDEX_SQL),\n );\n })();\n }\n return _initPromise;\n}\n\nasync function ensureToolDataItemId(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n if (pg) {\n await client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS item_id TEXT`,\n );\n return;\n }\n\n // Keep this additive: legacy rows with item_id=id are still read correctly\n // through COALESCE(item_id, id), so SQLite never needs a table rebuild here.\n try {\n await client.execute(`ALTER TABLE tool_data ADD COLUMN item_id TEXT`);\n } catch (err: any) {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n ) {\n throw err;\n }\n }\n}\n\nasync function ensureToolDataScope(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const addCol = (name: string, def: string) => {\n if (pg) {\n return client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS ${name} ${def}`,\n );\n }\n return client\n .execute(`ALTER TABLE tool_data ADD COLUMN ${name} ${def}`)\n .catch((err: any) => {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n )\n throw err;\n });\n };\n await addCol(\"scope\", \"TEXT NOT NULL DEFAULT 'user'\");\n await addCol(\"org_id\", \"TEXT\");\n await addCol(\"scope_key\", \"TEXT NOT NULL DEFAULT 'local@localhost'\");\n // One-time backfill migration: replaces the dev-mode DEFAULT scope_key\n // with each row's real owner_email. Not a per-request fallback.\n await client.execute(\n // guard:allow-localhost-fallback — one-time backfill migration replacing dev-mode default scope_key with the row's real owner_email\n `UPDATE tool_data SET scope_key = owner_email WHERE scope_key = 'local@localhost' AND owner_email != 'local@localhost'`,\n );\n}\n\nexport function registerToolsShareable() {\n registerShareableResource({\n type: \"tool\",\n resourceTable: tools,\n sharesTable: toolShares,\n displayName: \"Tool\",\n titleColumn: \"name\",\n getDb: () => getDb(),\n });\n}\n\nexport interface ToolRow {\n id: string;\n name: string;\n description: string;\n content: string;\n icon: string | null;\n createdAt: string;\n updatedAt: string;\n ownerEmail: string;\n orgId: string | null;\n visibility: \"private\" | \"org\" | \"public\";\n}\n\nexport async function listTools(): Promise<ToolRow[]> {\n await ensureToolsTables();\n const db = getDb();\n return db\n .select()\n .from(tools)\n .where(accessFilter(tools, toolShares)) as Promise<ToolRow[]>;\n}\n\nexport async function getTool(id: string): Promise<ToolRow | null> {\n await ensureToolsTables();\n const access = await resolveAccess(\"tool\", id);\n return (access?.resource as ToolRow | undefined) ?? null;\n}\n\nexport interface CreateToolData {\n name: string;\n description?: string;\n content?: string;\n icon?: string;\n}\n\nexport async function createTool(data: CreateToolData): Promise<ToolRow> {\n await ensureToolsTables();\n const db = getDb();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const orgId = getRequestOrgId();\n const id = randomUUID();\n const now = new Date().toISOString();\n const row: ToolRow = {\n id,\n name: data.name,\n description: data.description ?? \"\",\n content: data.content ?? \"\",\n icon: data.icon ?? null,\n createdAt: now,\n updatedAt: now,\n ownerEmail: userEmail,\n orgId: orgId ?? null,\n // Default to org-visibility when the user has an active organization so\n // teammates see the tool in their sidebar — matching how analytics\n // dashboards/analyses are scoped (`templates/analytics/server/lib/\n // dashboards-store.ts:356`). Solo users (no org) get the private\n // default. Owners can still flip back to private via update-tool.\n visibility: orgId ? \"org\" : \"private\",\n };\n await db.insert(tools).values(row);\n return row;\n}\n\nexport interface UpdateToolData {\n name?: string;\n description?: string;\n icon?: string;\n visibility?: \"private\" | \"org\" | \"public\";\n}\n\nexport async function updateTool(\n id: string,\n data: UpdateToolData,\n): Promise<ToolRow | null> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"editor\");\n const db = getDb();\n const updates: Record<string, unknown> = {\n updatedAt: new Date().toISOString(),\n };\n if (data.name !== undefined) updates.name = data.name;\n if (data.description !== undefined) updates.description = data.description;\n if (data.icon !== undefined) updates.icon = data.icon;\n if (data.visibility !== undefined) updates.visibility = data.visibility;\n await db.update(tools).set(updates).where(eq(tools.id, id));\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n return (rows[0] as ToolRow) ?? null;\n}\n\nexport interface UpdateToolContentOpts {\n content?: string;\n patches?: Array<{ find: string; replace: string }>;\n}\n\nexport async function updateToolContent(\n id: string,\n opts: UpdateToolContentOpts,\n): Promise<ToolRow | null> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"editor\");\n const db = getDb();\n\n let newContent: string;\n if (opts.content !== undefined) {\n newContent = opts.content;\n } else if (opts.patches) {\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n if (!rows[0]) return null;\n newContent = (rows[0] as ToolRow).content;\n for (const patch of opts.patches) {\n newContent = newContent.replace(patch.find, patch.replace);\n }\n } else {\n return null;\n }\n\n await db\n .update(tools)\n .set({ content: newContent, updatedAt: new Date().toISOString() })\n .where(eq(tools.id, id));\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n return (rows[0] as ToolRow) ?? null;\n}\n\nexport async function deleteTool(id: string): Promise<boolean> {\n await ensureToolsTables();\n await assertAccess(\"tool\", id, \"admin\");\n const db = getDb();\n const rows = await db.select().from(tools).where(eq(tools.id, id));\n if (!rows[0]) return false;\n await db.delete(toolShares).where(eq(toolShares.resourceId, id));\n await getDbExec().execute({\n sql: `DELETE FROM tool_data WHERE tool_id = ?`,\n args: [id],\n });\n const { cascadeDeleteToolSlots } = await import(\"./slots/store.js\");\n await cascadeDeleteToolSlots(id);\n await db.delete(tools).where(eq(tools.id, id));\n return true;\n}\n"]}
@@ -7,6 +7,7 @@
7
7
  * POSTHOG_API_KEY + POSTHOG_HOST → PostHog
8
8
  * MIXPANEL_TOKEN → Mixpanel
9
9
  * AMPLITUDE_API_KEY → Amplitude
10
+ * AGENT_NATIVE_ANALYTICS_PUBLIC_KEY → Agent Native Analytics
10
11
  *
11
12
  * Call `registerBuiltinProviders()` at server startup (done
12
13
  * automatically by the core-routes plugin).
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/tracking/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAqOH,wBAAgB,wBAAwB,IAAI,IAAI,CA6B/C"}
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/tracking/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmTH,wBAAgB,wBAAwB,IAAI,IAAI,CA6C/C"}
@@ -7,12 +7,14 @@
7
7
  * POSTHOG_API_KEY + POSTHOG_HOST → PostHog
8
8
  * MIXPANEL_TOKEN → Mixpanel
9
9
  * AMPLITUDE_API_KEY → Amplitude
10
+ * AGENT_NATIVE_ANALYTICS_PUBLIC_KEY → Agent Native Analytics
10
11
  *
11
12
  * Call `registerBuiltinProviders()` at server startup (done
12
13
  * automatically by the core-routes plugin).
13
14
  */
14
15
  import { registerTrackingProvider } from "./registry.js";
15
16
  const POSTHOG_DEFAULT_HOST = "https://us.i.posthog.com";
17
+ const AGENT_NATIVE_ANALYTICS_DEFAULT_ENDPOINT = "https://analytics.agent-native.com/track";
16
18
  const BATCH_INTERVAL_MS = 10_000;
17
19
  const MAX_BATCH_SIZE = 50;
18
20
  // Use globalThis so multiple ESM graph instances (Vite dev + Nitro symlinks)
@@ -58,6 +60,42 @@ function drainQueue() {
58
60
  }).catch(() => { });
59
61
  }
60
62
  }
63
+ function isLocalhostUrl(value) {
64
+ if (!value || !value.trim())
65
+ return false;
66
+ const raw = value.trim();
67
+ const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw)
68
+ ? raw
69
+ : `https://${raw}`;
70
+ try {
71
+ const { hostname } = new URL(withProtocol);
72
+ const h = hostname.toLowerCase();
73
+ return (h === "localhost" ||
74
+ h === "127.0.0.1" ||
75
+ h === "::1" ||
76
+ h === "[::1]" ||
77
+ h.endsWith(".localhost") ||
78
+ h.endsWith(".local"));
79
+ }
80
+ catch {
81
+ return false;
82
+ }
83
+ }
84
+ function shouldSkipAgentNativeAnalyticsForLocalhost() {
85
+ if (process.env.AGENT_NATIVE_ANALYTICS_ALLOW_LOCALHOST === "true") {
86
+ return false;
87
+ }
88
+ if (process.env.NODE_ENV === "development")
89
+ return true;
90
+ return [
91
+ process.env.APP_URL,
92
+ process.env.BETTER_AUTH_URL,
93
+ process.env.URL,
94
+ process.env.DEPLOY_URL,
95
+ process.env.VERCEL_PROJECT_PRODUCTION_URL,
96
+ process.env.VERCEL_URL,
97
+ ].some(isLocalhostUrl);
98
+ }
61
99
  // ─── PostHog ───────────────────────────────────────────────────────────────
62
100
  function createPostHogProvider(apiKey, host) {
63
101
  return {
@@ -185,6 +223,34 @@ function createWebhookProvider(url, authHeader) {
185
223
  },
186
224
  };
187
225
  }
226
+ // ─── Agent Native Analytics ───────────────────────────────────────────────
227
+ function createAgentNativeAnalyticsProvider(publicKey, endpoint) {
228
+ return {
229
+ name: "agent-native-analytics",
230
+ track(event) {
231
+ enqueue(endpoint, JSON.stringify({
232
+ publicKey,
233
+ event: event.name,
234
+ properties: event.properties ?? {},
235
+ userId: event.userId,
236
+ timestamp: event.timestamp,
237
+ }));
238
+ },
239
+ identify(userId, traits) {
240
+ enqueue(endpoint, JSON.stringify({
241
+ publicKey,
242
+ event: "$identify",
243
+ userId,
244
+ properties: traits ?? {},
245
+ timestamp: new Date().toISOString(),
246
+ }));
247
+ },
248
+ flush: () => {
249
+ drainQueue();
250
+ return Promise.resolve();
251
+ },
252
+ };
253
+ }
188
254
  // ─── Auto-registration ────────────────────────────────────────────────────
189
255
  let _registered = false;
190
256
  export function registerBuiltinProviders() {
@@ -204,6 +270,12 @@ export function registerBuiltinProviders() {
204
270
  if (amplitudeKey) {
205
271
  registerTrackingProvider(createAmplitudeProvider(amplitudeKey));
206
272
  }
273
+ const agentNativeAnalyticsKey = process.env.AGENT_NATIVE_ANALYTICS_PUBLIC_KEY;
274
+ if (agentNativeAnalyticsKey &&
275
+ !shouldSkipAgentNativeAnalyticsForLocalhost()) {
276
+ registerTrackingProvider(createAgentNativeAnalyticsProvider(agentNativeAnalyticsKey, (process.env.AGENT_NATIVE_ANALYTICS_ENDPOINT ||
277
+ AGENT_NATIVE_ANALYTICS_DEFAULT_ENDPOINT).replace(/\/+$/, "")));
278
+ }
207
279
  const webhookUrl = process.env.TRACKING_WEBHOOK_URL;
208
280
  if (webhookUrl) {
209
281
  registerTrackingProvider(createWebhookProvider(webhookUrl, process.env.TRACKING_WEBHOOK_AUTH));
@@ -1 +1 @@
1
- {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/tracking/providers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in tracking providers that auto-register from env vars.\n *\n * No SDK dependencies — uses raw HTTP to keep core lightweight.\n * Set the env var and tracking starts automatically.\n *\n * POSTHOG_API_KEY + POSTHOG_HOST → PostHog\n * MIXPANEL_TOKEN → Mixpanel\n * AMPLITUDE_API_KEY → Amplitude\n *\n * Call `registerBuiltinProviders()` at server startup (done\n * automatically by the core-routes plugin).\n */\n\nimport { registerTrackingProvider } from \"./registry.js\";\nimport type { TrackingProvider, TrackingEvent } from \"./types.js\";\n\nconst POSTHOG_DEFAULT_HOST = \"https://us.i.posthog.com\";\nconst BATCH_INTERVAL_MS = 10_000;\nconst MAX_BATCH_SIZE = 50;\n\n// ─── Batched sender ────────────────────────────────────────────────────────\n\ninterface QueuedEvent {\n url: string;\n body: string;\n headers?: Record<string, string>;\n}\n\n// Use globalThis so multiple ESM graph instances (Vite dev + Nitro symlinks)\n// share one queue, matching the same pattern as the tracking registry.\nconst QUEUE_KEY = Symbol.for(\"@agent-native/core/tracking.queue\");\nconst TIMER_KEY = Symbol.for(\"@agent-native/core/tracking.timer\");\n\ninterface GlobalWithQueue {\n [QUEUE_KEY]?: QueuedEvent[];\n [TIMER_KEY]?: ReturnType<typeof setTimeout> | null;\n}\n\nfunction getQueue(): QueuedEvent[] {\n const g = globalThis as unknown as GlobalWithQueue;\n if (!g[QUEUE_KEY]) g[QUEUE_KEY] = [];\n return g[QUEUE_KEY]!;\n}\n\nfunction getTimer(): ReturnType<typeof setTimeout> | null {\n const g = globalThis as unknown as GlobalWithQueue;\n return g[TIMER_KEY] ?? null;\n}\n\nfunction setTimer(t: ReturnType<typeof setTimeout> | null): void {\n (globalThis as unknown as GlobalWithQueue)[TIMER_KEY] = t;\n}\n\nfunction enqueue(\n url: string,\n body: string,\n headers?: Record<string, string>,\n): void {\n const queue = getQueue();\n queue.push({ url, body, headers });\n if (queue.length >= MAX_BATCH_SIZE) {\n drainQueue();\n } else if (!getTimer()) {\n setTimer(setTimeout(drainQueue, BATCH_INTERVAL_MS));\n }\n}\n\nfunction drainQueue(): void {\n const t = getTimer();\n if (t) {\n clearTimeout(t);\n setTimer(null);\n }\n const queue = getQueue();\n const batch = queue.splice(0, queue.length);\n for (const item of batch) {\n fetch(item.url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...item.headers },\n body: item.body,\n }).catch(() => {});\n }\n}\n\n// ─── PostHog ───────────────────────────────────────────────────────────────\n\nfunction createPostHogProvider(apiKey: string, host: string): TrackingProvider {\n return {\n name: \"posthog\",\n track(event: TrackingEvent) {\n enqueue(\n `${host}/capture/`,\n JSON.stringify({\n api_key: apiKey,\n event: event.name,\n distinct_id: event.userId || \"anonymous\",\n properties: {\n ...event.properties,\n timestamp: event.timestamp,\n },\n }),\n );\n },\n identify(userId, traits) {\n enqueue(\n `${host}/capture/`,\n JSON.stringify({\n api_key: apiKey,\n event: \"$identify\",\n distinct_id: userId,\n properties: { $set: traits },\n }),\n );\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Mixpanel ──────────────────────────────────────────────────────────────\n\nfunction createMixpanelProvider(token: string): TrackingProvider {\n return {\n name: \"mixpanel\",\n track(event: TrackingEvent) {\n const data = {\n event: event.name,\n properties: {\n token,\n distinct_id: event.userId || \"anonymous\",\n time: event.timestamp\n ? new Date(event.timestamp).getTime() / 1000\n : undefined,\n ...event.properties,\n },\n };\n enqueue(\"https://api.mixpanel.com/track\", JSON.stringify([data]));\n },\n identify(userId, traits) {\n const data = {\n $token: token,\n $distinct_id: userId,\n $set: traits,\n };\n enqueue(\"https://api.mixpanel.com/engage\", JSON.stringify([data]));\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Amplitude ─────────────────────────────────────────────────────────────\n\nfunction createAmplitudeProvider(apiKey: string): TrackingProvider {\n return {\n name: \"amplitude\",\n track(event: TrackingEvent) {\n const data = {\n api_key: apiKey,\n events: [\n {\n event_type: event.name,\n user_id: event.userId || \"anonymous\",\n event_properties: event.properties,\n time: event.timestamp\n ? new Date(event.timestamp).getTime()\n : undefined,\n },\n ],\n };\n enqueue(\"https://api2.amplitude.com/2/httpapi\", JSON.stringify(data));\n },\n identify(userId, traits) {\n const data = {\n api_key: apiKey,\n events: [\n {\n event_type: \"$identify\",\n user_id: userId,\n user_properties: { $set: traits },\n },\n ],\n };\n enqueue(\"https://api2.amplitude.com/2/httpapi\", JSON.stringify(data));\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Webhook (custom HTTP endpoint) ───────────────────────────────────────\n\nfunction createWebhookProvider(\n url: string,\n authHeader?: string,\n): TrackingProvider {\n const extra = authHeader ? { Authorization: authHeader } : undefined;\n return {\n name: \"webhook\",\n track(event: TrackingEvent) {\n enqueue(\n url,\n JSON.stringify({\n event: event.name,\n properties: event.properties,\n userId: event.userId,\n timestamp: event.timestamp,\n }),\n extra,\n );\n },\n identify(userId, traits) {\n enqueue(\n url,\n JSON.stringify({\n event: \"$identify\",\n userId,\n traits,\n timestamp: new Date().toISOString(),\n }),\n extra,\n );\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Auto-registration ────────────────────────────────────────────────────\n\nlet _registered = false;\n\nexport function registerBuiltinProviders(): void {\n if (_registered) return;\n _registered = true;\n\n const posthogKey = process.env.POSTHOG_API_KEY;\n if (posthogKey) {\n const host = (process.env.POSTHOG_HOST || POSTHOG_DEFAULT_HOST).replace(\n /\\/+$/,\n \"\",\n );\n registerTrackingProvider(createPostHogProvider(posthogKey, host));\n }\n\n const mixpanelToken = process.env.MIXPANEL_TOKEN;\n if (mixpanelToken) {\n registerTrackingProvider(createMixpanelProvider(mixpanelToken));\n }\n\n const amplitudeKey = process.env.AMPLITUDE_API_KEY;\n if (amplitudeKey) {\n registerTrackingProvider(createAmplitudeProvider(amplitudeKey));\n }\n\n const webhookUrl = process.env.TRACKING_WEBHOOK_URL;\n if (webhookUrl) {\n registerTrackingProvider(\n createWebhookProvider(webhookUrl, process.env.TRACKING_WEBHOOK_AUTH),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/tracking/providers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in tracking providers that auto-register from env vars.\n *\n * No SDK dependencies — uses raw HTTP to keep core lightweight.\n * Set the env var and tracking starts automatically.\n *\n * POSTHOG_API_KEY + POSTHOG_HOST → PostHog\n * MIXPANEL_TOKEN → Mixpanel\n * AMPLITUDE_API_KEY → Amplitude\n * AGENT_NATIVE_ANALYTICS_PUBLIC_KEY → Agent Native Analytics\n *\n * Call `registerBuiltinProviders()` at server startup (done\n * automatically by the core-routes plugin).\n */\n\nimport { registerTrackingProvider } from \"./registry.js\";\nimport type { TrackingProvider, TrackingEvent } from \"./types.js\";\n\nconst POSTHOG_DEFAULT_HOST = \"https://us.i.posthog.com\";\nconst AGENT_NATIVE_ANALYTICS_DEFAULT_ENDPOINT =\n \"https://analytics.agent-native.com/track\";\nconst BATCH_INTERVAL_MS = 10_000;\nconst MAX_BATCH_SIZE = 50;\n\n// ─── Batched sender ────────────────────────────────────────────────────────\n\ninterface QueuedEvent {\n url: string;\n body: string;\n headers?: Record<string, string>;\n}\n\n// Use globalThis so multiple ESM graph instances (Vite dev + Nitro symlinks)\n// share one queue, matching the same pattern as the tracking registry.\nconst QUEUE_KEY = Symbol.for(\"@agent-native/core/tracking.queue\");\nconst TIMER_KEY = Symbol.for(\"@agent-native/core/tracking.timer\");\n\ninterface GlobalWithQueue {\n [QUEUE_KEY]?: QueuedEvent[];\n [TIMER_KEY]?: ReturnType<typeof setTimeout> | null;\n}\n\nfunction getQueue(): QueuedEvent[] {\n const g = globalThis as unknown as GlobalWithQueue;\n if (!g[QUEUE_KEY]) g[QUEUE_KEY] = [];\n return g[QUEUE_KEY]!;\n}\n\nfunction getTimer(): ReturnType<typeof setTimeout> | null {\n const g = globalThis as unknown as GlobalWithQueue;\n return g[TIMER_KEY] ?? null;\n}\n\nfunction setTimer(t: ReturnType<typeof setTimeout> | null): void {\n (globalThis as unknown as GlobalWithQueue)[TIMER_KEY] = t;\n}\n\nfunction enqueue(\n url: string,\n body: string,\n headers?: Record<string, string>,\n): void {\n const queue = getQueue();\n queue.push({ url, body, headers });\n if (queue.length >= MAX_BATCH_SIZE) {\n drainQueue();\n } else if (!getTimer()) {\n setTimer(setTimeout(drainQueue, BATCH_INTERVAL_MS));\n }\n}\n\nfunction drainQueue(): void {\n const t = getTimer();\n if (t) {\n clearTimeout(t);\n setTimer(null);\n }\n const queue = getQueue();\n const batch = queue.splice(0, queue.length);\n for (const item of batch) {\n fetch(item.url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...item.headers },\n body: item.body,\n }).catch(() => {});\n }\n}\n\nfunction isLocalhostUrl(value: string | undefined): boolean {\n if (!value || !value.trim()) return false;\n const raw = value.trim();\n const withProtocol = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw)\n ? raw\n : `https://${raw}`;\n try {\n const { hostname } = new URL(withProtocol);\n const h = hostname.toLowerCase();\n return (\n h === \"localhost\" ||\n h === \"127.0.0.1\" ||\n h === \"::1\" ||\n h === \"[::1]\" ||\n h.endsWith(\".localhost\") ||\n h.endsWith(\".local\")\n );\n } catch {\n return false;\n }\n}\n\nfunction shouldSkipAgentNativeAnalyticsForLocalhost(): boolean {\n if (process.env.AGENT_NATIVE_ANALYTICS_ALLOW_LOCALHOST === \"true\") {\n return false;\n }\n if (process.env.NODE_ENV === \"development\") return true;\n return [\n process.env.APP_URL,\n process.env.BETTER_AUTH_URL,\n process.env.URL,\n process.env.DEPLOY_URL,\n process.env.VERCEL_PROJECT_PRODUCTION_URL,\n process.env.VERCEL_URL,\n ].some(isLocalhostUrl);\n}\n\n// ─── PostHog ───────────────────────────────────────────────────────────────\n\nfunction createPostHogProvider(apiKey: string, host: string): TrackingProvider {\n return {\n name: \"posthog\",\n track(event: TrackingEvent) {\n enqueue(\n `${host}/capture/`,\n JSON.stringify({\n api_key: apiKey,\n event: event.name,\n distinct_id: event.userId || \"anonymous\",\n properties: {\n ...event.properties,\n timestamp: event.timestamp,\n },\n }),\n );\n },\n identify(userId, traits) {\n enqueue(\n `${host}/capture/`,\n JSON.stringify({\n api_key: apiKey,\n event: \"$identify\",\n distinct_id: userId,\n properties: { $set: traits },\n }),\n );\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Mixpanel ──────────────────────────────────────────────────────────────\n\nfunction createMixpanelProvider(token: string): TrackingProvider {\n return {\n name: \"mixpanel\",\n track(event: TrackingEvent) {\n const data = {\n event: event.name,\n properties: {\n token,\n distinct_id: event.userId || \"anonymous\",\n time: event.timestamp\n ? new Date(event.timestamp).getTime() / 1000\n : undefined,\n ...event.properties,\n },\n };\n enqueue(\"https://api.mixpanel.com/track\", JSON.stringify([data]));\n },\n identify(userId, traits) {\n const data = {\n $token: token,\n $distinct_id: userId,\n $set: traits,\n };\n enqueue(\"https://api.mixpanel.com/engage\", JSON.stringify([data]));\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Amplitude ─────────────────────────────────────────────────────────────\n\nfunction createAmplitudeProvider(apiKey: string): TrackingProvider {\n return {\n name: \"amplitude\",\n track(event: TrackingEvent) {\n const data = {\n api_key: apiKey,\n events: [\n {\n event_type: event.name,\n user_id: event.userId || \"anonymous\",\n event_properties: event.properties,\n time: event.timestamp\n ? new Date(event.timestamp).getTime()\n : undefined,\n },\n ],\n };\n enqueue(\"https://api2.amplitude.com/2/httpapi\", JSON.stringify(data));\n },\n identify(userId, traits) {\n const data = {\n api_key: apiKey,\n events: [\n {\n event_type: \"$identify\",\n user_id: userId,\n user_properties: { $set: traits },\n },\n ],\n };\n enqueue(\"https://api2.amplitude.com/2/httpapi\", JSON.stringify(data));\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Webhook (custom HTTP endpoint) ───────────────────────────────────────\n\nfunction createWebhookProvider(\n url: string,\n authHeader?: string,\n): TrackingProvider {\n const extra = authHeader ? { Authorization: authHeader } : undefined;\n return {\n name: \"webhook\",\n track(event: TrackingEvent) {\n enqueue(\n url,\n JSON.stringify({\n event: event.name,\n properties: event.properties,\n userId: event.userId,\n timestamp: event.timestamp,\n }),\n extra,\n );\n },\n identify(userId, traits) {\n enqueue(\n url,\n JSON.stringify({\n event: \"$identify\",\n userId,\n traits,\n timestamp: new Date().toISOString(),\n }),\n extra,\n );\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Agent Native Analytics ───────────────────────────────────────────────\n\nfunction createAgentNativeAnalyticsProvider(\n publicKey: string,\n endpoint: string,\n): TrackingProvider {\n return {\n name: \"agent-native-analytics\",\n track(event: TrackingEvent) {\n enqueue(\n endpoint,\n JSON.stringify({\n publicKey,\n event: event.name,\n properties: event.properties ?? {},\n userId: event.userId,\n timestamp: event.timestamp,\n }),\n );\n },\n identify(userId, traits) {\n enqueue(\n endpoint,\n JSON.stringify({\n publicKey,\n event: \"$identify\",\n userId,\n properties: traits ?? {},\n timestamp: new Date().toISOString(),\n }),\n );\n },\n flush: () => {\n drainQueue();\n return Promise.resolve();\n },\n };\n}\n\n// ─── Auto-registration ────────────────────────────────────────────────────\n\nlet _registered = false;\n\nexport function registerBuiltinProviders(): void {\n if (_registered) return;\n _registered = true;\n\n const posthogKey = process.env.POSTHOG_API_KEY;\n if (posthogKey) {\n const host = (process.env.POSTHOG_HOST || POSTHOG_DEFAULT_HOST).replace(\n /\\/+$/,\n \"\",\n );\n registerTrackingProvider(createPostHogProvider(posthogKey, host));\n }\n\n const mixpanelToken = process.env.MIXPANEL_TOKEN;\n if (mixpanelToken) {\n registerTrackingProvider(createMixpanelProvider(mixpanelToken));\n }\n\n const amplitudeKey = process.env.AMPLITUDE_API_KEY;\n if (amplitudeKey) {\n registerTrackingProvider(createAmplitudeProvider(amplitudeKey));\n }\n\n const agentNativeAnalyticsKey = process.env.AGENT_NATIVE_ANALYTICS_PUBLIC_KEY;\n if (\n agentNativeAnalyticsKey &&\n !shouldSkipAgentNativeAnalyticsForLocalhost()\n ) {\n registerTrackingProvider(\n createAgentNativeAnalyticsProvider(\n agentNativeAnalyticsKey,\n (\n process.env.AGENT_NATIVE_ANALYTICS_ENDPOINT ||\n AGENT_NATIVE_ANALYTICS_DEFAULT_ENDPOINT\n ).replace(/\\/+$/, \"\"),\n ),\n );\n }\n\n const webhookUrl = process.env.TRACKING_WEBHOOK_URL;\n if (webhookUrl) {\n registerTrackingProvider(\n createWebhookProvider(webhookUrl, process.env.TRACKING_WEBHOOK_AUTH),\n );\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"action-types-plugin.d.ts","sourceRoot":"","sources":["../../src/vite/action-types-plugin.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAmMnC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAgC1C;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG1E"}
1
+ {"version":3,"file":"action-types-plugin.d.ts","sourceRoot":"","sources":["../../src/vite/action-types-plugin.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA6RnC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAuC1C;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG1E"}
@@ -97,6 +97,71 @@ function writeIfChanged(outFile, content) {
97
97
  fs.writeFileSync(outFile, content);
98
98
  }
99
99
  }
100
+ function findWorkspaceCoreActionsDir(projectRoot) {
101
+ let dir = path.resolve(projectRoot);
102
+ let workspaceRoot = null;
103
+ let packageName = null;
104
+ for (let i = 0; i < 20; i++) {
105
+ const pkgPath = path.join(dir, "package.json");
106
+ if (fs.existsSync(pkgPath)) {
107
+ try {
108
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
109
+ const declared = pkg?.["agent-native"]?.workspaceCore;
110
+ if (typeof declared === "string" && declared.length > 0) {
111
+ workspaceRoot = dir;
112
+ packageName = declared;
113
+ break;
114
+ }
115
+ }
116
+ catch {
117
+ // Keep walking on malformed package.json.
118
+ }
119
+ }
120
+ const parent = path.dirname(dir);
121
+ if (parent === dir)
122
+ break;
123
+ dir = parent;
124
+ }
125
+ if (!workspaceRoot || !packageName)
126
+ return null;
127
+ const nm = path.join(workspaceRoot, "node_modules", packageName);
128
+ if (fs.existsSync(path.join(nm, "package.json"))) {
129
+ const actionsDir = path.join(fs.realpathSync(nm), "actions");
130
+ return fs.existsSync(actionsDir) ? actionsDir : null;
131
+ }
132
+ const packagesDir = path.join(workspaceRoot, "packages");
133
+ const candidates = [];
134
+ if (fs.existsSync(packagesDir)) {
135
+ for (const entry of fs.readdirSync(packagesDir, { withFileTypes: true })) {
136
+ if (!entry.isDirectory())
137
+ continue;
138
+ candidates.push(path.join(packagesDir, entry.name));
139
+ if (entry.name.startsWith("@")) {
140
+ const scopeDir = path.join(packagesDir, entry.name);
141
+ for (const sub of fs.readdirSync(scopeDir, { withFileTypes: true })) {
142
+ if (sub.isDirectory())
143
+ candidates.push(path.join(scopeDir, sub.name));
144
+ }
145
+ }
146
+ }
147
+ }
148
+ for (const candidate of candidates) {
149
+ const pkgPath = path.join(candidate, "package.json");
150
+ if (!fs.existsSync(pkgPath))
151
+ continue;
152
+ try {
153
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
154
+ if (pkg?.name === packageName) {
155
+ const actionsDir = path.join(candidate, "actions");
156
+ return fs.existsSync(actionsDir) ? actionsDir : null;
157
+ }
158
+ }
159
+ catch {
160
+ // Ignore malformed package.json.
161
+ }
162
+ }
163
+ return null;
164
+ }
100
165
  /**
101
166
  * Scan the actions directory and emit the types + runtime registry files.
102
167
  * Only writes files whose content has changed, to avoid triggering rebuilds.
@@ -105,21 +170,44 @@ function generateActionArtifacts(actionsDir, projectRoot) {
105
170
  const outDir = path.resolve(projectRoot, ".generated");
106
171
  const relActionsDir = path.relative(outDir, actionsDir).replace(/\\/g, "/");
107
172
  const actionFiles = scanActionFiles(actionsDir);
173
+ const workspaceActionsDir = findWorkspaceCoreActionsDir(projectRoot);
174
+ const workspaceActionFiles = workspaceActionsDir
175
+ ? scanActionFiles(workspaceActionsDir)
176
+ : [];
108
177
  // Pre-compute template action names — used for skip-existing logic in both
109
178
  // the type declarations and the runtime registry below.
110
179
  const templateActionNames = new Set(actionFiles.map((f) => f.replace(/\.(ts|js)$/, "")));
111
- // --- types file ---------------------------------------------------------
112
- const typeEntries = actionFiles.map((f) => {
180
+ const registeredActionNames = new Set(templateActionNames);
181
+ const actionSources = actionFiles.map((f) => {
113
182
  const name = f.replace(/\.(ts|js)$/, "");
114
- const relPath = `${relActionsDir}/${name}`;
183
+ return {
184
+ name,
185
+ relPath: `${relActionsDir}/${name}`,
186
+ };
187
+ });
188
+ if (workspaceActionsDir) {
189
+ for (const f of workspaceActionFiles) {
190
+ const name = f.replace(/\.(ts|js)$/, "");
191
+ if (registeredActionNames.has(name))
192
+ continue;
193
+ const relPath = path
194
+ .relative(outDir, path.join(workspaceActionsDir, name))
195
+ .replace(/\\/g, "/");
196
+ actionSources.push({ name, relPath });
197
+ registeredActionNames.add(name);
198
+ }
199
+ }
200
+ // --- types file ---------------------------------------------------------
201
+ const typeEntries = actionSources.map(({ name, relPath }) => {
115
202
  return ` "${name}": ActionEntry<typeof import("${relPath}")>;`;
116
203
  });
117
204
  // Also declare types for framework-level sharing actions so callers don't
118
205
  // need `as any` casts (same skip-existing logic as the runtime registry).
119
206
  for (const entry of CORE_SHARING_ACTIONS) {
120
- if (templateActionNames.has(entry.name))
207
+ if (registeredActionNames.has(entry.name))
121
208
  continue;
122
209
  typeEntries.push(` "${entry.name}": ActionEntry<typeof import("${entry.specifier}")>;`);
210
+ registeredActionNames.add(entry.name);
123
211
  }
124
212
  const typesContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.
125
213
  // Regenerated when files in actions/ change.
@@ -149,23 +237,24 @@ export {};
149
237
  // `loadActionsIntoRegistry` in server/action-discovery.ts.
150
238
  const imports = [];
151
239
  const entries = [];
152
- for (const f of actionFiles) {
153
- const name = f.replace(/\.(ts|js)$/, "");
240
+ const runtimeActionNames = new Set();
241
+ for (const { name, relPath } of actionSources) {
154
242
  const ident = toIdent(name);
155
- const relPath = `${relActionsDir}/${name}`;
156
243
  imports.push(`import * as ${ident} from "${relPath}";`);
157
244
  entries.push(` ${JSON.stringify(name)}: ${ident},`);
245
+ runtimeActionNames.add(name);
158
246
  }
159
247
  // Framework-level sharing actions — only added when the template hasn't
160
248
  // provided a same-named file (skip-existing merge). Static imports ensure
161
249
  // bundlers pull these modules into the server bundle so
162
250
  // `/_agent-native/actions/share-resource` (etc.) always resolve.
163
251
  for (const entry of CORE_SHARING_ACTIONS) {
164
- if (templateActionNames.has(entry.name))
252
+ if (runtimeActionNames.has(entry.name))
165
253
  continue;
166
254
  const ident = toIdent(entry.name);
167
255
  imports.push(`import * as ${ident} from "${entry.specifier}";`);
168
256
  entries.push(` ${JSON.stringify(entry.name)}: ${ident},`);
257
+ runtimeActionNames.add(entry.name);
169
258
  }
170
259
  const registryContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.
171
260
  // Static-import registry of every action file. Bundlers (Nitro, Rolldown)
@@ -205,11 +294,13 @@ export default modules;
205
294
  export function actionTypesPlugin() {
206
295
  let projectRoot = "";
207
296
  let actionsDir = "";
297
+ let workspaceActionsDir = null;
208
298
  return {
209
299
  name: "agent-native-action-types",
210
300
  configResolved(config) {
211
301
  projectRoot = config.root;
212
302
  actionsDir = path.resolve(projectRoot, "actions");
303
+ workspaceActionsDir = findWorkspaceCoreActionsDir(projectRoot);
213
304
  },
214
305
  buildStart() {
215
306
  generateActionArtifacts(actionsDir, projectRoot);
@@ -220,11 +311,17 @@ export function actionTypesPlugin() {
220
311
  // Watch for changes in actions/
221
312
  const watcher = server.watcher;
222
313
  const handleChange = (file) => {
223
- if (file.startsWith(actionsDir) && /\.(ts|js)$/.test(file)) {
314
+ const inAppActions = file.startsWith(actionsDir);
315
+ const inWorkspaceActions = workspaceActionsDir
316
+ ? file.startsWith(workspaceActionsDir)
317
+ : false;
318
+ if ((inAppActions || inWorkspaceActions) && /\.(ts|js)$/.test(file)) {
224
319
  generateActionArtifacts(actionsDir, projectRoot);
225
320
  }
226
321
  };
227
322
  watcher.add(actionsDir);
323
+ if (workspaceActionsDir)
324
+ watcher.add(workspaceActionsDir);
228
325
  watcher.on("add", handleChange);
229
326
  watcher.on("unlink", handleChange);
230
327
  // Don't regenerate on content changes — only file additions/removals
@@ -1 +1 @@
1
- {"version":3,"file":"action-types-plugin.js","sourceRoot":"","sources":["../../src/vite/action-types-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vite plugin that generates end-to-end type-safe action types AND a runtime\n * registry of static imports so bundlers (Nitro on Netlify/Vercel/AWS-Lambda,\n * Rolldown, etc.) include every action file in the server bundle.\n *\n * Watches the `actions/` directory and emits:\n * - `.generated/action-types.d.ts` — type-only module that augments the\n * `ActionRegistry` interface in `@agent-native/core/client`, giving\n * `useActionQuery`/`useActionMutation` full inference.\n * - `.generated/actions-registry.ts` — runtime registry keyed by action\n * name, with static `import` statements for every action. Templates\n * import this file from their `server/plugins/agent-chat.ts` so Nitro\n * bundles the actions into the server function; without it the runtime\n * `fs.readdirSync` inside `autoDiscoverActions` finds nothing in a\n * bundled serverless function and every action route 404s.\n */\nimport path from \"path\";\nimport fs from \"fs\";\nimport type { Plugin } from \"vite\";\n\n/** Files to skip during discovery (matches action-discovery.ts). */\nconst SKIP_FILES = new Set([\n \"helpers\",\n \"run\",\n \"db-connect\",\n \"db-status\",\n \"registry\",\n]);\n\n/**\n * Framework-level sharing actions that must ALWAYS be in the generated\n * registry, even when the template's `actions/` directory doesn't contain\n * them. Each entry maps the action name to the bare-specifier import path so\n * bundlers see a static import and pull the module into the server bundle.\n *\n * Order matters: templates can override by defining a same-named file in\n * their own `actions/` directory — the merge below is skip-existing.\n */\nconst CORE_SHARING_ACTIONS: Array<{ name: string; specifier: string }> = [\n {\n name: \"share-resource\",\n specifier: \"@agent-native/core/sharing/actions/share-resource\",\n },\n {\n name: \"unshare-resource\",\n specifier: \"@agent-native/core/sharing/actions/unshare-resource\",\n },\n {\n name: \"list-resource-shares\",\n specifier: \"@agent-native/core/sharing/actions/list-resource-shares\",\n },\n {\n name: \"set-resource-visibility\",\n specifier: \"@agent-native/core/sharing/actions/set-resource-visibility\",\n },\n];\n\nfunction scanActionFiles(actionsDir: string): string[] {\n let files: string[];\n try {\n files = fs.readdirSync(actionsDir);\n } catch {\n return [];\n }\n return files.filter((f) => {\n if (!f.endsWith(\".ts\") && !f.endsWith(\".js\")) return false;\n const name = f.replace(/\\.(ts|js)$/, \"\");\n if (name.startsWith(\"_\")) return false;\n if (SKIP_FILES.has(name)) return false;\n // Only include files that actually call defineAction or explicitly\n // re-export a package action. CLI scripts or example templates that live\n // in actions/ but don't export an action would otherwise drag their own\n // (often app/, browser-only, or fs-only) imports into the serverless\n // bundle and fail to resolve.\n try {\n const content = fs.readFileSync(path.join(actionsDir, f), \"utf-8\");\n const reexportsDefaultAction =\n /export\\s*\\{\\s*default\\s*\\}\\s*from\\s*[\"'][^\"']+[\"']/.test(content);\n if (!content.includes(\"defineAction\") && !reexportsDefaultAction) {\n return false;\n }\n } catch {\n return false;\n }\n return true;\n });\n}\n\nfunction toIdent(name: string): string {\n return \"a_\" + name.replace(/[^a-zA-Z0-9_]/g, \"_\");\n}\n\nfunction writeIfChanged(outFile: string, content: string): void {\n const existing = fs.existsSync(outFile)\n ? fs.readFileSync(outFile, \"utf-8\")\n : \"\";\n if (existing !== content) {\n fs.mkdirSync(path.dirname(outFile), { recursive: true });\n fs.writeFileSync(outFile, content);\n }\n}\n\n/**\n * Scan the actions directory and emit the types + runtime registry files.\n * Only writes files whose content has changed, to avoid triggering rebuilds.\n */\nfunction generateActionArtifacts(\n actionsDir: string,\n projectRoot: string,\n): void {\n const outDir = path.resolve(projectRoot, \".generated\");\n const relActionsDir = path.relative(outDir, actionsDir).replace(/\\\\/g, \"/\");\n\n const actionFiles = scanActionFiles(actionsDir);\n\n // Pre-compute template action names — used for skip-existing logic in both\n // the type declarations and the runtime registry below.\n const templateActionNames = new Set<string>(\n actionFiles.map((f) => f.replace(/\\.(ts|js)$/, \"\")),\n );\n\n // --- types file ---------------------------------------------------------\n const typeEntries = actionFiles.map((f) => {\n const name = f.replace(/\\.(ts|js)$/, \"\");\n const relPath = `${relActionsDir}/${name}`;\n return ` \"${name}\": ActionEntry<typeof import(\"${relPath}\")>;`;\n });\n\n // Also declare types for framework-level sharing actions so callers don't\n // need `as any` casts (same skip-existing logic as the runtime registry).\n for (const entry of CORE_SHARING_ACTIONS) {\n if (templateActionNames.has(entry.name)) continue;\n typeEntries.push(\n ` \"${entry.name}\": ActionEntry<typeof import(\"${entry.specifier}\")>;`,\n );\n }\n\n const typesContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.\n// Regenerated when files in actions/ change.\n// This file augments the ActionRegistry interface so that useActionQuery and\n// useActionMutation infer the correct types from your action definitions.\n\n/** Extract the return type and parameter type from a defineAction module. */\ntype ActionEntry<T> = T extends { default: { run: (...args: infer A) => infer R } }\n ? {\n result: Awaited<R>;\n params: A extends [infer P, ...any[]] ? P : Record<string, any>;\n }\n : { result: any; params: Record<string, any> };\n\ndeclare module \"@agent-native/core/client\" {\n interface ActionRegistry {\n${typeEntries.join(\"\\n\")}\n }\n}\n\nexport {};\n`;\n\n writeIfChanged(path.join(outDir, \"action-types.d.ts\"), typesContent);\n\n // --- runtime registry ---------------------------------------------------\n // Static imports of each action's default export so bundlers see every\n // action and include it in the server bundle. Normalization matches\n // `loadActionsIntoRegistry` in server/action-discovery.ts.\n const imports: string[] = [];\n const entries: string[] = [];\n for (const f of actionFiles) {\n const name = f.replace(/\\.(ts|js)$/, \"\");\n const ident = toIdent(name);\n const relPath = `${relActionsDir}/${name}`;\n imports.push(`import * as ${ident} from \"${relPath}\";`);\n entries.push(` ${JSON.stringify(name)}: ${ident},`);\n }\n // Framework-level sharing actions — only added when the template hasn't\n // provided a same-named file (skip-existing merge). Static imports ensure\n // bundlers pull these modules into the server bundle so\n // `/_agent-native/actions/share-resource` (etc.) always resolve.\n for (const entry of CORE_SHARING_ACTIONS) {\n if (templateActionNames.has(entry.name)) continue;\n const ident = toIdent(entry.name);\n imports.push(`import * as ${ident} from \"${entry.specifier}\";`);\n entries.push(` ${JSON.stringify(entry.name)}: ${ident},`);\n }\n\n const registryContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.\n// Static-import registry of every action file. Bundlers (Nitro, Rolldown)\n// see these imports and include the action modules in the server bundle.\n// The agent-chat plugin normalizes each module into an ActionEntry shape.\n${imports.join(\"\\n\")}\n\nconst modules: Record<string, unknown> = {\n${entries.join(\"\\n\")}\n};\n\nexport default modules;\n`;\n\n // Always write the registry — even when the template has no actions/ files\n // we still emit imports for the framework-level sharing actions so they get\n // mounted on every template that consumes the registry.\n writeIfChanged(path.join(outDir, \"actions-registry.ts\"), registryContent);\n\n // Ensure .generated/ is in .gitignore\n const gitignorePath = path.join(projectRoot, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n const gitignore = fs.readFileSync(gitignorePath, \"utf-8\");\n if (!gitignore.includes(\".generated\")) {\n fs.appendFileSync(gitignorePath, \"\\n.generated/\\n\");\n }\n }\n}\n\n/**\n * Vite plugin that watches `actions/` and generates type-safe action types.\n *\n * Add to your Vite config (auto-included by `defineConfig` from `@agent-native/core`):\n *\n * ```ts\n * import { actionTypesPlugin } from \"@agent-native/core/vite/action-types-plugin\";\n * plugins: [actionTypesPlugin()]\n * ```\n */\nexport function actionTypesPlugin(): Plugin {\n let projectRoot = \"\";\n let actionsDir = \"\";\n\n return {\n name: \"agent-native-action-types\",\n configResolved(config) {\n projectRoot = config.root;\n actionsDir = path.resolve(projectRoot, \"actions\");\n },\n buildStart() {\n generateActionArtifacts(actionsDir, projectRoot);\n },\n configureServer(server) {\n // Generate on startup\n generateActionArtifacts(actionsDir, projectRoot);\n\n // Watch for changes in actions/\n const watcher = server.watcher;\n const handleChange = (file: string) => {\n if (file.startsWith(actionsDir) && /\\.(ts|js)$/.test(file)) {\n generateActionArtifacts(actionsDir, projectRoot);\n }\n };\n watcher.add(actionsDir);\n watcher.on(\"add\", handleChange);\n watcher.on(\"unlink\", handleChange);\n // Don't regenerate on content changes — only file additions/removals\n // affect the registry. Return type changes are picked up by TypeScript\n // from the source files via typeof import().\n },\n };\n}\n\n/**\n * Public helper to regenerate the types + registry from a non-Vite context\n * (e.g. the Nitro deploy build, where Vite plugins don't run).\n */\nexport function generateActionRegistryForProject(projectRoot: string): void {\n const actionsDir = path.resolve(projectRoot, \"actions\");\n generateActionArtifacts(actionsDir, projectRoot);\n}\n"]}
1
+ {"version":3,"file":"action-types-plugin.js","sourceRoot":"","sources":["../../src/vite/action-types-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vite plugin that generates end-to-end type-safe action types AND a runtime\n * registry of static imports so bundlers (Nitro on Netlify/Vercel/AWS-Lambda,\n * Rolldown, etc.) include every action file in the server bundle.\n *\n * Watches the `actions/` directory and emits:\n * - `.generated/action-types.d.ts` — type-only module that augments the\n * `ActionRegistry` interface in `@agent-native/core/client`, giving\n * `useActionQuery`/`useActionMutation` full inference.\n * - `.generated/actions-registry.ts` — runtime registry keyed by action\n * name, with static `import` statements for every action. Templates\n * import this file from their `server/plugins/agent-chat.ts` so Nitro\n * bundles the actions into the server function; without it the runtime\n * `fs.readdirSync` inside `autoDiscoverActions` finds nothing in a\n * bundled serverless function and every action route 404s.\n */\nimport path from \"path\";\nimport fs from \"fs\";\nimport type { Plugin } from \"vite\";\n\n/** Files to skip during discovery (matches action-discovery.ts). */\nconst SKIP_FILES = new Set([\n \"helpers\",\n \"run\",\n \"db-connect\",\n \"db-status\",\n \"registry\",\n]);\n\n/**\n * Framework-level sharing actions that must ALWAYS be in the generated\n * registry, even when the template's `actions/` directory doesn't contain\n * them. Each entry maps the action name to the bare-specifier import path so\n * bundlers see a static import and pull the module into the server bundle.\n *\n * Order matters: templates can override by defining a same-named file in\n * their own `actions/` directory — the merge below is skip-existing.\n */\nconst CORE_SHARING_ACTIONS: Array<{ name: string; specifier: string }> = [\n {\n name: \"share-resource\",\n specifier: \"@agent-native/core/sharing/actions/share-resource\",\n },\n {\n name: \"unshare-resource\",\n specifier: \"@agent-native/core/sharing/actions/unshare-resource\",\n },\n {\n name: \"list-resource-shares\",\n specifier: \"@agent-native/core/sharing/actions/list-resource-shares\",\n },\n {\n name: \"set-resource-visibility\",\n specifier: \"@agent-native/core/sharing/actions/set-resource-visibility\",\n },\n];\n\nfunction scanActionFiles(actionsDir: string): string[] {\n let files: string[];\n try {\n files = fs.readdirSync(actionsDir);\n } catch {\n return [];\n }\n return files.filter((f) => {\n if (!f.endsWith(\".ts\") && !f.endsWith(\".js\")) return false;\n const name = f.replace(/\\.(ts|js)$/, \"\");\n if (name.startsWith(\"_\")) return false;\n if (SKIP_FILES.has(name)) return false;\n // Only include files that actually call defineAction or explicitly\n // re-export a package action. CLI scripts or example templates that live\n // in actions/ but don't export an action would otherwise drag their own\n // (often app/, browser-only, or fs-only) imports into the serverless\n // bundle and fail to resolve.\n try {\n const content = fs.readFileSync(path.join(actionsDir, f), \"utf-8\");\n const reexportsDefaultAction =\n /export\\s*\\{\\s*default\\s*\\}\\s*from\\s*[\"'][^\"']+[\"']/.test(content);\n if (!content.includes(\"defineAction\") && !reexportsDefaultAction) {\n return false;\n }\n } catch {\n return false;\n }\n return true;\n });\n}\n\nfunction toIdent(name: string): string {\n return \"a_\" + name.replace(/[^a-zA-Z0-9_]/g, \"_\");\n}\n\nfunction writeIfChanged(outFile: string, content: string): void {\n const existing = fs.existsSync(outFile)\n ? fs.readFileSync(outFile, \"utf-8\")\n : \"\";\n if (existing !== content) {\n fs.mkdirSync(path.dirname(outFile), { recursive: true });\n fs.writeFileSync(outFile, content);\n }\n}\n\nfunction findWorkspaceCoreActionsDir(projectRoot: string): string | null {\n let dir = path.resolve(projectRoot);\n let workspaceRoot: string | null = null;\n let packageName: string | null = null;\n\n for (let i = 0; i < 20; i++) {\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const declared = pkg?.[\"agent-native\"]?.workspaceCore;\n if (typeof declared === \"string\" && declared.length > 0) {\n workspaceRoot = dir;\n packageName = declared;\n break;\n }\n } catch {\n // Keep walking on malformed package.json.\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n if (!workspaceRoot || !packageName) return null;\n\n const nm = path.join(workspaceRoot, \"node_modules\", packageName);\n if (fs.existsSync(path.join(nm, \"package.json\"))) {\n const actionsDir = path.join(fs.realpathSync(nm), \"actions\");\n return fs.existsSync(actionsDir) ? actionsDir : null;\n }\n\n const packagesDir = path.join(workspaceRoot, \"packages\");\n const candidates: string[] = [];\n if (fs.existsSync(packagesDir)) {\n for (const entry of fs.readdirSync(packagesDir, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n candidates.push(path.join(packagesDir, entry.name));\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = path.join(packagesDir, entry.name);\n for (const sub of fs.readdirSync(scopeDir, { withFileTypes: true })) {\n if (sub.isDirectory()) candidates.push(path.join(scopeDir, sub.name));\n }\n }\n }\n }\n\n for (const candidate of candidates) {\n const pkgPath = path.join(candidate, \"package.json\");\n if (!fs.existsSync(pkgPath)) continue;\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n if (pkg?.name === packageName) {\n const actionsDir = path.join(candidate, \"actions\");\n return fs.existsSync(actionsDir) ? actionsDir : null;\n }\n } catch {\n // Ignore malformed package.json.\n }\n }\n\n return null;\n}\n\n/**\n * Scan the actions directory and emit the types + runtime registry files.\n * Only writes files whose content has changed, to avoid triggering rebuilds.\n */\nfunction generateActionArtifacts(\n actionsDir: string,\n projectRoot: string,\n): void {\n const outDir = path.resolve(projectRoot, \".generated\");\n const relActionsDir = path.relative(outDir, actionsDir).replace(/\\\\/g, \"/\");\n\n const actionFiles = scanActionFiles(actionsDir);\n const workspaceActionsDir = findWorkspaceCoreActionsDir(projectRoot);\n const workspaceActionFiles = workspaceActionsDir\n ? scanActionFiles(workspaceActionsDir)\n : [];\n\n // Pre-compute template action names — used for skip-existing logic in both\n // the type declarations and the runtime registry below.\n const templateActionNames = new Set<string>(\n actionFiles.map((f) => f.replace(/\\.(ts|js)$/, \"\")),\n );\n const registeredActionNames = new Set(templateActionNames);\n\n const actionSources = actionFiles.map((f) => {\n const name = f.replace(/\\.(ts|js)$/, \"\");\n return {\n name,\n relPath: `${relActionsDir}/${name}`,\n };\n });\n\n if (workspaceActionsDir) {\n for (const f of workspaceActionFiles) {\n const name = f.replace(/\\.(ts|js)$/, \"\");\n if (registeredActionNames.has(name)) continue;\n const relPath = path\n .relative(outDir, path.join(workspaceActionsDir, name))\n .replace(/\\\\/g, \"/\");\n actionSources.push({ name, relPath });\n registeredActionNames.add(name);\n }\n }\n\n // --- types file ---------------------------------------------------------\n const typeEntries = actionSources.map(({ name, relPath }) => {\n return ` \"${name}\": ActionEntry<typeof import(\"${relPath}\")>;`;\n });\n\n // Also declare types for framework-level sharing actions so callers don't\n // need `as any` casts (same skip-existing logic as the runtime registry).\n for (const entry of CORE_SHARING_ACTIONS) {\n if (registeredActionNames.has(entry.name)) continue;\n typeEntries.push(\n ` \"${entry.name}\": ActionEntry<typeof import(\"${entry.specifier}\")>;`,\n );\n registeredActionNames.add(entry.name);\n }\n\n const typesContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.\n// Regenerated when files in actions/ change.\n// This file augments the ActionRegistry interface so that useActionQuery and\n// useActionMutation infer the correct types from your action definitions.\n\n/** Extract the return type and parameter type from a defineAction module. */\ntype ActionEntry<T> = T extends { default: { run: (...args: infer A) => infer R } }\n ? {\n result: Awaited<R>;\n params: A extends [infer P, ...any[]] ? P : Record<string, any>;\n }\n : { result: any; params: Record<string, any> };\n\ndeclare module \"@agent-native/core/client\" {\n interface ActionRegistry {\n${typeEntries.join(\"\\n\")}\n }\n}\n\nexport {};\n`;\n\n writeIfChanged(path.join(outDir, \"action-types.d.ts\"), typesContent);\n\n // --- runtime registry ---------------------------------------------------\n // Static imports of each action's default export so bundlers see every\n // action and include it in the server bundle. Normalization matches\n // `loadActionsIntoRegistry` in server/action-discovery.ts.\n const imports: string[] = [];\n const entries: string[] = [];\n const runtimeActionNames = new Set<string>();\n for (const { name, relPath } of actionSources) {\n const ident = toIdent(name);\n imports.push(`import * as ${ident} from \"${relPath}\";`);\n entries.push(` ${JSON.stringify(name)}: ${ident},`);\n runtimeActionNames.add(name);\n }\n // Framework-level sharing actions — only added when the template hasn't\n // provided a same-named file (skip-existing merge). Static imports ensure\n // bundlers pull these modules into the server bundle so\n // `/_agent-native/actions/share-resource` (etc.) always resolve.\n for (const entry of CORE_SHARING_ACTIONS) {\n if (runtimeActionNames.has(entry.name)) continue;\n const ident = toIdent(entry.name);\n imports.push(`import * as ${ident} from \"${entry.specifier}\";`);\n entries.push(` ${JSON.stringify(entry.name)}: ${ident},`);\n runtimeActionNames.add(entry.name);\n }\n\n const registryContent = `// AUTO-GENERATED by @agent-native/core — do not edit manually.\n// Static-import registry of every action file. Bundlers (Nitro, Rolldown)\n// see these imports and include the action modules in the server bundle.\n// The agent-chat plugin normalizes each module into an ActionEntry shape.\n${imports.join(\"\\n\")}\n\nconst modules: Record<string, unknown> = {\n${entries.join(\"\\n\")}\n};\n\nexport default modules;\n`;\n\n // Always write the registry — even when the template has no actions/ files\n // we still emit imports for the framework-level sharing actions so they get\n // mounted on every template that consumes the registry.\n writeIfChanged(path.join(outDir, \"actions-registry.ts\"), registryContent);\n\n // Ensure .generated/ is in .gitignore\n const gitignorePath = path.join(projectRoot, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n const gitignore = fs.readFileSync(gitignorePath, \"utf-8\");\n if (!gitignore.includes(\".generated\")) {\n fs.appendFileSync(gitignorePath, \"\\n.generated/\\n\");\n }\n }\n}\n\n/**\n * Vite plugin that watches `actions/` and generates type-safe action types.\n *\n * Add to your Vite config (auto-included by `defineConfig` from `@agent-native/core`):\n *\n * ```ts\n * import { actionTypesPlugin } from \"@agent-native/core/vite/action-types-plugin\";\n * plugins: [actionTypesPlugin()]\n * ```\n */\nexport function actionTypesPlugin(): Plugin {\n let projectRoot = \"\";\n let actionsDir = \"\";\n let workspaceActionsDir: string | null = null;\n\n return {\n name: \"agent-native-action-types\",\n configResolved(config) {\n projectRoot = config.root;\n actionsDir = path.resolve(projectRoot, \"actions\");\n workspaceActionsDir = findWorkspaceCoreActionsDir(projectRoot);\n },\n buildStart() {\n generateActionArtifacts(actionsDir, projectRoot);\n },\n configureServer(server) {\n // Generate on startup\n generateActionArtifacts(actionsDir, projectRoot);\n\n // Watch for changes in actions/\n const watcher = server.watcher;\n const handleChange = (file: string) => {\n const inAppActions = file.startsWith(actionsDir);\n const inWorkspaceActions = workspaceActionsDir\n ? file.startsWith(workspaceActionsDir)\n : false;\n if ((inAppActions || inWorkspaceActions) && /\\.(ts|js)$/.test(file)) {\n generateActionArtifacts(actionsDir, projectRoot);\n }\n };\n watcher.add(actionsDir);\n if (workspaceActionsDir) watcher.add(workspaceActionsDir);\n watcher.on(\"add\", handleChange);\n watcher.on(\"unlink\", handleChange);\n // Don't regenerate on content changes — only file additions/removals\n // affect the registry. Return type changes are picked up by TypeScript\n // from the source files via typeof import().\n },\n };\n}\n\n/**\n * Public helper to regenerate the types + registry from a non-Vite context\n * (e.g. the Nitro deploy build, where Vite plugins don't run).\n */\nexport function generateActionRegistryForProject(projectRoot: string): void {\n const actionsDir = path.resolve(projectRoot, \"actions\");\n generateActionArtifacts(actionsDir, projectRoot);\n}\n"]}