@mastra/factory 0.0.0-esbuild-bundle-worker-20260807173433

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 (329) hide show
  1. package/CHANGELOG.md +1008 -0
  2. package/LICENSE.md +30 -0
  3. package/README.md +27 -0
  4. package/dist/auth.d.ts +183 -0
  5. package/dist/auth.d.ts.map +1 -0
  6. package/dist/auth.js +507 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/capabilities/connection.d.ts +9 -0
  9. package/dist/capabilities/connection.d.ts.map +1 -0
  10. package/dist/capabilities/connection.js +1 -0
  11. package/dist/capabilities/intake.d.ts +141 -0
  12. package/dist/capabilities/intake.d.ts.map +1 -0
  13. package/dist/capabilities/intake.js +1 -0
  14. package/dist/capabilities/version-control.d.ts +247 -0
  15. package/dist/capabilities/version-control.d.ts.map +1 -0
  16. package/dist/capabilities/version-control.js +1 -0
  17. package/dist/factory.d.ts +159 -0
  18. package/dist/factory.d.ts.map +1 -0
  19. package/dist/factory.js +491 -0
  20. package/dist/factory.js.map +1 -0
  21. package/dist/index.d.ts +14 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +7 -0
  24. package/dist/integrations/base.d.ts +254 -0
  25. package/dist/integrations/base.d.ts.map +1 -0
  26. package/dist/integrations/base.js +1 -0
  27. package/dist/integrations/github/config.d.ts +60 -0
  28. package/dist/integrations/github/config.d.ts.map +1 -0
  29. package/dist/integrations/github/config.js +42 -0
  30. package/dist/integrations/github/config.js.map +1 -0
  31. package/dist/integrations/github/integration.d.ts +220 -0
  32. package/dist/integrations/github/integration.d.ts.map +1 -0
  33. package/dist/integrations/github/integration.js +1162 -0
  34. package/dist/integrations/github/integration.js.map +1 -0
  35. package/dist/integrations/github/issue-triage.d.ts +27 -0
  36. package/dist/integrations/github/issue-triage.d.ts.map +1 -0
  37. package/dist/integrations/github/issue-triage.js +82 -0
  38. package/dist/integrations/github/issue-triage.js.map +1 -0
  39. package/dist/integrations/github/pat.d.ts +38 -0
  40. package/dist/integrations/github/pat.d.ts.map +1 -0
  41. package/dist/integrations/github/pat.js +59 -0
  42. package/dist/integrations/github/pat.js.map +1 -0
  43. package/dist/integrations/github/provenance.d.ts +27 -0
  44. package/dist/integrations/github/provenance.d.ts.map +1 -0
  45. package/dist/integrations/github/provenance.js +75 -0
  46. package/dist/integrations/github/provenance.js.map +1 -0
  47. package/dist/integrations/github/reconcile-worker.d.ts +41 -0
  48. package/dist/integrations/github/reconcile-worker.d.ts.map +1 -0
  49. package/dist/integrations/github/reconcile-worker.js +125 -0
  50. package/dist/integrations/github/reconcile-worker.js.map +1 -0
  51. package/dist/integrations/github/routes.d.ts +69 -0
  52. package/dist/integrations/github/routes.d.ts.map +1 -0
  53. package/dist/integrations/github/routes.js +1335 -0
  54. package/dist/integrations/github/routes.js.map +1 -0
  55. package/dist/integrations/github/rules.d.ts +105 -0
  56. package/dist/integrations/github/rules.d.ts.map +1 -0
  57. package/dist/integrations/github/rules.js +551 -0
  58. package/dist/integrations/github/rules.js.map +1 -0
  59. package/dist/integrations/github/sandbox-release.d.ts +53 -0
  60. package/dist/integrations/github/sandbox-release.d.ts.map +1 -0
  61. package/dist/integrations/github/sandbox-release.js +115 -0
  62. package/dist/integrations/github/sandbox-release.js.map +1 -0
  63. package/dist/integrations/github/sandbox.d.ts +281 -0
  64. package/dist/integrations/github/sandbox.d.ts.map +1 -0
  65. package/dist/integrations/github/sandbox.js +547 -0
  66. package/dist/integrations/github/sandbox.js.map +1 -0
  67. package/dist/integrations/github/session-subscriptions.d.ts +26 -0
  68. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -0
  69. package/dist/integrations/github/session-subscriptions.js +192 -0
  70. package/dist/integrations/github/session-subscriptions.js.map +1 -0
  71. package/dist/integrations/github/subscriptions.d.ts +54 -0
  72. package/dist/integrations/github/subscriptions.d.ts.map +1 -0
  73. package/dist/integrations/github/subscriptions.js +62 -0
  74. package/dist/integrations/github/subscriptions.js.map +1 -0
  75. package/dist/integrations/github/token-refresh.d.ts +12 -0
  76. package/dist/integrations/github/token-refresh.d.ts.map +1 -0
  77. package/dist/integrations/github/token-refresh.js +24 -0
  78. package/dist/integrations/github/token-refresh.js.map +1 -0
  79. package/dist/integrations/github/webhook.d.ts +107 -0
  80. package/dist/integrations/github/webhook.d.ts.map +1 -0
  81. package/dist/integrations/github/webhook.js +371 -0
  82. package/dist/integrations/github/webhook.js.map +1 -0
  83. package/dist/integrations/linear/agent-tools.d.ts +34 -0
  84. package/dist/integrations/linear/agent-tools.d.ts.map +1 -0
  85. package/dist/integrations/linear/agent-tools.js +85 -0
  86. package/dist/integrations/linear/agent-tools.js.map +1 -0
  87. package/dist/integrations/linear/integration.d.ts +235 -0
  88. package/dist/integrations/linear/integration.d.ts.map +1 -0
  89. package/dist/integrations/linear/integration.js +676 -0
  90. package/dist/integrations/linear/integration.js.map +1 -0
  91. package/dist/integrations/linear/routes.d.ts +61 -0
  92. package/dist/integrations/linear/routes.d.ts.map +1 -0
  93. package/dist/integrations/linear/routes.js +240 -0
  94. package/dist/integrations/linear/routes.js.map +1 -0
  95. package/dist/integrations/linear/rules.d.ts +44 -0
  96. package/dist/integrations/linear/rules.d.ts.map +1 -0
  97. package/dist/integrations/linear/rules.js +133 -0
  98. package/dist/integrations/linear/rules.js.map +1 -0
  99. package/dist/integrations/linear/storage.d.ts +65 -0
  100. package/dist/integrations/linear/storage.d.ts.map +1 -0
  101. package/dist/integrations/linear/storage.js +1 -0
  102. package/dist/integrations/platform/api-client.d.ts +26 -0
  103. package/dist/integrations/platform/api-client.d.ts.map +1 -0
  104. package/dist/integrations/platform/api-client.js +156 -0
  105. package/dist/integrations/platform/api-client.js.map +1 -0
  106. package/dist/integrations/platform/github/event-worker.d.ts +44 -0
  107. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
  108. package/dist/integrations/platform/github/event-worker.js +349 -0
  109. package/dist/integrations/platform/github/event-worker.js.map +1 -0
  110. package/dist/integrations/platform/github/integration.d.ts +64 -0
  111. package/dist/integrations/platform/github/integration.d.ts.map +1 -0
  112. package/dist/integrations/platform/github/integration.js +1006 -0
  113. package/dist/integrations/platform/github/integration.js.map +1 -0
  114. package/dist/integrations/platform/linear/integration.d.ts +46 -0
  115. package/dist/integrations/platform/linear/integration.d.ts.map +1 -0
  116. package/dist/integrations/platform/linear/integration.js +483 -0
  117. package/dist/integrations/platform/linear/integration.js.map +1 -0
  118. package/dist/integrations/slack/connect-route.d.ts +46 -0
  119. package/dist/integrations/slack/connect-route.d.ts.map +1 -0
  120. package/dist/integrations/slack/connect-route.js +186 -0
  121. package/dist/integrations/slack/connect-route.js.map +1 -0
  122. package/dist/integrations/slack/integration.d.ts +62 -0
  123. package/dist/integrations/slack/integration.d.ts.map +1 -0
  124. package/dist/integrations/slack/integration.js +68 -0
  125. package/dist/integrations/slack/integration.js.map +1 -0
  126. package/dist/integrations/slack/slack.d.ts +200 -0
  127. package/dist/integrations/slack/slack.d.ts.map +1 -0
  128. package/dist/integrations/slack/slack.js +411 -0
  129. package/dist/integrations/slack/slack.js.map +1 -0
  130. package/dist/integrations/workos/integration.d.ts +39 -0
  131. package/dist/integrations/workos/integration.d.ts.map +1 -0
  132. package/dist/integrations/workos/integration.js +91 -0
  133. package/dist/integrations/workos/integration.js.map +1 -0
  134. package/dist/routes/config.d.ts +235 -0
  135. package/dist/routes/config.d.ts.map +1 -0
  136. package/dist/routes/config.js +972 -0
  137. package/dist/routes/config.js.map +1 -0
  138. package/dist/routes/custom-provider-source.d.ts +52 -0
  139. package/dist/routes/custom-provider-source.d.ts.map +1 -0
  140. package/dist/routes/custom-provider-source.js +124 -0
  141. package/dist/routes/custom-provider-source.js.map +1 -0
  142. package/dist/routes/fs.d.ts +151 -0
  143. package/dist/routes/fs.d.ts.map +1 -0
  144. package/dist/routes/fs.js +708 -0
  145. package/dist/routes/fs.js.map +1 -0
  146. package/dist/routes/intake.d.ts +23 -0
  147. package/dist/routes/intake.d.ts.map +1 -0
  148. package/dist/routes/intake.js +179 -0
  149. package/dist/routes/intake.js.map +1 -0
  150. package/dist/routes/oauth.d.ts +43 -0
  151. package/dist/routes/oauth.d.ts.map +1 -0
  152. package/dist/routes/oauth.js +463 -0
  153. package/dist/routes/oauth.js.map +1 -0
  154. package/dist/routes/projects.d.ts +19 -0
  155. package/dist/routes/projects.d.ts.map +1 -0
  156. package/dist/routes/projects.js +461 -0
  157. package/dist/routes/projects.js.map +1 -0
  158. package/dist/routes/provider-credentials.d.ts +81 -0
  159. package/dist/routes/provider-credentials.d.ts.map +1 -0
  160. package/dist/routes/provider-credentials.js +86 -0
  161. package/dist/routes/provider-credentials.js.map +1 -0
  162. package/dist/routes/route.d.ts +48 -0
  163. package/dist/routes/route.d.ts.map +1 -0
  164. package/dist/routes/route.js +15 -0
  165. package/dist/routes/route.js.map +1 -0
  166. package/dist/routes/skills.d.ts +30 -0
  167. package/dist/routes/skills.d.ts.map +1 -0
  168. package/dist/routes/skills.js +168 -0
  169. package/dist/routes/skills.js.map +1 -0
  170. package/dist/routes/surface.d.ts +107 -0
  171. package/dist/routes/surface.d.ts.map +1 -0
  172. package/dist/routes/surface.js +297 -0
  173. package/dist/routes/surface.js.map +1 -0
  174. package/dist/routes/tenant-credentials.d.ts +74 -0
  175. package/dist/routes/tenant-credentials.d.ts.map +1 -0
  176. package/dist/routes/tenant-credentials.js +156 -0
  177. package/dist/routes/tenant-credentials.js.map +1 -0
  178. package/dist/routes/work-items.d.ts +40 -0
  179. package/dist/routes/work-items.d.ts.map +1 -0
  180. package/dist/routes/work-items.js +695 -0
  181. package/dist/routes/work-items.js.map +1 -0
  182. package/dist/rules/binding-context.d.ts +5 -0
  183. package/dist/rules/binding-context.d.ts.map +1 -0
  184. package/dist/rules/binding-context.js +28 -0
  185. package/dist/rules/binding-context.js.map +1 -0
  186. package/dist/rules/defaults.d.ts +9 -0
  187. package/dist/rules/defaults.d.ts.map +1 -0
  188. package/dist/rules/defaults.js +322 -0
  189. package/dist/rules/defaults.js.map +1 -0
  190. package/dist/rules/dispatcher.d.ts +43 -0
  191. package/dist/rules/dispatcher.d.ts.map +1 -0
  192. package/dist/rules/dispatcher.js +547 -0
  193. package/dist/rules/dispatcher.js.map +1 -0
  194. package/dist/rules/index.d.ts +7 -0
  195. package/dist/rules/index.d.ts.map +1 -0
  196. package/dist/rules/index.js +5 -0
  197. package/dist/rules/processor.d.ts +54 -0
  198. package/dist/rules/processor.d.ts.map +1 -0
  199. package/dist/rules/processor.js +378 -0
  200. package/dist/rules/processor.js.map +1 -0
  201. package/dist/rules/resolve.d.ts +17 -0
  202. package/dist/rules/resolve.d.ts.map +1 -0
  203. package/dist/rules/resolve.js +30 -0
  204. package/dist/rules/resolve.js.map +1 -0
  205. package/dist/rules/start-coordinator.d.ts +60 -0
  206. package/dist/rules/start-coordinator.d.ts.map +1 -0
  207. package/dist/rules/start-coordinator.js +175 -0
  208. package/dist/rules/start-coordinator.js.map +1 -0
  209. package/dist/rules/tools.d.ts +10 -0
  210. package/dist/rules/tools.d.ts.map +1 -0
  211. package/dist/rules/tools.js +59 -0
  212. package/dist/rules/tools.js.map +1 -0
  213. package/dist/rules/transition-service.d.ts +49 -0
  214. package/dist/rules/transition-service.d.ts.map +1 -0
  215. package/dist/rules/transition-service.js +232 -0
  216. package/dist/rules/transition-service.js.map +1 -0
  217. package/dist/rules/types.d.ts +261 -0
  218. package/dist/rules/types.d.ts.map +1 -0
  219. package/dist/rules/types.js +43 -0
  220. package/dist/rules/types.js.map +1 -0
  221. package/dist/rules/validation.d.ts +11 -0
  222. package/dist/rules/validation.d.ts.map +1 -0
  223. package/dist/rules/validation.js +308 -0
  224. package/dist/rules/validation.js.map +1 -0
  225. package/dist/sandbox/fleet.d.ts +222 -0
  226. package/dist/sandbox/fleet.d.ts.map +1 -0
  227. package/dist/sandbox/fleet.js +322 -0
  228. package/dist/sandbox/fleet.js.map +1 -0
  229. package/dist/sandbox/reattach.d.ts +3 -0
  230. package/dist/sandbox/reattach.d.ts.map +1 -0
  231. package/dist/sandbox/reattach.js +16 -0
  232. package/dist/sandbox/reattach.js.map +1 -0
  233. package/dist/server-error.d.ts +12 -0
  234. package/dist/server-error.d.ts.map +1 -0
  235. package/dist/server-error.js +16 -0
  236. package/dist/server-error.js.map +1 -0
  237. package/dist/session/factory-session.d.ts +116 -0
  238. package/dist/session/factory-session.d.ts.map +1 -0
  239. package/dist/session/factory-session.js +162 -0
  240. package/dist/session/factory-session.js.map +1 -0
  241. package/dist/skills/service.d.ts +48 -0
  242. package/dist/skills/service.d.ts.map +1 -0
  243. package/dist/skills/service.js +40 -0
  244. package/dist/skills/service.js.map +1 -0
  245. package/dist/spa-static.d.ts +33 -0
  246. package/dist/spa-static.d.ts.map +1 -0
  247. package/dist/spa-static.js +104 -0
  248. package/dist/spa-static.js.map +1 -0
  249. package/dist/state-signing.d.ts +59 -0
  250. package/dist/state-signing.d.ts.map +1 -0
  251. package/dist/state-signing.js +83 -0
  252. package/dist/state-signing.js.map +1 -0
  253. package/dist/storage/domains/audit/agent-audit.d.ts +27 -0
  254. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
  255. package/dist/storage/domains/audit/agent-audit.js +66 -0
  256. package/dist/storage/domains/audit/agent-audit.js.map +1 -0
  257. package/dist/storage/domains/audit/base.d.ts +140 -0
  258. package/dist/storage/domains/audit/base.d.ts.map +1 -0
  259. package/dist/storage/domains/audit/base.js +184 -0
  260. package/dist/storage/domains/audit/base.js.map +1 -0
  261. package/dist/storage/domains/audit/domain.d.ts +76 -0
  262. package/dist/storage/domains/audit/domain.d.ts.map +1 -0
  263. package/dist/storage/domains/audit/domain.js +269 -0
  264. package/dist/storage/domains/audit/domain.js.map +1 -0
  265. package/dist/storage/domains/channel-identity/base.d.ts +96 -0
  266. package/dist/storage/domains/channel-identity/base.d.ts.map +1 -0
  267. package/dist/storage/domains/channel-identity/base.js +149 -0
  268. package/dist/storage/domains/channel-identity/base.js.map +1 -0
  269. package/dist/storage/domains/credentials/base.d.ts +134 -0
  270. package/dist/storage/domains/credentials/base.d.ts.map +1 -0
  271. package/dist/storage/domains/credentials/base.js +273 -0
  272. package/dist/storage/domains/credentials/base.js.map +1 -0
  273. package/dist/storage/domains/custom-providers/base.d.ts +57 -0
  274. package/dist/storage/domains/custom-providers/base.d.ts.map +1 -0
  275. package/dist/storage/domains/custom-providers/base.js +145 -0
  276. package/dist/storage/domains/custom-providers/base.js.map +1 -0
  277. package/dist/storage/domains/intake/base.d.ts +38 -0
  278. package/dist/storage/domains/intake/base.d.ts.map +1 -0
  279. package/dist/storage/domains/intake/base.js +80 -0
  280. package/dist/storage/domains/intake/base.js.map +1 -0
  281. package/dist/storage/domains/integrations/base.d.ts +126 -0
  282. package/dist/storage/domains/integrations/base.d.ts.map +1 -0
  283. package/dist/storage/domains/integrations/base.js +317 -0
  284. package/dist/storage/domains/integrations/base.js.map +1 -0
  285. package/dist/storage/domains/memory-settings/base.d.ts +62 -0
  286. package/dist/storage/domains/memory-settings/base.d.ts.map +1 -0
  287. package/dist/storage/domains/memory-settings/base.js +126 -0
  288. package/dist/storage/domains/memory-settings/base.js.map +1 -0
  289. package/dist/storage/domains/model-packs/base.d.ts +49 -0
  290. package/dist/storage/domains/model-packs/base.d.ts.map +1 -0
  291. package/dist/storage/domains/model-packs/base.js +96 -0
  292. package/dist/storage/domains/model-packs/base.js.map +1 -0
  293. package/dist/storage/domains/projects/base.d.ts +58 -0
  294. package/dist/storage/domains/projects/base.d.ts.map +1 -0
  295. package/dist/storage/domains/projects/base.js +111 -0
  296. package/dist/storage/domains/projects/base.js.map +1 -0
  297. package/dist/storage/domains/queue-health/base.d.ts +52 -0
  298. package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
  299. package/dist/storage/domains/queue-health/base.js +122 -0
  300. package/dist/storage/domains/queue-health/base.js.map +1 -0
  301. package/dist/storage/domains/source-control/base.d.ts +360 -0
  302. package/dist/storage/domains/source-control/base.d.ts.map +1 -0
  303. package/dist/storage/domains/source-control/base.js +914 -0
  304. package/dist/storage/domains/source-control/base.js.map +1 -0
  305. package/dist/storage/domains/source-control/inmemory.d.ts +175 -0
  306. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
  307. package/dist/storage/domains/source-control/inmemory.js +380 -0
  308. package/dist/storage/domains/source-control/inmemory.js.map +1 -0
  309. package/dist/storage/domains/work-items/base.d.ts +412 -0
  310. package/dist/storage/domains/work-items/base.d.ts.map +1 -0
  311. package/dist/storage/domains/work-items/base.js +1320 -0
  312. package/dist/storage/domains/work-items/base.js.map +1 -0
  313. package/dist/storage/domains/work-items/metrics.d.ts +101 -0
  314. package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
  315. package/dist/storage/domains/work-items/metrics.js +221 -0
  316. package/dist/storage/domains/work-items/metrics.js.map +1 -0
  317. package/dist/timing.d.ts +15 -0
  318. package/dist/timing.d.ts.map +1 -0
  319. package/dist/timing.js +34 -0
  320. package/dist/timing.js.map +1 -0
  321. package/dist/workspace.d.ts +24 -0
  322. package/dist/workspace.d.ts.map +1 -0
  323. package/dist/workspace.js +287 -0
  324. package/dist/workspace.js.map +1 -0
  325. package/factory-skills/configure-factory-rules/SKILL.md +67 -0
  326. package/factory-skills/factory-plan/SKILL.md +61 -0
  327. package/factory-skills/factory-review/SKILL.md +157 -0
  328. package/factory-skills/factory-triage/SKILL.md +99 -0
  329. package/package.json +83 -0
