@mclawnet/swarm 0.1.13 → 0.1.15

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 (320) hide show
  1. package/dist/__tests__/always-on-activity-reader.test.d.ts +2 -0
  2. package/dist/__tests__/always-on-activity-reader.test.d.ts.map +1 -0
  3. package/dist/__tests__/always-on-activity-reader.test.js +193 -0
  4. package/dist/__tests__/always-on-activity-reader.test.js.map +1 -0
  5. package/dist/__tests__/always-on-config.test.d.ts +2 -0
  6. package/dist/__tests__/always-on-config.test.d.ts.map +1 -0
  7. package/dist/__tests__/always-on-config.test.js +285 -0
  8. package/dist/__tests__/always-on-config.test.js.map +1 -0
  9. package/dist/__tests__/always-on-manager.test.d.ts +2 -0
  10. package/dist/__tests__/always-on-manager.test.d.ts.map +1 -0
  11. package/dist/__tests__/always-on-manager.test.js +797 -0
  12. package/dist/__tests__/always-on-manager.test.js.map +1 -0
  13. package/dist/__tests__/always-on-parity.test.d.ts +2 -0
  14. package/dist/__tests__/always-on-parity.test.d.ts.map +1 -0
  15. package/dist/__tests__/always-on-parity.test.js +20 -0
  16. package/dist/__tests__/always-on-parity.test.js.map +1 -0
  17. package/dist/__tests__/cascade-picker.test.d.ts +2 -0
  18. package/dist/__tests__/cascade-picker.test.d.ts.map +1 -0
  19. package/dist/__tests__/cascade-picker.test.js +122 -0
  20. package/dist/__tests__/cascade-picker.test.js.map +1 -0
  21. package/dist/__tests__/coordinator-shipment.test.d.ts +2 -0
  22. package/dist/__tests__/coordinator-shipment.test.d.ts.map +1 -0
  23. package/dist/__tests__/coordinator-shipment.test.js +280 -0
  24. package/dist/__tests__/coordinator-shipment.test.js.map +1 -0
  25. package/dist/__tests__/coordinator-workspace-recover.test.d.ts +2 -0
  26. package/dist/__tests__/coordinator-workspace-recover.test.d.ts.map +1 -0
  27. package/dist/__tests__/coordinator-workspace-recover.test.js +140 -0
  28. package/dist/__tests__/coordinator-workspace-recover.test.js.map +1 -0
  29. package/dist/__tests__/coordinator-workspace.test.d.ts +2 -0
  30. package/dist/__tests__/coordinator-workspace.test.d.ts.map +1 -0
  31. package/dist/__tests__/coordinator-workspace.test.js +135 -0
  32. package/dist/__tests__/coordinator-workspace.test.js.map +1 -0
  33. package/dist/__tests__/default-runner-epipe.test.d.ts +2 -0
  34. package/dist/__tests__/default-runner-epipe.test.d.ts.map +1 -0
  35. package/dist/__tests__/default-runner-epipe.test.js +43 -0
  36. package/dist/__tests__/default-runner-epipe.test.js.map +1 -0
  37. package/dist/__tests__/discovery-scheduler.test.d.ts +2 -0
  38. package/dist/__tests__/discovery-scheduler.test.d.ts.map +1 -0
  39. package/dist/__tests__/discovery-scheduler.test.js +367 -0
  40. package/dist/__tests__/discovery-scheduler.test.js.map +1 -0
  41. package/dist/__tests__/env-forward-e2e.test.d.ts +2 -0
  42. package/dist/__tests__/env-forward-e2e.test.d.ts.map +1 -0
  43. package/dist/__tests__/env-forward-e2e.test.js +57 -0
  44. package/dist/__tests__/env-forward-e2e.test.js.map +1 -0
  45. package/dist/__tests__/gh-pr-creator.test.d.ts +2 -0
  46. package/dist/__tests__/gh-pr-creator.test.d.ts.map +1 -0
  47. package/dist/__tests__/gh-pr-creator.test.js +107 -0
  48. package/dist/__tests__/gh-pr-creator.test.js.map +1 -0
  49. package/dist/__tests__/git-worktree-provider.test.d.ts +2 -0
  50. package/dist/__tests__/git-worktree-provider.test.d.ts.map +1 -0
  51. package/dist/__tests__/git-worktree-provider.test.js +98 -0
  52. package/dist/__tests__/git-worktree-provider.test.js.map +1 -0
  53. package/dist/__tests__/gitignore-check.test.d.ts +2 -0
  54. package/dist/__tests__/gitignore-check.test.d.ts.map +1 -0
  55. package/dist/__tests__/gitignore-check.test.js +39 -0
  56. package/dist/__tests__/gitignore-check.test.js.map +1 -0
  57. package/dist/__tests__/idea-research-source.test.d.ts +2 -0
  58. package/dist/__tests__/idea-research-source.test.d.ts.map +1 -0
  59. package/dist/__tests__/idea-research-source.test.js +425 -0
  60. package/dist/__tests__/idea-research-source.test.js.map +1 -0
  61. package/dist/__tests__/idea-todo-source.test.d.ts +2 -0
  62. package/dist/__tests__/idea-todo-source.test.d.ts.map +1 -0
  63. package/dist/__tests__/idea-todo-source.test.js +258 -0
  64. package/dist/__tests__/idea-todo-source.test.js.map +1 -0
  65. package/dist/__tests__/introspection-dedupe.test.d.ts +2 -0
  66. package/dist/__tests__/introspection-dedupe.test.d.ts.map +1 -0
  67. package/dist/__tests__/introspection-dedupe.test.js +484 -0
  68. package/dist/__tests__/introspection-dedupe.test.js.map +1 -0
  69. package/dist/__tests__/introspection-source.test.d.ts +2 -0
  70. package/dist/__tests__/introspection-source.test.d.ts.map +1 -0
  71. package/dist/__tests__/introspection-source.test.js +1051 -0
  72. package/dist/__tests__/introspection-source.test.js.map +1 -0
  73. package/dist/__tests__/migration-roles.test.js +1 -22
  74. package/dist/__tests__/migration-roles.test.js.map +1 -1
  75. package/dist/__tests__/reconcile-researching.test.d.ts +2 -0
  76. package/dist/__tests__/reconcile-researching.test.d.ts.map +1 -0
  77. package/dist/__tests__/reconcile-researching.test.js +224 -0
  78. package/dist/__tests__/reconcile-researching.test.js.map +1 -0
  79. package/dist/__tests__/role-loader-preamble-all.test.js +3 -1
  80. package/dist/__tests__/role-loader-preamble-all.test.js.map +1 -1
  81. package/dist/__tests__/role-loader.test.js +95 -0
  82. package/dist/__tests__/role-loader.test.js.map +1 -1
  83. package/dist/__tests__/role-prompt-no-legacy-protocol.test.js +3 -1
  84. package/dist/__tests__/role-prompt-no-legacy-protocol.test.js.map +1 -1
  85. package/dist/__tests__/secret-scrub.test.d.ts +2 -0
  86. package/dist/__tests__/secret-scrub.test.d.ts.map +1 -0
  87. package/dist/__tests__/secret-scrub.test.js +55 -0
  88. package/dist/__tests__/secret-scrub.test.js.map +1 -0
  89. package/dist/__tests__/shipment-actions.test.d.ts +2 -0
  90. package/dist/__tests__/shipment-actions.test.d.ts.map +1 -0
  91. package/dist/__tests__/shipment-actions.test.js +378 -0
  92. package/dist/__tests__/shipment-actions.test.js.map +1 -0
  93. package/dist/__tests__/shipment-persistence.test.d.ts +2 -0
  94. package/dist/__tests__/shipment-persistence.test.d.ts.map +1 -0
  95. package/dist/__tests__/shipment-persistence.test.js +120 -0
  96. package/dist/__tests__/shipment-persistence.test.js.map +1 -0
  97. package/dist/__tests__/shipment-pipeline.test.d.ts +2 -0
  98. package/dist/__tests__/shipment-pipeline.test.d.ts.map +1 -0
  99. package/dist/__tests__/shipment-pipeline.test.js +392 -0
  100. package/dist/__tests__/shipment-pipeline.test.js.map +1 -0
  101. package/dist/__tests__/shipment-report.test.d.ts +2 -0
  102. package/dist/__tests__/shipment-report.test.d.ts.map +1 -0
  103. package/dist/__tests__/shipment-report.test.js +78 -0
  104. package/dist/__tests__/shipment-report.test.js.map +1 -0
  105. package/dist/__tests__/shipment-stdin-integration.test.d.ts +2 -0
  106. package/dist/__tests__/shipment-stdin-integration.test.d.ts.map +1 -0
  107. package/dist/__tests__/shipment-stdin-integration.test.js +49 -0
  108. package/dist/__tests__/shipment-stdin-integration.test.js.map +1 -0
  109. package/dist/__tests__/shipment-type-parity.test.d.ts +2 -0
  110. package/dist/__tests__/shipment-type-parity.test.d.ts.map +1 -0
  111. package/dist/__tests__/shipment-type-parity.test.js +10 -0
  112. package/dist/__tests__/shipment-type-parity.test.js.map +1 -0
  113. package/dist/__tests__/snapshot-copy-provider.test.d.ts +2 -0
  114. package/dist/__tests__/snapshot-copy-provider.test.d.ts.map +1 -0
  115. package/dist/__tests__/snapshot-copy-provider.test.js +88 -0
  116. package/dist/__tests__/snapshot-copy-provider.test.js.map +1 -0
  117. package/dist/__tests__/swarm-coordinator-backend.test.js +153 -0
  118. package/dist/__tests__/swarm-coordinator-backend.test.js.map +1 -1
  119. package/dist/__tests__/swarm-coordinator-complete-intercept.test.d.ts +2 -0
  120. package/dist/__tests__/swarm-coordinator-complete-intercept.test.d.ts.map +1 -0
  121. package/dist/__tests__/swarm-coordinator-complete-intercept.test.js +111 -0
  122. package/dist/__tests__/swarm-coordinator-complete-intercept.test.js.map +1 -0
  123. package/dist/__tests__/task-store-source.test.d.ts +2 -0
  124. package/dist/__tests__/task-store-source.test.d.ts.map +1 -0
  125. package/dist/__tests__/task-store-source.test.js +56 -0
  126. package/dist/__tests__/task-store-source.test.js.map +1 -0
  127. package/dist/__tests__/transport-detect.test.d.ts +2 -0
  128. package/dist/__tests__/transport-detect.test.d.ts.map +1 -0
  129. package/dist/__tests__/transport-detect.test.js +92 -0
  130. package/dist/__tests__/transport-detect.test.js.map +1 -0
  131. package/dist/__tests__/workcycle-runner-cascade.test.d.ts +2 -0
  132. package/dist/__tests__/workcycle-runner-cascade.test.d.ts.map +1 -0
  133. package/dist/__tests__/workcycle-runner-cascade.test.js +203 -0
  134. package/dist/__tests__/workcycle-runner-cascade.test.js.map +1 -0
  135. package/dist/__tests__/workcycle-runner.test.d.ts +2 -0
  136. package/dist/__tests__/workcycle-runner.test.d.ts.map +1 -0
  137. package/dist/__tests__/workcycle-runner.test.js +369 -0
  138. package/dist/__tests__/workcycle-runner.test.js.map +1 -0
  139. package/dist/__tests__/workspace-diff.test.d.ts +2 -0
  140. package/dist/__tests__/workspace-diff.test.d.ts.map +1 -0
  141. package/dist/__tests__/workspace-diff.test.js +62 -0
  142. package/dist/__tests__/workspace-diff.test.js.map +1 -0
  143. package/dist/__tests__/workspace-manager.test.d.ts +2 -0
  144. package/dist/__tests__/workspace-manager.test.d.ts.map +1 -0
  145. package/dist/__tests__/workspace-manager.test.js +120 -0
  146. package/dist/__tests__/workspace-manager.test.js.map +1 -0
  147. package/dist/__tests__/workspace-types.test.d.ts +2 -0
  148. package/dist/__tests__/workspace-types.test.d.ts.map +1 -0
  149. package/dist/__tests__/workspace-types.test.js +37 -0
  150. package/dist/__tests__/workspace-types.test.js.map +1 -0
  151. package/dist/__tests__/worktree-gc.test.d.ts +2 -0
  152. package/dist/__tests__/worktree-gc.test.d.ts.map +1 -0
  153. package/dist/__tests__/worktree-gc.test.js +183 -0
  154. package/dist/__tests__/worktree-gc.test.js.map +1 -0
  155. package/dist/always-on/activity-reader.d.ts +27 -0
  156. package/dist/always-on/activity-reader.d.ts.map +1 -0
  157. package/dist/always-on/activity-reader.js +95 -0
  158. package/dist/always-on/activity-reader.js.map +1 -0
  159. package/dist/always-on/always-on-manager.d.ts +170 -0
  160. package/dist/always-on/always-on-manager.d.ts.map +1 -0
  161. package/dist/always-on/always-on-manager.js +538 -0
  162. package/dist/always-on/always-on-manager.js.map +1 -0
  163. package/dist/always-on/config.d.ts +141 -0
  164. package/dist/always-on/config.d.ts.map +1 -0
  165. package/dist/always-on/config.js +324 -0
  166. package/dist/always-on/config.js.map +1 -0
  167. package/dist/always-on/discovery-scheduler.d.ts +60 -0
  168. package/dist/always-on/discovery-scheduler.d.ts.map +1 -0
  169. package/dist/always-on/discovery-scheduler.js +287 -0
  170. package/dist/always-on/discovery-scheduler.js.map +1 -0
  171. package/dist/always-on/ideas-client.d.ts +23 -0
  172. package/dist/always-on/ideas-client.d.ts.map +1 -0
  173. package/dist/always-on/ideas-client.js +13 -0
  174. package/dist/always-on/ideas-client.js.map +1 -0
  175. package/dist/always-on/reconcile-researching.d.ts +42 -0
  176. package/dist/always-on/reconcile-researching.d.ts.map +1 -0
  177. package/dist/always-on/reconcile-researching.js +133 -0
  178. package/dist/always-on/reconcile-researching.js.map +1 -0
  179. package/dist/always-on/task-sources/cascade-picker.d.ts +42 -0
  180. package/dist/always-on/task-sources/cascade-picker.d.ts.map +1 -0
  181. package/dist/always-on/task-sources/cascade-picker.js +65 -0
  182. package/dist/always-on/task-sources/cascade-picker.js.map +1 -0
  183. package/dist/always-on/task-sources/idea-dedupe.d.ts +62 -0
  184. package/dist/always-on/task-sources/idea-dedupe.d.ts.map +1 -0
  185. package/dist/always-on/task-sources/idea-dedupe.js +130 -0
  186. package/dist/always-on/task-sources/idea-dedupe.js.map +1 -0
  187. package/dist/always-on/task-sources/idea-research-source.d.ts +46 -0
  188. package/dist/always-on/task-sources/idea-research-source.d.ts.map +1 -0
  189. package/dist/always-on/task-sources/idea-research-source.js +308 -0
  190. package/dist/always-on/task-sources/idea-research-source.js.map +1 -0
  191. package/dist/always-on/task-sources/idea-sort.d.ts +3 -0
  192. package/dist/always-on/task-sources/idea-sort.d.ts.map +1 -0
  193. package/dist/always-on/task-sources/idea-sort.js +25 -0
  194. package/dist/always-on/task-sources/idea-sort.js.map +1 -0
  195. package/dist/always-on/task-sources/idea-todo-source.d.ts +48 -0
  196. package/dist/always-on/task-sources/idea-todo-source.d.ts.map +1 -0
  197. package/dist/always-on/task-sources/idea-todo-source.js +226 -0
  198. package/dist/always-on/task-sources/idea-todo-source.js.map +1 -0
  199. package/dist/always-on/task-sources/introspection-source.d.ts +101 -0
  200. package/dist/always-on/task-sources/introspection-source.d.ts.map +1 -0
  201. package/dist/always-on/task-sources/introspection-source.js +695 -0
  202. package/dist/always-on/task-sources/introspection-source.js.map +1 -0
  203. package/dist/always-on/task-sources/task-store-source.d.ts +15 -0
  204. package/dist/always-on/task-sources/task-store-source.d.ts.map +1 -0
  205. package/dist/always-on/task-sources/task-store-source.js +59 -0
  206. package/dist/always-on/task-sources/task-store-source.js.map +1 -0
  207. package/dist/always-on/task-sources/types.d.ts +108 -0
  208. package/dist/always-on/task-sources/types.d.ts.map +1 -0
  209. package/dist/always-on/task-sources/types.js +13 -0
  210. package/dist/always-on/task-sources/types.js.map +1 -0
  211. package/dist/always-on/types.d.ts +76 -0
  212. package/dist/always-on/types.d.ts.map +1 -0
  213. package/dist/always-on/types.js +17 -0
  214. package/dist/always-on/types.js.map +1 -0
  215. package/dist/always-on/workcycle-runner.d.ts +115 -0
  216. package/dist/always-on/workcycle-runner.d.ts.map +1 -0
  217. package/dist/always-on/workcycle-runner.js +285 -0
  218. package/dist/always-on/workcycle-runner.js.map +1 -0
  219. package/dist/always-on/worktree-gc.d.ts +41 -0
  220. package/dist/always-on/worktree-gc.d.ts.map +1 -0
  221. package/dist/always-on/worktree-gc.js +167 -0
  222. package/dist/always-on/worktree-gc.js.map +1 -0
  223. package/dist/index.d.ts +26 -2
  224. package/dist/index.d.ts.map +1 -1
  225. package/dist/index.js +24 -1
  226. package/dist/index.js.map +1 -1
  227. package/dist/persistence.d.ts +37 -1
  228. package/dist/persistence.d.ts.map +1 -1
  229. package/dist/persistence.js +48 -0
  230. package/dist/persistence.js.map +1 -1
  231. package/dist/retrospective.d.ts.map +1 -1
  232. package/dist/retrospective.js +6 -0
  233. package/dist/retrospective.js.map +1 -1
  234. package/dist/roles/role-loader.d.ts +1 -1
  235. package/dist/roles/role-loader.d.ts.map +1 -1
  236. package/dist/roles/role-loader.js +18 -0
  237. package/dist/roles/role-loader.js.map +1 -1
  238. package/dist/roles/types.d.ts +12 -0
  239. package/dist/roles/types.d.ts.map +1 -1
  240. package/dist/shipment/gh-pr-creator.d.ts +28 -0
  241. package/dist/shipment/gh-pr-creator.d.ts.map +1 -0
  242. package/dist/shipment/gh-pr-creator.js +80 -0
  243. package/dist/shipment/gh-pr-creator.js.map +1 -0
  244. package/dist/shipment/report.d.ts +27 -0
  245. package/dist/shipment/report.d.ts.map +1 -0
  246. package/dist/shipment/report.js +41 -0
  247. package/dist/shipment/report.js.map +1 -0
  248. package/dist/shipment/secret-scrub.d.ts +12 -0
  249. package/dist/shipment/secret-scrub.d.ts.map +1 -0
  250. package/dist/shipment/secret-scrub.js +30 -0
  251. package/dist/shipment/secret-scrub.js.map +1 -0
  252. package/dist/shipment/shipment-actions.d.ts +85 -0
  253. package/dist/shipment/shipment-actions.d.ts.map +1 -0
  254. package/dist/shipment/shipment-actions.js +190 -0
  255. package/dist/shipment/shipment-actions.js.map +1 -0
  256. package/dist/shipment/shipment-pipeline.d.ts +48 -0
  257. package/dist/shipment/shipment-pipeline.d.ts.map +1 -0
  258. package/dist/shipment/shipment-pipeline.js +256 -0
  259. package/dist/shipment/shipment-pipeline.js.map +1 -0
  260. package/dist/shipment/transport-detect.d.ts +16 -0
  261. package/dist/shipment/transport-detect.d.ts.map +1 -0
  262. package/dist/shipment/transport-detect.js +54 -0
  263. package/dist/shipment/transport-detect.js.map +1 -0
  264. package/dist/shipment/workspace-diff.d.ts +39 -0
  265. package/dist/shipment/workspace-diff.d.ts.map +1 -0
  266. package/dist/shipment/workspace-diff.js +64 -0
  267. package/dist/shipment/workspace-diff.js.map +1 -0
  268. package/dist/swarm-coordinator.d.ts +20 -1
  269. package/dist/swarm-coordinator.d.ts.map +1 -1
  270. package/dist/swarm-coordinator.js +193 -10
  271. package/dist/swarm-coordinator.js.map +1 -1
  272. package/dist/types.d.ts +62 -0
  273. package/dist/types.d.ts.map +1 -1
  274. package/dist/workspace/git-worktree-provider.d.ts +11 -0
  275. package/dist/workspace/git-worktree-provider.d.ts.map +1 -0
  276. package/dist/workspace/git-worktree-provider.js +123 -0
  277. package/dist/workspace/git-worktree-provider.js.map +1 -0
  278. package/dist/workspace/gitignore-check.d.ts +10 -0
  279. package/dist/workspace/gitignore-check.d.ts.map +1 -0
  280. package/dist/workspace/gitignore-check.js +25 -0
  281. package/dist/workspace/gitignore-check.js.map +1 -0
  282. package/dist/workspace/index.d.ts +5 -0
  283. package/dist/workspace/index.d.ts.map +1 -0
  284. package/dist/workspace/index.js +5 -0
  285. package/dist/workspace/index.js.map +1 -0
  286. package/dist/workspace/snapshot-copy-provider.d.ts +11 -0
  287. package/dist/workspace/snapshot-copy-provider.d.ts.map +1 -0
  288. package/dist/workspace/snapshot-copy-provider.js +66 -0
  289. package/dist/workspace/snapshot-copy-provider.js.map +1 -0
  290. package/dist/workspace/types.d.ts +36 -0
  291. package/dist/workspace/types.d.ts.map +1 -0
  292. package/dist/workspace/types.js +2 -0
  293. package/dist/workspace/types.js.map +1 -0
  294. package/dist/workspace/workspace-manager.d.ts +30 -0
  295. package/dist/workspace/workspace-manager.d.ts.map +1 -0
  296. package/dist/workspace/workspace-manager.js +104 -0
  297. package/dist/workspace/workspace-manager.js.map +1 -0
  298. package/package.json +4 -4
  299. package/roles/queen.md +1 -0
  300. package/templates/introspection.md +64 -0
  301. package/templates/research-only.md +58 -0
  302. package/roles/preset-analyst-simons.md +0 -39
  303. package/roles/preset-architect-knuth.md +0 -39
  304. package/roles/preset-designer-norman.md +0 -39
  305. package/roles/preset-designer.md +0 -39
  306. package/roles/preset-dev-carmack.md +0 -39
  307. package/roles/preset-dev-gosling.md +0 -39
  308. package/roles/preset-developer.md +0 -52
  309. package/roles/preset-manager-grove.md +0 -39
  310. package/roles/preset-manager-musk.md +0 -39
  311. package/roles/preset-pm.md +0 -78
  312. package/roles/preset-researcher-feynman.md +0 -39
  313. package/roles/preset-reviewer.md +0 -46
  314. package/roles/preset-strategist-buffett.md +0 -39
  315. package/roles/preset-strategist-munger.md +0 -39
  316. package/roles/preset-strategist-sunzi.md +0 -39
  317. package/roles/preset-tester-beck.md +0 -40
  318. package/roles/preset-tester.md +0 -47
  319. package/roles/preset-writer-orwell.md +0 -39
  320. package/roles/preset-writer.md +0 -39
