@mastra/factory 0.0.0-fix-thread-subscription-multi-instance-redis-streams-20260730204150

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 (313) hide show
  1. package/CHANGELOG.md +695 -0
  2. package/LICENSE.md +30 -0
  3. package/README.md +27 -0
  4. package/dist/auth.d.ts +181 -0
  5. package/dist/auth.d.ts.map +1 -0
  6. package/dist/auth.js +505 -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 +140 -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 +245 -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 +156 -0
  18. package/dist/factory.d.ts.map +1 -0
  19. package/dist/factory.js +483 -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 +210 -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/factory-session.d.ts +12 -0
  32. package/dist/integrations/github/factory-session.d.ts.map +1 -0
  33. package/dist/integrations/github/factory-session.js +37 -0
  34. package/dist/integrations/github/factory-session.js.map +1 -0
  35. package/dist/integrations/github/integration.d.ts +191 -0
  36. package/dist/integrations/github/integration.d.ts.map +1 -0
  37. package/dist/integrations/github/integration.js +1077 -0
  38. package/dist/integrations/github/integration.js.map +1 -0
  39. package/dist/integrations/github/issue-triage.d.ts +27 -0
  40. package/dist/integrations/github/issue-triage.d.ts.map +1 -0
  41. package/dist/integrations/github/issue-triage.js +82 -0
  42. package/dist/integrations/github/issue-triage.js.map +1 -0
  43. package/dist/integrations/github/pat.d.ts +38 -0
  44. package/dist/integrations/github/pat.d.ts.map +1 -0
  45. package/dist/integrations/github/pat.js +59 -0
  46. package/dist/integrations/github/pat.js.map +1 -0
  47. package/dist/integrations/github/provenance.d.ts +27 -0
  48. package/dist/integrations/github/provenance.d.ts.map +1 -0
  49. package/dist/integrations/github/provenance.js +75 -0
  50. package/dist/integrations/github/provenance.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 +1324 -0
  54. package/dist/integrations/github/routes.js.map +1 -0
  55. package/dist/integrations/github/rules.d.ts +78 -0
  56. package/dist/integrations/github/rules.d.ts.map +1 -0
  57. package/dist/integrations/github/rules.js +362 -0
  58. package/dist/integrations/github/rules.js.map +1 -0
  59. package/dist/integrations/github/sandbox-release.d.ts +38 -0
  60. package/dist/integrations/github/sandbox-release.d.ts.map +1 -0
  61. package/dist/integrations/github/sandbox-release.js +74 -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 +87 -0
  80. package/dist/integrations/github/webhook.d.ts.map +1 -0
  81. package/dist/integrations/github/webhook.js +397 -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 +233 -0
  88. package/dist/integrations/linear/integration.d.ts.map +1 -0
  89. package/dist/integrations/linear/integration.js +672 -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 +239 -0
  94. package/dist/integrations/linear/routes.js.map +1 -0
  95. package/dist/integrations/linear/rules.d.ts +42 -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 +49 -0
  107. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
  108. package/dist/integrations/platform/github/event-worker.js +348 -0
  109. package/dist/integrations/platform/github/event-worker.js.map +1 -0
  110. package/dist/integrations/platform/github/integration.d.ts +50 -0
  111. package/dist/integrations/platform/github/integration.d.ts.map +1 -0
  112. package/dist/integrations/platform/github/integration.js +961 -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/workos/integration.d.ts +39 -0
  119. package/dist/integrations/workos/integration.d.ts.map +1 -0
  120. package/dist/integrations/workos/integration.js +91 -0
  121. package/dist/integrations/workos/integration.js.map +1 -0
  122. package/dist/routes/config.d.ts +235 -0
  123. package/dist/routes/config.d.ts.map +1 -0
  124. package/dist/routes/config.js +972 -0
  125. package/dist/routes/config.js.map +1 -0
  126. package/dist/routes/custom-provider-source.d.ts +52 -0
  127. package/dist/routes/custom-provider-source.d.ts.map +1 -0
  128. package/dist/routes/custom-provider-source.js +124 -0
  129. package/dist/routes/custom-provider-source.js.map +1 -0
  130. package/dist/routes/fs.d.ts +151 -0
  131. package/dist/routes/fs.d.ts.map +1 -0
  132. package/dist/routes/fs.js +708 -0
  133. package/dist/routes/fs.js.map +1 -0
  134. package/dist/routes/intake.d.ts +23 -0
  135. package/dist/routes/intake.d.ts.map +1 -0
  136. package/dist/routes/intake.js +179 -0
  137. package/dist/routes/intake.js.map +1 -0
  138. package/dist/routes/oauth.d.ts +43 -0
  139. package/dist/routes/oauth.d.ts.map +1 -0
  140. package/dist/routes/oauth.js +463 -0
  141. package/dist/routes/oauth.js.map +1 -0
  142. package/dist/routes/projects.d.ts +19 -0
  143. package/dist/routes/projects.d.ts.map +1 -0
  144. package/dist/routes/projects.js +461 -0
  145. package/dist/routes/projects.js.map +1 -0
  146. package/dist/routes/provider-credentials.d.ts +81 -0
  147. package/dist/routes/provider-credentials.d.ts.map +1 -0
  148. package/dist/routes/provider-credentials.js +86 -0
  149. package/dist/routes/provider-credentials.js.map +1 -0
  150. package/dist/routes/route.d.ts +48 -0
  151. package/dist/routes/route.d.ts.map +1 -0
  152. package/dist/routes/route.js +15 -0
  153. package/dist/routes/route.js.map +1 -0
  154. package/dist/routes/skills.d.ts +30 -0
  155. package/dist/routes/skills.d.ts.map +1 -0
  156. package/dist/routes/skills.js +168 -0
  157. package/dist/routes/skills.js.map +1 -0
  158. package/dist/routes/surface.d.ts +91 -0
  159. package/dist/routes/surface.d.ts.map +1 -0
  160. package/dist/routes/surface.js +260 -0
  161. package/dist/routes/surface.js.map +1 -0
  162. package/dist/routes/tenant-credentials.d.ts +74 -0
  163. package/dist/routes/tenant-credentials.d.ts.map +1 -0
  164. package/dist/routes/tenant-credentials.js +156 -0
  165. package/dist/routes/tenant-credentials.js.map +1 -0
  166. package/dist/routes/work-items.d.ts +40 -0
  167. package/dist/routes/work-items.d.ts.map +1 -0
  168. package/dist/routes/work-items.js +695 -0
  169. package/dist/routes/work-items.js.map +1 -0
  170. package/dist/rules/binding-context.d.ts +5 -0
  171. package/dist/rules/binding-context.d.ts.map +1 -0
  172. package/dist/rules/binding-context.js +28 -0
  173. package/dist/rules/binding-context.js.map +1 -0
  174. package/dist/rules/defaults.d.ts +9 -0
  175. package/dist/rules/defaults.d.ts.map +1 -0
  176. package/dist/rules/defaults.js +260 -0
  177. package/dist/rules/defaults.js.map +1 -0
  178. package/dist/rules/dispatcher.d.ts +42 -0
  179. package/dist/rules/dispatcher.d.ts.map +1 -0
  180. package/dist/rules/dispatcher.js +518 -0
  181. package/dist/rules/dispatcher.js.map +1 -0
  182. package/dist/rules/index.d.ts +7 -0
  183. package/dist/rules/index.d.ts.map +1 -0
  184. package/dist/rules/index.js +5 -0
  185. package/dist/rules/processor.d.ts +54 -0
  186. package/dist/rules/processor.d.ts.map +1 -0
  187. package/dist/rules/processor.js +378 -0
  188. package/dist/rules/processor.js.map +1 -0
  189. package/dist/rules/resolve.d.ts +17 -0
  190. package/dist/rules/resolve.d.ts.map +1 -0
  191. package/dist/rules/resolve.js +30 -0
  192. package/dist/rules/resolve.js.map +1 -0
  193. package/dist/rules/start-coordinator.d.ts +60 -0
  194. package/dist/rules/start-coordinator.d.ts.map +1 -0
  195. package/dist/rules/start-coordinator.js +194 -0
  196. package/dist/rules/start-coordinator.js.map +1 -0
  197. package/dist/rules/tools.d.ts +10 -0
  198. package/dist/rules/tools.d.ts.map +1 -0
  199. package/dist/rules/tools.js +58 -0
  200. package/dist/rules/tools.js.map +1 -0
  201. package/dist/rules/transition-service.d.ts +49 -0
  202. package/dist/rules/transition-service.d.ts.map +1 -0
  203. package/dist/rules/transition-service.js +232 -0
  204. package/dist/rules/transition-service.js.map +1 -0
  205. package/dist/rules/types.d.ts +234 -0
  206. package/dist/rules/types.d.ts.map +1 -0
  207. package/dist/rules/types.js +38 -0
  208. package/dist/rules/types.js.map +1 -0
  209. package/dist/rules/validation.d.ts +11 -0
  210. package/dist/rules/validation.d.ts.map +1 -0
  211. package/dist/rules/validation.js +308 -0
  212. package/dist/rules/validation.js.map +1 -0
  213. package/dist/sandbox/fleet.d.ts +222 -0
  214. package/dist/sandbox/fleet.d.ts.map +1 -0
  215. package/dist/sandbox/fleet.js +322 -0
  216. package/dist/sandbox/fleet.js.map +1 -0
  217. package/dist/sandbox/reattach.d.ts +3 -0
  218. package/dist/sandbox/reattach.d.ts.map +1 -0
  219. package/dist/sandbox/reattach.js +16 -0
  220. package/dist/sandbox/reattach.js.map +1 -0
  221. package/dist/server-error.d.ts +12 -0
  222. package/dist/server-error.d.ts.map +1 -0
  223. package/dist/server-error.js +16 -0
  224. package/dist/server-error.js.map +1 -0
  225. package/dist/skills/service.d.ts +48 -0
  226. package/dist/skills/service.d.ts.map +1 -0
  227. package/dist/skills/service.js +40 -0
  228. package/dist/skills/service.js.map +1 -0
  229. package/dist/spa-static.d.ts +33 -0
  230. package/dist/spa-static.d.ts.map +1 -0
  231. package/dist/spa-static.js +104 -0
  232. package/dist/spa-static.js.map +1 -0
  233. package/dist/state-signing.d.ts +59 -0
  234. package/dist/state-signing.d.ts.map +1 -0
  235. package/dist/state-signing.js +83 -0
  236. package/dist/state-signing.js.map +1 -0
  237. package/dist/storage/domains/audit/agent-audit.d.ts +27 -0
  238. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
  239. package/dist/storage/domains/audit/agent-audit.js +66 -0
  240. package/dist/storage/domains/audit/agent-audit.js.map +1 -0
  241. package/dist/storage/domains/audit/base.d.ts +140 -0
  242. package/dist/storage/domains/audit/base.d.ts.map +1 -0
  243. package/dist/storage/domains/audit/base.js +184 -0
  244. package/dist/storage/domains/audit/base.js.map +1 -0
  245. package/dist/storage/domains/audit/domain.d.ts +69 -0
  246. package/dist/storage/domains/audit/domain.d.ts.map +1 -0
  247. package/dist/storage/domains/audit/domain.js +167 -0
  248. package/dist/storage/domains/audit/domain.js.map +1 -0
  249. package/dist/storage/domains/channel-identity/base.d.ts +96 -0
  250. package/dist/storage/domains/channel-identity/base.d.ts.map +1 -0
  251. package/dist/storage/domains/channel-identity/base.js +149 -0
  252. package/dist/storage/domains/channel-identity/base.js.map +1 -0
  253. package/dist/storage/domains/credentials/base.d.ts +134 -0
  254. package/dist/storage/domains/credentials/base.d.ts.map +1 -0
  255. package/dist/storage/domains/credentials/base.js +273 -0
  256. package/dist/storage/domains/credentials/base.js.map +1 -0
  257. package/dist/storage/domains/custom-providers/base.d.ts +57 -0
  258. package/dist/storage/domains/custom-providers/base.d.ts.map +1 -0
  259. package/dist/storage/domains/custom-providers/base.js +145 -0
  260. package/dist/storage/domains/custom-providers/base.js.map +1 -0
  261. package/dist/storage/domains/intake/base.d.ts +38 -0
  262. package/dist/storage/domains/intake/base.d.ts.map +1 -0
  263. package/dist/storage/domains/intake/base.js +80 -0
  264. package/dist/storage/domains/intake/base.js.map +1 -0
  265. package/dist/storage/domains/integrations/base.d.ts +126 -0
  266. package/dist/storage/domains/integrations/base.d.ts.map +1 -0
  267. package/dist/storage/domains/integrations/base.js +317 -0
  268. package/dist/storage/domains/integrations/base.js.map +1 -0
  269. package/dist/storage/domains/memory-settings/base.d.ts +62 -0
  270. package/dist/storage/domains/memory-settings/base.d.ts.map +1 -0
  271. package/dist/storage/domains/memory-settings/base.js +126 -0
  272. package/dist/storage/domains/memory-settings/base.js.map +1 -0
  273. package/dist/storage/domains/model-packs/base.d.ts +49 -0
  274. package/dist/storage/domains/model-packs/base.d.ts.map +1 -0
  275. package/dist/storage/domains/model-packs/base.js +96 -0
  276. package/dist/storage/domains/model-packs/base.js.map +1 -0
  277. package/dist/storage/domains/projects/base.d.ts +58 -0
  278. package/dist/storage/domains/projects/base.d.ts.map +1 -0
  279. package/dist/storage/domains/projects/base.js +111 -0
  280. package/dist/storage/domains/projects/base.js.map +1 -0
  281. package/dist/storage/domains/queue-health/base.d.ts +52 -0
  282. package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
  283. package/dist/storage/domains/queue-health/base.js +122 -0
  284. package/dist/storage/domains/queue-health/base.js.map +1 -0
  285. package/dist/storage/domains/source-control/base.d.ts +358 -0
  286. package/dist/storage/domains/source-control/base.d.ts.map +1 -0
  287. package/dist/storage/domains/source-control/base.js +908 -0
  288. package/dist/storage/domains/source-control/base.js.map +1 -0
  289. package/dist/storage/domains/source-control/inmemory.d.ts +175 -0
  290. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
  291. package/dist/storage/domains/source-control/inmemory.js +377 -0
  292. package/dist/storage/domains/source-control/inmemory.js.map +1 -0
  293. package/dist/storage/domains/work-items/base.d.ts +412 -0
  294. package/dist/storage/domains/work-items/base.d.ts.map +1 -0
  295. package/dist/storage/domains/work-items/base.js +1309 -0
  296. package/dist/storage/domains/work-items/base.js.map +1 -0
  297. package/dist/storage/domains/work-items/metrics.d.ts +101 -0
  298. package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
  299. package/dist/storage/domains/work-items/metrics.js +221 -0
  300. package/dist/storage/domains/work-items/metrics.js.map +1 -0
  301. package/dist/timing.d.ts +15 -0
  302. package/dist/timing.d.ts.map +1 -0
  303. package/dist/timing.js +34 -0
  304. package/dist/timing.js.map +1 -0
  305. package/dist/workspace.d.ts +24 -0
  306. package/dist/workspace.d.ts.map +1 -0
  307. package/dist/workspace.js +286 -0
  308. package/dist/workspace.js.map +1 -0
  309. package/factory-skills/configure-factory-rules/SKILL.md +67 -0
  310. package/factory-skills/factory-plan/SKILL.md +61 -0
  311. package/factory-skills/factory-review/SKILL.md +155 -0
  312. package/factory-skills/factory-triage/SKILL.md +77 -0
  313. package/package.json +81 -0
