@united-workforce/cli 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/README.md +45 -11
  2. package/dist/.build-fingerprint +1 -0
  3. package/dist/__tests__/adapter-json-roundtrip.test.js +17 -7
  4. package/dist/__tests__/adapter-json-roundtrip.test.js.map +1 -1
  5. package/dist/__tests__/agent-resolution-llm-free.test.d.ts +2 -0
  6. package/dist/__tests__/agent-resolution-llm-free.test.d.ts.map +1 -0
  7. package/dist/__tests__/agent-resolution-llm-free.test.js +30 -0
  8. package/dist/__tests__/agent-resolution-llm-free.test.js.map +1 -0
  9. package/dist/__tests__/build-step-entry.test.d.ts +2 -0
  10. package/dist/__tests__/build-step-entry.test.d.ts.map +1 -0
  11. package/dist/__tests__/build-step-entry.test.js +173 -0
  12. package/dist/__tests__/build-step-entry.test.js.map +1 -0
  13. package/dist/__tests__/clear-thread-failed-attempts.test.d.ts +2 -0
  14. package/dist/__tests__/clear-thread-failed-attempts.test.d.ts.map +1 -0
  15. package/dist/__tests__/clear-thread-failed-attempts.test.js +93 -0
  16. package/dist/__tests__/clear-thread-failed-attempts.test.js.map +1 -0
  17. package/dist/__tests__/concurrency.test.d.ts +2 -0
  18. package/dist/__tests__/concurrency.test.d.ts.map +1 -0
  19. package/dist/__tests__/concurrency.test.js +196 -0
  20. package/dist/__tests__/concurrency.test.js.map +1 -0
  21. package/dist/__tests__/config.test.js +26 -302
  22. package/dist/__tests__/config.test.js.map +1 -1
  23. package/dist/__tests__/current-role.test.js +7 -6
  24. package/dist/__tests__/current-role.test.js.map +1 -1
  25. package/dist/__tests__/e2e-mock-agent.test.js +43 -30
  26. package/dist/__tests__/e2e-mock-agent.test.js.map +1 -1
  27. package/dist/__tests__/format-text-default.test.d.ts +2 -0
  28. package/dist/__tests__/format-text-default.test.d.ts.map +1 -0
  29. package/dist/__tests__/format-text-default.test.js +43 -0
  30. package/dist/__tests__/format-text-default.test.js.map +1 -0
  31. package/dist/__tests__/format-text-registry.test.d.ts +2 -0
  32. package/dist/__tests__/format-text-registry.test.d.ts.map +1 -0
  33. package/dist/__tests__/format-text-registry.test.js +158 -0
  34. package/dist/__tests__/format-text-registry.test.js.map +1 -0
  35. package/dist/__tests__/issue-180-workflow-ref-removed.test.d.ts +2 -0
  36. package/dist/__tests__/issue-180-workflow-ref-removed.test.d.ts.map +1 -0
  37. package/dist/__tests__/issue-180-workflow-ref-removed.test.js +40 -0
  38. package/dist/__tests__/issue-180-workflow-ref-removed.test.js.map +1 -0
  39. package/dist/__tests__/log-text-renderer.test.d.ts +2 -0
  40. package/dist/__tests__/log-text-renderer.test.d.ts.map +1 -0
  41. package/dist/__tests__/log-text-renderer.test.js +265 -0
  42. package/dist/__tests__/log-text-renderer.test.js.map +1 -0
  43. package/dist/__tests__/moderator-evaluate.test.js +9 -50
  44. package/dist/__tests__/moderator-evaluate.test.js.map +1 -1
  45. package/dist/__tests__/output-mapper-thread-list-startedat.test.d.ts +2 -0
  46. package/dist/__tests__/output-mapper-thread-list-startedat.test.d.ts.map +1 -0
  47. package/dist/__tests__/output-mapper-thread-list-startedat.test.js +102 -0
  48. package/dist/__tests__/output-mapper-thread-list-startedat.test.js.map +1 -0
  49. package/dist/__tests__/output-mapper-workflow-add.test.d.ts +2 -0
  50. package/dist/__tests__/output-mapper-workflow-add.test.d.ts.map +1 -0
  51. package/dist/__tests__/output-mapper-workflow-add.test.js +22 -0
  52. package/dist/__tests__/output-mapper-workflow-add.test.js.map +1 -0
  53. package/dist/__tests__/pid-recycling.test.d.ts +2 -0
  54. package/dist/__tests__/pid-recycling.test.d.ts.map +1 -0
  55. package/dist/__tests__/pid-recycling.test.js +273 -0
  56. package/dist/__tests__/pid-recycling.test.js.map +1 -0
  57. package/dist/__tests__/prompt.test.js +365 -2
  58. package/dist/__tests__/prompt.test.js.map +1 -1
  59. package/dist/__tests__/resolve-head-hash.test.js +12 -4
  60. package/dist/__tests__/resolve-head-hash.test.js.map +1 -1
  61. package/dist/__tests__/setup-agent-discovery.test.js +21 -30
  62. package/dist/__tests__/setup-agent-discovery.test.js.map +1 -1
  63. package/dist/__tests__/setup-complexity.test.js +2 -168
  64. package/dist/__tests__/setup-complexity.test.js.map +1 -1
  65. package/dist/__tests__/setup-no-llm.test.d.ts +2 -0
  66. package/dist/__tests__/setup-no-llm.test.d.ts.map +1 -0
  67. package/dist/__tests__/setup-no-llm.test.js +52 -0
  68. package/dist/__tests__/setup-no-llm.test.js.map +1 -0
  69. package/dist/__tests__/solve-issue-tea-worktree.test.js +27 -28
  70. package/dist/__tests__/solve-issue-tea-worktree.test.js.map +1 -1
  71. package/dist/__tests__/step-ask.test.d.ts +2 -0
  72. package/dist/__tests__/step-ask.test.d.ts.map +1 -0
  73. package/dist/__tests__/step-ask.test.js +507 -0
  74. package/dist/__tests__/step-ask.test.js.map +1 -0
  75. package/dist/__tests__/step-show-json.test.js +1 -0
  76. package/dist/__tests__/step-show-json.test.js.map +1 -1
  77. package/dist/__tests__/step-timing.test.js +2 -0
  78. package/dist/__tests__/step-timing.test.js.map +1 -1
  79. package/dist/__tests__/store-global-cas.test.js +2 -2
  80. package/dist/__tests__/store-global-cas.test.js.map +1 -1
  81. package/dist/__tests__/store-unified-threads.test.js +28 -26
  82. package/dist/__tests__/store-unified-threads.test.js.map +1 -1
  83. package/dist/__tests__/thread-cancel-status.test.js +25 -19
  84. package/dist/__tests__/thread-cancel-status.test.js.map +1 -1
  85. package/dist/__tests__/thread-cancel-text-renderer.test.d.ts +2 -0
  86. package/dist/__tests__/thread-cancel-text-renderer.test.d.ts.map +1 -0
  87. package/dist/__tests__/thread-cancel-text-renderer.test.js +110 -0
  88. package/dist/__tests__/thread-cancel-text-renderer.test.js.map +1 -0
  89. package/dist/__tests__/thread-list-filters.test.js +354 -17
  90. package/dist/__tests__/thread-list-filters.test.js.map +1 -1
  91. package/dist/__tests__/thread-list-template-ms-date.test.d.ts +2 -0
  92. package/dist/__tests__/thread-list-template-ms-date.test.d.ts.map +1 -0
  93. package/dist/__tests__/thread-list-template-ms-date.test.js +102 -0
  94. package/dist/__tests__/thread-list-template-ms-date.test.js.map +1 -0
  95. package/dist/__tests__/thread-list-workflow-corrupt.test.d.ts +2 -0
  96. package/dist/__tests__/thread-list-workflow-corrupt.test.d.ts.map +1 -0
  97. package/dist/__tests__/thread-list-workflow-corrupt.test.js +157 -0
  98. package/dist/__tests__/thread-list-workflow-corrupt.test.js.map +1 -0
  99. package/dist/__tests__/thread-poke.test.d.ts +2 -0
  100. package/dist/__tests__/thread-poke.test.d.ts.map +1 -0
  101. package/dist/__tests__/thread-poke.test.js +422 -0
  102. package/dist/__tests__/thread-poke.test.js.map +1 -0
  103. package/dist/__tests__/thread-read-xml-tags.test.js +10 -9
  104. package/dist/__tests__/thread-read-xml-tags.test.js.map +1 -1
  105. package/dist/__tests__/thread-resume.test.js +21 -15
  106. package/dist/__tests__/thread-resume.test.js.map +1 -1
  107. package/dist/__tests__/thread-show-status.test.js +17 -28
  108. package/dist/__tests__/thread-show-status.test.js.map +1 -1
  109. package/dist/__tests__/thread-start-cwd-cli.test.js +15 -3
  110. package/dist/__tests__/thread-start-cwd-cli.test.js.map +1 -1
  111. package/dist/__tests__/thread-stop-text-renderer.test.d.ts +2 -0
  112. package/dist/__tests__/thread-stop-text-renderer.test.d.ts.map +1 -0
  113. package/dist/__tests__/thread-stop-text-renderer.test.js +148 -0
  114. package/dist/__tests__/thread-stop-text-renderer.test.js.map +1 -0
  115. package/dist/__tests__/thread-suspend-step.test.js +13 -16
  116. package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
  117. package/dist/__tests__/thread-suspended-display.test.js +10 -22
  118. package/dist/__tests__/thread-suspended-display.test.js.map +1 -1
  119. package/dist/__tests__/thread-test-helpers.d.ts +7 -0
  120. package/dist/__tests__/thread-test-helpers.d.ts.map +1 -1
  121. package/dist/__tests__/thread-test-helpers.js +13 -0
  122. package/dist/__tests__/thread-test-helpers.js.map +1 -1
  123. package/dist/__tests__/thread.test.js +15 -13
  124. package/dist/__tests__/thread.test.js.map +1 -1
  125. package/dist/__tests__/validate-semantic.test.js +105 -23
  126. package/dist/__tests__/validate-semantic.test.js.map +1 -1
  127. package/dist/__tests__/workflow-list-recursive.test.d.ts +2 -0
  128. package/dist/__tests__/workflow-list-recursive.test.d.ts.map +1 -0
  129. package/dist/__tests__/workflow-list-recursive.test.js +286 -0
  130. package/dist/__tests__/workflow-list-recursive.test.js.map +1 -0
  131. package/dist/__tests__/workflow-resolution.test.js +46 -28
  132. package/dist/__tests__/workflow-resolution.test.js.map +1 -1
  133. package/dist/__tests__/workflow-show-resolution.test.d.ts +2 -0
  134. package/dist/__tests__/workflow-show-resolution.test.d.ts.map +1 -0
  135. package/dist/__tests__/workflow-show-resolution.test.js +213 -0
  136. package/dist/__tests__/workflow-show-resolution.test.js.map +1 -0
  137. package/dist/__tests__/workflow-validate.test.d.ts +2 -0
  138. package/dist/__tests__/workflow-validate.test.d.ts.map +1 -0
  139. package/dist/__tests__/workflow-validate.test.js +707 -0
  140. package/dist/__tests__/workflow-validate.test.js.map +1 -0
  141. package/dist/__tests__/write-envelope.test.d.ts +2 -0
  142. package/dist/__tests__/write-envelope.test.d.ts.map +1 -0
  143. package/dist/__tests__/write-envelope.test.js +201 -0
  144. package/dist/__tests__/write-envelope.test.js.map +1 -0
  145. package/dist/background/background.d.ts +22 -1
  146. package/dist/background/background.d.ts.map +1 -1
  147. package/dist/background/background.js +83 -6
  148. package/dist/background/background.js.map +1 -1
  149. package/dist/background/index.d.ts +1 -1
  150. package/dist/background/index.d.ts.map +1 -1
  151. package/dist/background/index.js +1 -1
  152. package/dist/background/index.js.map +1 -1
  153. package/dist/background/types.d.ts +1 -0
  154. package/dist/background/types.d.ts.map +1 -1
  155. package/dist/cli.js +120 -62
  156. package/dist/cli.js.map +1 -1
  157. package/dist/commands/config.d.ts +3 -1
  158. package/dist/commands/config.d.ts.map +1 -1
  159. package/dist/commands/config.js +17 -31
  160. package/dist/commands/config.js.map +1 -1
  161. package/dist/commands/prompt.d.ts.map +1 -1
  162. package/dist/commands/prompt.js +57 -31
  163. package/dist/commands/prompt.js.map +1 -1
  164. package/dist/commands/setup.d.ts +12 -39
  165. package/dist/commands/setup.d.ts.map +1 -1
  166. package/dist/commands/setup.js +72 -303
  167. package/dist/commands/setup.js.map +1 -1
  168. package/dist/commands/step.d.ts +44 -1
  169. package/dist/commands/step.d.ts.map +1 -1
  170. package/dist/commands/step.js +255 -11
  171. package/dist/commands/step.js.map +1 -1
  172. package/dist/commands/thread.d.ts +16 -3
  173. package/dist/commands/thread.d.ts.map +1 -1
  174. package/dist/commands/thread.js +423 -142
  175. package/dist/commands/thread.js.map +1 -1
  176. package/dist/commands/workflow.d.ts +9 -1
  177. package/dist/commands/workflow.d.ts.map +1 -1
  178. package/dist/commands/workflow.js +126 -6
  179. package/dist/commands/workflow.js.map +1 -1
  180. package/dist/concurrency/concurrency.d.ts +34 -0
  181. package/dist/concurrency/concurrency.d.ts.map +1 -0
  182. package/dist/concurrency/concurrency.js +216 -0
  183. package/dist/concurrency/concurrency.js.map +1 -0
  184. package/dist/concurrency/index.d.ts +3 -0
  185. package/dist/concurrency/index.d.ts.map +1 -0
  186. package/dist/concurrency/index.js +2 -0
  187. package/dist/concurrency/index.js.map +1 -0
  188. package/dist/concurrency/types.d.ts +19 -0
  189. package/dist/concurrency/types.d.ts.map +1 -0
  190. package/dist/concurrency/types.js +2 -0
  191. package/dist/concurrency/types.js.map +1 -0
  192. package/dist/format.d.ts +69 -2
  193. package/dist/format.d.ts.map +1 -1
  194. package/dist/format.js +198 -1
  195. package/dist/format.js.map +1 -1
  196. package/dist/moderator/__tests__/evaluate.test.js +31 -17
  197. package/dist/moderator/__tests__/evaluate.test.js.map +1 -1
  198. package/dist/moderator/evaluate.d.ts.map +1 -1
  199. package/dist/moderator/evaluate.js +4 -16
  200. package/dist/moderator/evaluate.js.map +1 -1
  201. package/dist/moderator/index.d.ts +1 -2
  202. package/dist/moderator/index.d.ts.map +1 -1
  203. package/dist/moderator/index.js +0 -1
  204. package/dist/moderator/index.js.map +1 -1
  205. package/dist/moderator/types.d.ts +6 -10
  206. package/dist/moderator/types.d.ts.map +1 -1
  207. package/dist/moderator/types.js +1 -3
  208. package/dist/moderator/types.js.map +1 -1
  209. package/dist/output-mappers.d.ts +122 -0
  210. package/dist/output-mappers.d.ts.map +1 -0
  211. package/dist/output-mappers.js +134 -0
  212. package/dist/output-mappers.js.map +1 -0
  213. package/dist/schemas.d.ts +6 -1
  214. package/dist/schemas.d.ts.map +1 -1
  215. package/dist/schemas.js +34 -5
  216. package/dist/schemas.js.map +1 -1
  217. package/dist/store.d.ts +28 -9
  218. package/dist/store.d.ts.map +1 -1
  219. package/dist/store.js +75 -16
  220. package/dist/store.js.map +1 -1
  221. package/dist/text-renderers.d.ts +30 -0
  222. package/dist/text-renderers.d.ts.map +1 -0
  223. package/dist/text-renderers.js +251 -0
  224. package/dist/text-renderers.js.map +1 -0
  225. package/dist/validate-semantic.d.ts.map +1 -1
  226. package/dist/validate-semantic.js +95 -61
  227. package/dist/validate-semantic.js.map +1 -1
  228. package/dist/validate.d.ts +6 -0
  229. package/dist/validate.d.ts.map +1 -1
  230. package/dist/validate.js +24 -0
  231. package/dist/validate.js.map +1 -1
  232. package/examples/brainstorm.yaml +130 -0
  233. package/examples/debate.yaml +169 -0
  234. package/examples/socratic-questioning.yaml +112 -0
  235. package/package.json +9 -10
  236. package/src/__tests__/adapter-json-roundtrip.test.ts +16 -7
  237. package/src/__tests__/agent-resolution-llm-free.test.ts +39 -0
  238. package/src/__tests__/build-step-entry.test.ts +203 -0
  239. package/src/__tests__/clear-thread-failed-attempts.test.ts +122 -0
  240. package/src/__tests__/concurrency.test.ts +266 -0
  241. package/src/__tests__/config.test.ts +33 -321
  242. package/src/__tests__/current-role.test.ts +7 -6
  243. package/src/__tests__/e2e-mock-agent.test.ts +65 -30
  244. package/src/__tests__/fixtures/e2e-count.workflow.yaml +1 -0
  245. package/src/__tests__/fixtures/e2e-linear.workflow.yaml +1 -0
  246. package/src/__tests__/fixtures/{e2e-mustache.workflow.yaml → e2e-liquid.workflow.yaml} +3 -2
  247. package/src/__tests__/fixtures/e2e-loop.workflow.yaml +1 -0
  248. package/src/__tests__/fixtures/e2e-suspend.mock.yaml +2 -2
  249. package/src/__tests__/fixtures/e2e-suspend.workflow.yaml +6 -10
  250. package/src/__tests__/format-text-default.test.ts +49 -0
  251. package/src/__tests__/format-text-registry.test.ts +173 -0
  252. package/src/__tests__/issue-180-workflow-ref-removed.test.ts +43 -0
  253. package/src/__tests__/log-text-renderer.test.ts +294 -0
  254. package/src/__tests__/moderator-evaluate.test.ts +9 -52
  255. package/src/__tests__/output-mapper-thread-list-startedat.test.ts +124 -0
  256. package/src/__tests__/output-mapper-workflow-add.test.ts +24 -0
  257. package/src/__tests__/pid-recycling.test.ts +329 -0
  258. package/src/__tests__/prompt.test.ts +443 -2
  259. package/src/__tests__/resolve-head-hash.test.ts +11 -4
  260. package/src/__tests__/setup-agent-discovery.test.ts +26 -51
  261. package/src/__tests__/setup-complexity.test.ts +1 -203
  262. package/src/__tests__/setup-no-llm.test.ts +68 -0
  263. package/src/__tests__/solve-issue-tea-worktree.test.ts +27 -31
  264. package/src/__tests__/step-ask.test.ts +677 -0
  265. package/src/__tests__/step-show-json.test.ts +1 -0
  266. package/src/__tests__/step-timing.test.ts +2 -0
  267. package/src/__tests__/store-global-cas.test.ts +2 -2
  268. package/src/__tests__/store-unified-threads.test.ts +30 -27
  269. package/src/__tests__/thread-cancel-status.test.ts +27 -20
  270. package/src/__tests__/thread-cancel-text-renderer.test.ts +125 -0
  271. package/src/__tests__/thread-list-filters.test.ts +443 -17
  272. package/src/__tests__/thread-list-template-ms-date.test.ts +110 -0
  273. package/src/__tests__/thread-list-workflow-corrupt.test.ts +198 -0
  274. package/src/__tests__/thread-poke.test.ts +554 -0
  275. package/src/__tests__/thread-read-xml-tags.test.ts +9 -11
  276. package/src/__tests__/thread-resume.test.ts +20 -15
  277. package/src/__tests__/thread-show-status.test.ts +17 -29
  278. package/src/__tests__/thread-start-cwd-cli.test.ts +15 -3
  279. package/src/__tests__/thread-stop-text-renderer.test.ts +168 -0
  280. package/src/__tests__/thread-suspend-step.test.ts +13 -16
  281. package/src/__tests__/thread-suspended-display.test.ts +10 -22
  282. package/src/__tests__/thread-test-helpers.ts +15 -1
  283. package/src/__tests__/thread.test.ts +14 -14
  284. package/src/__tests__/validate-semantic.test.ts +118 -33
  285. package/src/__tests__/workflow-list-recursive.test.ts +370 -0
  286. package/src/__tests__/workflow-resolution.test.ts +48 -29
  287. package/src/__tests__/workflow-show-resolution.test.ts +286 -0
  288. package/src/__tests__/workflow-validate.test.ts +828 -0
  289. package/src/__tests__/write-envelope.test.ts +257 -0
  290. package/src/background/background.ts +88 -6
  291. package/src/background/index.ts +2 -0
  292. package/src/background/types.ts +1 -0
  293. package/src/cli.ts +184 -77
  294. package/src/commands/config.ts +16 -33
  295. package/src/commands/prompt.ts +57 -31
  296. package/src/commands/setup.ts +80 -358
  297. package/src/commands/step.ts +339 -12
  298. package/src/commands/thread.ts +511 -171
  299. package/src/commands/workflow.ts +155 -4
  300. package/src/concurrency/concurrency.ts +245 -0
  301. package/src/concurrency/index.ts +10 -0
  302. package/src/concurrency/types.ts +19 -0
  303. package/src/format.ts +282 -2
  304. package/src/moderator/__tests__/evaluate.test.ts +34 -17
  305. package/src/moderator/evaluate.ts +5 -17
  306. package/src/moderator/index.ts +1 -6
  307. package/src/moderator/types.ts +6 -14
  308. package/src/output-mappers.ts +254 -0
  309. package/src/schemas.ts +51 -5
  310. package/src/store.ts +86 -20
  311. package/src/text-renderers.ts +355 -0
  312. package/src/validate-semantic.ts +125 -73
  313. package/src/validate.ts +27 -0
  314. package/dist/__tests__/setup-validate.test.d.ts +0 -2
  315. package/dist/__tests__/setup-validate.test.d.ts.map +0 -1
  316. package/dist/__tests__/setup-validate.test.js +0 -108
  317. package/dist/__tests__/setup-validate.test.js.map +0 -1
  318. package/src/__tests__/setup-validate.test.ts +0 -148
  319. /package/src/__tests__/fixtures/{e2e-mustache.mock.yaml → e2e-liquid.mock.yaml} +0 -0
