groundswell 0.0.2 → 1.0.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 (554) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -9
  3. package/dist/cache/cache-key.d.ts +86 -0
  4. package/dist/cache/cache-key.d.ts.map +1 -0
  5. package/dist/cache/cache-key.js +204 -0
  6. package/dist/cache/cache-key.js.map +1 -0
  7. package/dist/cache/cache.d.ts +104 -0
  8. package/dist/cache/cache.d.ts.map +1 -0
  9. package/dist/cache/cache.js +179 -0
  10. package/dist/cache/cache.js.map +1 -0
  11. package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
  12. package/dist/cache/index.d.ts.map +1 -0
  13. package/dist/cache/index.js +6 -0
  14. package/dist/cache/index.js.map +1 -0
  15. package/dist/core/agent.d.ts +203 -0
  16. package/dist/core/agent.d.ts.map +1 -0
  17. package/dist/core/agent.js +833 -0
  18. package/dist/core/agent.js.map +1 -0
  19. package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
  20. package/dist/core/context.d.ts.map +1 -0
  21. package/dist/core/context.js +80 -0
  22. package/dist/core/context.js.map +1 -0
  23. package/dist/core/event-tree.d.ts +72 -0
  24. package/dist/core/event-tree.d.ts.map +1 -0
  25. package/dist/core/event-tree.js +211 -0
  26. package/dist/core/event-tree.js.map +1 -0
  27. package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
  28. package/dist/core/factory.d.ts.map +1 -0
  29. package/dist/core/factory.js +110 -0
  30. package/dist/core/factory.js.map +1 -0
  31. package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +9 -0
  34. package/dist/core/index.js.map +1 -0
  35. package/dist/core/logger.d.ts +50 -0
  36. package/dist/core/logger.d.ts.map +1 -0
  37. package/dist/core/logger.js +91 -0
  38. package/dist/core/logger.js.map +1 -0
  39. package/dist/core/mcp-handler.d.ts +127 -0
  40. package/dist/core/mcp-handler.d.ts.map +1 -0
  41. package/dist/core/mcp-handler.js +323 -0
  42. package/dist/core/mcp-handler.js.map +1 -0
  43. package/dist/core/prompt.d.ts +80 -0
  44. package/dist/core/prompt.d.ts.map +1 -0
  45. package/dist/core/prompt.js +120 -0
  46. package/dist/core/prompt.js.map +1 -0
  47. package/dist/core/workflow-context.d.ts +61 -0
  48. package/dist/core/workflow-context.d.ts.map +1 -0
  49. package/dist/core/workflow-context.js +358 -0
  50. package/dist/core/workflow-context.js.map +1 -0
  51. package/dist/core/workflow.d.ts +543 -0
  52. package/dist/core/workflow.d.ts.map +1 -0
  53. package/dist/core/workflow.js +986 -0
  54. package/dist/core/workflow.js.map +1 -0
  55. package/dist/debugger/event-replayer.d.ts +422 -0
  56. package/dist/debugger/event-replayer.d.ts.map +1 -0
  57. package/dist/debugger/event-replayer.js +639 -0
  58. package/dist/debugger/event-replayer.js.map +1 -0
  59. package/dist/debugger/index.d.ts +2 -0
  60. package/dist/debugger/index.d.ts.map +1 -0
  61. package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
  62. package/dist/debugger/index.js.map +1 -0
  63. package/dist/debugger/tree-debugger.d.ts +240 -0
  64. package/dist/debugger/tree-debugger.d.ts.map +1 -0
  65. package/dist/debugger/tree-debugger.js +620 -0
  66. package/dist/debugger/tree-debugger.js.map +1 -0
  67. package/dist/decorators/index.d.ts +4 -0
  68. package/dist/decorators/index.d.ts.map +1 -0
  69. package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
  70. package/dist/decorators/index.js.map +1 -0
  71. package/dist/decorators/observed-state.d.ts +32 -0
  72. package/dist/decorators/observed-state.d.ts.map +1 -0
  73. package/dist/decorators/observed-state.js +79 -0
  74. package/dist/decorators/observed-state.js.map +1 -0
  75. package/dist/decorators/step.d.ts +15 -0
  76. package/dist/decorators/step.d.ts.map +1 -0
  77. package/dist/decorators/step.js +192 -0
  78. package/dist/decorators/step.js.map +1 -0
  79. package/dist/decorators/task.d.ts +50 -0
  80. package/dist/decorators/task.d.ts.map +1 -0
  81. package/dist/decorators/task.js +118 -0
  82. package/dist/decorators/task.js.map +1 -0
  83. package/dist/examples/index.d.ts +3 -0
  84. package/dist/examples/index.d.ts.map +1 -0
  85. package/{src/examples/index.ts → dist/examples/index.js} +1 -0
  86. package/dist/examples/index.js.map +1 -0
  87. package/dist/examples/tdd-orchestrator.d.ts +15 -0
  88. package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
  89. package/dist/examples/tdd-orchestrator.js +121 -0
  90. package/dist/examples/tdd-orchestrator.js.map +1 -0
  91. package/dist/examples/test-cycle-workflow.d.ts +14 -0
  92. package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
  93. package/dist/examples/test-cycle-workflow.js +116 -0
  94. package/dist/examples/test-cycle-workflow.js.map +1 -0
  95. package/dist/harnesses/claude-code-harness.d.ts +391 -0
  96. package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
  97. package/dist/harnesses/claude-code-harness.js +1076 -0
  98. package/dist/harnesses/claude-code-harness.js.map +1 -0
  99. package/dist/harnesses/harness-registry.d.ts +440 -0
  100. package/dist/harnesses/harness-registry.d.ts.map +1 -0
  101. package/dist/harnesses/harness-registry.js +543 -0
  102. package/dist/harnesses/harness-registry.js.map +1 -0
  103. package/dist/harnesses/index.d.ts +12 -0
  104. package/dist/harnesses/index.d.ts.map +1 -0
  105. package/dist/harnesses/index.js +11 -0
  106. package/dist/harnesses/index.js.map +1 -0
  107. package/dist/harnesses/pi-harness.d.ts +219 -0
  108. package/dist/harnesses/pi-harness.d.ts.map +1 -0
  109. package/dist/harnesses/pi-harness.js +676 -0
  110. package/dist/harnesses/pi-harness.js.map +1 -0
  111. package/dist/harnesses/pi-schema-converter.d.ts +24 -0
  112. package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
  113. package/dist/harnesses/pi-schema-converter.js +81 -0
  114. package/dist/harnesses/pi-schema-converter.js.map +1 -0
  115. package/dist/harnesses/register-defaults.d.ts +24 -0
  116. package/dist/harnesses/register-defaults.d.ts.map +1 -0
  117. package/dist/harnesses/register-defaults.js +40 -0
  118. package/dist/harnesses/register-defaults.js.map +1 -0
  119. package/dist/harnesses/session-store.d.ts +201 -0
  120. package/dist/harnesses/session-store.d.ts.map +1 -0
  121. package/dist/harnesses/session-store.js +254 -0
  122. package/dist/harnesses/session-store.js.map +1 -0
  123. package/dist/index.d.ts +37 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +57 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/reflection/index.d.ts +5 -0
  128. package/dist/reflection/index.d.ts.map +1 -0
  129. package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
  130. package/dist/reflection/index.js.map +1 -0
  131. package/dist/reflection/reflection.d.ts +84 -0
  132. package/dist/reflection/reflection.d.ts.map +1 -0
  133. package/dist/reflection/reflection.js +344 -0
  134. package/dist/reflection/reflection.js.map +1 -0
  135. package/dist/tools/index.d.ts +6 -0
  136. package/dist/tools/index.d.ts.map +1 -0
  137. package/dist/tools/index.js +11 -0
  138. package/dist/tools/index.js.map +1 -0
  139. package/dist/tools/introspection.d.ts +165 -0
  140. package/dist/tools/introspection.d.ts.map +1 -0
  141. package/dist/tools/introspection.js +324 -0
  142. package/dist/tools/introspection.js.map +1 -0
  143. package/dist/types/agent.d.ts +1317 -0
  144. package/dist/types/agent.d.ts.map +1 -0
  145. package/dist/types/agent.js +423 -0
  146. package/dist/types/agent.js.map +1 -0
  147. package/dist/types/decorators.d.ts +40 -0
  148. package/dist/types/decorators.d.ts.map +1 -0
  149. package/dist/types/decorators.js +2 -0
  150. package/dist/types/decorators.js.map +1 -0
  151. package/dist/types/error-strategy.d.ts +13 -0
  152. package/dist/types/error-strategy.d.ts.map +1 -0
  153. package/dist/types/error-strategy.js +2 -0
  154. package/dist/types/error-strategy.js.map +1 -0
  155. package/dist/types/error.d.ts +20 -0
  156. package/dist/types/error.d.ts.map +1 -0
  157. package/dist/types/error.js +2 -0
  158. package/dist/types/error.js.map +1 -0
  159. package/dist/types/events.d.ts +113 -0
  160. package/dist/types/events.d.ts.map +1 -0
  161. package/dist/types/events.js +2 -0
  162. package/dist/types/events.js.map +1 -0
  163. package/dist/types/harnesses.d.ts +474 -0
  164. package/dist/types/harnesses.d.ts.map +1 -0
  165. package/dist/types/harnesses.js +2 -0
  166. package/dist/types/harnesses.js.map +1 -0
  167. package/dist/types/index.d.ts +23 -0
  168. package/dist/types/index.d.ts.map +1 -0
  169. package/dist/types/index.js +8 -0
  170. package/dist/types/index.js.map +1 -0
  171. package/dist/types/logging.d.ts +24 -0
  172. package/dist/types/logging.d.ts.map +1 -0
  173. package/dist/types/logging.js +2 -0
  174. package/dist/types/logging.js.map +1 -0
  175. package/dist/types/observer.d.ts +18 -0
  176. package/dist/types/observer.d.ts.map +1 -0
  177. package/dist/types/observer.js +2 -0
  178. package/dist/types/observer.js.map +1 -0
  179. package/dist/types/prompt.d.ts +31 -0
  180. package/dist/types/prompt.d.ts.map +1 -0
  181. package/dist/types/prompt.js +6 -0
  182. package/dist/types/prompt.js.map +1 -0
  183. package/dist/types/providers.d.ts +691 -0
  184. package/dist/types/providers.d.ts.map +1 -0
  185. package/dist/types/providers.js +14 -0
  186. package/dist/types/providers.js.map +1 -0
  187. package/dist/types/reflection.d.ts +96 -0
  188. package/dist/types/reflection.d.ts.map +1 -0
  189. package/dist/types/reflection.js +24 -0
  190. package/dist/types/reflection.js.map +1 -0
  191. package/dist/types/restart.d.ts +132 -0
  192. package/dist/types/restart.d.ts.map +1 -0
  193. package/dist/types/restart.js +2 -0
  194. package/dist/types/restart.js.map +1 -0
  195. package/dist/types/sdk-primitives.d.ts +118 -0
  196. package/dist/types/sdk-primitives.d.ts.map +1 -0
  197. package/dist/types/sdk-primitives.js +6 -0
  198. package/dist/types/sdk-primitives.js.map +1 -0
  199. package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
  200. package/dist/types/snapshot.d.ts.map +1 -0
  201. package/dist/types/snapshot.js +2 -0
  202. package/dist/types/snapshot.js.map +1 -0
  203. package/dist/types/streaming.d.ts +194 -0
  204. package/dist/types/streaming.d.ts.map +1 -0
  205. package/dist/types/streaming.js +67 -0
  206. package/dist/types/streaming.js.map +1 -0
  207. package/dist/types/workflow-context.d.ts +275 -0
  208. package/dist/types/workflow-context.d.ts.map +1 -0
  209. package/dist/types/workflow-context.js +8 -0
  210. package/dist/types/workflow-context.js.map +1 -0
  211. package/dist/types/workflow.d.ts +30 -0
  212. package/dist/types/workflow.d.ts.map +1 -0
  213. package/dist/types/workflow.js +2 -0
  214. package/dist/types/workflow.js.map +1 -0
  215. package/dist/utils/agent-validation.d.ts +88 -0
  216. package/dist/utils/agent-validation.d.ts.map +1 -0
  217. package/dist/utils/agent-validation.js +87 -0
  218. package/dist/utils/agent-validation.js.map +1 -0
  219. package/dist/utils/delay.d.ts +7 -0
  220. package/dist/utils/delay.d.ts.map +1 -0
  221. package/dist/utils/delay.js +9 -0
  222. package/dist/utils/delay.js.map +1 -0
  223. package/dist/utils/harness-config.d.ts +180 -0
  224. package/dist/utils/harness-config.d.ts.map +1 -0
  225. package/dist/utils/harness-config.js +311 -0
  226. package/dist/utils/harness-config.js.map +1 -0
  227. package/dist/utils/id.d.ts +6 -0
  228. package/dist/utils/id.d.ts.map +1 -0
  229. package/dist/utils/id.js +12 -0
  230. package/dist/utils/id.js.map +1 -0
  231. package/dist/utils/index.d.ts +13 -0
  232. package/dist/utils/index.d.ts.map +1 -0
  233. package/dist/utils/index.js +11 -0
  234. package/dist/utils/index.js.map +1 -0
  235. package/dist/utils/model-spec.d.ts +110 -0
  236. package/dist/utils/model-spec.d.ts.map +1 -0
  237. package/dist/utils/model-spec.js +149 -0
  238. package/dist/utils/model-spec.js.map +1 -0
  239. package/dist/utils/observable.d.ts +54 -0
  240. package/dist/utils/observable.d.ts.map +1 -0
  241. package/dist/utils/observable.js +82 -0
  242. package/dist/utils/observable.js.map +1 -0
  243. package/dist/utils/provider-config.d.ts +10 -0
  244. package/dist/utils/provider-config.d.ts.map +1 -0
  245. package/dist/utils/provider-config.js +10 -0
  246. package/dist/utils/provider-config.js.map +1 -0
  247. package/dist/utils/restart-analysis.d.ts +202 -0
  248. package/dist/utils/restart-analysis.d.ts.map +1 -0
  249. package/dist/utils/restart-analysis.js +426 -0
  250. package/dist/utils/restart-analysis.js.map +1 -0
  251. package/dist/utils/session-serialization.d.ts +118 -0
  252. package/dist/utils/session-serialization.d.ts.map +1 -0
  253. package/dist/utils/session-serialization.js +217 -0
  254. package/dist/utils/session-serialization.js.map +1 -0
  255. package/dist/utils/workflow-error-utils.d.ts +22 -0
  256. package/dist/utils/workflow-error-utils.d.ts.map +1 -0
  257. package/dist/utils/workflow-error-utils.js +45 -0
  258. package/dist/utils/workflow-error-utils.js.map +1 -0
  259. package/package.json +34 -5
  260. package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
  261. package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
  262. package/.claude/commands/task-breakdown.md +0 -94
  263. package/.claude/settings.local.json +0 -9
  264. package/.claude/system_prompts/task-breakdown.md +0 -101
  265. package/CHANGELOG.md +0 -188
  266. package/PRD.md +0 -543
  267. package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
  268. package/PRPs/PRDs/002-agent-prompt.md +0 -390
  269. package/PRPs/PRDs/003-agent-prompt.md +0 -943
  270. package/PRPs/PRDs/004-agent-prompt.md +0 -1136
  271. package/PRPs/PRDs/tasks-001.json +0 -492
  272. package/PRPs/README.md +0 -83
  273. package/PRPs/templates/prp_base.md +0 -222
  274. package/docs/agent.md +0 -422
  275. package/docs/prompt.md +0 -419
  276. package/docs/workflow.md +0 -600
  277. package/examples/README.md +0 -258
  278. package/examples/examples/01-basic-workflow.ts +0 -100
  279. package/examples/examples/02-decorator-options.ts +0 -217
  280. package/examples/examples/03-parent-child.ts +0 -241
  281. package/examples/examples/04-observers-debugger.ts +0 -340
  282. package/examples/examples/05-error-handling.ts +0 -387
  283. package/examples/examples/06-concurrent-tasks.ts +0 -352
  284. package/examples/examples/07-agent-loops.ts +0 -432
  285. package/examples/examples/08-sdk-features.ts +0 -667
  286. package/examples/examples/09-reflection.ts +0 -573
  287. package/examples/examples/10-introspection.ts +0 -550
  288. package/examples/examples/11-reparenting-workflows.ts +0 -269
  289. package/examples/index.ts +0 -147
  290. package/examples/utils/helpers.ts +0 -57
  291. package/package-lock.json +0 -2398
  292. package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
  293. package/plan/001_d3bb02af4886/backlog.json +0 -867
  294. package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
  295. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
  296. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
  297. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
  298. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
  299. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
  300. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
  301. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
  302. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
  303. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
  304. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
  305. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
  306. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
  307. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
  308. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
  309. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
  310. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
  311. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
  312. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
  313. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
  314. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
  315. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
  316. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
  317. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
  318. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
  319. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
  320. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
  321. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
  322. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
  323. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
  324. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
  325. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
  326. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
  327. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
  328. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
  329. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
  330. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
  331. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
  332. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
  333. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
  334. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
  335. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
  336. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
  337. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
  338. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
  339. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
  340. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
  341. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
  342. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
  343. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
  344. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
  345. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
  346. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
  347. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
  348. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
  349. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
  350. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
  351. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
  352. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
  353. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
  354. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
  355. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
  356. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
  357. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
  358. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
  359. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
  360. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
  361. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
  362. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
  363. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
  364. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
  365. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
  366. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
  367. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
  368. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
  369. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
  370. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
  371. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
  372. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
  373. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
  374. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
  375. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
  376. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
  377. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
  378. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
  379. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
  380. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
  381. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
  382. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
  383. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
  384. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
  385. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
  386. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
  387. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
  388. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
  389. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
  390. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
  391. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
  392. package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
  393. package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
  394. package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
  395. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
  396. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
  397. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
  398. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
  399. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
  400. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
  401. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
  402. package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
  403. package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
  404. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
  405. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
  406. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
  407. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
  408. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
  409. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
  410. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
  411. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
  412. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
  413. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
  414. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
  415. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
  416. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
  417. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
  418. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
  419. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
  420. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
  421. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
  422. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
  423. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
  424. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
  425. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
  426. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
  427. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
  428. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
  429. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
  430. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
  431. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
  432. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
  433. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
  434. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
  435. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
  436. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
  437. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
  438. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
  439. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
  440. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
  441. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
  442. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
  443. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
  444. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
  445. package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
  446. package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
  447. package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
  448. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
  449. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
  450. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
  451. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
  452. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
  453. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
  454. package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
  455. package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
  456. package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
  457. package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
  458. package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
  459. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
  460. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
  461. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
  462. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
  463. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
  464. package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
  465. package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
  466. package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
  467. package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
  468. package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
  469. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
  470. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
  471. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
  472. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
  473. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
  474. package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
  475. package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
  476. package/scripts/generate-llms-full.ts +0 -206
  477. package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
  478. package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
  479. package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
  480. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
  481. package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
  482. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
  483. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
  484. package/src/__tests__/adversarial/edge-case.test.ts +0 -703
  485. package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
  486. package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
  487. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
  488. package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
  489. package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
  490. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
  491. package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
  492. package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
  493. package/src/__tests__/helpers/index.ts +0 -18
  494. package/src/__tests__/helpers/tree-verification.ts +0 -257
  495. package/src/__tests__/integration/agent-workflow.test.ts +0 -256
  496. package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
  497. package/src/__tests__/integration/observer-logging.test.ts +0 -643
  498. package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
  499. package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
  500. package/src/__tests__/unit/agent.test.ts +0 -169
  501. package/src/__tests__/unit/cache-key.test.ts +0 -182
  502. package/src/__tests__/unit/cache.test.ts +0 -172
  503. package/src/__tests__/unit/context.test.ts +0 -217
  504. package/src/__tests__/unit/decorators.test.ts +0 -100
  505. package/src/__tests__/unit/introspection-tools.test.ts +0 -277
  506. package/src/__tests__/unit/logger.test.ts +0 -293
  507. package/src/__tests__/unit/observable.test.ts +0 -321
  508. package/src/__tests__/unit/prompt.test.ts +0 -135
  509. package/src/__tests__/unit/reflection.test.ts +0 -210
  510. package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
  511. package/src/__tests__/unit/tree-debugger.test.ts +0 -85
  512. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
  513. package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
  514. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
  515. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
  516. package/src/__tests__/unit/workflow.test.ts +0 -357
  517. package/src/cache/cache-key.ts +0 -244
  518. package/src/cache/cache.ts +0 -236
  519. package/src/core/agent.ts +0 -593
  520. package/src/core/event-tree.ts +0 -260
  521. package/src/core/logger.ts +0 -112
  522. package/src/core/mcp-handler.ts +0 -184
  523. package/src/core/prompt.ts +0 -150
  524. package/src/core/workflow-context.ts +0 -351
  525. package/src/core/workflow.ts +0 -540
  526. package/src/debugger/tree-debugger.ts +0 -255
  527. package/src/decorators/observed-state.ts +0 -95
  528. package/src/decorators/step.ts +0 -139
  529. package/src/decorators/task.ts +0 -159
  530. package/src/examples/tdd-orchestrator.ts +0 -65
  531. package/src/examples/test-cycle-workflow.ts +0 -64
  532. package/src/index.ts +0 -142
  533. package/src/reflection/reflection.ts +0 -407
  534. package/src/tools/index.ts +0 -36
  535. package/src/tools/introspection.ts +0 -464
  536. package/src/types/agent.ts +0 -90
  537. package/src/types/decorators.ts +0 -32
  538. package/src/types/error-strategy.ts +0 -13
  539. package/src/types/error.ts +0 -20
  540. package/src/types/events.ts +0 -75
  541. package/src/types/index.ts +0 -55
  542. package/src/types/logging.ts +0 -24
  543. package/src/types/observer.ts +0 -18
  544. package/src/types/prompt.ts +0 -40
  545. package/src/types/reflection.ts +0 -117
  546. package/src/types/sdk-primitives.ts +0 -128
  547. package/src/types/workflow-context.ts +0 -163
  548. package/src/types/workflow.ts +0 -37
  549. package/src/utils/id.ts +0 -11
  550. package/src/utils/index.ts +0 -4
  551. package/src/utils/observable.ts +0 -106
  552. package/src/utils/workflow-error-utils.ts +0 -56
  553. package/tsconfig.json +0 -22
  554. package/vitest.config.ts +0 -16