@@ -0,0 +1,54 @@
1
+ import type { MastraDBMessage, MessageList } from '@mastra/core/agent/message-list';
2
+ import type { ComputeStateSignalArgs, ComputeStateSignalResult, ProcessInputStepArgs, Processor } from '@mastra/core/processors';
3
+ import type { FactoryRunBindingRecord, WorkItemsStorage, WorkItemRow } from '../storage/domains/work-items/base.js';
4
+ import type { FactoryTransitionService } from './transition-service.js';
5
+ import type { FactoryRuleJsonValue, FactoryRules } from './types.js';
6
+ type PersistedMessageReader = {
7
+ listMessages(input: {
8
+ threadId: string;
9
+ resourceId?: string;
10
+ page: number;
11
+ perPage: number;
12
+ filter?: {
13
+ dateRange?: {
14
+ start?: Date;
15
+ };
16
+ };
17
+ orderBy: {
18
+ field: 'createdAt';
19
+ direction: 'ASC';
20
+ };
21
+ }): Promise<{
22
+ messages: MastraDBMessage[];
23
+ hasMore: boolean;
24
+ }>;
25
+ };
26
+ export declare class FactoryPhaseStateProcessor implements Processor<'factory-phase'> {
27
+ private readonly options;
28
+ readonly id = "factory-phase";
29
+ readonly stateId = "factory-phase";
30
+ constructor(options: {
31
+ rules: FactoryRules;
32
+ storage: WorkItemsStorage;
33
+ transitionService?: Pick<FactoryTransitionService, 'transition'>;
34
+ messageReader?: PersistedMessageReader;
35
+ recordPullRequestProvenance?: (input: {
36
+ binding: FactoryRunBindingRecord;
37
+ item: WorkItemRow;
38
+ assistantMessageId: string;
39
+ toolCallId: string;
40
+ toolName: string;
41
+ toolInput: FactoryRuleJsonValue;
42
+ toolResult: FactoryRuleJsonValue;
43
+ status: 'success' | 'error';
44
+ }) => Promise<void>;
45
+ });
46
+ processInputStep(args: ProcessInputStepArgs): Promise<MessageList | undefined>;
47
+ computeStateSignal(args: ComputeStateSignalArgs): Promise<ComputeStateSignalResult>;
48
+ reconcileAllBoundThreads(): Promise<void>;
49
+ reconcileBinding(binding: FactoryRunBindingRecord): Promise<void>;
50
+ private ingestMessages;
51
+ private ingestToolResult;
52
+ }
53
+ export {};
54
+ //# sourceMappingURL=processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/rules/processor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,KAAK,EACV,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,SAAS,EACV,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGpH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,KAAK,EAIV,oBAAoB,EACpB,YAAY,EAEb,MAAM,YAAY,CAAC;AAiBpB,KAAK,sBAAsB,GAAG;IAC5B,YAAY,CAAC,KAAK,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE;YAAE,SAAS,CAAC,EAAE;gBAAE,KAAK,CAAC,EAAE,IAAI,CAAA;aAAE,CAAA;SAAE,CAAC;QAC1C,OAAO,EAAE;YAAE,KAAK,EAAE,WAAW,CAAC;YAAC,SAAS,EAAE,KAAK,CAAA;SAAE,CAAC;KACnD,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AA6JF,qBAAa,0BAA2B,YAAW,SAAS,CAAC,eAAe,CAAC;IAKzE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,QAAQ,CAAC,EAAE,mBAAY;IACvB,QAAQ,CAAC,OAAO,mBAAY;gBAGT,OAAO,EAAE;QACxB,KAAK,EAAE,YAAY,CAAC;QACpB,OAAO,EAAE,gBAAgB,CAAC;QAC1B,iBAAiB,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,CAAC;QACjE,aAAa,CAAC,EAAE,sBAAsB,CAAC;QACvC,2BAA2B,CAAC,EAAE,CAAC,KAAK,EAAE;YACpC,OAAO,EAAE,uBAAuB,CAAC;YACjC,IAAI,EAAE,WAAW,CAAC;YAClB,kBAAkB,EAAE,MAAM,CAAC;YAC3B,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,EAAE,oBAAoB,CAAC;YAChC,UAAU,EAAE,oBAAoB,CAAC;YACjC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;SAC7B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB;IAGG,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAY9E,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAqEnF,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzC,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YA+BzD,cAAc;YA6Bd,gBAAgB;CAiG/B"}
@@ -0,0 +1,378 @@
1
+ import { resolveFactoryToolRule } from "./resolve.js";
2
+ import { FACTORY_RULE_STAGES } from "./types.js";
3
+ import { normalizeFactoryRuleJsonValue, validateFactoryRuleDecisions } from "./validation.js";
4
+ import { getFactorySessionCoordinates } from "./binding-context.js";
5
+ import { createHash } from "crypto";
6
+ //#region src/rules/processor.ts
7
+ const STATE_ID = "factory-phase";
8
+ const RULE_TIMEOUT_MS = 5e3;
9
+ const TRANSCRIPT_PAGE_SIZE = 50;
10
+ const MAX_LINKED_ITEMS = 5;
11
+ const PHASE_LABELS = {
12
+ intake: "Intake",
13
+ triage: "Investigating",
14
+ planning: "Planning",
15
+ execute: "Building",
16
+ review: "Reviewing",
17
+ done: "Done",
18
+ canceled: "Canceled"
19
+ };
20
+ function workItemSource(item) {
21
+ if (!item.externalSource) return "manual";
22
+ if (item.externalSource.integrationId === "linear") return "linear-issue";
23
+ if (item.externalSource.integrationId !== "github") return "manual";
24
+ return item.externalSource.type === "pull-request" ? "github-pr" : "github-issue";
25
+ }
26
+ function workItemSourceKey(item) {
27
+ const source = item.externalSource;
28
+ return source ? `${source.integrationId}:${source.type}:${source.externalId}` : null;
29
+ }
30
+ function boardForItem(item) {
31
+ return item.externalSource?.type === "pull-request" ? "review" : "work";
32
+ }
33
+ function boundedError(value) {
34
+ return { message: (value instanceof Error ? value.message : typeof value === "string" ? value : "Tool execution failed.").slice(0, 2e3) };
35
+ }
36
+ function boundedResult(value) {
37
+ try {
38
+ return normalizeFactoryRuleJsonValue(value);
39
+ } catch {
40
+ return { message: "Tool result was not serializable." };
41
+ }
42
+ }
43
+ function messageParts(message) {
44
+ const content = message.content;
45
+ if (Array.isArray(content)) return content;
46
+ if (Array.isArray(content?.parts)) return content.parts;
47
+ return Array.isArray(content?.toolInvocations) ? content.toolInvocations : [];
48
+ }
49
+ function completedStepToolCallIds(steps) {
50
+ const ids = /* @__PURE__ */ new Set();
51
+ for (const rawStep of steps) {
52
+ if (!rawStep || typeof rawStep !== "object") continue;
53
+ const toolResults = rawStep.toolResults;
54
+ if (!Array.isArray(toolResults)) continue;
55
+ for (const rawResult of toolResults) {
56
+ if (!rawResult || typeof rawResult !== "object") continue;
57
+ const toolCallId = rawResult.toolCallId;
58
+ if (typeof toolCallId === "string") ids.add(toolCallId);
59
+ }
60
+ }
61
+ return ids;
62
+ }
63
+ function completedToolResults(message) {
64
+ if (message.role !== "assistant") return [];
65
+ const createdAt = message.createdAt instanceof Date ? message.createdAt : new Date(message.createdAt);
66
+ const completed = [];
67
+ for (const rawPart of messageParts(message)) {
68
+ if (!rawPart || typeof rawPart !== "object") continue;
69
+ const part = rawPart;
70
+ const invocation = part.type === "tool-invocation" && part.toolInvocation && typeof part.toolInvocation === "object" ? part.toolInvocation : part;
71
+ const state = invocation.state;
72
+ if (state !== "result" && state !== "error") continue;
73
+ const toolCallId = invocation.toolCallId;
74
+ const toolName = invocation.toolName ?? invocation.name;
75
+ if (typeof toolCallId !== "string" || typeof toolName !== "string") continue;
76
+ completed.push({
77
+ assistantMessageId: message.id,
78
+ messageCreatedAt: createdAt,
79
+ toolCallId,
80
+ toolName: toolName.slice(0, 256),
81
+ input: boundedResult(invocation.args ?? {}),
82
+ status: state === "error" ? "error" : "success",
83
+ value: state === "error" ? boundedError(invocation.result ?? invocation.error) : boundedResult(invocation.result)
84
+ });
85
+ }
86
+ return completed;
87
+ }
88
+ function currentCompletedToolMessage(messages, toolCallIds) {
89
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
90
+ const message = messages[index];
91
+ if (completedToolResults(message).some((result) => toolCallIds.has(result.toolCallId))) return message;
92
+ }
93
+ }
94
+ function phaseCacheKey(value, linked) {
95
+ return createHash("sha256").update(JSON.stringify({
96
+ ...value,
97
+ linked: linked.map((item) => [
98
+ item.id,
99
+ item.revision,
100
+ item.stages[0]
101
+ ])
102
+ })).digest("hex");
103
+ }
104
+ function escapeText(value) {
105
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
106
+ }
107
+ function phaseFromSignal(signal) {
108
+ return (signal?.metadata?.value)?.phase;
109
+ }
110
+ function latestPhase(args) {
111
+ for (const signal of [...args.activeStateSignals].reverse()) {
112
+ const phase = phaseFromSignal(signal);
113
+ if (phase) return phase;
114
+ }
115
+ return phaseFromSignal(args.lastSnapshot);
116
+ }
117
+ async function withRuleTimeout(operation) {
118
+ let timer;
119
+ try {
120
+ return await Promise.race([operation, new Promise((_, reject) => {
121
+ timer = setTimeout(() => reject(/* @__PURE__ */ new Error("FACTORY_RULE_TIMEOUT")), RULE_TIMEOUT_MS);
122
+ })]);
123
+ } finally {
124
+ if (timer) clearTimeout(timer);
125
+ }
126
+ }
127
+ var FactoryPhaseStateProcessor = class {
128
+ options;
129
+ id = STATE_ID;
130
+ stateId = STATE_ID;
131
+ constructor(options) {
132
+ this.options = options;
133
+ }
134
+ async processInputStep(args) {
135
+ const address = getFactorySessionCoordinates(args.requestContext);
136
+ if (!address) return;
137
+ const binding = await this.options.storage.findRunBindingBySession(address);
138
+ if (!binding || binding.status !== "active") return;
139
+ const completedToolCallIds = completedStepToolCallIds(args.steps);
140
+ const completedMessage = currentCompletedToolMessage(args.messages, completedToolCallIds);
141
+ if (completedMessage) await this.ingestMessages(binding, [completedMessage], completedToolCallIds);
142
+ }
143
+ async computeStateSignal(args) {
144
+ const address = getFactorySessionCoordinates(args.requestContext);
145
+ if (!address) return;
146
+ const binding = await this.options.storage.findRunBindingBySession(address);
147
+ const prior = latestPhase(args);
148
+ const hasBase = Boolean(args.lastSnapshot) && args.contextWindow.hasSnapshot;
149
+ if (!binding) return;
150
+ if (binding.status !== "active") {
151
+ if (!hasBase || prior?.status !== "active") return;
152
+ return {
153
+ id: STATE_ID,
154
+ cacheKey: `factory:none:${prior.bindingId ?? "revoked"}`,
155
+ mode: "snapshot",
156
+ tagName: "factory-phase",
157
+ contents: "\n",
158
+ value: { phase: { status: "none" } },
159
+ attributes: { status: "none" },
160
+ metadata: { value: { phase: { status: "none" } } }
161
+ };
162
+ }
163
+ const item = await this.options.storage.get({
164
+ orgId: binding.orgId,
165
+ id: binding.workItemId
166
+ });
167
+ if (!item || item.stages.length !== 1 || !FACTORY_RULE_STAGES.includes(item.stages[0])) return;
168
+ const linked = (await this.options.storage.list({
169
+ orgId: binding.orgId,
170
+ factoryProjectId: binding.factoryProjectId
171
+ })).filter((candidate) => candidate.parentWorkItemId === item.id || item.parentWorkItemId === candidate.id).slice(0, MAX_LINKED_ITEMS);
172
+ const board = boardForItem(item);
173
+ const stage = item.stages[0];
174
+ const value = {
175
+ status: "active",
176
+ bindingId: binding.id,
177
+ itemId: item.id,
178
+ revision: item.revision,
179
+ stage,
180
+ role: binding.role,
181
+ board,
182
+ ruleSetVersion: this.options.rules.version
183
+ };
184
+ const cacheKey = phaseCacheKey(value, linked);
185
+ if (hasBase && (args.tracking?.currentCacheKey ?? args.lastSnapshot?.metadata?.state?.cacheKey) === cacheKey) return;
186
+ const linkedText = linked.length ? `\nLinked items: ${linked.map((candidate) => `${workItemSource(candidate)} ${candidate.title}`).join("; ")}` : "";
187
+ const snapshotContents = `Factory ${board} phase: ${PHASE_LABELS[stage]} (${escapeText(stage)})\nWork item: ${escapeText(item.title)} (${item.id})\nRole: ${escapeText(binding.role)}\nRevision: ${item.revision}\nRules: ${escapeText(this.options.rules.version)}\nUse factory_transition_work_item with expectedRevision ${item.revision} to request a phase change.${escapeText(linkedText)}`;
188
+ const isDelta = hasBase && prior?.status === "active";
189
+ return {
190
+ id: STATE_ID,
191
+ cacheKey,
192
+ mode: isDelta ? "delta" : "snapshot",
193
+ tagName: "factory-phase",
194
+ contents: isDelta ? `Factory phase update:\n${snapshotContents}` : snapshotContents,
195
+ value: { phase: value },
196
+ ...isDelta ? { delta: { phase: value } } : {},
197
+ attributes: {
198
+ status: "active",
199
+ board,
200
+ stage,
201
+ role: binding.role,
202
+ revision: item.revision
203
+ },
204
+ metadata: { value: { phase: value } }
205
+ };
206
+ }
207
+ async reconcileAllBoundThreads() {
208
+ if (!this.options.messageReader) return;
209
+ const bindings = await this.options.storage.listActiveRunBindings();
210
+ for (const binding of bindings) await this.reconcileBinding(binding);
211
+ }
212
+ async reconcileBinding(binding) {
213
+ const reader = this.options.messageReader;
214
+ if (!reader || binding.status !== "active") return;
215
+ const cursor = await this.options.storage.getToolResultCursor(binding.orgId, binding.factoryProjectId, binding.id);
216
+ let page = 0;
217
+ while (true) {
218
+ const result = await reader.listMessages({
219
+ threadId: binding.threadId,
220
+ resourceId: binding.resourceId,
221
+ page,
222
+ perPage: TRANSCRIPT_PAGE_SIZE,
223
+ ...cursor ? { filter: { dateRange: { start: cursor.lastMessageCreatedAt } } } : {},
224
+ orderBy: {
225
+ field: "createdAt",
226
+ direction: "ASC"
227
+ }
228
+ });
229
+ await this.ingestMessages(binding, result.messages);
230
+ const last = result.messages.at(-1);
231
+ if (last) await this.options.storage.advanceToolResultCursor({
232
+ bindingId: binding.id,
233
+ orgId: binding.orgId,
234
+ factoryProjectId: binding.factoryProjectId,
235
+ lastMessageId: last.id,
236
+ lastMessageCreatedAt: last.createdAt instanceof Date ? last.createdAt : new Date(last.createdAt),
237
+ updatedAt: /* @__PURE__ */ new Date()
238
+ });
239
+ if (!result.hasMore) break;
240
+ page += 1;
241
+ }
242
+ }
243
+ async ingestMessages(binding, messages, toolCallIds) {
244
+ const item = await this.options.storage.get({
245
+ orgId: binding.orgId,
246
+ id: binding.workItemId
247
+ });
248
+ if (!item || item.stages.length !== 1 || !FACTORY_RULE_STAGES.includes(item.stages[0])) return;
249
+ for (const message of messages) for (const toolResult of completedToolResults(message)) {
250
+ if (toolCallIds && !toolCallIds.has(toolResult.toolCallId)) continue;
251
+ try {
252
+ await this.options.recordPullRequestProvenance?.({
253
+ binding,
254
+ item,
255
+ assistantMessageId: toolResult.assistantMessageId,
256
+ toolCallId: toolResult.toolCallId,
257
+ toolName: toolResult.toolName,
258
+ toolInput: toolResult.input,
259
+ toolResult: toolResult.value,
260
+ status: toolResult.status
261
+ });
262
+ } catch {}
263
+ await this.ingestToolResult(binding, item, toolResult);
264
+ }
265
+ }
266
+ async ingestToolResult(binding, item, toolResult) {
267
+ const rule = resolveFactoryToolRule(this.options.rules, toolResult.toolName);
268
+ if (!rule) return;
269
+ const ingressId = JSON.stringify([
270
+ binding.id,
271
+ binding.threadId,
272
+ toolResult.assistantMessageId,
273
+ toolResult.toolCallId
274
+ ]);
275
+ if (await this.options.storage.getTransitionResultByIngress(binding.orgId, binding.factoryProjectId, ingressId)) return;
276
+ const board = boardForItem(item);
277
+ const context = {
278
+ tenant: {
279
+ orgId: binding.orgId,
280
+ projectId: binding.factoryProjectId
281
+ },
282
+ actor: {
283
+ type: "agent",
284
+ bindingId: binding.id,
285
+ role: binding.role
286
+ },
287
+ ingress: {
288
+ type: "toolResult",
289
+ id: ingressId
290
+ },
291
+ cause: `Completed ${toolResult.toolName}`,
292
+ causalChain: [],
293
+ ruleSetVersion: this.options.rules.version,
294
+ item: {
295
+ id: item.id,
296
+ source: workItemSource(item),
297
+ sourceKey: workItemSourceKey(item),
298
+ parentWorkItemId: item.parentWorkItemId,
299
+ title: item.title,
300
+ url: item.externalSource?.url ?? null,
301
+ stages: item.stages
302
+ },
303
+ board,
304
+ itemRevision: item.revision,
305
+ toolName: toolResult.toolName,
306
+ threadId: binding.threadId,
307
+ assistantMessageId: toolResult.assistantMessageId,
308
+ toolCallId: toolResult.toolCallId,
309
+ result: {
310
+ status: toolResult.status,
311
+ value: toolResult.value
312
+ }
313
+ };
314
+ let decision = void 0;
315
+ let decisions = [];
316
+ let outcome = { status: "accepted" };
317
+ try {
318
+ decision = await withRuleTimeout(Promise.resolve(rule(Object.freeze(context))));
319
+ if (decision?.type === "reject") outcome = {
320
+ status: "rejected",
321
+ code: decision.code,
322
+ reason: decision.reason
323
+ };
324
+ else if (decision) decisions = validateFactoryRuleDecisions([decision]);
325
+ } catch (error) {
326
+ const timedOut = error instanceof Error && error.message === "FACTORY_RULE_TIMEOUT";
327
+ outcome = {
328
+ status: "rejected",
329
+ code: timedOut ? "timeout" : "rule_error",
330
+ reason: timedOut ? "Factory rule evaluation timed out." : error instanceof Error ? error.message.slice(0, 2e3) : "Factory tool-result rule failed."
331
+ };
332
+ }
333
+ if ((await this.options.storage.commitRuleEvaluation({
334
+ orgId: binding.orgId,
335
+ factoryProjectId: binding.factoryProjectId,
336
+ workItemId: item.id,
337
+ ingress: {
338
+ identity: ingressId,
339
+ triggerType: "tool.result"
340
+ },
341
+ ruleSetVersion: this.options.rules.version,
342
+ expectedRevision: item.revision,
343
+ actor: { ...context.actor },
344
+ outcome,
345
+ decisions: decisions.map((entry) => ({ ...entry })),
346
+ causalChain: [],
347
+ now: /* @__PURE__ */ new Date()
348
+ })).status !== "committed" || !this.options.transitionService) return;
349
+ for (const entry of decisions) {
350
+ if (entry.type !== "transition") continue;
351
+ await this.options.transitionService.transition({
352
+ orgId: binding.orgId,
353
+ factoryProjectId: binding.factoryProjectId,
354
+ workItemId: item.id,
355
+ board: entry.board,
356
+ stage: entry.stage,
357
+ expectedRevision: item.revision,
358
+ actor: {
359
+ type: "system",
360
+ id: "factory-tool-result-rule"
361
+ },
362
+ ingress: {
363
+ type: "rule",
364
+ identity: `decision:${entry.idempotencyKey}`
365
+ },
366
+ cause: "tool_result_rule",
367
+ causalChain: [{
368
+ ingressId,
369
+ decisionType: entry.type
370
+ }]
371
+ });
372
+ }
373
+ }
374
+ };
375
+ //#endregion
376
+ export { FactoryPhaseStateProcessor };
377
+
378
+ //# sourceMappingURL=processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.js","names":[],"sources":["../../src/rules/processor.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport type { MastraDBMessage, MessageList } from '@mastra/core/agent/message-list';\nimport type {\n ComputeStateSignalArgs,\n ComputeStateSignalResult,\n ProcessInputStepArgs,\n Processor,\n} from '@mastra/core/processors';\n\nimport type { FactoryRunBindingRecord, WorkItemsStorage, WorkItemRow } from '../storage/domains/work-items/base.js';\nimport { getFactorySessionCoordinates } from './binding-context.js';\nimport { resolveFactoryToolRule } from './resolve.js';\nimport type { FactoryTransitionService } from './transition-service.js';\nimport { FACTORY_RULE_STAGES } from './types.js';\nimport type {\n FactoryCommitDecision,\n FactoryRuleBoard,\n FactoryRuleDecision,\n FactoryRuleJsonValue,\n FactoryRules,\n FactoryToolResultRuleContext,\n} from './types.js';\nimport { normalizeFactoryRuleJsonValue, validateFactoryRuleDecisions } from './validation.js';\n\nconst STATE_ID = 'factory-phase';\nconst RULE_TIMEOUT_MS = 5_000;\nconst TRANSCRIPT_PAGE_SIZE = 50;\nconst MAX_LINKED_ITEMS = 5;\nconst PHASE_LABELS: Record<(typeof FACTORY_RULE_STAGES)[number], string> = {\n intake: 'Intake',\n triage: 'Investigating',\n planning: 'Planning',\n execute: 'Building',\n review: 'Reviewing',\n done: 'Done',\n canceled: 'Canceled',\n};\n\ntype PersistedMessageReader = {\n listMessages(input: {\n threadId: string;\n resourceId?: string;\n page: number;\n perPage: number;\n filter?: { dateRange?: { start?: Date } };\n orderBy: { field: 'createdAt'; direction: 'ASC' };\n }): Promise<{ messages: MastraDBMessage[]; hasMore: boolean }>;\n};\n\ntype CompletedToolResult = {\n assistantMessageId: string;\n messageCreatedAt: Date;\n toolCallId: string;\n toolName: string;\n input: FactoryRuleJsonValue;\n status: 'success' | 'error';\n value: FactoryRuleJsonValue;\n};\n\ntype PhaseSnapshotValue = {\n bindingId?: string;\n itemId?: string;\n revision?: number;\n stage?: string;\n role?: string;\n board?: FactoryRuleBoard;\n ruleSetVersion?: string;\n status: 'active' | 'none';\n};\n\nfunction workItemSource(item: WorkItemRow) {\n if (!item.externalSource) return 'manual' as const;\n if (item.externalSource.integrationId === 'linear') return 'linear-issue' as const;\n // See transition-service: non-GitHub, non-Linear provenance (Slack threads)\n // is a plain work item, not a GitHub issue.\n if (item.externalSource.integrationId !== 'github') return 'manual' as const;\n return item.externalSource.type === 'pull-request' ? ('github-pr' as const) : ('github-issue' as const);\n}\n\nfunction workItemSourceKey(item: WorkItemRow): string | null {\n const source = item.externalSource;\n return source ? `${source.integrationId}:${source.type}:${source.externalId}` : null;\n}\n\nfunction boardForItem(item: WorkItemRow): FactoryRuleBoard {\n return item.externalSource?.type === 'pull-request' ? 'review' : 'work';\n}\n\nfunction boundedError(value: unknown): FactoryRuleJsonValue {\n const message = value instanceof Error ? value.message : typeof value === 'string' ? value : 'Tool execution failed.';\n return { message: message.slice(0, 2_000) };\n}\n\nfunction boundedResult(value: unknown): FactoryRuleJsonValue {\n try {\n return normalizeFactoryRuleJsonValue(value);\n } catch {\n return { message: 'Tool result was not serializable.' };\n }\n}\n\nfunction messageParts(message: MastraDBMessage): unknown[] {\n const content = message.content as { parts?: unknown[]; toolInvocations?: unknown[] } | unknown[] | undefined;\n if (Array.isArray(content)) return content;\n if (Array.isArray(content?.parts)) return content.parts;\n return Array.isArray(content?.toolInvocations) ? content.toolInvocations : [];\n}\n\nfunction completedStepToolCallIds(steps: unknown[]): Set<string> {\n const ids = new Set<string>();\n for (const rawStep of steps) {\n if (!rawStep || typeof rawStep !== 'object') continue;\n const toolResults = (rawStep as { toolResults?: unknown[] }).toolResults;\n if (!Array.isArray(toolResults)) continue;\n for (const rawResult of toolResults) {\n if (!rawResult || typeof rawResult !== 'object') continue;\n const toolCallId = (rawResult as { toolCallId?: unknown }).toolCallId;\n if (typeof toolCallId === 'string') ids.add(toolCallId);\n }\n }\n return ids;\n}\n\nfunction completedToolResults(message: MastraDBMessage): CompletedToolResult[] {\n if (message.role !== 'assistant') return [];\n const createdAt = message.createdAt instanceof Date ? message.createdAt : new Date(message.createdAt);\n const completed: CompletedToolResult[] = [];\n for (const rawPart of messageParts(message)) {\n if (!rawPart || typeof rawPart !== 'object') continue;\n const part = rawPart as Record<string, unknown>;\n const invocation =\n part.type === 'tool-invocation' && part.toolInvocation && typeof part.toolInvocation === 'object'\n ? (part.toolInvocation as Record<string, unknown>)\n : part;\n const state = invocation.state;\n if (state !== 'result' && state !== 'error') continue;\n const toolCallId = invocation.toolCallId;\n const toolName = invocation.toolName ?? invocation.name;\n if (typeof toolCallId !== 'string' || typeof toolName !== 'string') continue;\n completed.push({\n assistantMessageId: message.id,\n messageCreatedAt: createdAt,\n toolCallId,\n toolName: toolName.slice(0, 256),\n input: boundedResult(invocation.args ?? {}),\n status: state === 'error' ? 'error' : 'success',\n value: state === 'error' ? boundedError(invocation.result ?? invocation.error) : boundedResult(invocation.result),\n });\n }\n return completed;\n}\n\nfunction currentCompletedToolMessage(\n messages: MastraDBMessage[],\n toolCallIds: ReadonlySet<string>,\n): MastraDBMessage | undefined {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index]!;\n if (completedToolResults(message).some(result => toolCallIds.has(result.toolCallId))) return message;\n }\n return undefined;\n}\n\nfunction phaseCacheKey(value: Omit<PhaseSnapshotValue, 'status'>, linked: WorkItemRow[]): string {\n return createHash('sha256')\n .update(\n JSON.stringify({\n ...value,\n linked: linked.map(item => [item.id, item.revision, item.stages[0]]),\n }),\n )\n .digest('hex');\n}\n\nfunction escapeText(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\n}\n\nfunction phaseFromSignal(signal: { metadata?: Record<string, unknown> } | undefined): PhaseSnapshotValue | undefined {\n return (signal?.metadata?.value as { phase?: PhaseSnapshotValue } | undefined)?.phase;\n}\n\nfunction latestPhase(args: ComputeStateSignalArgs): PhaseSnapshotValue | undefined {\n for (const signal of [...args.activeStateSignals].reverse()) {\n const phase = phaseFromSignal(signal);\n if (phase) return phase;\n }\n return phaseFromSignal(args.lastSnapshot);\n}\n\nasync function withRuleTimeout<T>(operation: Promise<T>): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), RULE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nexport class FactoryPhaseStateProcessor implements Processor<'factory-phase'> {\n readonly id = STATE_ID;\n readonly stateId = STATE_ID;\n\n constructor(\n private readonly options: {\n rules: FactoryRules;\n storage: WorkItemsStorage;\n transitionService?: Pick<FactoryTransitionService, 'transition'>;\n messageReader?: PersistedMessageReader;\n recordPullRequestProvenance?: (input: {\n binding: FactoryRunBindingRecord;\n item: WorkItemRow;\n assistantMessageId: string;\n toolCallId: string;\n toolName: string;\n toolInput: FactoryRuleJsonValue;\n toolResult: FactoryRuleJsonValue;\n status: 'success' | 'error';\n }) => Promise<void>;\n },\n ) {}\n\n async processInputStep(args: ProcessInputStepArgs): Promise<MessageList | undefined> {\n const address = getFactorySessionCoordinates(args.requestContext);\n if (!address) return;\n const binding = await this.options.storage.findRunBindingBySession(address);\n if (!binding || binding.status !== 'active') return;\n const completedToolCallIds = completedStepToolCallIds(args.steps);\n const completedMessage = currentCompletedToolMessage(args.messages, completedToolCallIds);\n if (completedMessage) {\n await this.ingestMessages(binding, [completedMessage], completedToolCallIds);\n }\n }\n\n async computeStateSignal(args: ComputeStateSignalArgs): Promise<ComputeStateSignalResult> {\n const address = getFactorySessionCoordinates(args.requestContext);\n if (!address) return;\n const binding = await this.options.storage.findRunBindingBySession(address);\n const prior = latestPhase(args);\n const hasBase = Boolean(args.lastSnapshot) && args.contextWindow.hasSnapshot;\n\n if (!binding) return;\n if (binding.status !== 'active') {\n if (!hasBase || prior?.status !== 'active') return;\n return {\n id: STATE_ID,\n cacheKey: `factory:none:${prior.bindingId ?? 'revoked'}`,\n mode: 'snapshot',\n tagName: 'factory-phase',\n contents: '\\n',\n value: { phase: { status: 'none' } },\n attributes: { status: 'none' },\n metadata: { value: { phase: { status: 'none' } } },\n };\n }\n\n const item = await this.options.storage.get({ orgId: binding.orgId, id: binding.workItemId });\n if (!item || item.stages.length !== 1 || !FACTORY_RULE_STAGES.includes(item.stages[0] as never)) return;\n const allItems = await this.options.storage.list({\n orgId: binding.orgId,\n factoryProjectId: binding.factoryProjectId,\n });\n const linked = allItems\n .filter(candidate => candidate.parentWorkItemId === item.id || item.parentWorkItemId === candidate.id)\n .slice(0, MAX_LINKED_ITEMS);\n const board = boardForItem(item);\n const stage = item.stages[0]!;\n const value: PhaseSnapshotValue = {\n status: 'active',\n bindingId: binding.id,\n itemId: item.id,\n revision: item.revision,\n stage,\n role: binding.role,\n board,\n ruleSetVersion: this.options.rules.version,\n };\n const cacheKey = phaseCacheKey(value, linked);\n if (hasBase && (args.tracking?.currentCacheKey ?? args.lastSnapshot?.metadata?.state?.cacheKey) === cacheKey)\n return;\n\n const linkedText = linked.length\n ? `\\nLinked items: ${linked.map(candidate => `${workItemSource(candidate)} ${candidate.title}`).join('; ')}`\n : '';\n const snapshotContents =\n `Factory ${board} phase: ${PHASE_LABELS[stage as keyof typeof PHASE_LABELS]} (${escapeText(stage)})\\n` +\n `Work item: ${escapeText(item.title)} (${item.id})\\n` +\n `Role: ${escapeText(binding.role)}\\nRevision: ${item.revision}\\nRules: ${escapeText(this.options.rules.version)}\\n` +\n `Use factory_transition_work_item with expectedRevision ${item.revision} to request a phase change.${escapeText(linkedText)}`;\n const isDelta = hasBase && prior?.status === 'active';\n return {\n id: STATE_ID,\n cacheKey,\n mode: isDelta ? 'delta' : 'snapshot',\n tagName: 'factory-phase',\n contents: isDelta ? `Factory phase update:\\n${snapshotContents}` : snapshotContents,\n value: { phase: value },\n ...(isDelta ? { delta: { phase: value } } : {}),\n attributes: { status: 'active', board, stage, role: binding.role, revision: item.revision },\n metadata: { value: { phase: value } },\n };\n }\n\n async reconcileAllBoundThreads(): Promise<void> {\n if (!this.options.messageReader) return;\n const bindings = await this.options.storage.listActiveRunBindings();\n for (const binding of bindings) await this.reconcileBinding(binding);\n }\n\n async reconcileBinding(binding: FactoryRunBindingRecord): Promise<void> {\n const reader = this.options.messageReader;\n if (!reader || binding.status !== 'active') return;\n const cursor = await this.options.storage.getToolResultCursor(binding.orgId, binding.factoryProjectId, binding.id);\n let page = 0;\n while (true) {\n const result = await reader.listMessages({\n threadId: binding.threadId,\n resourceId: binding.resourceId,\n page,\n perPage: TRANSCRIPT_PAGE_SIZE,\n ...(cursor ? { filter: { dateRange: { start: cursor.lastMessageCreatedAt } } } : {}),\n orderBy: { field: 'createdAt', direction: 'ASC' },\n });\n await this.ingestMessages(binding, result.messages);\n const last = result.messages.at(-1);\n if (last) {\n await this.options.storage.advanceToolResultCursor({\n bindingId: binding.id,\n orgId: binding.orgId,\n factoryProjectId: binding.factoryProjectId,\n lastMessageId: last.id,\n lastMessageCreatedAt: last.createdAt instanceof Date ? last.createdAt : new Date(last.createdAt),\n updatedAt: new Date(),\n });\n }\n if (!result.hasMore) break;\n page += 1;\n }\n }\n\n private async ingestMessages(\n binding: FactoryRunBindingRecord,\n messages: MastraDBMessage[],\n toolCallIds?: ReadonlySet<string>,\n ): Promise<void> {\n const item = await this.options.storage.get({ orgId: binding.orgId, id: binding.workItemId });\n if (!item || item.stages.length !== 1 || !FACTORY_RULE_STAGES.includes(item.stages[0] as never)) return;\n for (const message of messages) {\n for (const toolResult of completedToolResults(message)) {\n if (toolCallIds && !toolCallIds.has(toolResult.toolCallId)) continue;\n try {\n await this.options.recordPullRequestProvenance?.({\n binding,\n item,\n assistantMessageId: toolResult.assistantMessageId,\n toolCallId: toolResult.toolCallId,\n toolName: toolResult.toolName,\n toolInput: toolResult.input,\n toolResult: toolResult.value,\n status: toolResult.status,\n });\n } catch {\n // Provenance is supporting evidence and must not block authoritative rule ingress.\n }\n await this.ingestToolResult(binding, item, toolResult);\n }\n }\n }\n\n private async ingestToolResult(\n binding: FactoryRunBindingRecord,\n item: WorkItemRow,\n toolResult: CompletedToolResult,\n ): Promise<void> {\n const rule = resolveFactoryToolRule(this.options.rules, toolResult.toolName);\n if (!rule) return;\n const ingressId = JSON.stringify([\n binding.id,\n binding.threadId,\n toolResult.assistantMessageId,\n toolResult.toolCallId,\n ]);\n const prior = await this.options.storage.getTransitionResultByIngress(\n binding.orgId,\n binding.factoryProjectId,\n ingressId,\n );\n if (prior) return;\n const board = boardForItem(item);\n const context: FactoryToolResultRuleContext = {\n tenant: { orgId: binding.orgId, projectId: binding.factoryProjectId },\n actor: { type: 'agent', bindingId: binding.id, role: binding.role },\n ingress: { type: 'toolResult', id: ingressId },\n cause: `Completed ${toolResult.toolName}`,\n causalChain: [],\n ruleSetVersion: this.options.rules.version,\n item: {\n id: item.id,\n source: workItemSource(item),\n sourceKey: workItemSourceKey(item),\n parentWorkItemId: item.parentWorkItemId,\n title: item.title,\n url: item.externalSource?.url ?? null,\n stages: item.stages,\n },\n board,\n itemRevision: item.revision,\n toolName: toolResult.toolName,\n threadId: binding.threadId,\n assistantMessageId: toolResult.assistantMessageId,\n toolCallId: toolResult.toolCallId,\n result: { status: toolResult.status, value: toolResult.value },\n };\n\n let decision: FactoryRuleDecision | void = undefined;\n let decisions: FactoryCommitDecision[] = [];\n let outcome: { status: 'accepted' | 'rejected'; code?: string; reason?: string } = { status: 'accepted' };\n try {\n decision = await withRuleTimeout(Promise.resolve(rule(Object.freeze(context))));\n if (decision?.type === 'reject') {\n outcome = { status: 'rejected', code: decision.code, reason: decision.reason };\n } else if (decision) {\n decisions = validateFactoryRuleDecisions([decision]);\n }\n } catch (error) {\n const timedOut = error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT';\n outcome = {\n status: 'rejected',\n code: timedOut ? 'timeout' : 'rule_error',\n reason: timedOut\n ? 'Factory rule evaluation timed out.'\n : error instanceof Error\n ? error.message.slice(0, 2_000)\n : 'Factory tool-result rule failed.',\n };\n }\n const committed = await this.options.storage.commitRuleEvaluation({\n orgId: binding.orgId,\n factoryProjectId: binding.factoryProjectId,\n workItemId: item.id,\n ingress: { identity: ingressId, triggerType: 'tool.result' },\n ruleSetVersion: this.options.rules.version,\n expectedRevision: item.revision,\n actor: { ...context.actor },\n outcome,\n decisions: decisions.map(entry => ({ ...entry })),\n causalChain: [],\n now: new Date(),\n });\n if (committed.status !== 'committed' || !this.options.transitionService) return;\n for (const entry of decisions) {\n if (entry.type !== 'transition') continue;\n await this.options.transitionService.transition({\n orgId: binding.orgId,\n factoryProjectId: binding.factoryProjectId,\n workItemId: item.id,\n board: entry.board,\n stage: entry.stage,\n expectedRevision: item.revision,\n actor: { type: 'system', id: 'factory-tool-result-rule' },\n ingress: { type: 'rule', identity: `decision:${entry.idempotencyKey}` },\n cause: 'tool_result_rule',\n causalChain: [{ ingressId, decisionType: entry.type }],\n });\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FactoryGithubEventName, FactoryGithubRuleLeaf, FactoryLinearEventName, FactoryLinearRuleLeaf, FactoryRuleBoard, FactoryRuleHandler, FactoryRuleSource, FactoryRuleStage, FactoryRules, FactoryStageRuleContext, FactoryToolResultRuleContext, FactoryToolRuleLeaf } from './types.js';
2
+ export interface ResolvedFactoryStageRule {
3
+ phase: 'exit' | 'enter';
4
+ handler: FactoryRuleHandler<FactoryStageRuleContext>;
5
+ }
6
+ export declare function resolveFactoryStageRules(rules: FactoryRules, input: {
7
+ board: FactoryRuleBoard;
8
+ source: FactoryRuleSource;
9
+ fromStage: FactoryRuleStage;
10
+ toStage: FactoryRuleStage;
11
+ initialEntry?: boolean;
12
+ }): ResolvedFactoryStageRule[];
13
+ export declare function resolveFactoryToolRule(rules: FactoryRules, toolName: string): FactoryToolRuleLeaf['onResult'];
14
+ export declare function resolveFactoryGithubRule(rules: FactoryRules, event: FactoryGithubEventName): FactoryGithubRuleLeaf['onEvent'];
15
+ export declare function resolveFactoryLinearRule(rules: FactoryRules, event: FactoryLinearEventName): FactoryLinearRuleLeaf['onEvent'];
16
+ export type ResolvedFactoryToolRule = FactoryRuleHandler<FactoryToolResultRuleContext>;
17
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/rules/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;CACtD;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE;IACL,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GACA,wBAAwB,EAAE,CAS5B;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAE7G;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,sBAAsB,GAC5B,qBAAqB,CAAC,SAAS,CAAC,CAElC;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,sBAAsB,GAC5B,qBAAqB,CAAC,SAAS,CAAC,CAElC;AAED,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CAAC,4BAA4B,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ //#region src/rules/resolve.ts
2
+ function resolveFactoryStageRules(rules, input) {
3
+ if (input.fromStage === input.toStage && !input.initialEntry) return [];
4
+ const boardRules = rules[input.board];
5
+ const resolved = [];
6
+ const onExit = input.initialEntry ? void 0 : boardRules[input.fromStage]?.[input.source]?.onExit;
7
+ if (onExit) resolved.push({
8
+ phase: "exit",
9
+ handler: onExit
10
+ });
11
+ const onEnter = boardRules[input.toStage]?.[input.source]?.onEnter;
12
+ if (onEnter) resolved.push({
13
+ phase: "enter",
14
+ handler: onEnter
15
+ });
16
+ return resolved;
17
+ }
18
+ function resolveFactoryToolRule(rules, toolName) {
19
+ return rules.tools[toolName]?.onResult;
20
+ }
21
+ function resolveFactoryGithubRule(rules, event) {
22
+ return rules.github[event]?.onEvent;
23
+ }
24
+ function resolveFactoryLinearRule(rules, event) {
25
+ return rules.linear[event]?.onEvent;
26
+ }
27
+ //#endregion
28
+ export { resolveFactoryGithubRule, resolveFactoryLinearRule, resolveFactoryStageRules, resolveFactoryToolRule };
29
+
30
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","names":[],"sources":["../../src/rules/resolve.ts"],"sourcesContent":["import type {\n FactoryGithubEventName,\n FactoryGithubRuleLeaf,\n FactoryLinearEventName,\n FactoryLinearRuleLeaf,\n FactoryRuleBoard,\n FactoryRuleHandler,\n FactoryRuleSource,\n FactoryRuleStage,\n FactoryRules,\n FactoryStageRuleContext,\n FactoryToolResultRuleContext,\n FactoryToolRuleLeaf,\n} from './types.js';\n\nexport interface ResolvedFactoryStageRule {\n phase: 'exit' | 'enter';\n handler: FactoryRuleHandler<FactoryStageRuleContext>;\n}\n\nexport function resolveFactoryStageRules(\n rules: FactoryRules,\n input: {\n board: FactoryRuleBoard;\n source: FactoryRuleSource;\n fromStage: FactoryRuleStage;\n toStage: FactoryRuleStage;\n initialEntry?: boolean;\n },\n): ResolvedFactoryStageRule[] {\n if (input.fromStage === input.toStage && !input.initialEntry) return [];\n const boardRules = rules[input.board];\n const resolved: ResolvedFactoryStageRule[] = [];\n const onExit = input.initialEntry ? undefined : boardRules[input.fromStage]?.[input.source]?.onExit;\n if (onExit) resolved.push({ phase: 'exit', handler: onExit });\n const onEnter = boardRules[input.toStage]?.[input.source]?.onEnter;\n if (onEnter) resolved.push({ phase: 'enter', handler: onEnter });\n return resolved;\n}\n\nexport function resolveFactoryToolRule(rules: FactoryRules, toolName: string): FactoryToolRuleLeaf['onResult'] {\n return rules.tools[toolName]?.onResult;\n}\n\nexport function resolveFactoryGithubRule(\n rules: FactoryRules,\n event: FactoryGithubEventName,\n): FactoryGithubRuleLeaf['onEvent'] {\n return rules.github[event]?.onEvent;\n}\n\nexport function resolveFactoryLinearRule(\n rules: FactoryRules,\n event: FactoryLinearEventName,\n): FactoryLinearRuleLeaf['onEvent'] {\n return rules.linear[event]?.onEvent;\n}\n\nexport type ResolvedFactoryToolRule = FactoryRuleHandler<FactoryToolResultRuleContext>;\n"],"mappings":";AAoBA,SAAgB,yBACd,OACA,OAO4B;CAC5B,IAAI,MAAM,cAAc,MAAM,WAAW,CAAC,MAAM,cAAc,OAAO,CAAC;CACtE,MAAM,aAAa,MAAM,MAAM;CAC/B,MAAM,WAAuC,CAAC;CAC9C,MAAM,SAAS,MAAM,eAAe,KAAA,IAAY,WAAW,MAAM,UAAU,GAAG,MAAM,OAAO,EAAE;CAC7F,IAAI,QAAQ,SAAS,KAAK;EAAE,OAAO;EAAQ,SAAS;CAAO,CAAC;CAC5D,MAAM,UAAU,WAAW,MAAM,QAAQ,GAAG,MAAM,OAAO,EAAE;CAC3D,IAAI,SAAS,SAAS,KAAK;EAAE,OAAO;EAAS,SAAS;CAAQ,CAAC;CAC/D,OAAO;AACT;AAEA,SAAgB,uBAAuB,OAAqB,UAAmD;CAC7G,OAAO,MAAM,MAAM,SAAS,EAAE;AAChC;AAEA,SAAgB,yBACd,OACA,OACkC;CAClC,OAAO,MAAM,OAAO,MAAM,EAAE;AAC9B;AAEA,SAAgB,yBACd,OACA,OACkC;CAClC,OAAO,MAAM,OAAO,MAAM,EAAE;AAC9B"}
@@ -0,0 +1,60 @@
1
+ import type { MastraCodeState } from '@mastra/code-sdk/schema';
2
+ import type { AgentController } from '@mastra/core/agent-controller';
3
+ import { RequestContext } from '@mastra/core/request-context';
4
+ import type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';
5
+ import type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
6
+ import type { CreateWorkItemInput, WorkItemsStorage } from '../storage/domains/work-items/base.js';
7
+ import type { FactoryTransitionService } from './transition-service.js';
8
+ import type { FactoryRuleStage, FactoryTransitionResult } from './types.js';
9
+ export interface FactoryStartRequest {
10
+ orgId: string;
11
+ userId: string;
12
+ factoryProjectId: string;
13
+ sessionId: string;
14
+ threadTitle: string;
15
+ threadTags?: Record<string, string>;
16
+ kickoffKey: string;
17
+ invocation?: {
18
+ type: 'prompt';
19
+ prompt: string;
20
+ } | {
21
+ type: 'skill';
22
+ skillName: string;
23
+ arguments: string;
24
+ };
25
+ destinationStage: FactoryRuleStage;
26
+ defaultModelId?: string;
27
+ workItem: {
28
+ id?: string;
29
+ role: string;
30
+ input: CreateWorkItemInput;
31
+ };
32
+ requestContext?: RequestContext;
33
+ }
34
+ export declare class FactoryStartTransitionError extends Error {
35
+ readonly result: Extract<FactoryTransitionResult, {
36
+ status: 'rejected';
37
+ }>;
38
+ constructor(result: Extract<FactoryTransitionResult, {
39
+ status: 'rejected';
40
+ }>);
41
+ }
42
+ export interface FactoryStartPreparedResult {
43
+ workItemId: string;
44
+ bindingId: string;
45
+ threadId: string;
46
+ resourceId: string;
47
+ sessionId: string;
48
+ branch: string;
49
+ revision: number;
50
+ kickoffStatus: 'pending' | 'leased' | 'retry' | 'sent' | 'failed';
51
+ replayed: boolean;
52
+ }
53
+ type FactoryController = AgentController<MastraCodeState>;
54
+ export declare class FactoryStartCoordinator {
55
+ #private;
56
+ constructor(controller: FactoryController, storage: WorkItemsStorage, transitionService?: Pick<FactoryTransitionService, 'transition'>, sourceControl?: SourceControlStorageHandle, memorySettings?: MemorySettingsStorage);
57
+ prepare(request: FactoryStartRequest): Promise<FactoryStartPreparedResult>;
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=start-coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-coordinator.d.ts","sourceRoot":"","sources":["../../src/rules/start-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAC9G,OAAO,KAAK,EAAwB,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAClH,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,mBAAmB,CAAC;KAC5B,CAAC;IACF,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,uBAAuB,EAAE;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;gBAE9D,MAAM,EAAE,OAAO,CAAC,uBAAuB,EAAE;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;CAK7E;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,iBAAiB,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;AAiE1D,qBAAa,uBAAuB;;gBAQhC,UAAU,EAAE,iBAAiB,EAC7B,OAAO,EAAE,gBAAgB,EACzB,iBAAiB,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,EAChE,aAAa,CAAC,EAAE,0BAA0B,EAC1C,cAAc,CAAC,EAAE,qBAAqB;IASlC,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,0BAA0B,CAAC;CAsHjF"}