@@ -0,0 +1,104 @@
1
+ import { dirname, extname, join, normalize, resolve, sep } from "path";
2
+ import { readFile, stat } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import { fileURLToPath } from "url";
5
+ //#region src/spa-static.ts
6
+ /**
7
+ * Same-origin SPA serving for production.
8
+ *
9
+ * In dev the SPA is served by Vite (:5173) which proxies API paths to the
10
+ * server (:4111) — this module is effectively idle there. In production the
11
+ * built SPA (vite output) is served by the API server itself at `/`, so the
12
+ * app is a single origin and no CORS / separate static host is required.
13
+ *
14
+ * The middleware is mounted via the Mastra entry's `server.middleware`, which
15
+ * the deployer applies before routes: real file hits and SPA navigations are
16
+ * answered here, everything else falls through to the API routes.
17
+ */
18
+ const MIME = {
19
+ ".html": "text/html; charset=utf-8",
20
+ ".js": "text/javascript; charset=utf-8",
21
+ ".mjs": "text/javascript; charset=utf-8",
22
+ ".css": "text/css; charset=utf-8",
23
+ ".json": "application/json",
24
+ ".webmanifest": "application/manifest+json",
25
+ ".map": "application/json",
26
+ ".svg": "image/svg+xml",
27
+ ".png": "image/png",
28
+ ".jpg": "image/jpeg",
29
+ ".jpeg": "image/jpeg",
30
+ ".gif": "image/gif",
31
+ ".webp": "image/webp",
32
+ ".ico": "image/x-icon",
33
+ ".txt": "text/plain; charset=utf-8",
34
+ ".woff": "font/woff",
35
+ ".woff2": "font/woff2",
36
+ ".ttf": "font/ttf",
37
+ ".wasm": "application/wasm"
38
+ };
39
+ /** Server-owned path prefixes the SPA middleware must never answer for. */
40
+ const SERVER_PREFIXES = [
41
+ "/api",
42
+ "/web",
43
+ "/auth",
44
+ "/connect"
45
+ ];
46
+ /**
47
+ * Locate the built SPA (a dir containing `index.html`). Checked in order:
48
+ * 1. `MASTRACODE_UI_DIST` — explicit override for custom layouts.
49
+ * 2. `factory/` under cwd — both `mastra dev` (cwd is the Mastra public dir)
50
+ * and `mastra start` (cwd is `.mastra/output`) expose assets this way.
51
+ * 3. `factory/` next to the bundled server module.
52
+ * 4. Source-layout fallbacks under `MASTRA_PROJECT_ROOT` or cwd.
53
+ * Returns `undefined` when no build is found (e.g. plain `mastra dev` without
54
+ * a prior vite build), in which case the middleware is simply not mounted.
55
+ */
56
+ function resolveUiDistDir() {
57
+ const projectRoot = process.env.MASTRA_PROJECT_ROOT?.trim();
58
+ const candidates = [
59
+ process.env.MASTRACODE_UI_DIST,
60
+ resolve(process.cwd(), "factory"),
61
+ join(dirname(fileURLToPath(import.meta.url)), "factory"),
62
+ projectRoot && resolve(projectRoot, "src/mastra/public/factory"),
63
+ resolve(process.cwd(), "src/mastra/public/factory")
64
+ ];
65
+ for (const candidate of candidates) if (candidate && existsSync(join(candidate, "index.html"))) return resolve(candidate);
66
+ }
67
+ async function isFile(path) {
68
+ try {
69
+ return (await stat(path)).isFile();
70
+ } catch {
71
+ return false;
72
+ }
73
+ }
74
+ async function serveFile(c, filePath, immutable) {
75
+ const data = await readFile(filePath);
76
+ c.header("Content-Type", MIME[extname(filePath).toLowerCase()] ?? "application/octet-stream");
77
+ c.header("Cache-Control", immutable ? "public, max-age=31536000, immutable" : "no-cache");
78
+ return c.body(new Uint8Array(data));
79
+ }
80
+ /**
81
+ * Hono middleware serving the built SPA from `uiDist`:
82
+ * - exact file hits (js/css/assets) are served directly,
83
+ * - GET navigations to non-server paths fall back to `index.html` (SPA
84
+ * client-side routing),
85
+ * - `/api`, `/web`, `/auth` and non-GET requests always pass through.
86
+ */
87
+ function createSpaStaticMiddleware(uiDist) {
88
+ return async (c, next) => {
89
+ if (c.req.method !== "GET" && c.req.method !== "HEAD") return next();
90
+ const path = c.req.path;
91
+ if (SERVER_PREFIXES.some((prefix) => path === prefix || path.startsWith(`${prefix}/`))) return next();
92
+ const relative = normalize(decodeURIComponent(path)).replace(/^[/\\]+/, "");
93
+ const filePath = resolve(uiDist, relative);
94
+ const uiDistPrefix = uiDist.endsWith(sep) ? uiDist : uiDist + sep;
95
+ if (filePath.startsWith(uiDistPrefix) && relative !== "" && await isFile(filePath)) return serveFile(c, filePath, relative.startsWith("assets/"));
96
+ const accept = c.req.header("Accept") ?? "";
97
+ if (path === "/" || accept.includes("text/html")) return serveFile(c, join(uiDist, "index.html"), false);
98
+ return next();
99
+ };
100
+ }
101
+ //#endregion
102
+ export { createSpaStaticMiddleware, resolveUiDistDir };
103
+
104
+ //# sourceMappingURL=spa-static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spa-static.js","names":[],"sources":["../src/spa-static.ts"],"sourcesContent":["/**\n * Same-origin SPA serving for production.\n *\n * In dev the SPA is served by Vite (:5173) which proxies API paths to the\n * server (:4111) — this module is effectively idle there. In production the\n * built SPA (vite output) is served by the API server itself at `/`, so the\n * app is a single origin and no CORS / separate static host is required.\n *\n * The middleware is mounted via the Mastra entry's `server.middleware`, which\n * the deployer applies before routes: real file hits and SPA navigations are\n * answered here, everything else falls through to the API routes.\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, stat } from 'node:fs/promises';\nimport { dirname, extname, join, normalize, resolve, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { Context } from 'hono';\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json',\n '.webmanifest': 'application/manifest+json',\n '.map': 'application/json',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.ico': 'image/x-icon',\n '.txt': 'text/plain; charset=utf-8',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.wasm': 'application/wasm',\n};\n\n/** Server-owned path prefixes the SPA middleware must never answer for. */\nconst SERVER_PREFIXES = ['/api', '/web', '/auth', '/connect'];\n\n/**\n * Locate the built SPA (a dir containing `index.html`). Checked in order:\n * 1. `MASTRACODE_UI_DIST` — explicit override for custom layouts.\n * 2. `factory/` under cwd — both `mastra dev` (cwd is the Mastra public dir)\n * and `mastra start` (cwd is `.mastra/output`) expose assets this way.\n * 3. `factory/` next to the bundled server module.\n * 4. Source-layout fallbacks under `MASTRA_PROJECT_ROOT` or cwd.\n * Returns `undefined` when no build is found (e.g. plain `mastra dev` without\n * a prior vite build), in which case the middleware is simply not mounted.\n */\nexport function resolveUiDistDir(): string | undefined {\n const projectRoot = process.env.MASTRA_PROJECT_ROOT?.trim();\n const candidates = [\n process.env.MASTRACODE_UI_DIST,\n resolve(process.cwd(), 'factory'),\n join(dirname(fileURLToPath(import.meta.url)), 'factory'),\n projectRoot && resolve(projectRoot, 'src/mastra/public/factory'),\n resolve(process.cwd(), 'src/mastra/public/factory'),\n ];\n for (const candidate of candidates) {\n if (candidate && existsSync(join(candidate, 'index.html'))) return resolve(candidate);\n }\n return undefined;\n}\n\nasync function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\n }\n}\n\nasync function serveFile(c: Context, filePath: string, immutable: boolean): Promise<Response> {\n const data = await readFile(filePath);\n c.header('Content-Type', MIME[extname(filePath).toLowerCase()] ?? 'application/octet-stream');\n // Vite emits content-hashed filenames under assets/ — cache those forever;\n // index.html (and anything unhashed) must revalidate so deploys roll out.\n c.header('Cache-Control', immutable ? 'public, max-age=31536000, immutable' : 'no-cache');\n return c.body(new Uint8Array(data));\n}\n\n/**\n * Hono middleware serving the built SPA from `uiDist`:\n * - exact file hits (js/css/assets) are served directly,\n * - GET navigations to non-server paths fall back to `index.html` (SPA\n * client-side routing),\n * - `/api`, `/web`, `/auth` and non-GET requests always pass through.\n */\nexport function createSpaStaticMiddleware(uiDist: string) {\n return async (c: Context, next: () => Promise<void>): Promise<Response | void> => {\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD') return next();\n const path = c.req.path;\n if (SERVER_PREFIXES.some(prefix => path === prefix || path.startsWith(`${prefix}/`))) return next();\n\n // Resolve the request path inside uiDist, rejecting traversal escapes.\n const relative = normalize(decodeURIComponent(path)).replace(/^[/\\\\]+/, '');\n const filePath = resolve(uiDist, relative);\n // Use a trailing separator so a sibling like \"ui.key\" can't slip past the\n // prefix check (same pattern as fs-routes.ts isWithinRoot).\n const uiDistPrefix = uiDist.endsWith(sep) ? uiDist : uiDist + sep;\n if (filePath.startsWith(uiDistPrefix) && relative !== '' && (await isFile(filePath))) {\n return serveFile(c, filePath, relative.startsWith('assets/'));\n }\n\n // SPA fallback: serve index.html for root and html navigations.\n const accept = c.req.header('Accept') ?? '';\n if (path === '/' || accept.includes('text/html')) {\n return serveFile(c, join(uiDist, 'index.html'), false);\n }\n\n return next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,MAAM,OAA+B;CACnC,SAAS;CACT,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,gBAAgB;CAChB,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,UAAU;CACV,QAAQ;CACR,SAAS;AACX;;AAGA,MAAM,kBAAkB;CAAC;CAAQ;CAAQ;CAAS;AAAU;;;;;;;;;;;AAY5D,SAAgB,mBAAuC;CACrD,MAAM,cAAc,QAAQ,IAAI,qBAAqB,KAAK;CAC1D,MAAM,aAAa;EACjB,QAAQ,IAAI;EACZ,QAAQ,QAAQ,IAAI,GAAG,SAAS;EAChC,KAAK,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC,GAAG,SAAS;EACvD,eAAe,QAAQ,aAAa,2BAA2B;EAC/D,QAAQ,QAAQ,IAAI,GAAG,2BAA2B;CACpD;CACA,KAAK,MAAM,aAAa,YACtB,IAAI,aAAa,WAAW,KAAK,WAAW,YAAY,CAAC,GAAG,OAAO,QAAQ,SAAS;AAGxF;AAEA,eAAe,OAAO,MAAgC;CACpD,IAAI;EACF,QAAQ,MAAM,KAAK,IAAI,EAAA,CAAG,OAAO;CACnC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAe,UAAU,GAAY,UAAkB,WAAuC;CAC5F,MAAM,OAAO,MAAM,SAAS,QAAQ;CACpC,EAAE,OAAO,gBAAgB,KAAK,QAAQ,QAAQ,CAAC,CAAC,YAAY,MAAM,0BAA0B;CAG5F,EAAE,OAAO,iBAAiB,YAAY,wCAAwC,UAAU;CACxF,OAAO,EAAE,KAAK,IAAI,WAAW,IAAI,CAAC;AACpC;;;;;;;;AASA,SAAgB,0BAA0B,QAAgB;CACxD,OAAO,OAAO,GAAY,SAAwD;EAChF,IAAI,EAAE,IAAI,WAAW,SAAS,EAAE,IAAI,WAAW,QAAQ,OAAO,KAAK;EACnE,MAAM,OAAO,EAAE,IAAI;EACnB,IAAI,gBAAgB,MAAK,WAAU,SAAS,UAAU,KAAK,WAAW,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,KAAK;EAGlG,MAAM,WAAW,UAAU,mBAAmB,IAAI,CAAC,CAAC,CAAC,QAAQ,WAAW,EAAE;EAC1E,MAAM,WAAW,QAAQ,QAAQ,QAAQ;EAGzC,MAAM,eAAe,OAAO,SAAS,GAAG,IAAI,SAAS,SAAS;EAC9D,IAAI,SAAS,WAAW,YAAY,KAAK,aAAa,MAAO,MAAM,OAAO,QAAQ,GAChF,OAAO,UAAU,GAAG,UAAU,SAAS,WAAW,SAAS,CAAC;EAI9D,MAAM,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK;EACzC,IAAI,SAAS,OAAO,OAAO,SAAS,WAAW,GAC7C,OAAO,UAAU,GAAG,KAAK,QAAQ,YAAY,GAAG,KAAK;EAGvD,OAAO,KAAK;CACd;AACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared OAuth/install `state` signing for web integrations.
3
+ *
4
+ * The GitHub, Linear, and Slack OAuth/OIDC flows each round-trip a signed `state`
5
+ * value
6
+ * through the third party to bind the callback to the `(orgId, userId)` tenant
7
+ * that initiated it (CSRF protection + tenant routing). The signer is a system
8
+ * facility: `MastraFactory` creates ONE signer at boot and hands it to every
9
+ * registered integration through `IntegrationContext` (see
10
+ * `./factory-integration.ts`), so all integrations sign and verify with the
11
+ * same secret.
12
+ *
13
+ * Secret resolution happens in the factory, not here: explicit
14
+ * `config.stateSecret` → the GitHub integration's webhook secret → a
15
+ * per-process random secret. A random secret is NOT stable across replicas —
16
+ * a `state` signed by one replica cannot be verified by another — which is
17
+ * what the `stable` flag reports. The factory fails loud at boot when a
18
+ * registered integration requires a stable signer but only a random one is
19
+ * available.
20
+ *
21
+ * The wire format (base64url JSON payload + `.` + HMAC-SHA256 base64url
22
+ * signature) is unchanged from the previous `github/config.ts` implementation
23
+ * so in-flight OAuth states survive a deploy.
24
+ */
25
+ /** Verified tenant and optional Factory context carried by a signed `state`. */
26
+ export interface StateTenant {
27
+ orgId: string;
28
+ userId: string;
29
+ /** Factory that initiated the integration flow, when the caller supplied one. */
30
+ factoryProjectId?: string;
31
+ /**
32
+ * Per-`state` random value. A signed `state` stays valid for its whole
33
+ * lifetime, so a flow that must not run twice off one `state` (account
34
+ * binding, for instance) can key single-use bookkeeping on this.
35
+ */
36
+ nonce: string;
37
+ }
38
+ /** Signs and verifies OAuth `state` values bound to a tenant and optional Factory. */
39
+ export interface StateSigner {
40
+ /** Build a signed `state` bound to the tenant and optional initiating Factory. */
41
+ sign(orgId: string, userId: string, context?: {
42
+ factoryProjectId?: string;
43
+ }): string;
44
+ /** Verify a signed `state`; returns the bound tenant, or `null` if invalid. */
45
+ verify(state: string | undefined): StateTenant | null;
46
+ /**
47
+ * True when the signer was built from an explicit deployment-stable secret.
48
+ * False means a per-process random secret: fine for single-process/local
49
+ * dev, broken for multi-replica deploys (see module docs).
50
+ */
51
+ readonly stable: boolean;
52
+ }
53
+ /**
54
+ * Create a state signer. With a `secret`, the signer is deployment-stable
55
+ * (`stable: true`); without one it falls back to a per-process random secret
56
+ * (`stable: false`).
57
+ */
58
+ export declare function createStateSigner(secret?: string): StateSigner;
59
+ //# sourceMappingURL=state-signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-signing.d.ts","sourceRoot":"","sources":["../src/state-signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,sFAAsF;AACtF,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACrF,+EAA+E;IAC/E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC;IACtD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAaD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAqD9D"}
@@ -0,0 +1,83 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from "crypto";
2
+ //#region src/state-signing.ts
3
+ /**
4
+ * Shared OAuth/install `state` signing for web integrations.
5
+ *
6
+ * The GitHub, Linear, and Slack OAuth/OIDC flows each round-trip a signed `state`
7
+ * value
8
+ * through the third party to bind the callback to the `(orgId, userId)` tenant
9
+ * that initiated it (CSRF protection + tenant routing). The signer is a system
10
+ * facility: `MastraFactory` creates ONE signer at boot and hands it to every
11
+ * registered integration through `IntegrationContext` (see
12
+ * `./factory-integration.ts`), so all integrations sign and verify with the
13
+ * same secret.
14
+ *
15
+ * Secret resolution happens in the factory, not here: explicit
16
+ * `config.stateSecret` → the GitHub integration's webhook secret → a
17
+ * per-process random secret. A random secret is NOT stable across replicas —
18
+ * a `state` signed by one replica cannot be verified by another — which is
19
+ * what the `stable` flag reports. The factory fails loud at boot when a
20
+ * registered integration requires a stable signer but only a random one is
21
+ * available.
22
+ *
23
+ * The wire format (base64url JSON payload + `.` + HMAC-SHA256 base64url
24
+ * signature) is unchanged from the previous `github/config.ts` implementation
25
+ * so in-flight OAuth states survive a deploy.
26
+ */
27
+ /** Signed `state` values expire after this window to bound the CSRF token. */
28
+ const STATE_MAX_AGE_MS = 600 * 1e3;
29
+ /**
30
+ * Create a state signer. With a `secret`, the signer is deployment-stable
31
+ * (`stable: true`); without one it falls back to a per-process random secret
32
+ * (`stable: false`).
33
+ */
34
+ function createStateSigner(secret) {
35
+ const stable = typeof secret === "string" && secret.length > 0;
36
+ const key = stable ? secret : randomBytes(32).toString("hex");
37
+ return {
38
+ stable,
39
+ sign(orgId, userId, context) {
40
+ const payload = {
41
+ orgId,
42
+ userId,
43
+ ...context?.factoryProjectId ? { factoryProjectId: context.factoryProjectId } : {},
44
+ nonce: randomBytes(8).toString("hex"),
45
+ issuedAt: Date.now()
46
+ };
47
+ const body = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
48
+ return `${body}.${createHmac("sha256", key).update(body).digest("base64url")}`;
49
+ },
50
+ verify(state) {
51
+ if (!state) return null;
52
+ const dot = state.lastIndexOf(".");
53
+ if (dot <= 0) return null;
54
+ const body = state.slice(0, dot);
55
+ const sig = state.slice(dot + 1);
56
+ const expected = createHmac("sha256", key).update(body).digest("base64url");
57
+ const sigBuf = Buffer.from(sig);
58
+ const expectedBuf = Buffer.from(expected);
59
+ if (sigBuf.length !== expectedBuf.length || !timingSafeEqual(sigBuf, expectedBuf)) return null;
60
+ try {
61
+ const parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
62
+ if (typeof parsed.orgId !== "string" || typeof parsed.userId !== "string") return null;
63
+ if (typeof parsed.issuedAt !== "number" || !Number.isFinite(parsed.issuedAt)) return null;
64
+ if (typeof parsed.nonce !== "string" || parsed.nonce.length === 0) return null;
65
+ if (parsed.factoryProjectId !== void 0 && (typeof parsed.factoryProjectId !== "string" || parsed.factoryProjectId.length === 0)) return null;
66
+ const age = Date.now() - parsed.issuedAt;
67
+ if (age < 0 || age > STATE_MAX_AGE_MS) return null;
68
+ return {
69
+ orgId: parsed.orgId,
70
+ userId: parsed.userId,
71
+ ...parsed.factoryProjectId ? { factoryProjectId: parsed.factoryProjectId } : {},
72
+ nonce: parsed.nonce
73
+ };
74
+ } catch {
75
+ return null;
76
+ }
77
+ }
78
+ };
79
+ }
80
+ //#endregion
81
+ export { createStateSigner };
82
+
83
+ //# sourceMappingURL=state-signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-signing.js","names":[],"sources":["../src/state-signing.ts"],"sourcesContent":["/**\n * Shared OAuth/install `state` signing for web integrations.\n *\n * The GitHub, Linear, and Slack OAuth/OIDC flows each round-trip a signed `state`\n * value\n * through the third party to bind the callback to the `(orgId, userId)` tenant\n * that initiated it (CSRF protection + tenant routing). The signer is a system\n * facility: `MastraFactory` creates ONE signer at boot and hands it to every\n * registered integration through `IntegrationContext` (see\n * `./factory-integration.ts`), so all integrations sign and verify with the\n * same secret.\n *\n * Secret resolution happens in the factory, not here: explicit\n * `config.stateSecret` → the GitHub integration's webhook secret → a\n * per-process random secret. A random secret is NOT stable across replicas —\n * a `state` signed by one replica cannot be verified by another — which is\n * what the `stable` flag reports. The factory fails loud at boot when a\n * registered integration requires a stable signer but only a random one is\n * available.\n *\n * The wire format (base64url JSON payload + `.` + HMAC-SHA256 base64url\n * signature) is unchanged from the previous `github/config.ts` implementation\n * so in-flight OAuth states survive a deploy.\n */\n\nimport { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';\n\n/** Verified tenant and optional Factory context carried by a signed `state`. */\nexport interface StateTenant {\n orgId: string;\n userId: string;\n /** Factory that initiated the integration flow, when the caller supplied one. */\n factoryProjectId?: string;\n /**\n * Per-`state` random value. A signed `state` stays valid for its whole\n * lifetime, so a flow that must not run twice off one `state` (account\n * binding, for instance) can key single-use bookkeeping on this.\n */\n nonce: string;\n}\n\n/** Signs and verifies OAuth `state` values bound to a tenant and optional Factory. */\nexport interface StateSigner {\n /** Build a signed `state` bound to the tenant and optional initiating Factory. */\n sign(orgId: string, userId: string, context?: { factoryProjectId?: string }): string;\n /** Verify a signed `state`; returns the bound tenant, or `null` if invalid. */\n verify(state: string | undefined): StateTenant | null;\n /**\n * True when the signer was built from an explicit deployment-stable secret.\n * False means a per-process random secret: fine for single-process/local\n * dev, broken for multi-replica deploys (see module docs).\n */\n readonly stable: boolean;\n}\n\ninterface StatePayload {\n orgId: string;\n userId: string;\n factoryProjectId?: string;\n nonce: string;\n issuedAt: number;\n}\n\n/** Signed `state` values expire after this window to bound the CSRF token. */\nconst STATE_MAX_AGE_MS = 10 * 60 * 1000;\n\n/**\n * Create a state signer. With a `secret`, the signer is deployment-stable\n * (`stable: true`); without one it falls back to a per-process random secret\n * (`stable: false`).\n */\nexport function createStateSigner(secret?: string): StateSigner {\n const stable = typeof secret === 'string' && secret.length > 0;\n const key = stable ? secret : randomBytes(32).toString('hex');\n return {\n stable,\n sign(orgId: string, userId: string, context?: { factoryProjectId?: string }): string {\n const payload: StatePayload = {\n orgId,\n userId,\n ...(context?.factoryProjectId ? { factoryProjectId: context.factoryProjectId } : {}),\n nonce: randomBytes(8).toString('hex'),\n issuedAt: Date.now(),\n };\n const body = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64url');\n const sig = createHmac('sha256', key).update(body).digest('base64url');\n return `${body}.${sig}`;\n },\n verify(state: string | undefined): StateTenant | null {\n if (!state) return null;\n const dot = state.lastIndexOf('.');\n if (dot <= 0) return null;\n const body = state.slice(0, dot);\n const sig = state.slice(dot + 1);\n const expected = createHmac('sha256', key).update(body).digest('base64url');\n const sigBuf = Buffer.from(sig);\n const expectedBuf = Buffer.from(expected);\n if (sigBuf.length !== expectedBuf.length || !timingSafeEqual(sigBuf, expectedBuf)) {\n return null;\n }\n try {\n const parsed = JSON.parse(Buffer.from(body, 'base64url').toString('utf8')) as StatePayload;\n if (typeof parsed.orgId !== 'string' || typeof parsed.userId !== 'string') return null;\n if (typeof parsed.issuedAt !== 'number' || !Number.isFinite(parsed.issuedAt)) return null;\n if (typeof parsed.nonce !== 'string' || parsed.nonce.length === 0) return null;\n if (\n parsed.factoryProjectId !== undefined &&\n (typeof parsed.factoryProjectId !== 'string' || parsed.factoryProjectId.length === 0)\n ) {\n return null;\n }\n const age = Date.now() - parsed.issuedAt;\n if (age < 0 || age > STATE_MAX_AGE_MS) return null;\n return {\n orgId: parsed.orgId,\n userId: parsed.userId,\n ...(parsed.factoryProjectId ? { factoryProjectId: parsed.factoryProjectId } : {}),\n nonce: parsed.nonce,\n };\n } catch {\n return null;\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEA,MAAM,mBAAmB,MAAU;;;;;;AAOnC,SAAgB,kBAAkB,QAA8B;CAC9D,MAAM,SAAS,OAAO,WAAW,YAAY,OAAO,SAAS;CAC7D,MAAM,MAAM,SAAS,SAAS,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK;CAC5D,OAAO;EACL;EACA,KAAK,OAAe,QAAgB,SAAiD;GACnF,MAAM,UAAwB;IAC5B;IACA;IACA,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;IAClF,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK;IACpC,UAAU,KAAK,IAAI;GACrB;GACA,MAAM,OAAO,OAAO,KAAK,KAAK,UAAU,OAAO,GAAG,MAAM,CAAC,CAAC,SAAS,WAAW;GAE9E,OAAO,GAAG,KAAK,GADH,WAAW,UAAU,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,WACtC;EACtB;EACA,OAAO,OAA+C;GACpD,IAAI,CAAC,OAAO,OAAO;GACnB,MAAM,MAAM,MAAM,YAAY,GAAG;GACjC,IAAI,OAAO,GAAG,OAAO;GACrB,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG;GAC/B,MAAM,MAAM,MAAM,MAAM,MAAM,CAAC;GAC/B,MAAM,WAAW,WAAW,UAAU,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,WAAW;GAC1E,MAAM,SAAS,OAAO,KAAK,GAAG;GAC9B,MAAM,cAAc,OAAO,KAAK,QAAQ;GACxC,IAAI,OAAO,WAAW,YAAY,UAAU,CAAC,gBAAgB,QAAQ,WAAW,GAC9E,OAAO;GAET,IAAI;IACF,MAAM,SAAS,KAAK,MAAM,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC;IACzE,IAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,WAAW,UAAU,OAAO;IAClF,IAAI,OAAO,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,OAAO,QAAQ,GAAG,OAAO;IACrF,IAAI,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,WAAW,GAAG,OAAO;IAC1E,IACE,OAAO,qBAAqB,KAAA,MAC3B,OAAO,OAAO,qBAAqB,YAAY,OAAO,iBAAiB,WAAW,IAEnF,OAAO;IAET,MAAM,MAAM,KAAK,IAAI,IAAI,OAAO;IAChC,IAAI,MAAM,KAAK,MAAM,kBAAkB,OAAO;IAC9C,OAAO;KACL,OAAO,OAAO;KACd,QAAQ,OAAO;KACf,GAAI,OAAO,mBAAmB,EAAE,kBAAkB,OAAO,iBAAiB,IAAI,CAAC;KAC/E,OAAO,OAAO;IAChB;GACF,QAAQ;IACN,OAAO;GACT;EACF;CACF;AACF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Agent-level audit event detection (Audit v1.1).
3
+ *
4
+ * Git actions performed by agents inside runs never touch web routes, so this
5
+ * observer detects externally-visible git side effects and delegates recording
6
+ * to the factory-owned audit domain.
7
+ */
8
+ import type { RequestContext } from '@mastra/core/request-context';
9
+ import type { AuditAgentEmitter } from './domain.js';
10
+ interface ToolObserverContext {
11
+ toolName: string;
12
+ input: unknown;
13
+ output?: unknown;
14
+ error?: unknown;
15
+ context: RequestContext;
16
+ }
17
+ /**
18
+ * Detect externally-visible git side effects in a completed tool call and
19
+ * record `factory.agent.*` audit events for them. One command can emit
20
+ * multiple events (`git commit && git push` emits both). Never throws.
21
+ */
22
+ export declare function observeAgentGitAction({ audit, toolContext, }: {
23
+ audit: AuditAgentEmitter;
24
+ toolContext: ToolObserverContext;
25
+ }): Promise<void>;
26
+ export {};
27
+ //# sourceMappingURL=agent-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-audit.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;CACzB;AAgCD;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,KAAK,EACL,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,mBAAmB,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CAsChB"}
@@ -0,0 +1,66 @@
1
+ //#region src/storage/domains/audit/agent-audit.ts
2
+ /** Match command-start positions while ignoring command text embedded in heredoc bodies. */
3
+ const GIT_COMMIT_RE = /(?:^|\n|;|&&|\|\|)\s*git\s+commit(?:\s|$)/;
4
+ const GIT_PUSH_RE = /(?:^|\n|;|&&|\|\|)\s*git\s+push(?:\s|$)/;
5
+ function stripHeredocBodies(command) {
6
+ const lines = command.split("\n");
7
+ const executableLines = [];
8
+ let delimiter;
9
+ for (const line of lines) {
10
+ if (delimiter) {
11
+ if (line.trim() === delimiter) delimiter = void 0;
12
+ continue;
13
+ }
14
+ executableLines.push(line);
15
+ delimiter = line.match(/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/)?.[2];
16
+ }
17
+ return executableLines.join("\n");
18
+ }
19
+ /** Parse the branch from a plain `git push <remote> <branch>` invocation. */
20
+ function parsePushedBranch(command) {
21
+ return command.match(/(?:^|\n|;|&&|\|\|)\s*git\s+push\s+(?:-[^\s]+\s+)*([^\s;&|-][^\s;&|]*)\s+([^\s;&|-][^\s;&|]*)/)?.[2];
22
+ }
23
+ /**
24
+ * Detect externally-visible git side effects in a completed tool call and
25
+ * record `factory.agent.*` audit events for them. One command can emit
26
+ * multiple events (`git commit && git push` emits both). Never throws.
27
+ */
28
+ async function observeAgentGitAction({ audit, toolContext }) {
29
+ try {
30
+ if (toolContext.toolName !== "execute_command" || toolContext.error) return;
31
+ const rawCommand = toolContext.input?.command;
32
+ if (typeof rawCommand !== "string") return;
33
+ const command = stripHeredocBodies(rawCommand);
34
+ const worktreePath = toolContext.context.get("controller")?.scope;
35
+ if (GIT_COMMIT_RE.test(command)) await audit.emitAgent({
36
+ requestContext: toolContext.context,
37
+ input: {
38
+ action: "factory.agent.commit",
39
+ targets: worktreePath ? [{
40
+ type: "worktree",
41
+ id: worktreePath
42
+ }] : []
43
+ }
44
+ });
45
+ if (GIT_PUSH_RE.test(command)) {
46
+ const branch = parsePushedBranch(command);
47
+ await audit.emitAgent({
48
+ requestContext: toolContext.context,
49
+ input: {
50
+ action: "factory.agent.push",
51
+ targets: worktreePath ? [{
52
+ type: "worktree",
53
+ id: worktreePath
54
+ }] : [],
55
+ ...branch ? { metadata: { branch } } : {}
56
+ }
57
+ });
58
+ }
59
+ } catch (err) {
60
+ console.warn("[Audit] Failed to observe agent git action", { error: err instanceof Error ? err.message : String(err) });
61
+ }
62
+ }
63
+ //#endregion
64
+ export { observeAgentGitAction };
65
+
66
+ //# sourceMappingURL=agent-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-audit.js","names":[],"sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"sourcesContent":["/**\n * Agent-level audit event detection (Audit v1.1).\n *\n * Git actions performed by agents inside runs never touch web routes, so this\n * observer detects externally-visible git side effects and delegates recording\n * to the factory-owned audit domain.\n */\n\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nimport type { AuditAgentEmitter } from './domain.js';\n\ntype FactorySessionState = { factoryProjectId?: string; projectRepositoryId?: string };\n\ninterface ToolObserverContext {\n toolName: string;\n input: unknown;\n output?: unknown;\n error?: unknown;\n context: RequestContext;\n}\n\n/** Match command-start positions while ignoring command text embedded in heredoc bodies. */\nconst GIT_COMMIT_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+commit(?:\\s|$)/;\nconst GIT_PUSH_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push(?:\\s|$)/;\n\nfunction stripHeredocBodies(command: string): string {\n const lines = command.split('\\n');\n const executableLines: string[] = [];\n let delimiter: string | undefined;\n\n for (const line of lines) {\n if (delimiter) {\n if (line.trim() === delimiter) delimiter = undefined;\n continue;\n }\n executableLines.push(line);\n const heredoc = line.match(/<<-?\\s*(['\"]?)([A-Za-z_][A-Za-z0-9_]*)\\1/);\n delimiter = heredoc?.[2];\n }\n\n return executableLines.join('\\n');\n}\n\n/** Parse the branch from a plain `git push <remote> <branch>` invocation. */\nfunction parsePushedBranch(command: string): string | undefined {\n const match = command.match(\n /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push\\s+(?:-[^\\s]+\\s+)*([^\\s;&|-][^\\s;&|]*)\\s+([^\\s;&|-][^\\s;&|]*)/,\n );\n return match?.[2];\n}\n\n/**\n * Detect externally-visible git side effects in a completed tool call and\n * record `factory.agent.*` audit events for them. One command can emit\n * multiple events (`git commit && git push` emits both). Never throws.\n */\nexport async function observeAgentGitAction({\n audit,\n toolContext,\n}: {\n audit: AuditAgentEmitter;\n toolContext: ToolObserverContext;\n}): Promise<void> {\n try {\n if (toolContext.toolName !== 'execute_command' || toolContext.error) return;\n const rawCommand = (toolContext.input as { command?: unknown } | undefined)?.command;\n if (typeof rawCommand !== 'string') return;\n const command = stripHeredocBodies(rawCommand);\n\n const controller = toolContext.context.get('controller') as\n | AgentControllerRequestContext<FactorySessionState>\n | undefined;\n const worktreePath = controller?.scope;\n\n if (GIT_COMMIT_RE.test(command)) {\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: {\n action: 'factory.agent.commit',\n targets: worktreePath ? [{ type: 'worktree', id: worktreePath }] : [],\n },\n });\n }\n\n if (GIT_PUSH_RE.test(command)) {\n const branch = parsePushedBranch(command);\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: {\n action: 'factory.agent.push',\n targets: worktreePath ? [{ type: 'worktree', id: worktreePath }] : [],\n ...(branch ? { metadata: { branch } } : {}),\n },\n });\n }\n } catch (err) {\n console.warn('[Audit] Failed to observe agent git action', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n"],"mappings":";;AAwBA,MAAM,gBAAgB;AACtB,MAAM,cAAc;AAEpB,SAAS,mBAAmB,SAAyB;CACnD,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,MAAM,kBAA4B,CAAC;CACnC,IAAI;CAEJ,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,WAAW;GACb,IAAI,KAAK,KAAK,MAAM,WAAW,YAAY,KAAA;GAC3C;EACF;EACA,gBAAgB,KAAK,IAAI;EAEzB,YADgB,KAAK,MAAM,0CACT,CAAC,GAAG;CACxB;CAEA,OAAO,gBAAgB,KAAK,IAAI;AAClC;;AAGA,SAAS,kBAAkB,SAAqC;CAI9D,OAHc,QAAQ,MACpB,8FAES,CAAC,GAAG;AACjB;;;;;;AAOA,eAAsB,sBAAsB,EAC1C,OACA,eAIgB;CAChB,IAAI;EACF,IAAI,YAAY,aAAa,qBAAqB,YAAY,OAAO;EACrE,MAAM,aAAc,YAAY,OAA6C;EAC7E,IAAI,OAAO,eAAe,UAAU;EACpC,MAAM,UAAU,mBAAmB,UAAU;EAK7C,MAAM,eAHa,YAAY,QAAQ,IAAI,YAGb,CAAC,EAAE;EAEjC,IAAI,cAAc,KAAK,OAAO,GAC5B,MAAM,MAAM,UAAU;GACpB,gBAAgB,YAAY;GAC5B,OAAO;IACL,QAAQ;IACR,SAAS,eAAe,CAAC;KAAE,MAAM;KAAY,IAAI;IAAa,CAAC,IAAI,CAAC;GACtE;EACF,CAAC;EAGH,IAAI,YAAY,KAAK,OAAO,GAAG;GAC7B,MAAM,SAAS,kBAAkB,OAAO;GACxC,MAAM,MAAM,UAAU;IACpB,gBAAgB,YAAY;IAC5B,OAAO;KACL,QAAQ;KACR,SAAS,eAAe,CAAC;MAAE,MAAM;MAAY,IAAI;KAAa,CAAC,IAAI,CAAC;KACpE,GAAI,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;IAC3C;GACF,CAAC;EACH;CACF,SAAS,KAAK;EACZ,QAAQ,KAAK,8CAA8C,EACzD,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EACxD,CAAC;CACH;AACF"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Factory audit events domain — the append-only "who did what, when" trail
3
+ * behind the software factory.
4
+ *
5
+ * One `audit_events` row records a single audited mutation (work-item change,
6
+ * stage move, run start, worktree create/delete, git action, intake config
7
+ * change). Rows are append-only: there is no update/delete API, and the table
8
+ * is the local source of truth even when the WorkOS Audit Logs mirror is
9
+ * unavailable.
10
+ *
11
+ * Tenancy is **org-first**, like `work_items`: events are scoped by `org_id`
12
+ * and (usually) `factory_project_id`; `actor_id` records who acted but never
13
+ * scopes reads.
14
+ *
15
+ * v1 action taxonomy (register these in the WorkOS dashboard under
16
+ * Audit Logs → Events for the export mirror to accept them):
17
+ * - factory.work_item.created
18
+ * - factory.work_item.updated
19
+ * - factory.work_item.stage_moved
20
+ * - factory.work_item.deleted
21
+ * - factory.run.started
22
+ * - factory.worktree.created
23
+ * - factory.worktree.deleted
24
+ * - factory.triage.started
25
+ * - factory.git.commit
26
+ * - factory.git.push
27
+ * - factory.git.pr_opened
28
+ * - factory.intake.config_updated
29
+ *
30
+ * v1.1 adds agent-level actions (also register these in WorkOS):
31
+ * - factory.agent.commit
32
+ * - factory.agent.push
33
+ * - factory.agent.pr_opened
34
+ *
35
+ * Agent events carry `actor_type = 'agent'` with `actor_id = 'agent:<threadId>'`
36
+ * and `metadata.startedBy = <userId>` chaining accountability back to the human
37
+ * whose message drove the run.
38
+ */
39
+ import { FactoryStorageDomain } from '@mastra/core/storage';
40
+ import type { CollectionSchema } from '@mastra/core/storage';
41
+ /** What an audit event acted on (WorkOS Audit Logs target shape). */
42
+ export interface AuditTarget {
43
+ /** Target kind, e.g. 'work_item', 'worktree', 'issue', 'pull_request'. */
44
+ type: string;
45
+ /** Stable identifier of the target (row id, branch name, issue number...). */
46
+ id: string;
47
+ /** Human-readable label (work-item title, branch name...). */
48
+ name?: string;
49
+ }
50
+ /** Who performed the audited action. */
51
+ export type AuditActorType = 'human' | 'agent';
52
+ /** Request context captured alongside the event. */
53
+ export interface AuditContext {
54
+ /** Client IP (first hop of `x-forwarded-for`) when available. */
55
+ location?: string;
56
+ /** Request `user-agent` header when available. */
57
+ userAgent?: string;
58
+ }
59
+ /** One persisted audit event. */
60
+ export interface AuditEventRow {
61
+ id: string;
62
+ /** Owning WorkOS organization id — the trail is org-wide. */
63
+ orgId: string;
64
+ /** WorkOS user id of whoever performed the action, or `agent:<threadId>`. */
65
+ actorId: string;
66
+ /** Whether a human or an agent (inside a run) performed the action. */
67
+ actorType: AuditActorType;
68
+ /** Dot-namespaced action, e.g. 'factory.work_item.stage_moved'. */
69
+ action: string;
70
+ /** What was acted on. */
71
+ targets: AuditTarget[];
72
+ /** Bounded event summary — never full payloads, never secrets. */
73
+ metadata: Record<string, unknown>;
74
+ /** Factory project the event is scoped to; null for org-level events. */
75
+ factoryProjectId: string | null;
76
+ /** Project-repository link affected by a repository-specific action. */
77
+ projectRepositoryId: string | null;
78
+ /** Request context (`x-forwarded-for` / `user-agent`). */
79
+ context: AuditContext;
80
+ occurredAt: Date;
81
+ }
82
+ export interface RecordAuditEventInput {
83
+ orgId: string;
84
+ actorId: string;
85
+ /** Who performed the action; defaults to 'human'. */
86
+ actorType?: AuditActorType;
87
+ /** Dot-namespaced action, e.g. 'factory.work_item.stage_moved'. */
88
+ action: string;
89
+ targets: AuditTarget[];
90
+ metadata?: Record<string, unknown>;
91
+ factoryProjectId?: string;
92
+ projectRepositoryId?: string;
93
+ context?: AuditContext;
94
+ occurredAt?: Date;
95
+ }
96
+ /** A fully-normalized event ready to persist (id assigned on insert). */
97
+ export type AuditEventInsert = Omit<AuditEventRow, 'id'>;
98
+ export interface ListAuditEventsInput {
99
+ orgId: string;
100
+ factoryProjectId?: string;
101
+ /** Restrict to these actions (exact match). */
102
+ actions?: string[];
103
+ actorId?: string;
104
+ /** Opaque cursor from a previous page (`nextCursor`). */
105
+ before?: string;
106
+ limit?: number;
107
+ }
108
+ export interface AuditEventPage {
109
+ events: AuditEventRow[];
110
+ /** Pass back as `before` to fetch the next (older) page; absent at the end. */
111
+ nextCursor?: string;
112
+ }
113
+ /** Truncate oversized metadata rather than dropping the whole event. */
114
+ export declare function boundAuditMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown>;
115
+ /** Normalize a requested page size to a finite integer in `[1, MAX_PAGE_SIZE]`. */
116
+ export declare function clampAuditLimit(limit: number | undefined): number;
117
+ /** Encode the `(occurredAt, id)` keyset cursor of a row. */
118
+ export declare function encodeAuditCursor(row: AuditEventRow): string;
119
+ /** Decode a cursor back into its `(occurredAt, id)` parts, or `undefined`. */
120
+ export declare function decodeAuditCursor(cursor: string): {
121
+ occurredAt: Date;
122
+ id: string;
123
+ } | undefined;
124
+ export declare const AUDIT_EVENTS_SCHEMA: CollectionSchema;
125
+ /**
126
+ * Audit event storage, written once against the generic `FactoryStorageOps`
127
+ * surface. `record()` normalizes inputs (defaults, metadata bounding);
128
+ * `list()` is keyset-paginated on `(occurred_at, id)` newest-first.
129
+ */
130
+ export declare class AuditStorage extends FactoryStorageDomain {
131
+ #private;
132
+ constructor();
133
+ init(): Promise<void>;
134
+ dangerouslyClearAll(): Promise<void>;
135
+ /** Append one audit event. Throws on failure — swallow-on-failure lives in the caller. */
136
+ record(input: RecordAuditEventInput): Promise<AuditEventRow>;
137
+ /** List an org's audit events newest-first with keyset pagination. */
138
+ list(input: ListAuditEventsInput): Promise<AuditEventPage>;
139
+ }
140
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/audit/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAsC,MAAM,sBAAsB,CAAC;AAEjG,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/C,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,SAAS,EAAE,cAAc,CAAC;IAC1B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wEAAwE;IACxE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,0DAA0D;IAC1D,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzG;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjE;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE5D;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAO9F;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAmBjC,CAAC;AAiCF;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,oBAAoB;;;IAK9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C,0FAA0F;IACpF,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;IAgBlE,sEAAsE;IAChE,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;CA2BjE"}