@agent-native/core 0.99.2 → 0.100.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 (381) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/docs/content/a2a-protocol.mdx +42 -0
  4. package/corpus/core/docs/content/agent-surfaces.mdx +43 -0
  5. package/corpus/core/docs/content/external-agents.mdx +11 -0
  6. package/corpus/core/docs/content/locales/ar-SA/a2a-protocol.mdx +42 -0
  7. package/corpus/core/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  8. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  9. package/corpus/core/docs/content/locales/de-DE/a2a-protocol.mdx +42 -0
  10. package/corpus/core/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  11. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +10 -0
  12. package/corpus/core/docs/content/locales/es-ES/a2a-protocol.mdx +42 -0
  13. package/corpus/core/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  14. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +10 -0
  15. package/corpus/core/docs/content/locales/fr-FR/a2a-protocol.mdx +42 -0
  16. package/corpus/core/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  17. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  18. package/corpus/core/docs/content/locales/hi-IN/a2a-protocol.mdx +42 -0
  19. package/corpus/core/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  20. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  21. package/corpus/core/docs/content/locales/ja-JP/a2a-protocol.mdx +42 -0
  22. package/corpus/core/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  23. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  24. package/corpus/core/docs/content/locales/ko-KR/a2a-protocol.mdx +42 -0
  25. package/corpus/core/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  26. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  27. package/corpus/core/docs/content/locales/pt-BR/a2a-protocol.mdx +42 -0
  28. package/corpus/core/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  29. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  30. package/corpus/core/docs/content/locales/zh-CN/a2a-protocol.mdx +42 -0
  31. package/corpus/core/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  32. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  33. package/corpus/core/docs/content/locales/zh-TW/a2a-protocol.mdx +42 -0
  34. package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  35. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  36. package/corpus/core/package.json +1 -1
  37. package/corpus/core/src/agent/context-xray/actions/context-evict.ts +11 -0
  38. package/corpus/core/src/agent/context-xray/actions/context-pin.ts +11 -0
  39. package/corpus/core/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  40. package/corpus/core/src/agent/context-xray/actions/context-restore.ts +11 -0
  41. package/corpus/core/src/agent/context-xray/actions/errors.ts +20 -0
  42. package/corpus/core/src/agent/context-xray/manifest.ts +106 -7
  43. package/corpus/core/src/agent/engine/context-directives-transform.ts +5 -1
  44. package/corpus/core/src/agent/production-agent.ts +100 -38
  45. package/corpus/core/src/agent/run-loop-with-resume.ts +7 -2
  46. package/corpus/core/src/client/AgentPanel.tsx +35 -8
  47. package/corpus/core/src/client/agent-page/AgentContextTab.tsx +501 -0
  48. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +370 -0
  49. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +1084 -0
  50. package/corpus/core/src/client/agent-page/types.ts +18 -0
  51. package/corpus/core/src/client/agent-page/use-jobs.ts +150 -0
  52. package/corpus/core/src/client/context-xray/ContextMeter.tsx +22 -5
  53. package/corpus/core/src/client/context-xray/ContextTreemap.tsx +16 -1
  54. package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +168 -3
  55. package/corpus/core/src/client/context-xray/format.ts +6 -0
  56. package/corpus/core/src/client/index.ts +6 -0
  57. package/corpus/core/src/client/resources/ResourcesPanel.tsx +51 -23
  58. package/corpus/core/src/client/settings/AutomationsSection.tsx +407 -387
  59. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +105 -0
  60. package/corpus/core/src/jobs/actions/manage-recurring-job.ts +85 -0
  61. package/corpus/core/src/jobs/tools.ts +1 -1
  62. package/corpus/core/src/localization/default-messages.ts +110 -0
  63. package/corpus/core/src/mcp/build-server.ts +1 -0
  64. package/corpus/core/src/mcp/connect-route.ts +62 -65
  65. package/corpus/core/src/server/action-discovery.ts +23 -0
  66. package/corpus/core/src/server/agent-chat/prompt-resources.ts +174 -2
  67. package/corpus/core/src/server/agent-chat-plugin.ts +175 -2
  68. package/corpus/core/src/server/auth.ts +1 -7
  69. package/corpus/core/src/server/google-oauth.ts +1 -7
  70. package/corpus/core/src/server/workspace-oauth.ts +31 -0
  71. package/corpus/core/src/shared/context-xray.ts +84 -1
  72. package/corpus/core/src/shared/mcp-connect-content.ts +130 -0
  73. package/corpus/core/src/templates/default/app/routes/_index.tsx +11 -0
  74. package/corpus/core/src/templates/default/app/routes/agent.tsx +33 -0
  75. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  76. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  77. package/corpus/core/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  78. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  79. package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  80. package/corpus/core/src/triggers/actions/list-automations.ts +99 -0
  81. package/corpus/core/src/triggers/actions/manage-automation.ts +78 -0
  82. package/corpus/templates/analytics/actions/data-source-status.ts +33 -15
  83. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  84. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +149 -24
  85. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +17 -0
  86. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  87. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -0
  88. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +8 -0
  89. package/corpus/templates/analytics/app/i18n/zh-TW.ts +1 -0
  90. package/corpus/templates/analytics/app/i18n-data.ts +1 -0
  91. package/corpus/templates/analytics/app/routes/agent.tsx +5 -0
  92. package/corpus/templates/analytics/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-13-analytics-answers-can-use-built-in-first-party-event-data.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-13-chart-legends-can-filter-to-one-series-or-hide-a-series-on-h.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-13-gpt-5-6-luna-answers-now-recover-normally-instead-of-showing.md +6 -0
  96. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
  97. package/corpus/templates/assets/app/components/layout/Header.tsx +1 -0
  98. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -0
  99. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -0
  100. package/corpus/templates/assets/app/routes/agent.tsx +5 -0
  101. package/corpus/templates/assets/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  102. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -0
  103. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +4 -1
  104. package/corpus/templates/brain/app/lib/brain.ts +11 -0
  105. package/corpus/templates/brain/app/root.tsx +15 -1
  106. package/corpus/templates/brain/app/routes/agent.tsx +11 -0
  107. package/corpus/templates/brain/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  108. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -0
  109. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +2 -0
  110. package/corpus/templates/calendar/app/root.tsx +17 -1
  111. package/corpus/templates/calendar/app/routes/_app.agent.tsx +25 -0
  112. package/corpus/templates/calendar/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  113. package/corpus/templates/chat/app/components/layout/Header.tsx +1 -0
  114. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  115. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +7 -0
  116. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +3 -0
  117. package/corpus/templates/chat/app/root.tsx +24 -2
  118. package/corpus/templates/chat/app/routes/agent.tsx +15 -0
  119. package/corpus/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  120. package/corpus/templates/clips/app/components/library/library-layout.tsx +8 -0
  121. package/corpus/templates/clips/app/i18n/ar-SA.ts +2 -0
  122. package/corpus/templates/clips/app/i18n/de-DE.ts +2 -0
  123. package/corpus/templates/clips/app/i18n/en-US.ts +2 -0
  124. package/corpus/templates/clips/app/i18n/es-ES.ts +2 -0
  125. package/corpus/templates/clips/app/i18n/fr-FR.ts +2 -0
  126. package/corpus/templates/clips/app/i18n/hi-IN.ts +2 -0
  127. package/corpus/templates/clips/app/i18n/ja-JP.ts +2 -0
  128. package/corpus/templates/clips/app/i18n/ko-KR.ts +2 -0
  129. package/corpus/templates/clips/app/i18n/pt-BR.ts +2 -0
  130. package/corpus/templates/clips/app/i18n/zh-CN.ts +2 -0
  131. package/corpus/templates/clips/app/i18n/zh-TW.ts +2 -0
  132. package/corpus/templates/clips/app/root.tsx +7 -1
  133. package/corpus/templates/clips/app/routes/_app.agent.tsx +15 -0
  134. package/corpus/templates/clips/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  135. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -0
  136. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +36 -0
  137. package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
  138. package/corpus/templates/content/app/i18n-data.ts +44 -6
  139. package/corpus/templates/content/app/root.tsx +8 -0
  140. package/corpus/templates/content/app/routes/_app.agent.tsx +15 -0
  141. package/corpus/templates/content/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  142. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  143. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
  144. package/corpus/templates/design/app/i18n/zh-TW.ts +2 -0
  145. package/corpus/templates/design/app/i18n-data.ts +20 -0
  146. package/corpus/templates/design/app/root.tsx +7 -1
  147. package/corpus/templates/design/app/routes/agent.tsx +15 -0
  148. package/corpus/templates/design/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  149. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +10 -1
  150. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +2 -0
  151. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  152. package/corpus/templates/dispatch/app/root.tsx +7 -2
  153. package/corpus/templates/dispatch/app/routes/agent.tsx +18 -0
  154. package/corpus/templates/dispatch/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  155. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  156. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -0
  157. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  158. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  159. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  160. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  161. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  162. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  163. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  164. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  165. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  166. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  167. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  168. package/corpus/templates/forms/app/root.tsx +6 -1
  169. package/corpus/templates/forms/app/routes/_app.agent.tsx +15 -0
  170. package/corpus/templates/forms/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  171. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +14 -2
  172. package/corpus/templates/macros/app/components/layout/Header.tsx +1 -0
  173. package/corpus/templates/macros/app/root.tsx +17 -2
  174. package/corpus/templates/macros/app/routes/agent.tsx +15 -0
  175. package/corpus/templates/macros/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  176. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +42 -0
  177. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +6 -0
  178. package/corpus/templates/mail/app/routes/agent.tsx +15 -0
  179. package/corpus/templates/mail/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  180. package/corpus/templates/plan/app/components/layout/Header.tsx +1 -0
  181. package/corpus/templates/plan/app/components/layout/Layout.tsx +1 -0
  182. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +2 -0
  183. package/corpus/templates/plan/app/root.tsx +8 -0
  184. package/corpus/templates/plan/app/routes/agent.tsx +15 -0
  185. package/corpus/templates/plan/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  186. package/corpus/templates/slides/app/components/layout/Header.tsx +1 -0
  187. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -0
  188. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +2 -0
  189. package/corpus/templates/slides/app/root.tsx +10 -1
  190. package/corpus/templates/slides/app/routes/agent.tsx +15 -0
  191. package/corpus/templates/slides/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  192. package/dist/agent/context-xray/actions/context-evict.js +5 -2
  193. package/dist/agent/context-xray/actions/context-evict.js.map +1 -1
  194. package/dist/agent/context-xray/actions/context-pin.js +5 -2
  195. package/dist/agent/context-xray/actions/context-pin.js.map +1 -1
  196. package/dist/agent/context-xray/actions/context-preview-get.d.ts +17 -0
  197. package/dist/agent/context-xray/actions/context-preview-get.d.ts.map +1 -0
  198. package/dist/agent/context-xray/actions/context-preview-get.js +94 -0
  199. package/dist/agent/context-xray/actions/context-preview-get.js.map +1 -0
  200. package/dist/agent/context-xray/actions/context-restore.js +5 -2
  201. package/dist/agent/context-xray/actions/context-restore.js.map +1 -1
  202. package/dist/agent/context-xray/actions/errors.d.ts +3 -0
  203. package/dist/agent/context-xray/actions/errors.d.ts.map +1 -1
  204. package/dist/agent/context-xray/actions/errors.js +6 -0
  205. package/dist/agent/context-xray/actions/errors.js.map +1 -1
  206. package/dist/agent/context-xray/manifest.d.ts +18 -1
  207. package/dist/agent/context-xray/manifest.d.ts.map +1 -1
  208. package/dist/agent/context-xray/manifest.js +68 -6
  209. package/dist/agent/context-xray/manifest.js.map +1 -1
  210. package/dist/agent/engine/context-directives-transform.d.ts +2 -0
  211. package/dist/agent/engine/context-directives-transform.d.ts.map +1 -1
  212. package/dist/agent/engine/context-directives-transform.js +2 -1
  213. package/dist/agent/engine/context-directives-transform.js.map +1 -1
  214. package/dist/agent/production-agent.d.ts +15 -0
  215. package/dist/agent/production-agent.d.ts.map +1 -1
  216. package/dist/agent/production-agent.js +74 -36
  217. package/dist/agent/production-agent.js.map +1 -1
  218. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  219. package/dist/agent/run-loop-with-resume.js +6 -3
  220. package/dist/agent/run-loop-with-resume.js.map +1 -1
  221. package/dist/client/AgentPanel.d.ts +5 -1
  222. package/dist/client/AgentPanel.d.ts.map +1 -1
  223. package/dist/client/AgentPanel.js +9 -11
  224. package/dist/client/AgentPanel.js.map +1 -1
  225. package/dist/client/agent-page/AgentContextTab.d.ts +5 -0
  226. package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -0
  227. package/dist/client/agent-page/AgentContextTab.js +202 -0
  228. package/dist/client/agent-page/AgentContextTab.js.map +1 -0
  229. package/dist/client/agent-page/AgentJobsTab.d.ts +3 -0
  230. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -0
  231. package/dist/client/agent-page/AgentJobsTab.js +98 -0
  232. package/dist/client/agent-page/AgentJobsTab.js.map +1 -0
  233. package/dist/client/agent-page/AgentTabsPage.d.ts +20 -0
  234. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -0
  235. package/dist/client/agent-page/AgentTabsPage.js +420 -0
  236. package/dist/client/agent-page/AgentTabsPage.js.map +1 -0
  237. package/dist/client/agent-page/types.d.ts +17 -0
  238. package/dist/client/agent-page/types.d.ts.map +1 -0
  239. package/dist/client/agent-page/types.js +9 -0
  240. package/dist/client/agent-page/types.js.map +1 -0
  241. package/dist/client/agent-page/use-jobs.d.ts +61 -0
  242. package/dist/client/agent-page/use-jobs.d.ts.map +1 -0
  243. package/dist/client/agent-page/use-jobs.js +71 -0
  244. package/dist/client/agent-page/use-jobs.js.map +1 -0
  245. package/dist/client/context-xray/ContextMeter.d.ts +3 -1
  246. package/dist/client/context-xray/ContextMeter.d.ts.map +1 -1
  247. package/dist/client/context-xray/ContextMeter.js +14 -5
  248. package/dist/client/context-xray/ContextMeter.js.map +1 -1
  249. package/dist/client/context-xray/ContextTreemap.d.ts +3 -2
  250. package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -1
  251. package/dist/client/context-xray/ContextTreemap.js +9 -1
  252. package/dist/client/context-xray/ContextTreemap.js.map +1 -1
  253. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
  254. package/dist/client/context-xray/ContextXRayPanel.js +95 -20
  255. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
  256. package/dist/client/context-xray/format.d.ts.map +1 -1
  257. package/dist/client/context-xray/format.js +12 -0
  258. package/dist/client/context-xray/format.js.map +1 -1
  259. package/dist/client/index.d.ts +3 -0
  260. package/dist/client/index.d.ts.map +1 -1
  261. package/dist/client/index.js +1 -0
  262. package/dist/client/index.js.map +1 -1
  263. package/dist/client/resources/ResourcesPanel.d.ts +9 -1
  264. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  265. package/dist/client/resources/ResourcesPanel.js +26 -10
  266. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  267. package/dist/client/settings/AutomationsSection.d.ts +9 -0
  268. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  269. package/dist/client/settings/AutomationsSection.js +128 -147
  270. package/dist/client/settings/AutomationsSection.js.map +1 -1
  271. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  272. package/dist/jobs/actions/list-recurring-jobs.d.ts +21 -0
  273. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -0
  274. package/dist/jobs/actions/list-recurring-jobs.js +74 -0
  275. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -0
  276. package/dist/jobs/actions/manage-recurring-job.d.ts +18 -0
  277. package/dist/jobs/actions/manage-recurring-job.d.ts.map +1 -0
  278. package/dist/jobs/actions/manage-recurring-job.js +68 -0
  279. package/dist/jobs/actions/manage-recurring-job.js.map +1 -0
  280. package/dist/jobs/tools.d.ts +13 -0
  281. package/dist/jobs/tools.d.ts.map +1 -1
  282. package/dist/jobs/tools.js +1 -1
  283. package/dist/jobs/tools.js.map +1 -1
  284. package/dist/localization/default-messages.d.ts +96 -0
  285. package/dist/localization/default-messages.d.ts.map +1 -1
  286. package/dist/localization/default-messages.js +96 -0
  287. package/dist/localization/default-messages.js.map +1 -1
  288. package/dist/mcp/build-server.d.ts.map +1 -1
  289. package/dist/mcp/build-server.js +1 -0
  290. package/dist/mcp/build-server.js.map +1 -1
  291. package/dist/mcp/connect-route.d.ts.map +1 -1
  292. package/dist/mcp/connect-route.js +44 -59
  293. package/dist/mcp/connect-route.js.map +1 -1
  294. package/dist/notifications/routes.d.ts +2 -2
  295. package/dist/resources/handlers.d.ts +1 -1
  296. package/dist/server/action-discovery.d.ts.map +1 -1
  297. package/dist/server/action-discovery.js +23 -0
  298. package/dist/server/action-discovery.js.map +1 -1
  299. package/dist/server/agent-chat/prompt-resources.d.ts +14 -0
  300. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  301. package/dist/server/agent-chat/prompt-resources.js +139 -2
  302. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  303. package/dist/server/agent-chat-plugin.d.ts +1 -0
  304. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  305. package/dist/server/agent-chat-plugin.js +136 -3
  306. package/dist/server/agent-chat-plugin.js.map +1 -1
  307. package/dist/server/auth.d.ts.map +1 -1
  308. package/dist/server/auth.js +1 -4
  309. package/dist/server/auth.js.map +1 -1
  310. package/dist/server/google-oauth.d.ts.map +1 -1
  311. package/dist/server/google-oauth.js +1 -4
  312. package/dist/server/google-oauth.js.map +1 -1
  313. package/dist/server/transcribe-voice.d.ts +1 -1
  314. package/dist/server/workspace-oauth.d.ts +11 -0
  315. package/dist/server/workspace-oauth.d.ts.map +1 -0
  316. package/dist/server/workspace-oauth.js +25 -0
  317. package/dist/server/workspace-oauth.js.map +1 -0
  318. package/dist/shared/context-xray.d.ts +45 -1
  319. package/dist/shared/context-xray.d.ts.map +1 -1
  320. package/dist/shared/context-xray.js +12 -0
  321. package/dist/shared/context-xray.js.map +1 -1
  322. package/dist/shared/mcp-connect-content.d.ts +37 -0
  323. package/dist/shared/mcp-connect-content.d.ts.map +1 -0
  324. package/dist/shared/mcp-connect-content.js +92 -0
  325. package/dist/shared/mcp-connect-content.js.map +1 -0
  326. package/dist/templates/default/app/routes/_index.tsx +11 -0
  327. package/dist/templates/default/app/routes/agent.tsx +33 -0
  328. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  329. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  330. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  331. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  332. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  333. package/dist/triggers/actions/list-automations.d.ts +24 -0
  334. package/dist/triggers/actions/list-automations.d.ts.map +1 -0
  335. package/dist/triggers/actions/list-automations.js +72 -0
  336. package/dist/triggers/actions/list-automations.js.map +1 -0
  337. package/dist/triggers/actions/manage-automation.d.ts +18 -0
  338. package/dist/triggers/actions/manage-automation.d.ts.map +1 -0
  339. package/dist/triggers/actions/manage-automation.js +60 -0
  340. package/dist/triggers/actions/manage-automation.js.map +1 -0
  341. package/docs/content/a2a-protocol.mdx +42 -0
  342. package/docs/content/agent-surfaces.mdx +43 -0
  343. package/docs/content/external-agents.mdx +11 -0
  344. package/docs/content/locales/ar-SA/a2a-protocol.mdx +42 -0
  345. package/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  346. package/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  347. package/docs/content/locales/de-DE/a2a-protocol.mdx +42 -0
  348. package/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  349. package/docs/content/locales/de-DE/external-agents.mdx +10 -0
  350. package/docs/content/locales/es-ES/a2a-protocol.mdx +42 -0
  351. package/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  352. package/docs/content/locales/es-ES/external-agents.mdx +10 -0
  353. package/docs/content/locales/fr-FR/a2a-protocol.mdx +42 -0
  354. package/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  355. package/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  356. package/docs/content/locales/hi-IN/a2a-protocol.mdx +42 -0
  357. package/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  358. package/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  359. package/docs/content/locales/ja-JP/a2a-protocol.mdx +42 -0
  360. package/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  361. package/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  362. package/docs/content/locales/ko-KR/a2a-protocol.mdx +42 -0
  363. package/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  364. package/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  365. package/docs/content/locales/pt-BR/a2a-protocol.mdx +42 -0
  366. package/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  367. package/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  368. package/docs/content/locales/zh-CN/a2a-protocol.mdx +42 -0
  369. package/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  370. package/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  371. package/docs/content/locales/zh-TW/a2a-protocol.mdx +42 -0
  372. package/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  373. package/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  374. package/package.json +1 -1
  375. package/src/templates/default/app/routes/_index.tsx +11 -0
  376. package/src/templates/default/app/routes/agent.tsx +33 -0
  377. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  378. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  379. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  380. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  381. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