@@ -0,0 +1,196 @@
1
+ import { mkdir, mkdtemp, readdir, rm, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
5
+ import { acquireSlot, cleanStaleSlots, countActiveSlots, DEFAULT_MAX_RUNNING, getSlotsDir, installSlotCleanup, } from "../concurrency/index.js";
6
+ // ── test setup ────────────────────────────────────────────────────────────────
7
+ let tmpDir;
8
+ beforeEach(async () => {
9
+ tmpDir = await mkdtemp(join(tmpdir(), "concurrency-test-"));
10
+ });
11
+ afterEach(async () => {
12
+ await rm(tmpDir, { recursive: true, force: true });
13
+ });
14
+ // ── Spec: concurrency-acquire-slot-under-limit ──────────────────────────────
15
+ describe("acquireSlot succeeds immediately when below maxRunning", () => {
16
+ test("creates slot file and returns SlotHandle when under limit", async () => {
17
+ const handle = await acquireSlot(tmpDir, 2);
18
+ // Slot file exists
19
+ const slotsDir = getSlotsDir(tmpDir);
20
+ const files = await readdir(slotsDir);
21
+ expect(files).toContain(`${process.pid}.slot`);
22
+ // Returns a SlotHandle with release()
23
+ expect(handle).toHaveProperty("release");
24
+ expect(typeof handle.release).toBe("function");
25
+ // countActiveSlots returns 1
26
+ const count = await countActiveSlots(tmpDir);
27
+ expect(count).toBe(1);
28
+ // Cleanup
29
+ await handle.release();
30
+ });
31
+ test("returns immediately (no blocking) when slots available", async () => {
32
+ const start = Date.now();
33
+ const handle = await acquireSlot(tmpDir, 2);
34
+ const elapsed = Date.now() - start;
35
+ // Should complete in well under 1 second (no polling delay)
36
+ expect(elapsed).toBeLessThan(500);
37
+ await handle.release();
38
+ });
39
+ });
40
+ // ── Spec: concurrency-acquire-slot-blocks-at-limit ──────────────────────────
41
+ describe("acquireSlot blocks when at capacity", () => {
42
+ test("calls onWaiting when all slots are occupied", async () => {
43
+ // Create a slot file for a "live" process — use parent PID (same user, signalable)
44
+ const slotsDir = getSlotsDir(tmpDir);
45
+ await mkdir(slotsDir, { recursive: true });
46
+ const blockerPid = process.ppid;
47
+ await writeFile(join(slotsDir, `${blockerPid}.slot`), "", "utf8");
48
+ const onWaiting = vi.fn();
49
+ const onAcquired = vi.fn();
50
+ // maxRunning=1, one slot occupied → should block
51
+ // Release the blocking slot after a brief delay
52
+ setTimeout(async () => {
53
+ await rm(join(slotsDir, `${blockerPid}.slot`), { force: true });
54
+ }, 200);
55
+ const handle = await acquireSlot(tmpDir, 1, {
56
+ onWaiting,
57
+ onAcquired,
58
+ pollIntervalMs: 100,
59
+ });
60
+ expect(onWaiting).toHaveBeenCalled();
61
+ expect(onAcquired).toHaveBeenCalled();
62
+ await handle.release();
63
+ });
64
+ test("polls with interval and proceeds after slot is freed", async () => {
65
+ const slotsDir = getSlotsDir(tmpDir);
66
+ await mkdir(slotsDir, { recursive: true });
67
+ const blockerPid = process.ppid;
68
+ await writeFile(join(slotsDir, `${blockerPid}.slot`), "", "utf8");
69
+ // Remove after 250ms
70
+ setTimeout(async () => {
71
+ await rm(join(slotsDir, `${blockerPid}.slot`), { force: true });
72
+ }, 250);
73
+ const start = Date.now();
74
+ const handle = await acquireSlot(tmpDir, 1, { pollIntervalMs: 100 });
75
+ const elapsed = Date.now() - start;
76
+ // Should have waited at least ~200ms (polling)
77
+ expect(elapsed).toBeGreaterThanOrEqual(150);
78
+ await handle.release();
79
+ });
80
+ });
81
+ // ── Spec: concurrency-stale-slot-cleanup ────────────────────────────────────
82
+ describe("cleanStaleSlots removes slot files for dead PIDs", () => {
83
+ test("removes slot file for dead PID, preserves live PID", async () => {
84
+ const slotsDir = getSlotsDir(tmpDir);
85
+ await mkdir(slotsDir, { recursive: true });
86
+ // Dead PID (99999999 should not exist)
87
+ await writeFile(join(slotsDir, "99999999.slot"), "", "utf8");
88
+ // Live PID (current process)
89
+ await writeFile(join(slotsDir, `${process.pid}.slot`), "", "utf8");
90
+ const cleaned = await cleanStaleSlots(tmpDir);
91
+ expect(cleaned).toBe(1);
92
+ const files = await readdir(slotsDir);
93
+ expect(files).not.toContain("99999999.slot");
94
+ expect(files).toContain(`${process.pid}.slot`);
95
+ });
96
+ test("countActiveSlots reflects correct count after cleanup", async () => {
97
+ const slotsDir = getSlotsDir(tmpDir);
98
+ await mkdir(slotsDir, { recursive: true });
99
+ // 1 dead + 1 live
100
+ await writeFile(join(slotsDir, "99999999.slot"), "", "utf8");
101
+ await writeFile(join(slotsDir, `${process.pid}.slot`), "", "utf8");
102
+ // Before cleanup: 2 files
103
+ const beforeFiles = await readdir(slotsDir);
104
+ expect(beforeFiles.filter((f) => f.endsWith(".slot")).length).toBe(2);
105
+ await cleanStaleSlots(tmpDir);
106
+ // After cleanup
107
+ const count = await countActiveSlots(tmpDir);
108
+ expect(count).toBe(1);
109
+ });
110
+ });
111
+ // ── Spec: concurrency-race-protection-rollback ──────────────────────────────
112
+ describe("acquireSlot rolls back on race condition", () => {
113
+ test("rolls back slot file if post-write count exceeds maxRunning", async () => {
114
+ const slotsDir = getSlotsDir(tmpDir);
115
+ await mkdir(slotsDir, { recursive: true });
116
+ // Simulate: maxRunning=2, and we already have 1 slot from another live process
117
+ const blockerPid = process.ppid;
118
+ await writeFile(join(slotsDir, `${blockerPid}.slot`), "", "utf8");
119
+ // Our process writes its slot, making count=2 which equals maxRunning=2
120
+ // This should succeed (at limit, not over)
121
+ const handle = await acquireSlot(tmpDir, 2);
122
+ const count = await countActiveSlots(tmpDir);
123
+ expect(count).toBe(2);
124
+ await handle.release();
125
+ });
126
+ test("when another slot appears during write, rollback occurs", async () => {
127
+ // This tests the double-check logic. We'll simulate by pre-filling to capacity.
128
+ const slotsDir = getSlotsDir(tmpDir);
129
+ await mkdir(slotsDir, { recursive: true });
130
+ // maxRunning=1, one slot already occupied by parent PID
131
+ const blockerPid = process.ppid;
132
+ await writeFile(join(slotsDir, `${blockerPid}.slot`), "", "utf8");
133
+ // Release after delay so acquireSlot can proceed
134
+ setTimeout(async () => {
135
+ await rm(join(slotsDir, `${blockerPid}.slot`), { force: true });
136
+ }, 200);
137
+ const handle = await acquireSlot(tmpDir, 1, { pollIntervalMs: 100 });
138
+ // After acquiring, only our slot should exist
139
+ const files = await readdir(slotsDir);
140
+ const slotFiles = files.filter((f) => f.endsWith(".slot"));
141
+ expect(slotFiles).toContain(`${process.pid}.slot`);
142
+ await handle.release();
143
+ });
144
+ });
145
+ // ── Spec: concurrency-exec-signal-cleanup ────────────────────────────────────
146
+ describe("installSlotCleanup removes slot on signal", () => {
147
+ test("release function removes slot file", async () => {
148
+ const handle = await acquireSlot(tmpDir, 2);
149
+ // Verify slot exists
150
+ const slotsDir = getSlotsDir(tmpDir);
151
+ const filesBefore = await readdir(slotsDir);
152
+ expect(filesBefore).toContain(`${process.pid}.slot`);
153
+ // installSlotCleanup returns a cleanup function
154
+ const cleanup = installSlotCleanup(handle);
155
+ // Call release directly (simulating what signal handler would do)
156
+ await handle.release();
157
+ const filesAfter = await readdir(slotsDir);
158
+ expect(filesAfter).not.toContain(`${process.pid}.slot`);
159
+ // Uninstall the cleanup handler
160
+ cleanup();
161
+ });
162
+ });
163
+ // ── Spec: concurrency-default-max-running ────────────────────────────────────
164
+ describe("DEFAULT_MAX_RUNNING is 2", () => {
165
+ test("constant equals 2", () => {
166
+ expect(DEFAULT_MAX_RUNNING).toBe(2);
167
+ });
168
+ });
169
+ // ── Spec: concurrency-exec-uses-slot (unit level) ───────────────────────────
170
+ describe("slot lifecycle during exec", () => {
171
+ test("acquireSlot + release = 0 active slots", async () => {
172
+ const handle = await acquireSlot(tmpDir, 2);
173
+ expect(await countActiveSlots(tmpDir)).toBe(1);
174
+ await handle.release();
175
+ expect(await countActiveSlots(tmpDir)).toBe(0);
176
+ });
177
+ test("release is idempotent", async () => {
178
+ const handle = await acquireSlot(tmpDir, 2);
179
+ await handle.release();
180
+ // Calling release again should not throw
181
+ await handle.release();
182
+ expect(await countActiveSlots(tmpDir)).toBe(0);
183
+ });
184
+ });
185
+ // ── Spec: concurrency-config-set-max-running ─────────────────────────────────
186
+ describe("config set concurrency.maxRunning", () => {
187
+ test("concurrency config key is validated correctly", async () => {
188
+ // Import config module to test the key validation
189
+ const { parseDotPath, setNestedValue } = await import("../commands/config.js");
190
+ const config = {};
191
+ const path = parseDotPath("concurrency.maxRunning");
192
+ setNestedValue(config, path, 3);
193
+ expect(config).toEqual({ concurrency: { maxRunning: 3 } });
194
+ });
195
+ });
196
+ //# sourceMappingURL=concurrency.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.test.js","sourceRoot":"","sources":["../../src/__tests__/concurrency.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE3E,OAAO,EACL,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AAEjC,iFAAiF;AAEjF,IAAI,MAAc,CAAC;AAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACtE,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAE5C,mBAAmB;QACnB,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;QAE/C,sCAAsC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE/C,6BAA6B;QAC7B,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,UAAU;QACV,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAEnC,4DAA4D;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAElC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC7D,mFAAmF;QACnF,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAElE,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAE3B,iDAAiD;QACjD,gDAAgD;QAChD,UAAU,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE;YAC1C,SAAS;YACT,UAAU;YACV,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAEtC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAElE,qBAAqB;QACrB,UAAU,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAEnC,+CAA+C;QAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAE5C,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,uCAAuC;QACvC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAC7D,6BAA6B;QAC7B,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAEnE,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAExB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,kBAAkB;QAClB,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAEnE,0BAA0B;QAC1B,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtE,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QAE9B,gBAAgB;QAChB,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,+EAA+E;QAC/E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAElE,wEAAwE;QACxE,2CAA2C;QAC3C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACzE,gFAAgF;QAChF,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,wDAAwD;QACxD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QAElE,iDAAiD;QACjD,UAAU,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,UAAU,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;QAErE,8CAA8C;QAC9C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;QAEnD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,IAAI,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAE5C,qBAAqB;QACrB,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;QAErD,gDAAgD;QAChD,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAE3C,kEAAkE;QAClE,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAEvB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;QAExD,gCAAgC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,IAAI,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE/C,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,yCAAyC;QACzC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC/D,kDAAkD;QAClD,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAE/E,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;QACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}