@agent-native/core 0.7.7 → 0.7.11

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 (338) hide show
  1. package/dist/agent/engine/ai-sdk-engine.d.ts +14 -2
  2. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/ai-sdk-engine.js +70 -54
  4. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  5. package/dist/agent/engine/anthropic-engine.d.ts +1 -6
  6. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  7. package/dist/agent/engine/anthropic-engine.js +3 -14
  8. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  9. package/dist/agent/engine/builtin.d.ts.map +1 -1
  10. package/dist/agent/engine/builtin.js +3 -0
  11. package/dist/agent/engine/builtin.js.map +1 -1
  12. package/dist/agent/engine/translate-ai-sdk.d.ts +35 -10
  13. package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
  14. package/dist/agent/engine/translate-ai-sdk.js +190 -91
  15. package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
  16. package/dist/agent/engine/types.d.ts +10 -1
  17. package/dist/agent/engine/types.d.ts.map +1 -1
  18. package/dist/agent/production-agent.d.ts +15 -1
  19. package/dist/agent/production-agent.d.ts.map +1 -1
  20. package/dist/agent/production-agent.js +78 -21
  21. package/dist/agent/production-agent.js.map +1 -1
  22. package/dist/agent/thread-data-builder.js +1 -1
  23. package/dist/agent/thread-data-builder.js.map +1 -1
  24. package/dist/agent/types.d.ts +4 -0
  25. package/dist/agent/types.d.ts.map +1 -1
  26. package/dist/application-state/script-helpers.d.ts +12 -5
  27. package/dist/application-state/script-helpers.d.ts.map +1 -1
  28. package/dist/application-state/script-helpers.js +41 -20
  29. package/dist/application-state/script-helpers.js.map +1 -1
  30. package/dist/catalog.json +15 -0
  31. package/dist/chat-threads/store.d.ts.map +1 -1
  32. package/dist/chat-threads/store.js +7 -5
  33. package/dist/chat-threads/store.js.map +1 -1
  34. package/dist/checkpoints/index.d.ts +3 -0
  35. package/dist/checkpoints/index.d.ts.map +1 -0
  36. package/dist/checkpoints/index.js +3 -0
  37. package/dist/checkpoints/index.js.map +1 -0
  38. package/dist/checkpoints/service.d.ts +6 -0
  39. package/dist/checkpoints/service.d.ts.map +1 -0
  40. package/dist/checkpoints/service.js +107 -0
  41. package/dist/checkpoints/service.js.map +1 -0
  42. package/dist/checkpoints/store.d.ts +27 -0
  43. package/dist/checkpoints/store.d.ts.map +1 -0
  44. package/dist/checkpoints/store.js +92 -0
  45. package/dist/checkpoints/store.js.map +1 -0
  46. package/dist/cli/create.d.ts.map +1 -1
  47. package/dist/cli/create.js +85 -1
  48. package/dist/cli/create.js.map +1 -1
  49. package/dist/cli/index.js +46 -3
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cli/templates-meta.d.ts.map +1 -1
  52. package/dist/cli/templates-meta.js +33 -0
  53. package/dist/cli/templates-meta.js.map +1 -1
  54. package/dist/client/AgentPanel.d.ts.map +1 -1
  55. package/dist/client/AgentPanel.js +3 -1
  56. package/dist/client/AgentPanel.js.map +1 -1
  57. package/dist/client/AssistantChat.d.ts +15 -0
  58. package/dist/client/AssistantChat.d.ts.map +1 -1
  59. package/dist/client/AssistantChat.js +145 -67
  60. package/dist/client/AssistantChat.js.map +1 -1
  61. package/dist/client/CommandMenu.d.ts.map +1 -1
  62. package/dist/client/CommandMenu.js +9 -5
  63. package/dist/client/CommandMenu.js.map +1 -1
  64. package/dist/client/ConnectBuilderCard.js +1 -1
  65. package/dist/client/ConnectBuilderCard.js.map +1 -1
  66. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  67. package/dist/client/MultiTabAssistantChat.js +78 -4
  68. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  69. package/dist/client/agent-chat-adapter.d.ts +6 -0
  70. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  71. package/dist/client/agent-chat-adapter.js +4 -0
  72. package/dist/client/agent-chat-adapter.js.map +1 -1
  73. package/dist/client/composer/TiptapComposer.d.ts +12 -1
  74. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  75. package/dist/client/composer/TiptapComposer.js +71 -3
  76. package/dist/client/composer/TiptapComposer.js.map +1 -1
  77. package/dist/client/notifications/NotificationsBell.d.ts +23 -0
  78. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -0
  79. package/dist/client/notifications/NotificationsBell.js +165 -0
  80. package/dist/client/notifications/NotificationsBell.js.map +1 -0
  81. package/dist/client/notifications/index.d.ts +2 -0
  82. package/dist/client/notifications/index.d.ts.map +1 -0
  83. package/dist/client/notifications/index.js +2 -0
  84. package/dist/client/notifications/index.js.map +1 -0
  85. package/dist/client/onboarding/OnboardingPanel.js +6 -3
  86. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  87. package/dist/client/progress/RunsTray.d.ts +18 -0
  88. package/dist/client/progress/RunsTray.d.ts.map +1 -0
  89. package/dist/client/progress/RunsTray.js +70 -0
  90. package/dist/client/progress/RunsTray.js.map +1 -0
  91. package/dist/client/progress/index.d.ts +2 -0
  92. package/dist/client/progress/index.d.ts.map +1 -0
  93. package/dist/client/progress/index.js +2 -0
  94. package/dist/client/progress/index.js.map +1 -0
  95. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  96. package/dist/client/resources/ResourcesPanel.js +19 -4
  97. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  98. package/dist/client/settings/AutomationsSection.d.ts +2 -0
  99. package/dist/client/settings/AutomationsSection.d.ts.map +1 -0
  100. package/dist/client/settings/AutomationsSection.js +214 -0
  101. package/dist/client/settings/AutomationsSection.js.map +1 -0
  102. package/dist/client/settings/ComingSoonSection.d.ts.map +1 -1
  103. package/dist/client/settings/ComingSoonSection.js +2 -1
  104. package/dist/client/settings/ComingSoonSection.js.map +1 -1
  105. package/dist/client/settings/LLMSection.d.ts.map +1 -1
  106. package/dist/client/settings/LLMSection.js +137 -10
  107. package/dist/client/settings/LLMSection.js.map +1 -1
  108. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  109. package/dist/client/settings/SecretsSection.js +122 -3
  110. package/dist/client/settings/SecretsSection.js.map +1 -1
  111. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  112. package/dist/client/settings/SettingsPanel.js +140 -11
  113. package/dist/client/settings/SettingsPanel.js.map +1 -1
  114. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  115. package/dist/client/settings/VoiceTranscriptionSection.js +2 -2
  116. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  117. package/dist/client/use-pausing-interval.d.ts +11 -0
  118. package/dist/client/use-pausing-interval.d.ts.map +1 -0
  119. package/dist/client/use-pausing-interval.js +49 -0
  120. package/dist/client/use-pausing-interval.js.map +1 -0
  121. package/dist/db/client.d.ts +26 -0
  122. package/dist/db/client.d.ts.map +1 -1
  123. package/dist/db/client.js +84 -2
  124. package/dist/db/client.js.map +1 -1
  125. package/dist/db/drizzle-config.d.ts +33 -0
  126. package/dist/db/drizzle-config.d.ts.map +1 -0
  127. package/dist/db/drizzle-config.js +132 -0
  128. package/dist/db/drizzle-config.js.map +1 -0
  129. package/dist/db/migrations.d.ts.map +1 -1
  130. package/dist/db/migrations.js +11 -6
  131. package/dist/db/migrations.js.map +1 -1
  132. package/dist/deploy/build.js +2 -1
  133. package/dist/deploy/build.js.map +1 -1
  134. package/dist/event-bus/bus.d.ts +20 -0
  135. package/dist/event-bus/bus.d.ts.map +1 -0
  136. package/dist/event-bus/bus.js +108 -0
  137. package/dist/event-bus/bus.js.map +1 -0
  138. package/dist/event-bus/index.d.ts +4 -0
  139. package/dist/event-bus/index.d.ts.map +1 -0
  140. package/dist/event-bus/index.js +3 -0
  141. package/dist/event-bus/index.js.map +1 -0
  142. package/dist/event-bus/registry.d.ts +22 -0
  143. package/dist/event-bus/registry.d.ts.map +1 -0
  144. package/dist/event-bus/registry.js +63 -0
  145. package/dist/event-bus/registry.js.map +1 -0
  146. package/dist/event-bus/types.d.ts +27 -0
  147. package/dist/event-bus/types.d.ts.map +1 -0
  148. package/dist/event-bus/types.js +2 -0
  149. package/dist/event-bus/types.js.map +1 -0
  150. package/dist/integrations/config-store.d.ts.map +1 -1
  151. package/dist/integrations/config-store.js +16 -12
  152. package/dist/integrations/config-store.js.map +1 -1
  153. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  154. package/dist/integrations/google-docs-poller.js +5 -1
  155. package/dist/integrations/google-docs-poller.js.map +1 -1
  156. package/dist/jobs/scheduler.d.ts.map +1 -1
  157. package/dist/jobs/scheduler.js +7 -3
  158. package/dist/jobs/scheduler.js.map +1 -1
  159. package/dist/notifications/actions.d.ts +10 -0
  160. package/dist/notifications/actions.d.ts.map +1 -0
  161. package/dist/notifications/actions.js +114 -0
  162. package/dist/notifications/actions.js.map +1 -0
  163. package/dist/notifications/channels.d.ts +15 -0
  164. package/dist/notifications/channels.d.ts.map +1 -0
  165. package/dist/notifications/channels.js +97 -0
  166. package/dist/notifications/channels.js.map +1 -0
  167. package/dist/notifications/index.d.ts +4 -0
  168. package/dist/notifications/index.d.ts.map +1 -0
  169. package/dist/notifications/index.js +3 -0
  170. package/dist/notifications/index.js.map +1 -0
  171. package/dist/notifications/registry.d.ts +9 -0
  172. package/dist/notifications/registry.d.ts.map +1 -0
  173. package/dist/notifications/registry.js +146 -0
  174. package/dist/notifications/registry.js.map +1 -0
  175. package/dist/notifications/routes.d.ts +34 -0
  176. package/dist/notifications/routes.d.ts.map +1 -0
  177. package/dist/notifications/routes.js +69 -0
  178. package/dist/notifications/routes.js.map +1 -0
  179. package/dist/notifications/store.d.ts +25 -0
  180. package/dist/notifications/store.d.ts.map +1 -0
  181. package/dist/notifications/store.js +158 -0
  182. package/dist/notifications/store.js.map +1 -0
  183. package/dist/notifications/types.d.ts +43 -0
  184. package/dist/notifications/types.d.ts.map +1 -0
  185. package/dist/notifications/types.js +2 -0
  186. package/dist/notifications/types.js.map +1 -0
  187. package/dist/org/handlers.d.ts.map +1 -1
  188. package/dist/org/handlers.js +7 -26
  189. package/dist/org/handlers.js.map +1 -1
  190. package/dist/progress/actions.d.ts +8 -0
  191. package/dist/progress/actions.d.ts.map +1 -0
  192. package/dist/progress/actions.js +158 -0
  193. package/dist/progress/actions.js.map +1 -0
  194. package/dist/progress/index.d.ts +3 -0
  195. package/dist/progress/index.d.ts.map +1 -0
  196. package/dist/progress/index.js +2 -0
  197. package/dist/progress/index.js.map +1 -0
  198. package/dist/progress/registry.d.ts +22 -0
  199. package/dist/progress/registry.d.ts.map +1 -0
  200. package/dist/progress/registry.js +98 -0
  201. package/dist/progress/registry.js.map +1 -0
  202. package/dist/progress/routes.d.ts +21 -0
  203. package/dist/progress/routes.d.ts.map +1 -0
  204. package/dist/progress/routes.js +59 -0
  205. package/dist/progress/routes.js.map +1 -0
  206. package/dist/progress/store.d.ts +7 -0
  207. package/dist/progress/store.d.ts.map +1 -0
  208. package/dist/progress/store.js +195 -0
  209. package/dist/progress/store.js.map +1 -0
  210. package/dist/progress/types.d.ts +49 -0
  211. package/dist/progress/types.d.ts.map +1 -0
  212. package/dist/progress/types.js +7 -0
  213. package/dist/progress/types.js.map +1 -0
  214. package/dist/resources/store.d.ts.map +1 -1
  215. package/dist/resources/store.js +19 -15
  216. package/dist/resources/store.js.map +1 -1
  217. package/dist/secrets/index.d.ts +3 -2
  218. package/dist/secrets/index.d.ts.map +1 -1
  219. package/dist/secrets/index.js +3 -2
  220. package/dist/secrets/index.js.map +1 -1
  221. package/dist/secrets/routes.d.ts +41 -2
  222. package/dist/secrets/routes.d.ts.map +1 -1
  223. package/dist/secrets/routes.js +167 -1
  224. package/dist/secrets/routes.js.map +1 -1
  225. package/dist/secrets/schema.d.ts +39 -1
  226. package/dist/secrets/schema.d.ts.map +1 -1
  227. package/dist/secrets/schema.js +6 -0
  228. package/dist/secrets/schema.js.map +1 -1
  229. package/dist/secrets/storage.d.ts +26 -0
  230. package/dist/secrets/storage.d.ts.map +1 -1
  231. package/dist/secrets/storage.js +111 -5
  232. package/dist/secrets/storage.js.map +1 -1
  233. package/dist/secrets/substitution.d.ts +39 -0
  234. package/dist/secrets/substitution.d.ts.map +1 -0
  235. package/dist/secrets/substitution.js +93 -0
  236. package/dist/secrets/substitution.js.map +1 -0
  237. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  238. package/dist/server/agent-chat-plugin.js +1657 -1410
  239. package/dist/server/agent-chat-plugin.js.map +1 -1
  240. package/dist/server/auth.d.ts +11 -0
  241. package/dist/server/auth.d.ts.map +1 -1
  242. package/dist/server/auth.js +74 -21
  243. package/dist/server/auth.js.map +1 -1
  244. package/dist/server/better-auth-instance.d.ts.map +1 -1
  245. package/dist/server/better-auth-instance.js +34 -16
  246. package/dist/server/better-auth-instance.js.map +1 -1
  247. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  248. package/dist/server/core-routes-plugin.js +115 -1
  249. package/dist/server/core-routes-plugin.js.map +1 -1
  250. package/dist/server/email-templates.d.ts +43 -0
  251. package/dist/server/email-templates.d.ts.map +1 -0
  252. package/dist/server/email-templates.js +86 -0
  253. package/dist/server/email-templates.js.map +1 -0
  254. package/dist/server/framework-request-handler.d.ts +15 -0
  255. package/dist/server/framework-request-handler.d.ts.map +1 -1
  256. package/dist/server/framework-request-handler.js +64 -1
  257. package/dist/server/framework-request-handler.js.map +1 -1
  258. package/dist/server/onboarding-html.d.ts +11 -0
  259. package/dist/server/onboarding-html.d.ts.map +1 -1
  260. package/dist/server/onboarding-html.js +275 -16
  261. package/dist/server/onboarding-html.js.map +1 -1
  262. package/dist/server/schema-prompt.d.ts.map +1 -1
  263. package/dist/server/schema-prompt.js +5 -0
  264. package/dist/server/schema-prompt.js.map +1 -1
  265. package/dist/shared/index.d.ts +1 -0
  266. package/dist/shared/index.d.ts.map +1 -1
  267. package/dist/shared/index.js +1 -0
  268. package/dist/shared/index.js.map +1 -1
  269. package/dist/shared/truncate.d.ts +8 -0
  270. package/dist/shared/truncate.d.ts.map +1 -0
  271. package/dist/shared/truncate.js +12 -0
  272. package/dist/shared/truncate.js.map +1 -0
  273. package/dist/templates/default/.agents/skills/agent-engines/SKILL.md +60 -4
  274. package/dist/templates/default/.agents/skills/notifications/SKILL.md +95 -0
  275. package/dist/templates/default/.agents/skills/progress/SKILL.md +97 -0
  276. package/dist/templates/default/AGENTS.md +12 -10
  277. package/dist/templates/default/package.json +10 -10
  278. package/dist/templates/workspace-core/package.json +5 -5
  279. package/dist/templates/workspace-root/package.json +1 -1
  280. package/dist/templates/workspace-root/tsconfig.base.json +1 -2
  281. package/dist/tools/fetch-tool.d.ts +22 -0
  282. package/dist/tools/fetch-tool.d.ts.map +1 -0
  283. package/dist/tools/fetch-tool.js +156 -0
  284. package/dist/tools/fetch-tool.js.map +1 -0
  285. package/dist/tracking/index.d.ts +4 -0
  286. package/dist/tracking/index.d.ts.map +1 -0
  287. package/dist/tracking/index.js +3 -0
  288. package/dist/tracking/index.js.map +1 -0
  289. package/dist/tracking/providers.d.ts +15 -0
  290. package/dist/tracking/providers.d.ts.map +1 -0
  291. package/dist/tracking/providers.js +195 -0
  292. package/dist/tracking/providers.js.map +1 -0
  293. package/dist/tracking/registry.d.ts +10 -0
  294. package/dist/tracking/registry.d.ts.map +1 -0
  295. package/dist/tracking/registry.js +75 -0
  296. package/dist/tracking/registry.js.map +1 -0
  297. package/dist/tracking/types.d.ts +13 -0
  298. package/dist/tracking/types.d.ts.map +1 -0
  299. package/dist/tracking/types.js +2 -0
  300. package/dist/tracking/types.js.map +1 -0
  301. package/dist/triggers/actions.d.ts +10 -0
  302. package/dist/triggers/actions.d.ts.map +1 -0
  303. package/dist/triggers/actions.js +277 -0
  304. package/dist/triggers/actions.js.map +1 -0
  305. package/dist/triggers/condition-evaluator.d.ts +15 -0
  306. package/dist/triggers/condition-evaluator.d.ts.map +1 -0
  307. package/dist/triggers/condition-evaluator.js +107 -0
  308. package/dist/triggers/condition-evaluator.js.map +1 -0
  309. package/dist/triggers/dispatcher.d.ts +32 -0
  310. package/dist/triggers/dispatcher.d.ts.map +1 -0
  311. package/dist/triggers/dispatcher.js +291 -0
  312. package/dist/triggers/dispatcher.js.map +1 -0
  313. package/dist/triggers/index.d.ts +5 -0
  314. package/dist/triggers/index.d.ts.map +1 -0
  315. package/dist/triggers/index.js +4 -0
  316. package/dist/triggers/index.js.map +1 -0
  317. package/dist/triggers/types.d.ts +35 -0
  318. package/dist/triggers/types.d.ts.map +1 -0
  319. package/dist/triggers/types.js +9 -0
  320. package/dist/triggers/types.js.map +1 -0
  321. package/dist/vite/client.d.ts.map +1 -1
  322. package/dist/vite/client.js +66 -16
  323. package/dist/vite/client.js.map +1 -1
  324. package/docs/content/automations.md +239 -0
  325. package/docs/content/multi-tenancy.md +88 -0
  326. package/docs/content/notifications.md +199 -0
  327. package/docs/content/progress.md +176 -0
  328. package/docs/content/tracking.md +168 -0
  329. package/package.json +54 -35
  330. package/src/templates/default/.agents/skills/agent-engines/SKILL.md +60 -4
  331. package/src/templates/default/.agents/skills/notifications/SKILL.md +95 -0
  332. package/src/templates/default/.agents/skills/progress/SKILL.md +97 -0
  333. package/src/templates/default/AGENTS.md +12 -10
  334. package/src/templates/default/package.json +10 -10
  335. package/src/templates/workspace-core/package.json +5 -5
  336. package/src/templates/workspace-root/package.json +1 -1
  337. package/src/templates/workspace-root/tsconfig.base.json +1 -2
  338. package/tsconfig.base.json +1 -1
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Framework-level agent actions for the notifications primitive.
3
+ *
4
+ * Registered as native tools (not template actions) so they're available in
5
+ * every template. The agent uses `notify` to surface progress, completions,
6
+ * and alerts to the user through the in-app inbox and any registered channels.
7
+ */
8
+ import { notify, listNotifications, countUnread } from "./registry.js";
9
+ export function createNotificationToolEntries(getCurrentUser) {
10
+ return {
11
+ notify: {
12
+ tool: {
13
+ description: "Send a notification to the user. Always persisted to the in-app inbox so the bell + toast surface shows it. Registered channels (webhook, Slack, etc.) also run. Use `info` for FYI, `warning` for things the user should look at, `critical` for things that need immediate attention.",
14
+ parameters: {
15
+ type: "object",
16
+ properties: {
17
+ severity: {
18
+ type: "string",
19
+ enum: ["info", "warning", "critical"],
20
+ description: "Severity level — drives styling and per-severity channel routing.",
21
+ },
22
+ title: {
23
+ type: "string",
24
+ description: "Short, human-readable headline (≤100 chars).",
25
+ },
26
+ body: {
27
+ type: "string",
28
+ description: "Optional longer description.",
29
+ },
30
+ metadataJson: {
31
+ type: "string",
32
+ description: 'Optional JSON metadata (URLs, entity ids, etc.). Example: \'{"threadId":"abc","link":"/inbox/abc"}\'.',
33
+ },
34
+ channels: {
35
+ type: "string",
36
+ description: 'Optional comma-separated channel allowlist (e.g. "inbox,webhook"). Omit to run all registered channels.',
37
+ },
38
+ },
39
+ required: ["severity", "title"],
40
+ },
41
+ },
42
+ run: async (args) => {
43
+ const owner = getCurrentUser();
44
+ if (!args.severity || !args.title) {
45
+ return "Error: --severity and --title are required.";
46
+ }
47
+ const severity = args.severity;
48
+ if (!["info", "warning", "critical"].includes(severity)) {
49
+ return `Error: severity must be info, warning, or critical (got "${severity}").`;
50
+ }
51
+ let metadata;
52
+ if (args.metadataJson) {
53
+ try {
54
+ metadata = JSON.parse(args.metadataJson);
55
+ }
56
+ catch {
57
+ return "Error: metadataJson must be valid JSON.";
58
+ }
59
+ }
60
+ const channels = args.channels
61
+ ? args.channels
62
+ .split(",")
63
+ .map((s) => s.trim())
64
+ .filter(Boolean)
65
+ : undefined;
66
+ const stored = await notify({
67
+ severity,
68
+ title: args.title,
69
+ body: args.body || undefined,
70
+ metadata,
71
+ channels,
72
+ }, { owner });
73
+ return stored
74
+ ? `Notification sent (id: ${stored.id})`
75
+ : "Notification dispatched to channels (not persisted).";
76
+ },
77
+ },
78
+ "list-notifications": {
79
+ tool: {
80
+ description: "List recent notifications for the current user. Useful when the user asks about prior alerts.",
81
+ parameters: {
82
+ type: "object",
83
+ properties: {
84
+ unreadOnly: {
85
+ type: "boolean",
86
+ description: "When true, only include unread notifications.",
87
+ },
88
+ limit: {
89
+ type: "number",
90
+ description: "Max rows to return (default 20, max 200).",
91
+ },
92
+ },
93
+ },
94
+ },
95
+ run: async (args) => {
96
+ const owner = getCurrentUser();
97
+ const rows = await listNotifications(owner, {
98
+ unreadOnly: args.unreadOnly === true || args.unreadOnly === "true",
99
+ limit: Math.min(Number(args.limit ?? 20), 200),
100
+ });
101
+ if (rows.length === 0) {
102
+ return args.unreadOnly
103
+ ? "No unread notifications."
104
+ : "No notifications.";
105
+ }
106
+ const unreadCount = await countUnread(owner);
107
+ const lines = rows.map((n) => `[${n.readAt ? " " : "•"}] (${n.severity}) ${n.title}${n.body ? ` — ${n.body}` : ""} · ${n.createdAt}`);
108
+ return `${unreadCount} unread\n\n${lines.join("\n")}`;
109
+ },
110
+ readOnly: true,
111
+ },
112
+ };
113
+ }
114
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/notifications/actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Built-in notification channels.
3
+ *
4
+ * Set environment variables to auto-register the webhook channel at startup.
5
+ * Extra channels can be registered at any time via
6
+ * `registerNotificationChannel()` from a server plugin.
7
+ *
8
+ * NOTIFICATIONS_WEBHOOK_URL → POST notifications as JSON to this URL.
9
+ * Supports `${keys.NAME}` substitution — the raw
10
+ * value never enters the agent context.
11
+ * NOTIFICATIONS_WEBHOOK_AUTH → optional `Authorization` header value (also
12
+ * supports `${keys.NAME}`).
13
+ */
14
+ export declare function registerBuiltinNotificationChannels(): void;
15
+ //# sourceMappingURL=channels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/notifications/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,wBAAgB,mCAAmC,IAAI,IAAI,CAQ1D"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Built-in notification channels.
3
+ *
4
+ * Set environment variables to auto-register the webhook channel at startup.
5
+ * Extra channels can be registered at any time via
6
+ * `registerNotificationChannel()` from a server plugin.
7
+ *
8
+ * NOTIFICATIONS_WEBHOOK_URL → POST notifications as JSON to this URL.
9
+ * Supports `${keys.NAME}` substitution — the raw
10
+ * value never enters the agent context.
11
+ * NOTIFICATIONS_WEBHOOK_AUTH → optional `Authorization` header value (also
12
+ * supports `${keys.NAME}`).
13
+ */
14
+ import { registerNotificationChannel } from "./registry.js";
15
+ import { resolveKeyReferences, validateUrlAllowlist, getKeyAllowlist, } from "../secrets/substitution.js";
16
+ let _registered = false;
17
+ export function registerBuiltinNotificationChannels() {
18
+ if (_registered)
19
+ return;
20
+ _registered = true;
21
+ const url = process.env.NOTIFICATIONS_WEBHOOK_URL;
22
+ if (url) {
23
+ registerNotificationChannel(createWebhookChannel(url));
24
+ }
25
+ }
26
+ function createWebhookChannel(urlTemplate) {
27
+ const authTemplate = process.env.NOTIFICATIONS_WEBHOOK_AUTH;
28
+ return {
29
+ name: "webhook",
30
+ async deliver(input, meta) {
31
+ // Resolve `${keys.NAME}` references against the owner's user-scope
32
+ // secrets. Missing keys throw — the error surfaces in logs and the
33
+ // channel is marked un-delivered, but other channels still run.
34
+ const { resolved: url } = await resolveKeyReferences(urlTemplate, "user", meta.owner);
35
+ const headers = {
36
+ "Content-Type": "application/json",
37
+ };
38
+ if (authTemplate) {
39
+ const { resolved: auth } = await resolveKeyReferences(authTemplate, "user", meta.owner);
40
+ headers.Authorization = auth;
41
+ }
42
+ // If the user set an allowlist on a referenced key, enforce it here —
43
+ // origin-level check, same rule the automations fetch-tool applies.
44
+ const keyNames = Array.from(new Set(Array.from(urlTemplate.matchAll(/\$\{keys\.([A-Za-z0-9_-]+)\}/g), (m) => m[1])));
45
+ const allowlists = await Promise.all(keyNames.map((name) => getKeyAllowlist(name, "user", meta.owner)));
46
+ keyNames.forEach((name, i) => {
47
+ if (!validateUrlAllowlist(url, allowlists[i])) {
48
+ throw new Error(`[notifications] webhook URL ${new URL(url).origin} is not in the allowlist for key "${name}"`);
49
+ }
50
+ });
51
+ const res = await fetch(url, {
52
+ method: "POST",
53
+ headers,
54
+ body: JSON.stringify({
55
+ severity: input.severity,
56
+ title: input.title,
57
+ body: input.body,
58
+ metadata: input.metadata,
59
+ owner: meta.owner,
60
+ emittedAt: new Date().toISOString(),
61
+ }),
62
+ });
63
+ if (!res.ok) {
64
+ throw new Error(`[notifications] webhook ${new URL(url).origin} returned ${res.status}${(await readErrorSnippet(res)) || ""}`);
65
+ }
66
+ },
67
+ };
68
+ }
69
+ /**
70
+ * Read up to ~1 KB from the body for error context. Streams chunks so a
71
+ * misbehaving endpoint returning a large error page doesn't pin that whole
72
+ * payload in memory per failed webhook.
73
+ */
74
+ async function readErrorSnippet(res) {
75
+ const reader = res.body?.getReader();
76
+ if (!reader)
77
+ return "";
78
+ const decoder = new TextDecoder();
79
+ const MAX = 1024;
80
+ let buf = "";
81
+ try {
82
+ while (buf.length < MAX) {
83
+ const { value, done } = await reader.read();
84
+ if (done)
85
+ break;
86
+ buf += decoder.decode(value, { stream: true });
87
+ }
88
+ reader.cancel().catch(() => { });
89
+ }
90
+ catch {
91
+ return "";
92
+ }
93
+ if (!buf)
94
+ return "";
95
+ return `: ${buf.slice(0, 200)}`;
96
+ }
97
+ //# sourceMappingURL=channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/notifications/channels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type { Notification, NotificationSeverity, NotificationInput, NotificationMeta, NotificationChannel, } from "./types.js";
2
+ export { notify, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
3
+ export { registerBuiltinNotificationChannels } from "./channels.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,MAAM,EACN,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { notify, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
2
+ export { registerBuiltinNotificationChannels } from "./channels.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,MAAM,EACN,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type NotificationChannel, type NotificationInput, type NotificationMeta, type Notification } from "./types.js";
2
+ export declare function registerNotificationChannel(channel: NotificationChannel): void;
3
+ export declare function unregisterNotificationChannel(name: string): boolean;
4
+ export declare function listNotificationChannels(): string[];
5
+ export declare function notify(input: NotificationInput, meta: NotificationMeta): Promise<Notification | undefined>;
6
+ /** Test helper — drops all registered channels. */
7
+ export declare function __resetNotificationChannels(): void;
8
+ export { listNotifications, markNotificationRead, markAllNotificationsRead, deleteNotification, countUnread, } from "./store.js";
9
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAsCpB,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CAUN;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,wBAAwB,IAAI,MAAM,EAAE,CAEnD;AAgBD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAoFnC;AASD,mDAAmD;AACnD,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,GACZ,MAAM,YAAY,CAAC"}
@@ -0,0 +1,146 @@
1
+ import { z } from "zod";
2
+ import { NOTIFICATION_SEVERITIES, } from "./types.js";
3
+ import { insertNotification, updateDeliveredChannels } from "./store.js";
4
+ import { emit as emitBusEvent } from "../event-bus/bus.js";
5
+ import { registerEvent } from "../event-bus/registry.js";
6
+ import { truncate } from "../shared/truncate.js";
7
+ registerEvent({
8
+ name: "notification.sent",
9
+ description: "Fires after notify() delivers to at least one channel. Automations can chain off this — e.g. fan critical notifications to Slack.",
10
+ payloadSchema: z.object({
11
+ notificationId: z.string().optional(),
12
+ severity: z.enum(NOTIFICATION_SEVERITIES),
13
+ title: z.string(),
14
+ body: z.string().optional(),
15
+ deliveredChannels: z.array(z.string()),
16
+ }),
17
+ example: {
18
+ notificationId: "ntf_abc",
19
+ severity: "critical",
20
+ title: "Payment failed",
21
+ body: "Card ending 4242 declined",
22
+ deliveredChannels: ["inbox", "webhook"],
23
+ },
24
+ });
25
+ const REGISTRY_KEY = Symbol.for("@agent-native/core/notifications.registry");
26
+ function getRegistry() {
27
+ const g = globalThis;
28
+ if (!g[REGISTRY_KEY])
29
+ g[REGISTRY_KEY] = new Map();
30
+ return g[REGISTRY_KEY];
31
+ }
32
+ export function registerNotificationChannel(channel) {
33
+ if (!channel?.name) {
34
+ throw new Error("registerNotificationChannel: channel.name is required");
35
+ }
36
+ if (typeof channel.deliver !== "function") {
37
+ throw new Error("registerNotificationChannel: channel.deliver must be a function");
38
+ }
39
+ getRegistry().set(channel.name, channel);
40
+ }
41
+ export function unregisterNotificationChannel(name) {
42
+ return getRegistry().delete(name);
43
+ }
44
+ export function listNotificationChannels() {
45
+ return Array.from(getRegistry().keys());
46
+ }
47
+ /**
48
+ * Deliver a notification.
49
+ *
50
+ * The `inbox` channel always persists a row that drives the in-app UI
51
+ * (bell + toast). Additional channels (webhook, custom) run in parallel,
52
+ * best-effort. Returns the stored Notification when `inbox` ran, otherwise
53
+ * `undefined`.
54
+ *
55
+ * Also emits `notification.sent` on the event bus so automations can react
56
+ * to notifications (e.g. "when a critical notification fires, also page me").
57
+ */
58
+ const MAX_TITLE_LEN = 100;
59
+ const MAX_BODY_LEN = 2000;
60
+ export async function notify(input, meta) {
61
+ if (!meta?.owner) {
62
+ throw new Error("notify: meta.owner is required");
63
+ }
64
+ input = {
65
+ ...input,
66
+ title: truncate(input.title, MAX_TITLE_LEN),
67
+ body: truncate(input.body, MAX_BODY_LEN),
68
+ };
69
+ const channels = selectChannels(input.channels);
70
+ // The inbox channel is always included unless explicitly excluded.
71
+ const runInbox = !input.channels || input.channels.includes("inbox");
72
+ const delivered = [];
73
+ let stored;
74
+ if (runInbox) {
75
+ try {
76
+ // Stored with just "inbox" first; the real delivered list is written
77
+ // after fan-out so a failing webhook doesn't claim it was delivered.
78
+ stored = await insertNotification({
79
+ owner: meta.owner,
80
+ severity: input.severity,
81
+ title: input.title,
82
+ body: input.body,
83
+ metadata: input.metadata,
84
+ deliveredChannels: ["inbox"],
85
+ });
86
+ delivered.push("inbox");
87
+ }
88
+ catch (err) {
89
+ console.error("[notifications] inbox persist failed:", err);
90
+ }
91
+ }
92
+ // Await every channel so a 500-ing webhook doesn't end up in `delivered`.
93
+ const results = await Promise.allSettled(channels.map(async (channel) => {
94
+ await channel.deliver(input, meta);
95
+ return channel.name;
96
+ }));
97
+ results.forEach((r, i) => {
98
+ if (r.status === "fulfilled") {
99
+ delivered.push(r.value);
100
+ }
101
+ else {
102
+ console.error(`[notifications] channel "${channels[i].name}" failed:`, r.reason);
103
+ }
104
+ });
105
+ const hasExtraChannel = delivered.some((c) => c !== "inbox");
106
+ if (stored && hasExtraChannel) {
107
+ try {
108
+ await updateDeliveredChannels(stored.id, delivered);
109
+ stored = { ...stored, deliveredChannels: delivered };
110
+ }
111
+ catch (err) {
112
+ console.error("[notifications] delivered-channel update failed:", err);
113
+ }
114
+ }
115
+ // Only emit when at least one channel delivered — an emission with an
116
+ // empty delivery list (and likely a null notificationId) would mislead
117
+ // any automation chaining off this event.
118
+ if (delivered.length > 0) {
119
+ try {
120
+ emitBusEvent("notification.sent", {
121
+ notificationId: stored?.id,
122
+ severity: input.severity,
123
+ title: input.title,
124
+ body: input.body,
125
+ deliveredChannels: delivered,
126
+ }, { owner: meta.owner });
127
+ }
128
+ catch {
129
+ // best-effort
130
+ }
131
+ }
132
+ return stored;
133
+ }
134
+ function selectChannels(allowlist) {
135
+ const registry = getRegistry();
136
+ const all = Array.from(registry.values());
137
+ if (!allowlist)
138
+ return all;
139
+ return all.filter((c) => allowlist.includes(c.name));
140
+ }
141
+ /** Test helper — drops all registered channels. */
142
+ export function __resetNotificationChannels() {
143
+ getRegistry().clear();
144
+ }
145
+ export { listNotifications, markNotificationRead, markAllNotificationsRead, deleteNotification, countUnread, } from "./store.js";
146
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * H3 event handlers for the notifications inbox.
3
+ *
4
+ * Mounted under `/_agent-native/notifications/*` by `core-routes-plugin`.
5
+ *
6
+ * GET /_agent-native/notifications?unread=true&limit=50&before=ISO
7
+ * — list for the session owner
8
+ * GET /_agent-native/notifications/count — unread count
9
+ * POST /_agent-native/notifications/:id/read — mark as read
10
+ * POST /_agent-native/notifications/read-all — mark all read
11
+ * DELETE /_agent-native/notifications/:id — delete
12
+ */
13
+ export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<import("./types.js").Notification[] | {
14
+ count: number;
15
+ updated?: undefined;
16
+ error?: undefined;
17
+ ok?: undefined;
18
+ } | {
19
+ updated: number;
20
+ count?: undefined;
21
+ error?: undefined;
22
+ ok?: undefined;
23
+ } | {
24
+ error: string;
25
+ count?: undefined;
26
+ updated?: undefined;
27
+ ok?: undefined;
28
+ } | {
29
+ ok: boolean;
30
+ count?: undefined;
31
+ updated?: undefined;
32
+ error?: undefined;
33
+ }>>;
34
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/notifications/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuBH,wBAAgB,0BAA0B;;;;;;;;;;;;;;;;;;;;IAsDzC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * H3 event handlers for the notifications inbox.
3
+ *
4
+ * Mounted under `/_agent-native/notifications/*` by `core-routes-plugin`.
5
+ *
6
+ * GET /_agent-native/notifications?unread=true&limit=50&before=ISO
7
+ * — list for the session owner
8
+ * GET /_agent-native/notifications/count — unread count
9
+ * POST /_agent-native/notifications/:id/read — mark as read
10
+ * POST /_agent-native/notifications/read-all — mark all read
11
+ * DELETE /_agent-native/notifications/:id — delete
12
+ */
13
+ import { defineEventHandler, getMethod, getQuery, setResponseStatus, } from "h3";
14
+ import { getSession } from "../server/auth.js";
15
+ import { listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./store.js";
16
+ async function resolveOwner(event) {
17
+ const session = await getSession(event).catch(() => null);
18
+ return session?.email || "local@localhost";
19
+ }
20
+ export function createNotificationsHandler() {
21
+ return defineEventHandler(async (event) => {
22
+ const method = getMethod(event);
23
+ const pathname = (event.url?.pathname || "")
24
+ .replace(/^\/+/, "")
25
+ .replace(/\/+$/, "");
26
+ const parts = pathname ? pathname.split("/") : [];
27
+ const owner = await resolveOwner(event);
28
+ // GET / — list
29
+ if (method === "GET" && parts.length === 0) {
30
+ const q = getQuery(event);
31
+ return listNotifications(owner, {
32
+ unreadOnly: q.unread === "true" || q.unread === "1",
33
+ limit: q.limit ? Math.min(Number(q.limit) || 50, 200) : 50,
34
+ before: typeof q.before === "string" ? q.before : undefined,
35
+ });
36
+ }
37
+ // GET /count
38
+ if (method === "GET" && parts.length === 1 && parts[0] === "count") {
39
+ const count = await countUnread(owner);
40
+ return { count };
41
+ }
42
+ // POST /read-all
43
+ if (method === "POST" && parts.length === 1 && parts[0] === "read-all") {
44
+ const updated = await markAllNotificationsRead(owner);
45
+ return { updated };
46
+ }
47
+ // POST /:id/read
48
+ if (method === "POST" && parts.length === 2 && parts[1] === "read") {
49
+ const ok = await markNotificationRead(parts[0], owner);
50
+ if (!ok) {
51
+ setResponseStatus(event, 404);
52
+ return { error: "Not found or already read" };
53
+ }
54
+ return { ok: true };
55
+ }
56
+ // DELETE /:id
57
+ if (method === "DELETE" && parts.length === 1) {
58
+ const ok = await deleteNotification(parts[0], owner);
59
+ if (!ok) {
60
+ setResponseStatus(event, 404);
61
+ return { error: "Not found" };
62
+ }
63
+ return { ok: true };
64
+ }
65
+ setResponseStatus(event, 404);
66
+ return { error: "Not found" };
67
+ });
68
+ }
69
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/notifications/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Notification, NotificationSeverity } from "./types.js";
2
+ export interface InsertNotificationInput {
3
+ owner: string;
4
+ severity: NotificationSeverity;
5
+ title: string;
6
+ body?: string;
7
+ metadata?: Record<string, unknown>;
8
+ deliveredChannels?: string[];
9
+ }
10
+ export declare function insertNotification(input: InsertNotificationInput): Promise<Notification>;
11
+ export declare function updateDeliveredChannels(id: string, channels: string[]): Promise<void>;
12
+ export interface ListNotificationsOptions {
13
+ /** When true, only return unread (read_at IS NULL). */
14
+ unreadOnly?: boolean;
15
+ /** Max rows to return. Default 50. */
16
+ limit?: number;
17
+ /** ISO timestamp cursor — returns rows with created_at < cursor. */
18
+ before?: string;
19
+ }
20
+ export declare function listNotifications(owner: string, options?: ListNotificationsOptions): Promise<Notification[]>;
21
+ export declare function countUnread(owner: string): Promise<number>;
22
+ export declare function markNotificationRead(id: string, owner: string): Promise<boolean>;
23
+ export declare function markAllNotificationsRead(owner: string): Promise<number>;
24
+ export declare function deleteNotification(id: string, owner: string): Promise<boolean>;
25
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/notifications/store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA+DrE,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAgCvB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,MAAM,WAAW,wBAAwB;IACvC,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW7E;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAWlB"}