@@ -1,129 +1,123 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { IconBolt, IconClock, IconLoader2, IconPlayerPlay, IconPlus, IconTrash, } from "@tabler/icons-react";
3
- import { useEffect, useState, useCallback } from "react";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@agent-native/toolkit/ui/button";
3
+ import { IconBolt, IconClock, IconEye, IconLoader2, IconPlayerPause, IconPlayerPlay, IconPlus, IconTrash, } from "@tabler/icons-react";
4
+ import { useCallback, useState } from "react";
4
5
  import { sendToAgentChat } from "../agent-chat.js";
6
+ import { useAutomations, useManageAutomation, } from "../agent-page/use-jobs.js";
5
7
  import { agentNativePath } from "../api-path.js";
8
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
6
9
  import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
7
- import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
8
10
  import { PromptComposer } from "../composer/PromptComposer.js";
9
- function flattenJobs(nodes) {
10
- const items = [];
11
- for (const node of nodes) {
12
- if (node.type === "folder" && node.children) {
13
- items.push(...flattenJobs(node.children));
14
- }
15
- if (node.type === "file" &&
16
- node.kind === "job" &&
17
- node.resource &&
18
- node.jobMeta) {
19
- const name = node.name.replace(/\.md$/, "").replace(/-/g, " ");
20
- items.push({
21
- id: node.resource.id,
22
- name,
23
- path: node.resource.path,
24
- schedule: node.jobMeta.schedule,
25
- scheduleDescription: node.jobMeta.scheduleDescription,
26
- enabled: node.jobMeta.enabled ?? false,
27
- lastStatus: node.jobMeta.lastStatus,
28
- lastRun: node.jobMeta.lastRun,
29
- nextRun: node.jobMeta.nextRun,
30
- });
31
- }
11
+ import { useFormatters, useT } from "../i18n.js";
12
+ export const AUTOMATION_CREATION_SCOPE = "personal";
13
+ export function automationCreationContext() {
14
+ return `The user wants to create a new ${AUTOMATION_CREATION_SCOPE} automation. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`;
15
+ }
16
+ export function AutomationsList({ scope = "user", compact = false, emptyMessage, }) {
17
+ const t = useT();
18
+ const { formatDate } = useFormatters();
19
+ const query = useAutomations(scope);
20
+ const mutation = useManageAutomation(scope);
21
+ const [deleteTarget, setDeleteTarget] = useState(null);
22
+ const [detailsTarget, setDetailsTarget] = useState(null);
23
+ const formatDateTime = (value) => {
24
+ if (!value || Number.isNaN(new Date(value).getTime()))
25
+ return null;
26
+ return formatDate(value, {
27
+ month: "short",
28
+ day: "numeric",
29
+ hour: "numeric",
30
+ minute: "2-digit",
31
+ });
32
+ };
33
+ if (query.isLoading) {
34
+ return (_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", "aria-busy": "true", children: [_jsx(IconLoader2, { className: "size-4 animate-spin" }), t("jobs.loading", { defaultValue: "Loading…" })] }));
35
+ }
36
+ if (query.error) {
37
+ return (_jsx("p", { className: "text-sm text-destructive", children: t("jobs.automationsLoadError", {
38
+ defaultValue: "Could not load automations.",
39
+ }) }));
32
40
  }
33
- return items;
41
+ const automations = query.data ?? [];
42
+ if (automations.length === 0) {
43
+ return (_jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage ??
44
+ t("jobs.automationsEmpty", {
45
+ defaultValue: "No automations yet. Ask the agent to set up an event-triggered or scheduled task.",
46
+ }) }));
47
+ }
48
+ return (_jsxs("div", { className: compact ? "space-y-2" : "space-y-3", children: [automations.map((automation) => {
49
+ const lastRun = formatDateTime(automation.lastRun);
50
+ const nextRun = formatDateTime(automation.nextRun);
51
+ const trigger = automation.triggerType === "event"
52
+ ? t("jobs.automationEventTrigger", {
53
+ defaultValue: "On {{event}}",
54
+ event: automation.event ?? "event",
55
+ })
56
+ : (automation.scheduleDescription ??
57
+ automation.schedule ??
58
+ t("jobs.automationScheduleTrigger", {
59
+ defaultValue: "Scheduled task",
60
+ }));
61
+ return (_jsx("article", { className: "rounded-lg border border-border bg-card p-3", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-0.5 text-muted-foreground", children: automation.triggerType === "event" ? (_jsx(IconBolt, { className: "size-4" })) : (_jsx(IconClock, { className: "size-4" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-medium text-foreground", children: automation.name.replace(/-/g, " ") }), _jsx("span", { className: automation.enabled
62
+ ? "rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400"
63
+ : "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: automation.enabled
64
+ ? t("jobs.enabled", { defaultValue: "Enabled" })
65
+ : t("jobs.disabled", { defaultValue: "Disabled" }) }), automation.lastStatus ? (_jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: automation.lastStatus })) : null] }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: trigger }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground/80", children: automation.body }), lastRun || nextRun ? (_jsxs("div", { className: "mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground", children: [lastRun ? (_jsxs("span", { children: [t("jobs.lastRun", { defaultValue: "Last run" }), ":", " ", lastRun] })) : null, nextRun ? (_jsxs("span", { children: [t("jobs.nextRun", { defaultValue: "Next run" }), ":", " ", nextRun] })) : null] })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", onClick: () => setDetailsTarget(automation), children: [_jsx(IconEye, { className: "size-3.5" }), t("jobs.details", { defaultValue: "Details" })] }), automation.canUpdate ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutation.isPending, onClick: () => mutation.mutate({
66
+ operation: "update",
67
+ name: automation.name,
68
+ scope: automation.scope,
69
+ enabled: !automation.enabled,
70
+ }), children: [automation.enabled ? (_jsx(IconPlayerPause, { className: "size-3.5" })) : (_jsx(IconPlayerPlay, { className: "size-3.5" })), automation.enabled
71
+ ? t("jobs.pause", { defaultValue: "Pause" })
72
+ : t("jobs.resume", { defaultValue: "Resume" })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 cursor-pointer text-muted-foreground hover:text-destructive", "aria-label": t("jobs.delete", { defaultValue: "Delete" }), onClick: () => setDeleteTarget(automation), children: _jsx(IconTrash, { className: "size-3.5" }) })] })) : null] })] }) }, automation.id));
73
+ }), mutation.error ? (_jsx("p", { className: "text-sm text-destructive", children: mutation.error.message ||
74
+ t("jobs.automationUpdateError", {
75
+ defaultValue: "Could not update automation.",
76
+ }) })) : null, _jsx(Dialog, { open: deleteTarget !== null, onOpenChange: (open) => {
77
+ if (!open && !mutation.isPending)
78
+ setDeleteTarget(null);
79
+ }, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t("jobs.deleteAutomationTitle", {
80
+ defaultValue: "Delete automation?",
81
+ }) }), _jsx(DialogDescription, { children: t("jobs.deleteAutomationDescription", {
82
+ defaultValue: "This permanently removes the automation and cannot be undone.",
83
+ }) })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", className: "cursor-pointer", disabled: mutation.isPending, onClick: () => setDeleteTarget(null), children: t("jobs.cancel", { defaultValue: "Cancel" }) }), _jsxs(Button, { type: "button", variant: "destructive", className: "cursor-pointer", disabled: mutation.isPending, onClick: () => {
84
+ if (!deleteTarget)
85
+ return;
86
+ mutation.mutate({
87
+ operation: "delete",
88
+ name: deleteTarget.name,
89
+ scope: deleteTarget.scope,
90
+ }, { onSuccess: () => setDeleteTarget(null) });
91
+ }, children: [mutation.isPending ? (_jsx(IconLoader2, { className: "size-4 animate-spin" })) : null, t("jobs.delete", { defaultValue: "Delete" })] })] })] }) }), _jsx(Dialog, { open: detailsTarget !== null, onOpenChange: (open) => {
92
+ if (!open)
93
+ setDetailsTarget(null);
94
+ }, children: _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: detailsTarget?.name.replace(/-/g, " ") ??
95
+ t("jobs.automationDetails", {
96
+ defaultValue: "Automation details",
97
+ }) }), _jsx(DialogDescription, { children: detailsTarget
98
+ ? detailsTarget.triggerType === "event"
99
+ ? t("jobs.automationEventDetails", {
100
+ defaultValue: "Runs when {{event}}.",
101
+ event: detailsTarget.event ?? "an event fires",
102
+ })
103
+ : (detailsTarget.scheduleDescription ??
104
+ detailsTarget.schedule ??
105
+ t("jobs.automationScheduleTrigger", {
106
+ defaultValue: "Scheduled task",
107
+ }))
108
+ : null })] }), detailsTarget ? (_jsxs("div", { className: "space-y-3", children: [detailsTarget.condition ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.condition", { defaultValue: "Condition" }) }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: detailsTarget.condition })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.instructions", { defaultValue: "Instructions" }) }), _jsx("p", { className: "mt-1 whitespace-pre-wrap text-sm text-muted-foreground", children: detailsTarget.body })] })] })) : null] }) })] }));
34
109
  }