@@ -0,0 +1,48 @@
1
+ import type { IdeasClient } from "../ideas-client.js";
2
+ import { sortIdeasByPriorityThenAge } from "./idea-sort.js";
3
+ import type { TaskSource } from "./types.js";
4
+ export interface IdeaTodoSourceOptions {
5
+ ideasClient: IdeasClient;
6
+ /**
7
+ * Per-cycle list cap forwarded to the ideas API. Default 50 is plenty —
8
+ * we only consume the head after sorting.
9
+ */
10
+ listLimit?: number;
11
+ /** Optional warn logger; defaults to silent. */
12
+ warn?: (obj: Record<string, unknown>, msg?: string) => void;
13
+ /** Optional info logger; defaults to silent. */
14
+ info?: (obj: Record<string, unknown>, msg?: string) => void;
15
+ }
16
+ /**
17
+ * Re-export the shared sort under the original name for back-compat with
18
+ * tests that imported `sortIdeasForPicking` from this module. S5 hotfix
19
+ * consolidates the implementation into `./idea-sort` so both sources stay
20
+ * in lockstep.
21
+ */
22
+ export declare const sortIdeasForPicking: typeof sortIdeasByPriorityThenAge;
23
+ export declare function createIdeaTodoSource(opts: IdeaTodoSourceOptions): TaskSource;
24
+ /**
25
+ * Helper exposed for callers that want to manually PATCH the idea to
26
+ * researching + linkedSwarmTaskId outside the cascade flow. Internally the
27
+ * IdeaTodoSource calls the same logic via its `onClaim` hook.
28
+ */
29
+ export declare function markIdeaResearching(ideasClient: IdeasClient, ideaId: string, swarmId: string, log?: {
30
+ warn?: (o: Record<string, unknown>, m?: string) => void;
31
+ }): Promise<void>;
32
+ /**
33
+ * PR-B Sub-PR-B3 — classify a swarm failure error into one of 4 categories
34
+ * used by `shipFailureReason`. The taxonomy intentionally collapses noisy
35
+ * variants:
36
+ * - "network": ENOTFOUND / ETIMEDOUT / ECONNRESET / "network" anywhere
37
+ * in the message — pick() applies a 5min cooldown before retry
38
+ * - "rate-limit": "rate limit" / HTTP 429 — same 5min cooldown
39
+ * - "auth": "401" / "403" / "auth" / "token" — NOT cooldowned (user
40
+ * likely fixed the token between cycles)
41
+ * - "other": anything else, no cooldown (retry immediately so we can
42
+ * refresh the diagnosis)
43
+ *
44
+ * Exported for unit tests; callers should use `IdeaTodoSource.onFailure`
45
+ * which delegates here.
46
+ */
47
+ export declare function classifyShipFailure(error?: string): string;
48
+ //# sourceMappingURL=idea-todo-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idea-todo-source.d.ts","sourceRoot":"","sources":["../../../src/always-on/task-sources/idea-todo-source.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,gDAAgD;IAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,mCAA6B,CAAC;AAE9D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,UAAU,CAkL5E;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAChE,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAmB1D"}
@@ -0,0 +1,226 @@
1
+ // M8.0 — IdeaTodoSource: consumes ideas with status="todo" and drives them
2
+ // through researching → developed (success) or back to todo (failure).
3
+ //
4
+ // Flow (D1 in design doc):
5
+ // idea.status="todo" → pick → PATCH status=researching, linkedSwarmTaskId
6
+ // → swarm runs
7
+ // on success: PATCH status=developed
8
+ // on failure: PATCH status=todo (revert)
9
+ //
10
+ // `researching` is treated as "in flight" by M8.0; M8.1 will introduce a
11
+ // separate research-cycle flow that also uses `researching` but disambiguates
12
+ // via the presence of a research report. The status enum only has 5 values
13
+ // (idea/todo/researching/developed/archived) so we accept the overload.
14
+ import { encodeCwd } from "@mclawnet/shared";
15
+ import { sortIdeasByPriorityThenAge } from "./idea-sort.js";
16
+ /**
17
+ * Re-export the shared sort under the original name for back-compat with
18
+ * tests that imported `sortIdeasForPicking` from this module. S5 hotfix
19
+ * consolidates the implementation into `./idea-sort` so both sources stay
20
+ * in lockstep.
21
+ */
22
+ export const sortIdeasForPicking = sortIdeasByPriorityThenAge;
23
+ export function createIdeaTodoSource(opts) {
24
+ const { ideasClient, listLimit = 50, warn, info } = opts;
25
+ /**
26
+ * PR-B Sub-PR-B3 — cooldown duration for retryable shipFailureReason
27
+ * categories. 5min is short enough that transient outages don't strand
28
+ * the idea for hours, long enough that we don't burn budget retrying
29
+ * during an actual ongoing GH outage. Non-retryable reasons (auth /
30
+ * other) don't get a cooldown — they get retried immediately so the
31
+ * next cycle's onFailure can refresh the diagnosis (auth token may have
32
+ * been renewed; "other" may have resolved itself).
33
+ */
34
+ const RETRY_COOLDOWN_MS = 5 * 60 * 1000;
35
+ const RETRYABLE_REASONS = new Set(["network", "rate-limit"]);
36
+ return {
37
+ name: "idea-todo",
38
+ kind: "idea-todo",
39
+ async pick(projectRoot) {
40
+ let projectId;
41
+ try {
42
+ projectId = encodeCwd(projectRoot);
43
+ }
44
+ catch (err) {
45
+ warn?.({ err: err instanceof Error ? err.message : String(err), projectRoot }, "idea-todo-source: encodeCwd failed");
46
+ return null;
47
+ }
48
+ let ideas;
49
+ try {
50
+ ideas = await ideasClient.list({
51
+ status: "todo",
52
+ projectId,
53
+ limit: listLimit,
54
+ });
55
+ }
56
+ catch (err) {
57
+ warn?.({ err: err instanceof Error ? err.message : String(err), projectId }, "idea-todo-source: list failed");
58
+ return null;
59
+ }
60
+ // Defensive filter: skip ideas without a projectId (the design says
61
+ // project-less ideas are not consumed) and double-check status in case
62
+ // the server returned a wider set.
63
+ // PR-B Sub-PR-B3: also skip ideas in retry cooldown — their previous
64
+ // ship failed with a transient reason (network/rate-limit) less than
65
+ // 5 min ago, so picking them now will just hit the same wall.
66
+ const nowMs = Date.now();
67
+ const matching = ideas.filter((i) => {
68
+ if (i.status !== "todo" || i.projectId !== projectId)
69
+ return false;
70
+ const reason = i.shipFailureReason;
71
+ if (reason && RETRYABLE_REASONS.has(reason)) {
72
+ const updatedAt = Date.parse(i.updatedAt);
73
+ if (Number.isFinite(updatedAt) && nowMs - updatedAt < RETRY_COOLDOWN_MS) {
74
+ info?.({ ideaId: i.id, reason, msSinceFailure: nowMs - updatedAt }, "idea-todo-source: skipping idea in ship-failure cooldown");
75
+ return false;
76
+ }
77
+ }
78
+ return true;
79
+ });
80
+ if (matching.length === 0)
81
+ return null;
82
+ const sorted = sortIdeasByPriorityThenAge(matching);
83
+ const head = sorted[0];
84
+ const description = head.body && head.body.trim().length > 0 ? head.body : undefined;
85
+ const taskRef = {
86
+ // The synthetic cycle TaskRef.id is the idea id — there's no other
87
+ // backing record. Downstream code that needs to disambiguate uses
88
+ // sourceKind + sourceId.
89
+ id: head.id,
90
+ title: head.title,
91
+ ...(description ? { description } : {}),
92
+ sourceKind: "idea-todo",
93
+ sourceId: head.id,
94
+ };
95
+ info?.({ ideaId: head.id, priority: head.priority, projectId }, "idea-todo-source: picked");
96
+ return taskRef;
97
+ },
98
+ async onClaim(taskRef, swarmId) {
99
+ const ideaId = taskRef.sourceId ?? taskRef.id;
100
+ try {
101
+ // M8.1: also stamp researchKind="execute" so this idea is
102
+ // distinguishable from a status=researching idea that was claimed by
103
+ // the M8.1 IdeaResearchSource (which sets researchKind="investigate").
104
+ //
105
+ // S3 hotfix note (M8 holistic review): the field is named
106
+ // `linkedSwarmTaskId` for back-compat (DB column shipped that way in
107
+ // migration 0014) but it actually stores a swarmId, not a taskId.
108
+ // Renaming would require a destructive migration; treat the name as
109
+ // historical until a future major bump consolidates the schema.
110
+ // S9 note: there's a known TOCTOU window between this PATCH and the
111
+ // hub-side write — if two agents race to claim the same idea, both
112
+ // can flip it to researching. M8 ships single-agent only; M9+ may
113
+ // add optimistic locking (If-Match etag or version field).
114
+ await ideasClient.patch(ideaId, {
115
+ status: "researching",
116
+ researchKind: "execute",
117
+ linkedSwarmTaskId: swarmId,
118
+ // PR-B Sub-PR-B3: clear stale failure reason on new claim — this
119
+ // is a fresh attempt, the cooldown check above already gated us
120
+ // through, and the UI shouldn't show "last ship failed: network"
121
+ // on an idea that's currently in flight.
122
+ shipFailureReason: null,
123
+ });
124
+ info?.({ ideaId, swarmId }, "idea-todo-source: claimed → researching (execute)");
125
+ }
126
+ catch (err) {
127
+ warn?.({ err: err instanceof Error ? err.message : String(err), ideaId, swarmId }, "idea-todo-source: onClaim patch failed");
128
+ }
129
+ },
130
+ async onSuccess(taskRef, swarmId) {
131
+ const ideaId = taskRef.sourceId ?? taskRef.id;
132
+ try {
133
+ // M8.1: clear researchKind on terminal transition — the idea is no
134
+ // longer in any researching flow.
135
+ // PR-B Sub-PR-B3: also clear shipFailureReason on success.
136
+ await ideasClient.patch(ideaId, {
137
+ status: "developed",
138
+ researchKind: null,
139
+ shipFailureReason: null,
140
+ });
141
+ info?.({ ideaId, swarmId }, "idea-todo-source: marked developed");
142
+ }
143
+ catch (err) {
144
+ warn?.({ err: err instanceof Error ? err.message : String(err), ideaId, swarmId }, "idea-todo-source: onSuccess patch failed");
145
+ }
146
+ },
147
+ async onFailure(taskRef, swarmId, error) {
148
+ const ideaId = taskRef.sourceId ?? taskRef.id;
149
+ const reason = classifyShipFailure(error);
150
+ try {
151
+ // Revert to todo so the next cycle can pick it up again. Also clear
152
+ // linkedSwarmTaskId — B3: leaving it pointed at a destroyed swarm
153
+ // surfaces a dead deep-link in the UI and confuses cascade observers
154
+ // ("which swarm is this idea bound to?"). The breadcrumb was useful
155
+ // for in-flight debugging but stale once the cycle has failed.
156
+ // researchKind is also cleared so the idea is no longer in any
157
+ // researching flow on the UI.
158
+ // PR-B Sub-PR-B3: classify the error and persist as
159
+ // shipFailureReason so pick() can apply a 5-min cooldown on
160
+ // transient categories (network / rate-limit).
161
+ await ideasClient.patch(ideaId, {
162
+ status: "todo",
163
+ researchKind: null,
164
+ linkedSwarmTaskId: null,
165
+ shipFailureReason: reason,
166
+ });
167
+ info?.({ ideaId, swarmId, error: error ?? null, shipFailureReason: reason }, "idea-todo-source: reverted to todo after failure");
168
+ }
169
+ catch (err) {
170
+ warn?.({ err: err instanceof Error ? err.message : String(err), ideaId, swarmId, originalError: error }, "idea-todo-source: onFailure revert failed");
171
+ }
172
+ },
173
+ };
174
+ }
175
+ /**
176
+ * Helper exposed for callers that want to manually PATCH the idea to
177
+ * researching + linkedSwarmTaskId outside the cascade flow. Internally the
178
+ * IdeaTodoSource calls the same logic via its `onClaim` hook.
179
+ */
180
+ export async function markIdeaResearching(ideasClient, ideaId, swarmId, log) {
181
+ try {
182
+ await ideasClient.patch(ideaId, {
183
+ status: "researching",
184
+ researchKind: "execute",
185
+ linkedSwarmTaskId: swarmId,
186
+ });
187
+ }
188
+ catch (err) {
189
+ log?.warn?.({ err: err instanceof Error ? err.message : String(err), ideaId, swarmId }, "idea-todo-source: markIdeaResearching failed");
190
+ }
191
+ }
192
+ /**
193
+ * PR-B Sub-PR-B3 — classify a swarm failure error into one of 4 categories
194
+ * used by `shipFailureReason`. The taxonomy intentionally collapses noisy
195
+ * variants:
196
+ * - "network": ENOTFOUND / ETIMEDOUT / ECONNRESET / "network" anywhere
197
+ * in the message — pick() applies a 5min cooldown before retry
198
+ * - "rate-limit": "rate limit" / HTTP 429 — same 5min cooldown
199
+ * - "auth": "401" / "403" / "auth" / "token" — NOT cooldowned (user
200
+ * likely fixed the token between cycles)
201
+ * - "other": anything else, no cooldown (retry immediately so we can
202
+ * refresh the diagnosis)
203
+ *
204
+ * Exported for unit tests; callers should use `IdeaTodoSource.onFailure`
205
+ * which delegates here.
206
+ */
207
+ export function classifyShipFailure(error) {
208
+ if (!error)
209
+ return "other";
210
+ const lower = error.toLowerCase();
211
+ if (lower.includes("enotfound") ||
212
+ lower.includes("etimedout") ||
213
+ lower.includes("econnreset") ||
214
+ lower.includes("econnrefused") ||
215
+ lower.includes("network")) {
216
+ return "network";
217
+ }
218
+ if (lower.includes("rate limit") || lower.includes("rate-limit") || lower.includes("429")) {
219
+ return "rate-limit";
220
+ }
221
+ if (lower.includes("401") || lower.includes("403") || lower.includes("auth") || lower.includes("token")) {
222
+ return "auth";
223
+ }
224
+ return "other";
225
+ }
226
+ //# sourceMappingURL=idea-todo-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idea-todo-source.js","sourceRoot":"","sources":["../../../src/always-on/task-sources/idea-todo-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import type { SwarmCoordinator } from "../../swarm-coordinator.js";
2
+ import type { AlwaysOnConfig, AlwaysOnPersistedConfig } from "../config.js";
3
+ import type { IdeasClient } from "../ideas-client.js";
4
+ import type { TaskSource } from "./types.js";
5
+ export declare const INTROSPECTION_TEMPLATE_NAME = "introspection";
6
+ export declare const INTROSPECTION_SOURCE_TAG = "auto-discovered";
7
+ export declare const INTROSPECTION_SOURCE_ROLE = "queen-introspection";
8
+ /** Hard cap per design doc D4 — no more than 3 ideas per introspection. */
9
+ export declare const INTROSPECTION_MAX_IDEAS = 3;
10
+ /**
11
+ * M8.2c — write-race guard for the spawner-owned completion signal. The
12
+ * queen's `cat > <output> <<'EOF' ... EOF` lands as several syscalls; we
13
+ * require N ms of mtime stillness before declaring "queen finished writing".
14
+ */
15
+ export declare const SPAWNER_COMPLETE_MTIME_GUARD_MS = 5000;
16
+ /**
17
+ * M8.2c — absolute spawn-to-ingest cap. Even if the output file never lands
18
+ * (queen crashed / token exhausted / coordinator lost the swarm), the
19
+ * spawner stops waiting after this. `processPendingSwarm` then takes the
20
+ * "missing output" path: clears the pending breadcrumb and the next cycle
21
+ * (subject to cooldown) gets to retry. Set high enough that a normal
22
+ * introspection cycle (~30s of read+grep+write) is never near the cap.
23
+ */
24
+ export declare const SPAWNER_COMPLETE_HARD_TIMEOUT_MS: number;
25
+ /**
26
+ * Loose shape of one candidate JSON object the queen produces. Anything the
27
+ * queen wrote that isn't a string is dropped / coerced; priority is always
28
+ * overridden to "low" downstream.
29
+ */
30
+ export interface IntrospectionCandidate {
31
+ title: string;
32
+ body?: string;
33
+ /** Recorded but overridden to "low" before POST. */
34
+ priority?: string;
35
+ }
36
+ export interface IntrospectionSourceOptions {
37
+ ideasClient: IdeasClient;
38
+ swarmCoordinator: SwarmCoordinator;
39
+ /**
40
+ * Read the persisted always-on config for a project. Called fresh on every
41
+ * pick() so the source sees the latest disk state without holding stale
42
+ * references. One IntrospectionSource serves N projects in the AlwaysOnManager
43
+ * cascade — that's why this is keyed by projectRoot.
44
+ */
45
+ getConfig: (projectRoot: string) => AlwaysOnPersistedConfig;
46
+ /**
47
+ * Apply a partial config patch for a project (lastIntrospectionAt /
48
+ * lastIntrospectionRejected / pendingIntrospectionSwarmId). Implementation
49
+ * persists via mergeAlwaysOnConfig + saveAlwaysOnConfig under the hood —
50
+ * the source treats this as opaque.
51
+ */
52
+ updateConfig: (projectRoot: string, patch: Omit<Partial<AlwaysOnConfig>, "lastIntrospectionAt" | "lastIntrospectionRejected" | "pendingIntrospectionSwarmId" | "pendingIntrospectionWorkspaceCwd"> & {
53
+ lastIntrospectionAt?: string | null;
54
+ lastIntrospectionRejected?: boolean | null;
55
+ pendingIntrospectionSwarmId?: string | null;
56
+ pendingIntrospectionWorkspaceCwd?: string | null;
57
+ }) => Promise<void>;
58
+ /** Override template name (tests + future custom flows). Defaults to "introspection". */
59
+ introspectionTemplateName?: string;
60
+ /** Test seam: clock. */
61
+ clock?: () => Date;
62
+ /** Optional logger. */
63
+ warn?: (obj: Record<string, unknown>, msg?: string) => void;
64
+ info?: (obj: Record<string, unknown>, msg?: string) => void;
65
+ /**
66
+ * Test seam: synthesise the swarm id used for the introspection cycle.
67
+ * Defaults to `m8-introspect-<uuid>` (prefix lets ops grep these out of
68
+ * regular work cycles in the always-on log).
69
+ */
70
+ generateSwarmId?: () => string;
71
+ /**
72
+ * Test seam: resolve the absolute output path the queen will write to.
73
+ * Defaults to `<projectRoot>/.clawnet/introspection/<swarmId>.json`.
74
+ */
75
+ resolveOutputPath?: (projectRoot: string, swarmId: string) => string;
76
+ }
77
+ /**
78
+ * Parse the queen's output file into a candidate array. Accepts either:
79
+ * (a) a clean JSON file whose root is an array, or
80
+ * (b) a file that contains other text and ends with a JSON array — we
81
+ * scan for the *last* `[` and try JSON.parse from there.
82
+ *
83
+ * Returns [] on any failure. Callers treat [] as "queen produced nothing
84
+ * useful" — they still bump lastIntrospectionAt so cooldown holds.
85
+ */
86
+ export declare function parseCandidatesOutput(raw: string): IntrospectionCandidate[];
87
+ /**
88
+ * Build the task prompt handed to the introspection swarm. Embeds a
89
+ * workspace-RELATIVE output path so the queen writes inside whatever cwd
90
+ * her role process is given (workspace.cwd when worktree isolation is on,
91
+ * or projectRoot when it falls through to no workspace). Spawner reads it
92
+ * back by resolving the same relative path against the actual workspace
93
+ * cwd at drain time.
94
+ *
95
+ * Pre-B4: this used to embed `<projectRoot>/.clawnet/introspection/<id>.json`
96
+ * absolute and the queen would `cat >` straight to projectRoot, bypassing
97
+ * the worktree. PR-B Suspect B fix.
98
+ */
99
+ export declare function buildIntrospectionTaskPrompt(projectRoot: string, relativeOutputPath: string): string;
100
+ export declare function createIntrospectionSource(opts: IntrospectionSourceOptions): TaskSource;
101
+ //# sourceMappingURL=introspection-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection-source.d.ts","sourceRoot":"","sources":["../../../src/always-on/task-sources/introspection-source.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EACV,cAAc,EACd,uBAAuB,EACxB,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAyB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAO7E,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtD,eAAO,MAAM,2BAA2B,kBAAkB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AACrD;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,QAAqB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC;;;;;OAKG;IACH,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,uBAAuB,CAAC;IAC5D;;;;;OAKG;IACH,YAAY,EAAE,CACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,IAAI,CACT,OAAO,CAAC,cAAc,CAAC,EACvB,qBAAqB,GAAG,2BAA2B,GAAG,6BAA6B,GAAG,kCAAkC,CACzH,GAAG;QACF,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,yBAAyB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAC3C,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5C,gCAAgC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClD,KACE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,yFAAyF;IACzF,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CACtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAqD3E;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAkBR;AAqBD,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,UAAU,CAqkBZ"}