@@ -1,1066 +0,0 @@
1
- name: "P1.M2.T2.S2 - Implement Error Aggregation Logic in @Task Decorator"
2
- description: |
3
-
4
- ---
5
-
6
- ## Goal
7
-
8
- **Feature Goal**: Implement error aggregation logic in the @Task decorator to support the `errorMergeStrategy` option, enabling users to configure how multiple concurrent workflow errors are merged and propagated.
9
-
10
- **Deliverable**: Updated @Task decorator (`src/decorators/task.ts`) that:
11
-
12
- 1. Checks if `opts.errorMergeStrategy?.enabled` is true after collecting errors from Promise.allSettled()
13
- 2. Calls `opts.errorMergeStrategy.combine?(errors)` if provided, otherwise uses a default error merger
14
- 3. Throws the merged error instead of the first error when error merge strategy is enabled
15
- 4. Emits error event with the merged error (single event for all failures)
16
-
17
- **Success Definition**:
18
-
19
- * When `errorMergeStrategy?.enabled === true`, all concurrent workflow errors are aggregated
20
- * When `combine()` function is provided, it is called with array of WorkflowError objects
21
- * When `combine()` is not provided, a default merger creates an AggregateError-like structure
22
- * The merged error contains aggregated information from all failures
23
- * A single error event is emitted with the merged error
24
- * Backward compatibility is maintained: when `errorMergeStrategy` is not provided, first error is thrown
25
- * All existing tests continue to pass
26
-
27
- ## User Persona (if applicable)
28
-
29
- **Target User**: Library Developer / Workflow Architect
30
-
31
- **Use Case**: A developer running concurrent child workflows wants to receive comprehensive error information when multiple workflows fail, instead of just the first error.
32
-
33
- **User Journey**:
34
-
35
- 1. Developer creates a parent workflow with multiple concurrent child workflows
36
- 2. Some child workflows fail
37
- 3. Developer wants to see ALL errors, not just the first one
38
- 4. Developer enables `errorMergeStrategy: { enabled: true }` in @Task decorator options
39
- 5. Developer optionally provides a custom `combine()` function to merge errors
40
- 6. When failures occur, all errors are aggregated and thrown as a single merged error
41
- 7. Developer can inspect the merged error to see all failures
42
-
43
- **Pain Points Addressed**:
44
-
45
- * Currently only the first error from concurrent failures is visible
46
- * Other concurrent failures are collected but not surfaced to the caller
47
- * No way to customize how multiple errors should be merged
48
- * Difficult to debug when multiple independent workflows fail
49
-
50
- ## Why
51
-
52
- * **Observability**: Multiple concurrent failures should be visible together, not hidden
53
- * **Debugging**: Developers need to see ALL errors to understand patterns and root causes
54
- * **Production Patterns**: Aligns with workflow engines like Airflow (trigger rules) and Step Functions (parallel error aggregation)
55
- * **PRD Compliance**: PRD Section 10 specifies "Optional Multi-Error Merging" as a feature
56
- * **Enable P1.M2.T2.S3**: Default error merger implementation depends on this being complete
57
- * **Enable P1.M2.T2.S4**: ErrorMergeStrategy tests depend on this implementation
58
-
59
- ## What
60
-
61
- Modify the @Task decorator in `src/decorators/task.ts` to implement error aggregation logic when `errorMergeStrategy.enabled === true`.
62
-
63
- ### Current Implementation (Lines 111-121)
64
-
65
- ```typescript
66
- if (runnable.length > 0) {
67
- const results = await Promise.allSettled(runnable.map((w) => w.run()));
68
-
69
- const rejected = results.filter(
70
- (r): r is PromiseRejectedResult => r.status === 'rejected'
71
- );
72
-
73
- if (rejected.length > 0) {
74
- throw rejected[0].reason; // First error wins (backward compatible)
75
- }
76
- }
77
- ```
78
-
79
- ### Target Implementation
80
-
81
- ```typescript
82
- if (runnable.length > 0) {
83
- const results = await Promise.allSettled(runnable.map((w) => w.run()));
84
-
85
- const rejected = results.filter(
86
- (r): r is PromiseRejectedResult => r.status === 'rejected'
87
- );
88
-
89
- if (rejected.length > 0) {
90
- // Check if error merge strategy is enabled
91
- if (opts.errorMergeStrategy?.enabled) {
92
- // Extract WorkflowError objects from rejected promises
93
- const errors = rejected.map((r) => r.reason as WorkflowError);
94
-
95
- // Merge errors using custom combine() or default merger
96
- const mergedError = opts.errorMergeStrategy?.combine
97
- ? opts.errorMergeStrategy.combine(errors)
98
- : defaultErrorMerger(errors, taskName, wf.id, runnable.length);
99
-
100
- // Emit error event with merged error
101
- wf.emitEvent({
102
- type: 'error',
103
- node: wf.node,
104
- error: mergedError,
105
- });
106
-
107
- // Throw merged error
108
- throw mergedError;
109
- }
110
-
111
- // Backward compatibility: throw first error
112
- throw rejected[0].reason;
113
- }
114
- }
115
- ```
116
-
117
- ### Success Criteria
118
-
119
- * [ ] Check `opts.errorMergeStrategy?.enabled` before throwing error
120
- * [ ] Extract WorkflowError array from rejected promises
121
- * [ ] Call custom `combine()` function if provided
122
- * [ ] Use default error merger when `combine()` is not provided
123
- * [ ] Emit error event with merged error (not first error)
124
- * [ ] Throw merged error instead of first error when enabled
125
- * [ ] Backward compatibility maintained when `errorMergeStrategy` not provided
126
- * [ ] All existing tests pass
127
- * [ ] New tests for error aggregation pass
128
-
129
- ## All Needed Context
130
-
131
- ### Context Completeness Check
132
-
133
- **"No Prior Knowledge" Test**: If someone knew nothing about this codebase, would they have everything needed to implement this successfully?
134
-
135
- **Answer**: YES - This PRP provides:
136
-
137
- * Exact file location with line numbers (src/decorators/task.ts:111-121)
138
- * Complete current implementation code
139
- * Type definitions for all interfaces used
140
- * Error handling patterns to follow
141
- * Default error merger implementation
142
- * Test patterns for validation
143
- * External research documentation with URLs
144
-
145
- ### Documentation & References
146
-
147
- ```yaml
148
- # MUST READ - Current Implementation
149
- - file: src/decorators/task.ts
150
- lines: 104-122
151
- why: Target section to modify - contains Promise.allSettled error handling
152
- pattern: Error collection with rejected.filter() and first-error-wins throw
153
- gotcha: rejected[].reason is already WorkflowError (wrapped by @Step decorator)
154
-
155
- - file: src/decorators/task.ts
156
- lines: 1-136 (full file)
157
- why: Complete @Task decorator context including imports and event emission
158
- pattern: Task decorator wrapper with event emission and child attachment
159
-
160
- - file: src/types/decorators.ts
161
- why: TaskOptions interface definition - errorMergeStrategy field added in P1.M2.T2.S1
162
- current_content: |
163
- import type { ErrorMergeStrategy } from './error-strategy.js';
164
-
165
- export interface TaskOptions {
166
- name?: string;
167
- concurrent?: boolean;
168
- errorMergeStrategy?: ErrorMergeStrategy;
169
- }
170
-
171
- - file: src/types/error-strategy.ts
172
- why: ErrorMergeStrategy interface definition
173
- current_content: |
174
- import type { WorkflowError } from './error.js';
175
-
176
- export interface ErrorMergeStrategy {
177
- enabled: boolean;
178
- maxMergeDepth?: number;
179
- combine?(errors: WorkflowError[]): WorkflowError;
180
- }
181
-
182
- - file: src/types/error.ts
183
- why: WorkflowError interface structure - what errors look like in this codebase
184
- current_content: |
185
- export interface WorkflowError {
186
- message: string;
187
- original: unknown;
188
- workflowId: string;
189
- stack?: string;
190
- state: SerializedWorkflowState;
191
- logs: LogEntry[];
192
- }
193
-
194
- - file: src/types/events.ts
195
- why: WorkflowEvent union type - error event structure
196
- current_content: |
197
- | { type: 'error'; node: WorkflowNode; error: WorkflowError }
198
-
199
- - file: src/decorators/step.ts
200
- lines: 109-134
201
- why: Shows how WorkflowError objects are created and error events emitted
202
- pattern: Error capture with getObservedState(), event emission
203
- critical: Each failing workflow already emits error event - don't duplicate
204
-
205
- # ARCHITECTURE DOCUMENTATION - Implementation Guidance
206
- - docfile: plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md
207
- why: Internal guidance on error aggregation strategies
208
- section: Lines 597-638 ("Groundswell Implementation Recommendation")
209
- critical: |
210
- Shows recommended implementation pattern:
211
- - Check opts.errorMergeStrategy?.enabled
212
- - Call opts.errorMergeStrategy.combine?(errors)
213
- - Throw merged error instead of first error
214
- - Emit error event with merged error
215
-
216
- # EXTERNAL RESEARCH - Error Aggregation Patterns
217
- - url: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
218
- why: Official documentation for Promise.allSettled() method
219
- section: #description
220
- critical: Promise.allSettled ALWAYS resolves - manual error checking required
221
-
222
- - url: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
223
- why: Official documentation for AggregateError - useful pattern reference
224
- section: #description
225
- critical: AggregateError can contain multiple errors as cause chain
226
-
227
- - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S2/research/05_comprehensive_summary.md
228
- why: Comprehensive summary of external research findings
229
- section: "Recommended Implementation for Groundswell"
230
- critical: Complete code examples for error aggregation patterns
231
-
232
- - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md
233
- why: TypeScript-specific error aggregation patterns
234
- section: "Production-Grade Patterns"
235
- critical: Type guards, error normalization, context preservation
236
-
237
- # PREVIOUS PRPS - Understanding What Was Done Before
238
- - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md
239
- why: P1.M2.T2.S1 added errorMergeStrategy field to TaskOptions
240
- section: "What" section shows Target State
241
- critical: TaskOptions interface now has errorMergeStrategy?: ErrorMergeStrategy field
242
-
243
- - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md
244
- why: P1.M2.T1.S2 implemented Promise.allSettled with error collection
245
- section: "Implementation Blueprint" shows the replaced Promise.all logic
246
- critical: rejected array already available - just need to aggregate it
247
-
248
- # TEST PATTERNS - Follow for Validation
249
- - file: src/__tests__/adversarial/concurrent-task-failures.test.ts
250
- why: Tests for concurrent task failure scenarios
251
- pattern: Testing multiple failing workflows with error verification
252
-
253
- - file: src/__tests__/adversarial/edge-case.test.ts
254
- lines: 366-430
255
- why: Contains concurrent task execution tests with mixed success/failure
256
- pattern: Testing concurrent workflows with errors
257
-
258
- - docfile: plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S2/research/RESEARCH_REPORT.md
259
- why: Complete testing guide for error aggregation
260
- section: "Key Research Findings" and "Best Practices Summary"
261
- critical: Test patterns, assertion patterns, edge cases to cover
262
-
263
- # TYPE REFERENCES - TypeScript Type Safety
264
- - url: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#type-predicates
265
- why: TypeScript type guard documentation
266
- section: Type Predicates
267
- critical: Type guard pattern: (r): r is PromiseRejectedResult => r.status === 'rejected'
268
- ```
269
-
270
- ### Current Codebase Tree
271
-
272
- ```bash
273
- /home/dustin/projects/groundswell
274
- ├── src/
275
- │ ├── decorators/
276
- │ │ ├── index.ts # Exports Task decorator
277
- │ │ ├── step.ts # @Step decorator with error wrapping (lines 109-134)
278
- │ │ └── task.ts # PRIMARY: Lines 111-121 to modify - TARGET FILE
279
- │ ├── types/
280
- │ │ ├── index.ts # Re-exports all types
281
- │ │ ├── decorators.ts # TaskOptions with errorMergeStrategy field (from P1.M2.T2.S1)
282
- │ │ ├── error-strategy.ts # ErrorMergeStrategy interface
283
- │ │ ├── error.ts # WorkflowError interface
284
- │ │ └── events.ts # WorkflowEvent union type with error event
285
- │ └── __tests__/
286
- │ ├── adversarial/
287
- │ │ ├── concurrent-task-failures.test.ts # P1.M2.T1.S3 tests
288
- │ │ └── edge-case.test.ts # Concurrent execution tests
289
- │ └── unit/
290
- │ └── decorators.test.ts # General decorator tests
291
- ├── plan/
292
- │ └── 001_d3bb02af4886/
293
- │ ├── bugfix/
294
- │ │ └── 001_e8e04329daf3/
295
- │ │ ├── P1M2T2S2/
296
- │ │ │ ├── research/ # External research storage
297
- │ │ │ └── PRP.md # ← THIS FILE
298
- │ │ └── architecture/
299
- │ │ └── concurrent_execution_best_practices.md
300
- └── vitest.config.ts # Test configuration
301
- ```
302
-
303
- ### Desired Codebase Tree (Changes for This Task)
304
-
305
- ```bash
306
- # MODIFIED FILES:
307
- src/decorators/task.ts # Add error aggregation logic (lines 111-121)
308
-
309
- # NO NEW FILES for this task
310
- # P1.M2.T2.S3 will add default error merger utility
311
- # P1.M2.T2.S4 will add tests for ErrorMergeStrategy functionality
312
- ```
313
-
314
- ### Known Gotchas of Our Codebase & Library Quirks
315
-
316
- ```typescript
317
- // CRITICAL GOTCHA #1: rejected[].reason is already WorkflowError
318
- // Each failing workflow has its error wrapped by @Step decorator
319
- // No need to create new WorkflowError objects
320
- // The error object already contains: message, original, workflowId, stack, state, logs
321
- // BAD: const errors = rejected.map(r => createWorkflowError(r.reason));
322
- // GOOD: const errors = rejected.map(r => r.reason as WorkflowError);
323
-
324
- // CRITICAL GOTCHA #2: Error events already emitted by @Step decorator
325
- // src/decorators/step.ts:126-130 emits error events for each failing workflow
326
- // DO NOT emit error events for individual failures in @Task decorator
327
- // Only emit a SINGLE error event with the merged error when errorMergeStrategy is enabled
328
- // When errorMergeStrategy is NOT enabled, no error event here (individual events already emitted)
329
-
330
- // CRITICAL GOTCHA #3: combine() function signature
331
- // combine?(errors: WorkflowError[]): WorkflowError
332
- // Takes array of WorkflowError, returns single WorkflowError
333
- // User-provided function must return valid WorkflowError object
334
- // If user returns something invalid, it will fail at emitEvent or throw
335
-
336
- // CRITICAL GOTCHA #4: maxMergeDepth is NOT used in this task
337
- // The maxMergeDepth option exists in ErrorMergeStrategy interface
338
- // It's intended for future recursive error merging (nested concurrent tasks)
339
- // This task does NOT implement recursive merging - just flat aggregation
340
- // Ignore maxMergeDepth for now, will be used in future enhancements
341
-
342
- // CRITICAL GOTCHA #5: Backward compatibility is MANDATORY
343
- // When errorMergeStrategy is undefined or enabled is false:
344
- // - MUST throw rejected[0].reason (first error)
345
- // - MUST NOT emit error event (already emitted by @Step)
346
- // When errorMergeStrategy.enabled is true:
347
- // - MUST throw merged error (not first error)
348
- // - MUST emit error event with merged error
349
- // Tests will verify both behaviors work correctly
350
-
351
- // CRITICAL GOTCHA #6: Type safety for WorkflowError
352
- // rejected[0].reason is technically `unknown`, not WorkflowError
353
- // Must cast to WorkflowError: `as WorkflowError`
354
- // TypeScript won't automatically narrow based on our knowledge of @Step behavior
355
-
356
- // CRITICAL GOTCHA #7: Runnable workflow context
357
- // rejected array contains results, not workflow objects
358
- // To get workflow info (id, name), access via runnable array index
359
- // Each rejected[i] corresponds to runnable[i]
360
- // Not needed for default merger (WorkflowError already has workflowId)
361
-
362
- // CRITICAL GOTCHA #8: Event emission timing
363
- // Emit error event BEFORE throwing the error
364
- // This matches @Step decorator pattern (emit then throw)
365
- // Observers see the error before it propagates up the call stack
366
- ```
367
-
368
- ## Implementation Blueprint
369
-
370
- ### Data Models and Structure
371
-
372
- **No new data models for this task** - using existing types:
373
-
374
- * `WorkflowError` from `src/types/error.ts` (error structure)
375
- * `ErrorMergeStrategy` from `src/types/error-strategy.ts` (configuration)
376
- * `WorkflowEvent` from `src/types/events.ts` (error event structure)
377
-
378
- **Inline Default Error Merger** (to be extracted to utils in P1.M2.T2.S3):
379
-
380
- ```typescript
381
- // Inline default error merger (will be extracted to src/utils/error-merger.ts in P1.M2.T2.S3)
382
- // This function creates a merged WorkflowError containing information from all errors
383
- const defaultErrorMerger = (
384
- errors: WorkflowError[],
385
- taskName: string,
386
- parentWorkflowId: string,
387
- totalChildren: number
388
- ): WorkflowError => {
389
- // Create merged error message
390
- const message = `${errors.length} of ${totalChildren} concurrent child workflows failed in task '${taskName}'`;
391
-
392
- // Get all unique workflow IDs that failed
393
- const failedWorkflowIds = [...new Set(errors.map((e) => e.workflowId))];
394
-
395
- // Aggregate all logs
396
- const allLogs = errors.flatMap((e) => e.logs);
397
-
398
- // Create merged WorkflowError
399
- const mergedError: WorkflowError = {
400
- message,
401
- original: {
402
- name: 'WorkflowAggregateError',
403
- message,
404
- errors,
405
- totalChildren,
406
- failedChildren: errors.length,
407
- failedWorkflowIds,
408
- } as unknown,
409
- workflowId: parentWorkflowId,
410
- stack: errors[0]?.stack, // Use first error's stack trace
411
- state: errors[0]?.state || {} as SerializedWorkflowState, // Use first error's state
412
- logs: allLogs,
413
- };
414
-
415
- return mergedError;
416
- };
417
- ```
418
-
419
- ### Implementation Tasks (ordered by dependencies)
420
-
421
- ```yaml
422
- Task 1: MODIFY src/decorators/task.ts - Add type imports for error aggregation
423
- - ADD: No new imports needed - WorkflowError already in type imports
424
- - VERIFY: TaskOptions import includes errorMergeStrategy field
425
- - DEPENDENCIES: None
426
-
427
- Task 2: MODIFY src/decorators/task.ts - Add inline default error merger function
428
- - ADD: defaultErrorMerger function before Task decorator (after line 16)
429
- - PATTERN: Follow inline helper pattern (similar to type guards)
430
- - PARAMETERS: (errors: WorkflowError[], taskName: string, workflowId: string, totalChildren: number)
431
- - RETURN: WorkflowError (merged error with aggregated information)
432
- - IMPLEMENTATION: See "Inline Default Error Merger" section above
433
- - DEPENDENCIES: None
434
-
435
- Task 3: MODIFY src/decorators/task.ts - Replace error throwing logic (lines 118-120)
436
- - CURRENT CODE:
437
- if (rejected.length > 0) {
438
- throw rejected[0].reason;
439
- }
440
-
441
- - REPLACE WITH:
442
- if (rejected.length > 0) {
443
- // Check if error merge strategy is enabled
444
- if (opts.errorMergeStrategy?.enabled) {
445
- // Extract WorkflowError objects from rejected promises
446
- const errors = rejected.map((r) => r.reason as WorkflowError);
447
-
448
- // Merge errors using custom combine() or default merger
449
- const mergedError = opts.errorMergeStrategy?.combine
450
- ? opts.errorMergeStrategy.combine(errors)
451
- : defaultErrorMerger(errors, taskName, wf.id, runnable.length);
452
-
453
- // Emit error event with merged error
454
- wf.emitEvent({
455
- type: 'error',
456
- node: wf.node,
457
- error: mergedError,
458
- });
459
-
460
- // Throw merged error
461
- throw mergedError;
462
- }
463
-
464
- // Backward compatibility: throw first error
465
- throw rejected[0].reason;
466
- }
467
-
468
- - DEPENDENCIES: Task 2
469
-
470
- Task 4: VERIFY TypeScript compilation
471
- - RUN: npx tsc --noEmit
472
- - EXPECTED: No type errors
473
- - VERIFY: WorkflowError type is available
474
- - VERIFY: opts.errorMergeStrategy type is correct
475
- - DEPENDENCIES: Task 3
476
-
477
- Task 5: RUN existing tests
478
- - RUN: npm test
479
- - VERIFY: All existing tests pass (backward compatibility)
480
- - VERIFY: No behavior changes when errorMergeStrategy not provided
481
- - DEPENDENCIES: Task 4
482
-
483
- Task 6: MANUAL TEST - Verify error aggregation works
484
- - CREATE: Test workflow with errorMergeStrategy enabled
485
- - VERIFY: Multiple errors are aggregated
486
- - VERIFY: Merged error contains all error information
487
- - VERIFY: Error event is emitted with merged error
488
- - DEPENDENCIES: Task 5
489
- ```
490
-
491
- ### Implementation Patterns & Key Details
492
-
493
- ```typescript
494
- // ============================================
495
- // PATTERN 1: Error Merge Strategy Check
496
- // Location: src/decorators/task.ts lines 118-120
497
- // ============================================
498
-
499
- // BEFORE (current):
500
- if (rejected.length > 0) {
501
- throw rejected[0].reason;
502
- }
503
-
504
- // AFTER (target):
505
- if (rejected.length > 0) {
506
- // Check if error merge strategy is enabled
507
- if (opts.errorMergeStrategy?.enabled) {
508
- // Error aggregation logic...
509
- // Emit error event with merged error
510
- // Throw merged error
511
- }
512
-
513
- // Backward compatibility: throw first error
514
- throw rejected[0].reason;
515
- }
516
-
517
- // KEY INSIGHTS:
518
- // - Optional chaining (?.) safely checks if errorMergeStrategy exists
519
- // - Check enabled property before aggregating
520
- // - Fall through to original behavior if not enabled
521
- // - Maintains exact backward compatibility
522
-
523
- // ============================================
524
- // PATTERN 2: Extract WorkflowError Array
525
- // Location: src/decorators/task.ts inside error merge strategy block
526
- // ============================================
527
-
528
- // Extract WorkflowError objects from rejected promises
529
- const errors = rejected.map((r) => r.reason as WorkflowError);
530
-
531
- // KEY INSIGHTS:
532
- // - rejected[].reason is technically `unknown` (Promise rejection type)
533
- // - Cast to WorkflowError because we know @Step decorator wraps errors
534
- // - Map operation creates array of WorkflowError
535
- // - Array is passed to combine() function or default merger
536
- // - Type assertion is safe because of Groundswell's error wrapping pattern
537
-
538
- // ============================================
539
- // PATTERN 3: Custom combine() vs Default Merger
540
- // Location: src/decorators/task.ts inside error merge strategy block
541
- // ============================================
542
-
543
- // Merge errors using custom combine() or default merger
544
- const mergedError = opts.errorMergeStrategy?.combine
545
- ? opts.errorMergeStrategy.combine(errors)
546
- : defaultErrorMerger(errors, taskName, wf.id, runnable.length);
547
-
548
- // KEY INSIGHTS:
549
- // - Ternary operator chooses between custom and default merger
550
- // - opts.errorMergeStrategy?.combine is optional function
551
- // - If provided, call it with errors array
552
- // - If not provided, use inline default error merger
553
- // - Both return WorkflowError object
554
- // - User has full control over error merging when providing combine()
555
-
556
- // ============================================
557
- // PATTERN 4: Default Error Merger Implementation
558
- // Location: src/decorators/task.ts (inline function before Task decorator)
559
- // ============================================
560
-
561
- const defaultErrorMerger = (
562
- errors: WorkflowError[],
563
- taskName: string,
564
- parentWorkflowId: string,
565
- totalChildren: number
566
- ): WorkflowError => {
567
- // Create merged error message
568
- const message = `${errors.length} of ${totalChildren} concurrent child workflows failed in task '${taskName}'`;
569
-
570
- // Get all unique workflow IDs that failed
571
- const failedWorkflowIds = [...new Set(errors.map((e) => e.workflowId))];
572
-
573
- // Aggregate all logs
574
- const allLogs = errors.flatMap((e) => e.logs);
575
-
576
- // Create merged WorkflowError
577
- const mergedError: WorkflowError = {
578
- message,
579
- original: {
580
- name: 'WorkflowAggregateError',
581
- message,
582
- errors,
583
- totalChildren,
584
- failedChildren: errors.length,
585
- failedWorkflowIds,
586
- } as unknown,
587
- workflowId: parentWorkflowId,
588
- stack: errors[0]?.stack,
589
- state: errors[0]?.state || {} as SerializedWorkflowState,
590
- logs: allLogs,
591
- };
592
-
593
- return mergedError;
594
- };
595
-
596
- // KEY INSIGHTS:
597
- // - Message is descriptive (counts, task name, parent workflow)
598
- // - Aggregates all logs from all errors (flatMap)
599
- // - Stores aggregated metadata in original field (as unknown for flexibility)
600
- // - Uses first error's stack trace (representative stack)
601
- // - Uses first error's state (representative state)
602
- // - Returns valid WorkflowError object (can be emitted in error event)
603
-
604
- // ============================================
605
- // PATTERN 5: Error Event Emission with Merged Error
606
- // Location: src/decorators/task.ts inside error merge strategy block
607
- // ============================================
608
-
609
- // Emit error event with merged error
610
- wf.emitEvent({
611
- type: 'error',
612
- node: wf.node,
613
- error: mergedError,
614
- });
615
-
616
- // KEY INSIGHTS:
617
- // - Emit BEFORE throwing (matches @Step decorator pattern)
618
- // - Single error event for ALL failures (not one per failure)
619
- // - Observers receive aggregated error information
620
- // - Enables monitoring of aggregate failure scenarios
621
- // - Only emitted when errorMergeStrategy.enabled === true
622
- // - When not enabled, individual workflow error events already emitted by @Step
623
-
624
- // ============================================
625
- // PATTERN 6: Throw Merged Error
626
- // Location: src/decorators/task.ts after error event emission
627
- // ============================================
628
-
629
- // Throw merged error
630
- throw mergedError;
631
-
632
- // KEY INSIGHTS:
633
- // - Throw AFTER emitting event (observers see it before propagation)
634
- // - Thrown error is WorkflowError (same type as individual errors)
635
- // - Caller can check if it's an aggregate by inspecting original field
636
- // - Maintains error type consistency across the codebase
637
- // - Stack trace will point to this location (expected behavior)
638
-
639
- // ============================================
640
- // PATTERN 7: Backward Compatibility Fallthrough
641
- // Location: src/decorators/task.ts after error merge strategy block
642
- // ============================================
643
-
644
- // Backward compatibility: throw first error
645
- throw rejected[0].reason;
646
-
647
- // KEY INSIGHTS:
648
- // - This code runs when errorMergeStrategy is undefined or enabled === false
649
- // - Maintains EXACT same behavior as before this change
650
- // - First error is thrown (fail-fast behavior)
651
- // - No error event emitted here (individual events already emitted by @Step)
652
- // - Existing tests verify this behavior is preserved
653
- ```
654
-
655
- ### Integration Points
656
-
657
- ```yaml
658
- TASK_DECORATOR:
659
- - modify: src/decorators/task.ts
660
- lines: 118-120 (error throwing logic)
661
- add: errorMergeStrategy check, error aggregation, merged error event
662
-
663
- - add: inline defaultErrorMerger function (before Task decorator, after line 16)
664
-
665
- TASK_OPTIONS:
666
- - reference: src/types/decorators.ts
667
- field: errorMergeStrategy?: ErrorMergeStrategy
668
- note: Already added in P1.M2.T2.S1
669
-
670
- - access: opts.errorMergeStrategy?.enabled
671
- - access: opts.errorMergeStrategy?.combine
672
-
673
- ERROR_TYPES:
674
- - reference: src/types/error.ts
675
- interface: WorkflowError
676
- fields: message, original, workflowId, stack, state, logs
677
-
678
- - cast: rejected[].reason as WorkflowError
679
- - return: WorkflowError from combine() and defaultErrorMerger()
680
-
681
- EVENT_SYSTEM:
682
- - emit: wf.emitEvent({ type: 'error', node: wf.node, error: mergedError })
683
- - note: Only when errorMergeStrategy.enabled === true
684
- - note: Single event for all failures (not per-failure)
685
-
686
- FUTURE_INTEGRATIONS (P1.M2.T2.S3):
687
- - extract: defaultErrorMerger to src/utils/error-merger.ts
688
- - add: more sophisticated error aggregation patterns
689
- - add: pretty printing and statistics generation
690
-
691
- FUTURE_INTEGRATIONS (P1.M2.T2.S4):
692
- - add: comprehensive tests for error aggregation
693
- - add: tests for custom combine() function
694
- - add: tests for default error merger
695
- - add: tests for backward compatibility
696
- ```
697
-
698
- ## Validation Loop
699
-
700
- ### Level 1: Syntax & Style (Immediate Feedback)
701
-
702
- ```bash
703
- # After modifying src/decorators/task.ts, run these checks
704
-
705
- # TypeScript type checking
706
- npx tsc --noEmit
707
-
708
- # Expected: Zero type errors
709
- # Common errors to fix:
710
- # - "Property 'errorMergeStrategy' does not exist" → Check TaskOptions import
711
- # - "Cannot cast to WorkflowError" → Check error type casting
712
- # - "Property 'combine' does not exist" → Check optional chaining
713
-
714
- # If available, run linter
715
- npm run lint 2>/dev/null || echo "No linter configured"
716
- ```
717
-
718
- ### Level 2: Unit Tests (Component Validation)
719
-
720
- ```bash
721
- # Run all existing tests to verify backward compatibility
722
- npm test
723
-
724
- # Run specific concurrent execution tests
725
- npm test -- src/__tests__/adversarial/concurrent-task-failures.test.ts
726
- npm test -- src/__tests__/adversarial/edge-case.test.ts
727
-
728
- # Expected: All existing tests pass without modification
729
- # If tests fail, debug - should maintain exact backward compatibility
730
- ```
731
-
732
- ### Level 3: Integration Testing (System Validation)
733
-
734
- ```bash
735
- # Create manual test to verify error aggregation
736
- cat > /tmp/test_error_merge.js << 'EOF'
737
- // Manual test for error merge strategy
738
- import { Workflow, Task, Step } from './src/index.js';
739
-
740
- class FailingWorkflow extends Workflow {
741
- constructor(id: string, parent?: Workflow) {
742
- super(id, parent);
743
- }
744
-
745
- @Step()
746
- async run() {
747
- throw new Error(`Failure in ${this.id}`);
748
- }
749
- }
750
-
751
- class ParentWorkflow extends Workflow {
752
- constructor(id: string, useMergeStrategy: boolean = true) {
753
- super(id);
754
- this.useMergeStrategy = useMergeStrategy;
755
- }
756
-
757
- private useMergeStrategy: boolean;
758
-
759
- @Task({
760
- concurrent: true,
761
- errorMergeStrategy: this.useMergeStrategy ? {
762
- enabled: true,
763
- // Custom combine function
764
- combine: (errors) => ({
765
- message: `Custom merge: ${errors.length} workflows failed`,
766
- original: errors,
767
- workflowId: 'parent',
768
- logs: errors.flatMap(e => e.logs),
769
- }),
770
- } : undefined,
771
- })
772
- async spawnFailingChildren() {
773
- return [
774
- new FailingWorkflow('child1', this),
775
- new FailingWorkflow('child2', this),
776
- new FailingWorkflow('child3', this),
777
- ];
778
- }
779
-
780
- async run() {
781
- return this.spawnFailingChildren();
782
- }
783
- }
784
-
785
- async function test() {
786
- console.log('=== Test 1: With Error Merge Strategy ===');
787
- const parent1 = new ParentWorkflow('parent1', true);
788
- try {
789
- await parent1.run();
790
- } catch (error) {
791
- console.log('Caught merged error:', error.message);
792
- console.log('Original field contains errors array:', Array.isArray(error.original));
793
- console.log('Number of errors:', error.original?.length || 0);
794
- }
795
-
796
- console.log('\n=== Test 2: Without Error Merge Strategy (Backward Compat) ===');
797
- const parent2 = new ParentWorkflow('parent2', false);
798
- try {
799
- await parent2.run();
800
- } catch (error) {
801
- console.log('Caught first error:', error.message);
802
- console.log('Is WorkflowError:', 'workflowId' in error);
803
- }
804
- }
805
-
806
- test();
807
- EOF
808
-
809
- node /tmp/test_error_merge.js
810
-
811
- # Expected output:
812
- # Test 1: Shows custom merged error with all 3 errors
813
- # Test 2: Shows first error only (backward compatible)
814
-
815
- # Clean up
816
- rm /tmp/test_error_merge.js
817
- ```
818
-
819
- ### Level 4: Domain-Specific Validation
820
-
821
- ```bash
822
- # Test default error merger (without custom combine)
823
- cat > /tmp/test_default_merger.js << 'EOF'
824
- import { Workflow, Task, Step } from './src/index.js';
825
-
826
- class FailingWorkflow extends Workflow {
827
- @Step()
828
- async run() {
829
- throw new Error(`Failed in ${this.id}`);
830
- }
831
- }
832
-
833
- class ParentWorkflow extends Workflow {
834
- @Task({
835
- concurrent: true,
836
- errorMergeStrategy: { enabled: true }, // No combine function - use default
837
- })
838
- async spawnChildren() {
839
- return [
840
- new FailingWorkflow('child1', this),
841
- new FailingWorkflow('child2', this),
842
- ];
843
- }
844
-
845
- async run() {
846
- return this.spawnChildren();
847
- }
848
- }
849
-
850
- async function test() {
851
- const parent = new ParentWorkflow('parent');
852
- try {
853
- await parent.run();
854
- } catch (error) {
855
- console.log('Default merged error message:', error.message);
856
- console.log('Original field:', JSON.stringify(error.original, null, 2));
857
- }
858
- }
859
-
860
- test();
861
- EOF
862
-
863
- node /tmp/test_default_merger.js
864
-
865
- # Expected: Default merger creates proper WorkflowError with:
866
- # - Descriptive message with counts
867
- # - Original field containing errors array
868
- # - All logs aggregated
869
- ```
870
-
871
- ## Final Validation Checklist
872
-
873
- ### Technical Validation
874
-
875
- * [ ] TypeScript compilation succeeds: `npx tsc --noEmit`
876
- * [ ] defaultErrorMerger function returns valid WorkflowError
877
- * [ ] opts.errorMergeStrategy?.enabled check uses optional chaining
878
- * [ ] errors array correctly cast to WorkflowError[]
879
- * [ ] Custom combine() called when provided
880
- * [ ] Default merger used when combine() not provided
881
- * [ ] Error event emitted with merged error
882
- * [ ] Merged error thrown instead of first error when enabled
883
-
884
- ### Backward Compatibility Validation
885
-
886
- * [ ] When errorMergeStrategy is undefined: first error thrown
887
- * [ ] When errorMergeStrategy.enabled is false: first error thrown
888
- * [ ] When errorMergeStrategy.enabled is true: merged error thrown
889
- * [ ] No error event emitted when merge strategy not enabled
890
- * [ ] All existing tests pass without modification
891
-
892
- ### Feature Validation
893
-
894
- * [ ] Multiple concurrent workflow errors are aggregated
895
- * [ ] Custom combine() function receives WorkflowError array
896
- * [ ] Custom combine() return value is used as merged error
897
- * [ ] Default merger creates WorkflowError with aggregated information
898
- * [ ] Merged error message includes failure count
899
- * [ ] All logs from all errors are aggregated
900
- * [ ] Error event contains merged error
901
-
902
- ### Code Quality Validation
903
-
904
- * [ ] Follows existing code patterns (indentation, naming, style)
905
- * [ ] No console.log or debug statements left in
906
- * [ ] Error handling is specific (throwing exact error, not new wrapper)
907
- * [ ] Type safety maintained (all casts are safe)
908
- * [ ] Comments added for clarity (optional chaining, backward compatibility)
909
-
910
- ### Documentation & Deployment
911
-
912
- * [ ] Code is self-documenting with clear variable names
913
- * [ ] Inline comments explain error merge strategy logic
914
- * [ ] Backward compatibility is clearly documented in comments
915
- * [ ] No breaking changes to public API
916
-
917
- ## Anti-Patterns to Avoid
918
-
919
- * ❌ **Don't create new WorkflowError objects** - rejected[].reason is already WorkflowError
920
- * ❌ **Don't emit error events for individual failures** - @Step decorator already does this
921
- * ❌ **Don't throw error without emitting event** - Must emit before throw (pattern consistency)
922
- * ❌ **Don't ignore combine() return value** - User's custom function must be used when provided
923
- * ❌ **Don't assume combine() returns WorkflowError** - Trust user's implementation, TypeScript validates
924
- * ❌ **Don't aggregate when errorMergeStrategy is undefined** - Must check both exists AND enabled
925
- * ❌ **Don't break backward compatibility** - Default behavior must be unchanged
926
- * ❌ **Don't use maxMergeDepth in this task** - Future enhancement, ignore for now
927
- * ❌ **Don't add try-catch around combine()** - Let user errors propagate naturally
928
- * ❌ **Don't create new files** - This task only modifies task.ts (P1.M2.T2.S3 adds utility file)
929
-
930
- ## Success Metrics
931
-
932
- **Confidence Score**: 9/10 for one-pass implementation success
933
-
934
- **Definition of Done**:
935
-
936
- 1. src/decorators/task.ts implements error aggregation when errorMergeStrategy.enabled === true
937
- 2. Custom combine() function is called when provided
938
- 3. Default error merger is used when combine() is not provided
939
- 4. Merged error is thrown instead of first error when enabled
940
- 5. Error event is emitted with merged error
941
- 6. Backward compatibility maintained (first error thrown when not enabled)
942
- 7. All existing tests pass
943
- 8. Zero TypeScript type errors
944
-
945
- **Validation**: The implementation enables configurable error aggregation for concurrent workflows while maintaining complete backward compatibility.
946
-
947
- ---
948
-
949
- ## Appendix: Complete Code Change Reference
950
-
951
- ### Exact Change Required (src/decorators/task.ts)
952
-
953
- **Add after line 16 (before Task decorator):**
954
-
955
- ```typescript
956
- // Default error merger for concurrent workflow failures
957
- // This will be extracted to src/utils/error-merger.ts in P1.M2.T2.S3
958
- const defaultErrorMerger = (
959
- errors: WorkflowError[],
960
- taskName: string,
961
- parentWorkflowId: string,
962
- totalChildren: number
963
- ): WorkflowError => {
964
- // Create merged error message
965
- const message = `${errors.length} of ${totalChildren} concurrent child workflows failed in task '${taskName}'`;
966
-
967
- // Get all unique workflow IDs that failed
968
- const failedWorkflowIds = [...new Set(errors.map((e) => e.workflowId))];
969
-
970
- // Aggregate all logs
971
- const allLogs = errors.flatMap((e) => e.logs);
972
-
973
- // Create merged WorkflowError
974
- const mergedError: WorkflowError = {
975
- message,
976
- original: {
977
- name: 'WorkflowAggregateError',
978
- message,
979
- errors,
980
- totalChildren,
981
- failedChildren: errors.length,
982
- failedWorkflowIds,
983
- } as unknown,
984
- workflowId: parentWorkflowId,
985
- stack: errors[0]?.stack,
986
- state: errors[0]?.state || {} as SerializedWorkflowState,
987
- logs: allLogs,
988
- };
989
-
990
- return mergedError;
991
- };
992
- ```
993
-
994
- **Replace lines 118-120:**
995
-
996
- ```typescript
997
- // BEFORE:
998
- if (rejected.length > 0) {
999
- throw rejected[0].reason;
1000
- }
1001
-
1002
- // AFTER:
1003
- if (rejected.length > 0) {
1004
- // Check if error merge strategy is enabled
1005
- if (opts.errorMergeStrategy?.enabled) {
1006
- // Extract WorkflowError objects from rejected promises
1007
- const errors = rejected.map((r) => r.reason as WorkflowError);
1008
-
1009
- // Merge errors using custom combine() or default merger
1010
- const mergedError = opts.errorMergeStrategy?.combine
1011
- ? opts.errorMergeStrategy.combine(errors)
1012
- : defaultErrorMerger(errors, taskName, wf.id, runnable.length);
1013
-
1014
- // Emit error event with merged error
1015
- wf.emitEvent({
1016
- type: 'error',
1017
- node: wf.node,
1018
- error: mergedError,
1019
- });
1020
-
1021
- // Throw merged error
1022
- throw mergedError;
1023
- }
1024
-
1025
- // Backward compatibility: throw first error
1026
- throw rejected[0].reason;
1027
- }
1028
- ```
1029
-
1030
- **Diff Summary:**
1031
-
1032
- ```diff
1033
- + // Default error merger for concurrent workflow failures
1034
- + const defaultErrorMerger = (...)
1035
- +
1036
- if (rejected.length > 0) {
1037
- + // Check if error merge strategy is enabled
1038
- + if (opts.errorMergeStrategy?.enabled) {
1039
- + // Extract WorkflowError objects from rejected promises
1040
- + const errors = rejected.map((r) => r.reason as WorkflowError);
1041
- +
1042
- + // Merge errors using custom combine() or default merger
1043
- + const mergedError = opts.errorMergeStrategy?.combine
1044
- + ? opts.errorMergeStrategy.combine(errors)
1045
- + : defaultErrorMerger(errors, taskName, wf.id, runnable.length);
1046
- +
1047
- + // Emit error event with merged error
1048
- + wf.emitEvent({
1049
- + type: 'error',
1050
- + node: wf.node,
1051
- + error: mergedError,
1052
- + });
1053
- +
1054
- + // Throw merged error
1055
- + throw mergedError;
1056
- + }
1057
- +
1058
- // Backward compatibility: throw first error
1059
- throw rejected[0].reason;
1060
- }
1061
- ```
1062
-
1063
- ---
1064
-
1065
- **PRP Status**: ✅ Complete - Ready for Implementation
1066
- **Next Task**: P1.M2.T2.S3 - Create default error merger implementation