35
110
  export function AutomationsSection() {
36
- const [automations, setAutomations] = useState([]);
37
- const [loading, setLoading] = useState(true);
38
- const [error, setError] = useState(null);
39
- const [togglingId, setTogglingId] = useState(null);
40
- const [deletingId, setDeletingId] = useState(null);
41
- const [confirmDeleteId, setConfirmDeleteId] = useState(null);
111
+ const t = useT();
112
+ const { data: automations = [] } = useAutomations("user");
113
+ const [newOpen, setNewOpen] = useState(false);
42
114
  const [toast, setToast] = useState(null);
43
- const [reloadToken, setReloadToken] = useState(0);
44
115
  const showToast = useCallback((kind, text, ms = 2500) => {
45
116
  setToast({ kind, text });
46
- setTimeout(() => setToast(null), ms);
117
+ window.setTimeout(() => setToast(null), ms);
47
118
  }, []);
48
- useEffect(() => {
49
- let cancelled = false;
50
- setLoading(true);
51
- fetch(agentNativePath("/_agent-native/resources/tree"))
52
- .then(async (r) => {
53
- if (!r.ok)
54
- throw new Error(`Failed to load (${r.status})`);
55
- return (await r.json());
56
- })
57
- .then(({ tree }) => {
58
- if (cancelled)
59
- return;
60
- const jobsFolder = tree.find((n) => n.name === "jobs" && n.type === "folder");
61
- const items = jobsFolder?.children
62
- ? flattenJobs(jobsFolder.children)
63
- : [];
64
- setAutomations(items);
65
- setLoading(false);
66
- })
67
- .catch((err) => {
68
- if (cancelled)
69
- return;
70
- setError(err?.message ?? "Failed to load");
71
- setLoading(false);
72
- });
73
- return () => {
74
- cancelled = true;
75
- };
76
- }, [reloadToken]);
77
- const reload = useCallback(() => setReloadToken((t) => t + 1), []);
78
- const handleToggle = useCallback(async (item) => {
79
- setTogglingId(item.id);
80
- try {
81
- const res = await fetch(agentNativePath(`/_agent-native/resources/${encodeURIComponent(item.id)}`));
82
- if (!res.ok) {
83
- showToast("err", "Failed to read automation");
84
- return;
85
- }
86
- const resource = await res.json();
87
- const content = resource.content ?? "";
88
- const newEnabled = !item.enabled;
89
- const updated = content.replace(/^(enabled:\s*)(true|false)/m, `$1${newEnabled}`);
90
- const putRes = await fetch(agentNativePath(`/_agent-native/resources/${encodeURIComponent(item.id)}`), {
91
- method: "PUT",
92
- headers: { "Content-Type": "application/json" },
93
- body: JSON.stringify({ content: updated }),
94
- });
95
- if (!putRes.ok) {
96
- showToast("err", "Failed to update automation");
97
- return;
98
- }
99
- showToast("ok", newEnabled ? "Enabled" : "Disabled");
100
- reload();
101
- }
102
- finally {
103
- setTogglingId(null);
104
- }
105
- }, [reload, showToast]);
106
- const handleDelete = useCallback(async (item) => {
107
- setDeletingId(item.id);
108
- try {
109
- const res = await fetch(agentNativePath(`/_agent-native/resources/${encodeURIComponent(item.id)}`), {
110
- method: "DELETE",
111
- headers: { "Content-Type": "application/json" },
112
- });
113
- if (!res.ok) {
114
- showToast("err", "Failed to delete automation");
115
- return;
116
- }
117
- showToast("ok", "Deleted");
118
- setConfirmDeleteId(null);
119
- reload();
120
- }
121
- finally {
122
- setDeletingId(null);
123
- }
124
- }, [reload, showToast]);
125
119
  const handleFireTestEvent = useCallback(async () => {
126
- showToast("ok", "Firing test event...");
120
+ showToast("ok", t("jobs.firingTestEvent", { defaultValue: "Firing test event" }));
127
121
  try {
128
122
  const res = await fetch(agentNativePath("/_agent-native/automations/fire-test"), {
129
123
  method: "POST",
@@ -131,17 +125,22 @@ export function AutomationsSection() {
131
125
  body: JSON.stringify({ data: {} }),
132
126
  });
133
127
  if (!res.ok) {
134
- showToast("err", `Failed to fire event (${res.status})`);
128
+ showToast("err", t("jobs.fireEventError", {
129
+ defaultValue: "Failed to fire event ({{status}})",
130
+ status: res.status,
131
+ }));
135
132
  return;
136
133
  }
137
- showToast("ok", "Event fired");
134
+ showToast("ok", t("jobs.eventFired", { defaultValue: "Event fired" }));
138
135
  }
139
136
  catch (err) {
140
- showToast("err", err?.message ?? "Failed to fire event");
137
+ showToast("err", err instanceof Error
138
+ ? err.message
139
+ : t("jobs.fireEventErrorGeneric", {
140
+ defaultValue: "Failed to fire event.",
141
+ }));
141
142
  }
142
- }, [showToast]);
143
- const [newOpen, setNewOpen] = useState(false);
144
- const [newScope, setNewScope] = useState("personal");
143
+ }, [showToast, t]);
145
144
  const handleNewSubmit = useCallback((text) => {
146
145
  const trimmed = text.trim();
147
146
  if (!trimmed)
@@ -151,36 +150,18 @@ export function AutomationsSection() {
151
150
  }));
152
151
  sendToAgentChat({
153
152
  message: trimmed,
154
- context: `The user wants to create a new automation. Scope: ${newScope}. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`,
153
+ context: automationCreationContext(),
155
154
  submit: true,
156
155
  newTab: true,
157
156
  });
158
157
  setNewOpen(false);
159
- }, [newScope]);
160
- if (error) {
161
- return (_jsxs("p", { className: "text-[10px] text-red-500", children: ["Failed to load automations: ", error] }));
162
- }
163
- if (loading) {
164
- return (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading..."] }));
165
- }
166
- return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(Popover, { open: newOpen, onOpenChange: setNewOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-accent/40", children: [_jsx(IconPlus, { size: 10 }), "New Automation"] }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 6, collisionPadding: 8, className: "z-[260] w-[calc(100vw-24px)] max-w-[380px] p-3", children: [_jsx("p", { className: "px-1 pb-2 text-sm font-semibold text-foreground", children: "New automation" }), _jsx(PromptComposer, { autoFocus: true, placeholder: "Describe what you want to automate...", draftScope: "automations:create", onSubmit: handleNewSubmit }), _jsx("div", { className: "mt-2", children: _jsxs("select", { value: newScope, onChange: (e) => setNewScope(e.target.value), className: "w-full cursor-pointer rounded-md border border-input bg-background px-3 py-1.5 text-[12px] text-foreground", children: [_jsx("option", { value: "personal", children: "Personal" }), _jsx("option", { value: "organization", children: "Organization" })] }) })] })] }), automations.length > 0 && (_jsxs("button", { type: "button", onClick: handleFireTestEvent, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-accent/40", children: [_jsx(IconPlayerPlay, { size: 10 }), "Fire Test Event"] }))] }), automations.length === 0 ? (_jsx("p", { className: "text-[10px] text-muted-foreground", children: "No automations yet. Click \"New Automation\" to create one, or ask the agent to set up a scheduled or event-triggered task." })) : (automations.map((item) => (_jsxs("div", { className: "rounded-md border border-border px-2.5 py-2 bg-accent/30", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground shrink-0", children: item.schedule ? (_jsx(IconClock, { size: 11 })) : (_jsx(IconBolt, { size: 11 })) }), _jsx("span", { className: "text-[11px] font-medium text-foreground truncate capitalize", children: item.name })] }), item.scheduleDescription && (_jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5 ms-[17px]", children: item.scheduleDescription })), item.schedule && !item.scheduleDescription && (_jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5 ms-[17px] font-mono", children: item.schedule }))] }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [_jsx(StatusBadge, { status: item.lastStatus }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => handleToggle(item), disabled: togglingId === item.id, className: `rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${item.enabled
167
- ? "bg-green-500/15 text-green-500"
168
- : "bg-accent/60 text-muted-foreground"} hover:opacity-80 disabled:opacity-40`, children: togglingId === item.id ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : item.enabled ? ("On") : ("Off") }) }), _jsx(TooltipContent, { children: item.enabled ? "Disable" : "Enable" })] }), confirmDeleteId === item.id ? (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => handleDelete(item), disabled: deletingId === item.id, className: "rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40", children: deletingId === item.id ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Confirm") }), _jsx("button", { type: "button", onClick: () => setConfirmDeleteId(null), className: "rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground", children: "Cancel" })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => setConfirmDeleteId(item.id), className: "text-muted-foreground hover:text-red-500 disabled:opacity-40", children: _jsx(IconTrash, { size: 12 }) }) }), _jsx(TooltipContent, { children: "Delete" })] }))] })] }), item.lastRun && (_jsxs("p", { className: "text-[10px] text-muted-foreground mt-1 ms-[17px]", children: ["Last run:", " ", new Date(item.lastRun).toLocaleString(undefined, {
169
- month: "short",
170
- day: "numeric",
171
- hour: "numeric",
172
- minute: "2-digit",
173
- })] }))] }, item.id)))), toast && (_jsx("p", { className: `text-[10px] ${toast.kind === "ok" ? "text-green-500" : "text-red-500"}`, children: toast.text }))] }));
174
- }
175
- function StatusBadge({ status }) {
176
- if (!status)
177
- return null;
178
- const styles = {
179
- success: "bg-green-500/15 text-green-500",
180
- error: "bg-red-500/15 text-red-500",
181
- running: "bg-blue-500/15 text-blue-500",
182
- skipped: "bg-accent/60 text-muted-foreground",
183
- };
184
- return (_jsx("span", { className: `rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${styles[status] ?? styles.skipped}`, children: status }));
158
+ }, []);
159
+ return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(Popover, { open: newOpen, onOpenChange: setNewOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "cursor-pointer", children: [_jsx(IconPlus, { className: "size-3.5" }), t("jobs.newAutomation", { defaultValue: "New automation" })] }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 6, collisionPadding: 8, className: "z-[260] w-[calc(100vw-24px)] max-w-[380px] p-3", children: [_jsx("p", { className: "px-1 pb-2 text-sm font-semibold text-foreground", children: t("jobs.newAutomation", { defaultValue: "New automation" }) }), _jsx(PromptComposer, { autoFocus: true, placeholder: t("jobs.automationPlaceholder", {
160
+ defaultValue: "Describe what you want to automate…",
161
+ }), draftScope: "automations:create", onSubmit: handleNewSubmit })] })] }), automations.length > 0 ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "cursor-pointer", onClick: handleFireTestEvent, children: [_jsx(IconPlayerPlay, { className: "size-3.5" }), t("jobs.fireTestEvent", { defaultValue: "Fire test event" })] })) : null] }), toast ? (_jsx("p", { className: toast.kind === "ok"
162
+ ? "text-xs text-emerald-600"
163
+ : "text-xs text-destructive", children: toast.text })) : null, _jsx(AutomationsList, { scope: "user", compact: true, emptyMessage: t("jobs.automationsEmptySettings", {
164
+ defaultValue: 'No automations yet. Click "New automation" or ask the agent to set one up.',
165
+ }) })] }));
185
166
  }
186
167
  //# sourceMappingURL=AutomationsSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutomationsSection.js","sourceRoot":"","sources":["../../../src/client/settings/AutomationsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconBolt,\n IconClock,\n IconLoader2,\n IconPlayerPlay,\n IconPlus,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useEffect, useState, useCallback } from \"react\";\n\nimport { sendToAgentChat } from \"../agent-chat.js\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { PromptComposer } from \"../composer/PromptComposer.js\";\n\ninterface TreeNode {\n name: string;\n path: string;\n type: \"file\" | \"folder\";\n kind?: string;\n children?: TreeNode[];\n resource?: {\n id: string;\n path: string;\n owner: string;\n mimeType: string;\n size: number;\n createdAt: number;\n updatedAt: number;\n };\n jobMeta?: {\n schedule?: string;\n scheduleDescription?: string;\n enabled?: boolean;\n lastStatus?: string;\n lastRun?: string;\n nextRun?: string;\n };\n}\n\ninterface AutomationItem {\n id: string;\n name: string;\n path: string;\n schedule?: string;\n scheduleDescription?: string;\n enabled: boolean;\n lastStatus?: string;\n lastRun?: string;\n nextRun?: string;\n}\n\nfunction flattenJobs(nodes: TreeNode[]): AutomationItem[] {\n const items: AutomationItem[] = [];\n for (const node of nodes) {\n if (node.type === \"folder\" && node.children) {\n items.push(...flattenJobs(node.children));\n }\n if (\n node.type === \"file\" &&\n node.kind === \"job\" &&\n node.resource &&\n node.jobMeta\n ) {\n const name = node.name.replace(/\\.md$/, \"\").replace(/-/g, \" \");\n items.push({\n id: node.resource.id,\n name,\n path: node.resource.path,\n schedule: node.jobMeta.schedule,\n scheduleDescription: node.jobMeta.scheduleDescription,\n enabled: node.jobMeta.enabled ?? false,\n lastStatus: node.jobMeta.lastStatus,\n lastRun: node.jobMeta.lastRun,\n nextRun: node.jobMeta.nextRun,\n });\n }\n }\n return items;\n}\n\nexport function AutomationsSection() {\n const [automations, setAutomations] = useState<AutomationItem[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [togglingId, setTogglingId] = useState<string | null>(null);\n const [deletingId, setDeletingId] = useState<string | null>(null);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetch(agentNativePath(\"/_agent-native/resources/tree\"))\n .then(async (r) => {\n if (!r.ok) throw new Error(`Failed to load (${r.status})`);\n return (await r.json()) as { tree: TreeNode[] };\n })\n .then(({ tree }) => {\n if (cancelled) return;\n const jobsFolder = tree.find(\n (n) => n.name === \"jobs\" && n.type === \"folder\",\n );\n const items = jobsFolder?.children\n ? flattenJobs(jobsFolder.children)\n : [];\n setAutomations(items);\n setLoading(false);\n })\n .catch((err) => {\n if (cancelled) return;\n setError(err?.message ?? \"Failed to load\");\n setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n const handleToggle = useCallback(\n async (item: AutomationItem) => {\n setTogglingId(item.id);\n try {\n const res = await fetch(\n agentNativePath(\n `/_agent-native/resources/${encodeURIComponent(item.id)}`,\n ),\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to read automation\");\n return;\n }\n const resource = await res.json();\n const content: string = resource.content ?? \"\";\n\n const newEnabled = !item.enabled;\n const updated = content.replace(\n /^(enabled:\\s*)(true|false)/m,\n `$1${newEnabled}`,\n );\n\n const putRes = await fetch(\n agentNativePath(\n `/_agent-native/resources/${encodeURIComponent(item.id)}`,\n ),\n {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content: updated }),\n },\n );\n if (!putRes.ok) {\n showToast(\"err\", \"Failed to update automation\");\n return;\n }\n showToast(\"ok\", newEnabled ? \"Enabled\" : \"Disabled\");\n reload();\n } finally {\n setTogglingId(null);\n }\n },\n [reload, showToast],\n );\n\n const handleDelete = useCallback(\n async (item: AutomationItem) => {\n setDeletingId(item.id);\n try {\n const res = await fetch(\n agentNativePath(\n `/_agent-native/resources/${encodeURIComponent(item.id)}`,\n ),\n {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to delete automation\");\n return;\n }\n showToast(\"ok\", \"Deleted\");\n setConfirmDeleteId(null);\n reload();\n } finally {\n setDeletingId(null);\n }\n },\n [reload, showToast],\n );\n\n const handleFireTestEvent = useCallback(async () => {\n showToast(\"ok\", \"Firing test event...\");\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/automations/fire-test\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ data: {} }),\n },\n );\n if (!res.ok) {\n showToast(\"err\", `Failed to fire event (${res.status})`);\n return;\n }\n showToast(\"ok\", \"Event fired\");\n } catch (err: any) {\n showToast(\"err\", err?.message ?? \"Failed to fire event\");\n }\n }, [showToast]);\n\n const [newOpen, setNewOpen] = useState(false);\n const [newScope, setNewScope] = useState<\"personal\" | \"organization\">(\n \"personal\",\n );\n\n const handleNewSubmit = useCallback(\n (text: string) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n sendToAgentChat({\n message: trimmed,\n context: `The user wants to create a new automation. Scope: ${newScope}. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`,\n submit: true,\n newTab: true,\n });\n setNewOpen(false);\n },\n [newScope],\n );\n\n if (error) {\n return (\n <p className=\"text-[10px] text-red-500\">\n Failed to load automations: {error}\n </p>\n );\n }\n\n if (loading) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading...\n </div>\n );\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <Popover open={newOpen} onOpenChange={setNewOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n <IconPlus size={10} />\n New Automation\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={6}\n collisionPadding={8}\n className=\"z-[260] w-[calc(100vw-24px)] max-w-[380px] p-3\"\n >\n <p className=\"px-1 pb-2 text-sm font-semibold text-foreground\">\n New automation\n </p>\n <PromptComposer\n autoFocus\n placeholder=\"Describe what you want to automate...\"\n draftScope=\"automations:create\"\n onSubmit={handleNewSubmit}\n />\n <div className=\"mt-2\">\n <select\n value={newScope}\n onChange={(e) =>\n setNewScope(e.target.value as \"personal\" | \"organization\")\n }\n className=\"w-full cursor-pointer rounded-md border border-input bg-background px-3 py-1.5 text-[12px] text-foreground\"\n >\n <option value=\"personal\">Personal</option>\n <option value=\"organization\">Organization</option>\n </select>\n </div>\n </PopoverContent>\n </Popover>\n {automations.length > 0 && (\n <button\n type=\"button\"\n onClick={handleFireTestEvent}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n <IconPlayerPlay size={10} />\n Fire Test Event\n </button>\n )}\n </div>\n\n {automations.length === 0 ? (\n <p className=\"text-[10px] text-muted-foreground\">\n No automations yet. Click \"New Automation\" to create one, or ask the\n agent to set up a scheduled or event-triggered task.\n </p>\n ) : (\n automations.map((item) => (\n <div\n key={item.id}\n className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-muted-foreground shrink-0\">\n {item.schedule ? (\n <IconClock size={11} />\n ) : (\n <IconBolt size={11} />\n )}\n </span>\n <span className=\"text-[11px] font-medium text-foreground truncate capitalize\">\n {item.name}\n </span>\n </div>\n {item.scheduleDescription && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5 ms-[17px]\">\n {item.scheduleDescription}\n </p>\n )}\n {item.schedule && !item.scheduleDescription && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5 ms-[17px] font-mono\">\n {item.schedule}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-1.5 shrink-0\">\n <StatusBadge status={item.lastStatus} />\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => handleToggle(item)}\n disabled={togglingId === item.id}\n className={`rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${\n item.enabled\n ? \"bg-green-500/15 text-green-500\"\n : \"bg-accent/60 text-muted-foreground\"\n } hover:opacity-80 disabled:opacity-40`}\n >\n {togglingId === item.id ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : item.enabled ? (\n \"On\"\n ) : (\n \"Off\"\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {item.enabled ? \"Disable\" : \"Enable\"}\n </TooltipContent>\n </Tooltip>\n {confirmDeleteId === item.id ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => handleDelete(item)}\n disabled={deletingId === item.id}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40\"\n >\n {deletingId === item.id ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteId(null)}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteId(item.id)}\n className=\"text-muted-foreground hover:text-red-500 disabled:opacity-40\"\n >\n <IconTrash size={12} />\n </button>\n </TooltipTrigger>\n <TooltipContent>Delete</TooltipContent>\n </Tooltip>\n )}\n </div>\n </div>\n {item.lastRun && (\n <p className=\"text-[10px] text-muted-foreground mt-1 ms-[17px]\">\n Last run:{\" \"}\n {new Date(item.lastRun).toLocaleString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n })}\n </p>\n )}\n </div>\n ))\n )}\n\n {toast && (\n <p\n className={`text-[10px] ${toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n\nfunction StatusBadge({ status }: { status?: string }) {\n if (!status) return null;\n\n const styles: Record<string, string> = {\n success: \"bg-green-500/15 text-green-500\",\n error: \"bg-red-500/15 text-red-500\",\n running: \"bg-blue-500/15 text-blue-500\",\n skipped: \"bg-accent/60 text-muted-foreground\",\n };\n\n return (\n <span\n className={`rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${styles[status] ?? styles.skipped}`}\n >\n {status}\n </span>\n );\n}\n"]}
1
+ {"version":3,"file":"AutomationsSection.js","sourceRoot":"","sources":["../../../src/client/settings/AutomationsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Button } from \"@agent-native/toolkit/ui/button\";\nimport {\n IconBolt,\n IconClock,\n IconEye,\n IconLoader2,\n IconPlayerPause,\n IconPlayerPlay,\n IconPlus,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useCallback, useState } from \"react\";\n\nimport { sendToAgentChat } from \"../agent-chat.js\";\nimport {\n useAutomations,\n useManageAutomation,\n type Automation,\n type JobsScope,\n} from \"../agent-page/use-jobs.js\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../components/ui/dialog.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { PromptComposer } from \"../composer/PromptComposer.js\";\nimport { useFormatters, useT } from \"../i18n.js\";\n\nexport interface AutomationsListProps {\n scope?: JobsScope;\n compact?: boolean;\n emptyMessage?: string;\n}\n\nexport const AUTOMATION_CREATION_SCOPE = \"personal\" as const;\n\nexport function automationCreationContext(): string {\n return `The user wants to create a new ${AUTOMATION_CREATION_SCOPE} automation. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`;\n}\n\nexport function AutomationsList({\n scope = \"user\",\n compact = false,\n emptyMessage,\n}: AutomationsListProps) {\n const t = useT();\n const { formatDate } = useFormatters();\n const query = useAutomations(scope);\n const mutation = useManageAutomation(scope);\n const [deleteTarget, setDeleteTarget] = useState<Automation | null>(null);\n const [detailsTarget, setDetailsTarget] = useState<Automation | null>(null);\n\n const formatDateTime = (value: string | null) => {\n if (!value || Number.isNaN(new Date(value).getTime())) return null;\n return formatDate(value, {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n };\n\n if (query.isLoading) {\n return (\n <div\n className=\"flex items-center gap-2 text-sm text-muted-foreground\"\n aria-busy=\"true\"\n >\n <IconLoader2 className=\"size-4 animate-spin\" />\n {t(\"jobs.loading\", { defaultValue: \"Loading…\" })}\n </div>\n );\n }\n\n if (query.error) {\n return (\n <p className=\"text-sm text-destructive\">\n {t(\"jobs.automationsLoadError\", {\n defaultValue: \"Could not load automations.\",\n })}\n </p>\n );\n }\n\n const automations = query.data ?? [];\n if (automations.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground\">\n {emptyMessage ??\n t(\"jobs.automationsEmpty\", {\n defaultValue:\n \"No automations yet. Ask the agent to set up an event-triggered or scheduled task.\",\n })}\n </p>\n );\n }\n\n return (\n <div className={compact ? \"space-y-2\" : \"space-y-3\"}>\n {automations.map((automation) => {\n const lastRun = formatDateTime(automation.lastRun);\n const nextRun = formatDateTime(automation.nextRun);\n const trigger =\n automation.triggerType === \"event\"\n ? t(\"jobs.automationEventTrigger\", {\n defaultValue: \"On {{event}}\",\n event: automation.event ?? \"event\",\n })\n : (automation.scheduleDescription ??\n automation.schedule ??\n t(\"jobs.automationScheduleTrigger\", {\n defaultValue: \"Scheduled task\",\n }));\n\n return (\n <article\n key={automation.id}\n className=\"rounded-lg border border-border bg-card p-3\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 text-muted-foreground\">\n {automation.triggerType === \"event\" ? (\n <IconBolt className=\"size-4\" />\n ) : (\n <IconClock className=\"size-4\" />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"truncate text-sm font-medium text-foreground\">\n {automation.name.replace(/-/g, \" \")}\n </h3>\n <span\n className={\n automation.enabled\n ? \"rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400\"\n : \"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\"\n }\n >\n {automation.enabled\n ? t(\"jobs.enabled\", { defaultValue: \"Enabled\" })\n : t(\"jobs.disabled\", { defaultValue: \"Disabled\" })}\n </span>\n {automation.lastStatus ? (\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {automation.lastStatus}\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">{trigger}</p>\n <p className=\"mt-1 line-clamp-2 text-xs text-muted-foreground/80\">\n {automation.body}\n </p>\n {lastRun || nextRun ? (\n <div className=\"mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground\">\n {lastRun ? (\n <span>\n {t(\"jobs.lastRun\", { defaultValue: \"Last run\" })}:{\" \"}\n {lastRun}\n </span>\n ) : null}\n {nextRun ? (\n <span>\n {t(\"jobs.nextRun\", { defaultValue: \"Next run\" })}:{\" \"}\n {nextRun}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n onClick={() => setDetailsTarget(automation)}\n >\n <IconEye className=\"size-3.5\" />\n {t(\"jobs.details\", { defaultValue: \"Details\" })}\n </Button>\n {automation.canUpdate ? (\n <>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"cursor-pointer px-2 text-xs\"\n disabled={mutation.isPending}\n onClick={() =>\n mutation.mutate({\n operation: \"update\",\n name: automation.name,\n scope: automation.scope,\n enabled: !automation.enabled,\n })\n }\n >\n {automation.enabled ? (\n <IconPlayerPause className=\"size-3.5\" />\n ) : (\n <IconPlayerPlay className=\"size-3.5\" />\n )}\n {automation.enabled\n ? t(\"jobs.pause\", { defaultValue: \"Pause\" })\n : t(\"jobs.resume\", { defaultValue: \"Resume\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 cursor-pointer text-muted-foreground hover:text-destructive\"\n aria-label={t(\"jobs.delete\", { defaultValue: \"Delete\" })}\n onClick={() => setDeleteTarget(automation)}\n >\n <IconTrash className=\"size-3.5\" />\n </Button>\n </>\n ) : null}\n </div>\n </div>\n </article>\n );\n })}\n\n {mutation.error ? (\n <p className=\"text-sm text-destructive\">\n {mutation.error.message ||\n t(\"jobs.automationUpdateError\", {\n defaultValue: \"Could not update automation.\",\n })}\n </p>\n ) : null}\n\n <Dialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open && !mutation.isPending) setDeleteTarget(null);\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"jobs.deleteAutomationTitle\", {\n defaultValue: \"Delete automation?\",\n })}\n </DialogTitle>\n <DialogDescription>\n {t(\"jobs.deleteAutomationDescription\", {\n defaultValue:\n \"This permanently removes the automation and cannot be undone.\",\n })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"cursor-pointer\"\n disabled={mutation.isPending}\n onClick={() => setDeleteTarget(null)}\n >\n {t(\"jobs.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n className=\"cursor-pointer\"\n disabled={mutation.isPending}\n onClick={() => {\n if (!deleteTarget) return;\n mutation.mutate(\n {\n operation: \"delete\",\n name: deleteTarget.name,\n scope: deleteTarget.scope,\n },\n { onSuccess: () => setDeleteTarget(null) },\n );\n }}\n >\n {mutation.isPending ? (\n <IconLoader2 className=\"size-4 animate-spin\" />\n ) : null}\n {t(\"jobs.delete\", { defaultValue: \"Delete\" })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n <Dialog\n open={detailsTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDetailsTarget(null);\n }}\n >\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>\n {detailsTarget?.name.replace(/-/g, \" \") ??\n t(\"jobs.automationDetails\", {\n defaultValue: \"Automation details\",\n })}\n </DialogTitle>\n <DialogDescription>\n {detailsTarget\n ? detailsTarget.triggerType === \"event\"\n ? t(\"jobs.automationEventDetails\", {\n defaultValue: \"Runs when {{event}}.\",\n event: detailsTarget.event ?? \"an event fires\",\n })\n : (detailsTarget.scheduleDescription ??\n detailsTarget.schedule ??\n t(\"jobs.automationScheduleTrigger\", {\n defaultValue: \"Scheduled task\",\n }))\n : null}\n </DialogDescription>\n </DialogHeader>\n {detailsTarget ? (\n <div className=\"space-y-3\">\n {detailsTarget.condition ? (\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.condition\", { defaultValue: \"Condition\" })}\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {detailsTarget.condition}\n </p>\n </div>\n ) : null}\n <div>\n <p className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.instructions\", { defaultValue: \"Instructions\" })}\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-muted-foreground\">\n {detailsTarget.body}\n </p>\n </div>\n </div>\n ) : null}\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n\nexport function AutomationsSection() {\n const t = useT();\n const { data: automations = [] } = useAutomations(\"user\");\n const [newOpen, setNewOpen] = useState(false);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n window.setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n const handleFireTestEvent = useCallback(async () => {\n showToast(\n \"ok\",\n t(\"jobs.firingTestEvent\", { defaultValue: \"Firing test event…\" }),\n );\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/automations/fire-test\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ data: {} }),\n },\n );\n if (!res.ok) {\n showToast(\n \"err\",\n t(\"jobs.fireEventError\", {\n defaultValue: \"Failed to fire event ({{status}})\",\n status: res.status,\n }),\n );\n return;\n }\n showToast(\"ok\", t(\"jobs.eventFired\", { defaultValue: \"Event fired\" }));\n } catch (err: unknown) {\n showToast(\n \"err\",\n err instanceof Error\n ? err.message\n : t(\"jobs.fireEventErrorGeneric\", {\n defaultValue: \"Failed to fire event.\",\n }),\n );\n }\n }, [showToast, t]);\n\n const handleNewSubmit = useCallback((text: string) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n sendToAgentChat({\n message: trimmed,\n context: automationCreationContext(),\n submit: true,\n newTab: true,\n });\n setNewOpen(false);\n }, []);\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <Popover open={newOpen} onOpenChange={setNewOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"cursor-pointer\"\n >\n <IconPlus className=\"size-3.5\" />\n {t(\"jobs.newAutomation\", { defaultValue: \"New automation\" })}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={6}\n collisionPadding={8}\n className=\"z-[260] w-[calc(100vw-24px)] max-w-[380px] p-3\"\n >\n <p className=\"px-1 pb-2 text-sm font-semibold text-foreground\">\n {t(\"jobs.newAutomation\", { defaultValue: \"New automation\" })}\n </p>\n <PromptComposer\n autoFocus\n placeholder={t(\"jobs.automationPlaceholder\", {\n defaultValue: \"Describe what you want to automate…\",\n })}\n draftScope=\"automations:create\"\n onSubmit={handleNewSubmit}\n />\n </PopoverContent>\n </Popover>\n {automations.length > 0 ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"cursor-pointer\"\n onClick={handleFireTestEvent}\n >\n <IconPlayerPlay className=\"size-3.5\" />\n {t(\"jobs.fireTestEvent\", { defaultValue: \"Fire test event\" })}\n </Button>\n ) : null}\n </div>\n {toast ? (\n <p\n className={\n toast.kind === \"ok\"\n ? \"text-xs text-emerald-600\"\n : \"text-xs text-destructive\"\n }\n >\n {toast.text}\n </p>\n ) : null}\n <AutomationsList\n scope=\"user\"\n compact\n emptyMessage={t(\"jobs.automationsEmptySettings\", {\n defaultValue:\n 'No automations yet. Click \"New automation\" or ask the agent to set one up.',\n })}\n />\n </div>\n );\n}\n"]}
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
28
28
  //# sourceMappingURL=upload-image.d.ts.map
@@ -0,0 +1,21 @@
1
+ export interface RecurringJobActionItem {
2
+ id: string;
3
+ name: string;
4
+ path: string;
5
+ scope: "personal" | "organization";
6
+ schedule: string;
7
+ scheduleDescription: string;
8
+ instructions: string;
9
+ enabled: boolean;
10
+ lastRun: string | null;
11
+ lastStatus: string | null;
12
+ lastError: string | null;
13
+ nextRun: string | null;
14
+ createdBy: string | null;
15
+ canUpdate: boolean;
16
+ }
17
+ declare const _default: import("../../action.js").ActionDefinition<{
18
+ scope?: "organization" | "personal";
19
+ }, RecurringJobActionItem[]>;
20
+ export default _default;
21
+ //# sourceMappingURL=list-recurring-jobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-recurring-jobs.d.ts","sourceRoot":"","sources":["../../../src/jobs/actions/list-recurring-jobs.ts"],"names":[],"mappings":"AAkCA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,GAAG,cAAc,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB"}
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import { defineAction } from "../../action.js";
3
+ import { organizationResourceOwner, resourceGetByPath, resourceList, } from "../../resources/store.js";
4
+ import { describeCron, isValidCron, nextOccurrence } from "../cron.js";
5
+ import { parseJobFrontmatter } from "../scheduler.js";
6
+ import { authorizeJobMutation } from "../tools.js";
7
+ const scopeSchema = z.enum(["personal", "organization"]);
8
+ function hasTriggerFrontmatter(content) {
9
+ const header = content.match(/^---\n([\s\S]*?)\n---/m)?.[1] ?? "";
10
+ return /^triggerType\s*:/m.test(header);
11
+ }
12
+ function jobName(path) {
13
+ return path.replace(/^jobs\//, "").replace(/\.md$/, "");
14
+ }
15
+ function nextRun(meta) {
16
+ if (!meta.enabled)
17
+ return null;
18
+ if (meta.nextRun)
19
+ return meta.nextRun;
20
+ if (meta.schedule && isValidCron(meta.schedule)) {
21
+ return nextOccurrence(meta.schedule).toISOString();
22
+ }
23
+ return null;
24
+ }
25
+ export default defineAction({
26
+ description: "List recurring cron jobs visible in the selected personal or organization scope. This read surface is used by the Agent Jobs page.",
27
+ agentTool: false,
28
+ schema: z.object({
29
+ scope: scopeSchema.default("personal"),
30
+ }),
31
+ http: { method: "GET" },
32
+ readOnly: true,
33
+ parallelSafe: true,
34
+ run: async ({ scope }, ctx) => {
35
+ const userEmail = ctx?.userEmail;
36
+ if (!userEmail)
37
+ throw new Error("Not authenticated.");
38
+ if (scope === "organization" && !ctx?.orgId)
39
+ return [];
40
+ const owner = scope === "organization"
41
+ ? organizationResourceOwner(ctx.orgId)
42
+ : userEmail;
43
+ const resources = await resourceList(owner, "jobs/");
44
+ const jobs = [];
45
+ for (const resource of resources) {
46
+ if (!resource.path.endsWith(".md") || resource.path.endsWith(".keep")) {
47
+ continue;
48
+ }
49
+ const full = await resourceGetByPath(owner, resource.path);
50
+ if (!full || hasTriggerFrontmatter(full.content))
51
+ continue;
52
+ const { meta, body } = parseJobFrontmatter(full.content);
53
+ const canUpdate = scope === "personal" || !(await authorizeJobMutation(owner, meta));
54
+ jobs.push({
55
+ id: full.id,
56
+ name: jobName(full.path),
57
+ path: full.path,
58
+ scope,
59
+ schedule: meta.schedule,
60
+ scheduleDescription: meta.schedule ? describeCron(meta.schedule) : "",
61
+ instructions: body,
62
+ enabled: meta.enabled,
63
+ lastRun: meta.lastRun ?? null,
64
+ lastStatus: meta.lastStatus ?? null,
65
+ lastError: meta.lastError ?? null,
66
+ nextRun: nextRun(meta),
67
+ createdBy: meta.createdBy ?? null,
68
+ canUpdate,
69
+ });
70
+ }
71
+ return jobs;
72
+ },
73
+ });
74
+ //# sourceMappingURL=list-recurring-jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-recurring-jobs.js","sourceRoot":"","sources":["../../../src/jobs/actions/list-recurring-jobs.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n organizationResourceOwner,\n resourceGetByPath,\n resourceList,\n} from \"../../resources/store.js\";\nimport { describeCron, isValidCron, nextOccurrence } from \"../cron.js\";\nimport { parseJobFrontmatter } from \"../scheduler.js\";\nimport { authorizeJobMutation } from \"../tools.js\";\n\nconst scopeSchema = z.enum([\"personal\", \"organization\"]);\n\nfunction hasTriggerFrontmatter(content: string): boolean {\n const header = content.match(/^---\\n([\\s\\S]*?)\\n---/m)?.[1] ?? \"\";\n return /^triggerType\\s*:/m.test(header);\n}\n\nfunction jobName(path: string): string {\n return path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n}\n\nfunction nextRun(\n meta: ReturnType<typeof parseJobFrontmatter>[\"meta\"],\n): string | null {\n if (!meta.enabled) return null;\n if (meta.nextRun) return meta.nextRun;\n if (meta.schedule && isValidCron(meta.schedule)) {\n return nextOccurrence(meta.schedule).toISOString();\n }\n return null;\n}\n\nexport interface RecurringJobActionItem {\n id: string;\n name: string;\n path: string;\n scope: \"personal\" | \"organization\";\n schedule: string;\n scheduleDescription: string;\n instructions: string;\n enabled: boolean;\n lastRun: string | null;\n lastStatus: string | null;\n lastError: string | null;\n nextRun: string | null;\n createdBy: string | null;\n canUpdate: boolean;\n}\n\nexport default defineAction({\n description:\n \"List recurring cron jobs visible in the selected personal or organization scope. This read surface is used by the Agent Jobs page.\",\n agentTool: false,\n schema: z.object({\n scope: scopeSchema.default(\"personal\"),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n parallelSafe: true,\n run: async ({ scope }, ctx): Promise<RecurringJobActionItem[]> => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n\n if (scope === \"organization\" && !ctx?.orgId) return [];\n\n const owner =\n scope === \"organization\"\n ? organizationResourceOwner(ctx.orgId as string)\n : userEmail;\n const resources = await resourceList(owner, \"jobs/\");\n const jobs: RecurringJobActionItem[] = [];\n\n for (const resource of resources) {\n if (!resource.path.endsWith(\".md\") || resource.path.endsWith(\".keep\")) {\n continue;\n }\n const full = await resourceGetByPath(owner, resource.path);\n if (!full || hasTriggerFrontmatter(full.content)) continue;\n\n const { meta, body } = parseJobFrontmatter(full.content);\n const canUpdate =\n scope === \"personal\" || !(await authorizeJobMutation(owner, meta));\n jobs.push({\n id: full.id,\n name: jobName(full.path),\n path: full.path,\n scope,\n schedule: meta.schedule,\n scheduleDescription: meta.schedule ? describeCron(meta.schedule) : \"\",\n instructions: body,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: nextRun(meta),\n createdBy: meta.createdBy ?? null,\n canUpdate,\n });\n }\n\n return jobs;\n },\n});\n"]}
@@ -0,0 +1,18 @@
1
+ declare const _default: import("../../action.js").ActionDefinition<{
2
+ operation: "delete" | "update";
3
+ name: string;
4
+ scope?: "organization" | "personal";
5
+ enabled?: boolean;
6
+ }, {
7
+ deleted: boolean;
8
+ name: string;
9
+ enabled?: undefined;
10
+ nextRun?: undefined;
11
+ } | {
12
+ deleted?: undefined;
13
+ name: string;
14
+ enabled: boolean;
15
+ nextRun: string;
16
+ }>;
17
+ export default _default;
18
+ //# sourceMappingURL=manage-recurring-job.d.ts.map