groundswell 0.0.1 → 0.0.2

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 (242) hide show
  1. package/.claude/commands/subtask-planning/prp-base-create.md +120 -0
  2. package/.claude/commands/subtask-planning/prp-base-execute.md +65 -0
  3. package/.claude/commands/task-breakdown.md +94 -0
  4. package/.claude/system_prompts/task-breakdown.md +1 -0
  5. package/CHANGELOG.md +188 -0
  6. package/PRD.md +543 -0
  7. package/README.md +99 -5
  8. package/examples/README.md +15 -1
  9. package/examples/examples/11-reparenting-workflows.ts +269 -0
  10. package/examples/index.ts +4 -0
  11. package/package-lock.json +2398 -0
  12. package/package.json +3 -1
  13. package/plan/001_d3bb02af4886/TEST_RESULTS.md +259 -0
  14. package/plan/001_d3bb02af4886/bug_fix_tasks.json +484 -0
  15. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +488 -0
  16. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +581 -0
  17. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +687 -0
  18. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +492 -0
  19. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +932 -0
  20. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +1109 -0
  21. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +802 -0
  22. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +603 -0
  23. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +564 -0
  24. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +518 -0
  25. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +1252 -0
  26. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +364 -0
  27. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +114 -0
  28. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +205 -0
  29. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +199 -0
  30. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +134 -0
  31. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +495 -0
  32. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +435 -0
  33. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +506 -0
  34. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +612 -0
  35. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +558 -0
  36. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +788 -0
  37. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +460 -0
  38. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +454 -0
  39. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +520 -0
  40. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +417 -0
  41. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +760 -0
  42. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +245 -0
  43. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +792 -0
  44. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +535 -0
  45. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +190 -0
  46. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +654 -0
  47. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +227 -0
  48. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +345 -0
  49. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +193 -0
  50. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +1323 -0
  51. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +1011 -0
  52. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +927 -0
  53. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +505 -0
  54. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +401 -0
  55. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +142 -0
  56. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +112 -0
  57. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +159 -0
  58. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +549 -0
  59. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +368 -0
  60. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +172 -0
  61. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +175 -0
  62. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +696 -0
  63. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +860 -0
  64. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +1066 -0
  65. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +1103 -0
  66. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +789 -0
  67. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +1098 -0
  68. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +1037 -0
  69. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +916 -0
  70. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +1045 -0
  71. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +890 -0
  72. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +822 -0
  73. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +668 -0
  74. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +706 -0
  75. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +265 -0
  76. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +655 -0
  77. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +1103 -0
  78. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +426 -0
  79. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +506 -0
  80. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +114 -0
  81. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +316 -0
  82. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +754 -0
  83. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +612 -0
  84. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +719 -0
  85. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +215 -0
  86. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +765 -0
  87. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +718 -0
  88. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +149 -0
  89. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +470 -0
  90. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +332 -0
  91. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +167 -0
  92. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +265 -0
  93. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +273 -0
  94. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +760 -0
  95. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +434 -0
  96. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +717 -0
  97. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +472 -0
  98. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +125 -0
  99. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +301 -0
  100. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +1170 -0
  101. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +940 -0
  102. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +151 -0
  103. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +650 -0
  104. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +259 -0
  105. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +457 -0
  106. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +346 -0
  107. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +311 -0
  108. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +1565 -0
  109. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +288 -0
  110. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +741 -0
  111. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +652 -0
  112. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +527 -0
  113. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +415 -0
  114. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +378 -0
  115. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +713 -0
  116. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +370 -0
  117. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +499 -0
  118. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +230 -0
  119. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +1134 -0
  120. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +179 -0
  121. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +629 -0
  122. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +214 -0
  123. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +629 -0
  124. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +529 -0
  125. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +142 -0
  126. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +304 -0
  127. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +558 -0
  128. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +256 -0
  129. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +346 -0
  130. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +415 -0
  131. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +489 -0
  132. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +218 -0
  133. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +380 -0
  134. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +1923 -0
  135. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +319 -0
  136. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +115 -0
  137. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +134 -0
  138. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +153 -0
  139. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +132 -0
  140. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +716 -0
  141. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +186 -0
  142. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +604 -0
  143. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +213 -0
  144. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +30 -0
  145. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +56 -0
  146. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +53 -0
  147. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +49 -0
  148. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +958 -0
  149. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +339 -0
  150. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +305 -0
  151. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +433 -0
  152. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +1574 -0
  153. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +1014 -0
  154. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +376 -0
  155. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +1507 -0
  156. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +949 -0
  157. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +619 -0
  158. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +723 -0
  159. package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-security-guide.md +56 -0
  160. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +460 -0
  161. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +324 -0
  162. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +175 -0
  163. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +499 -0
  164. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +163 -0
  165. package/plan/bugfix/BUG_FIX_SUMMARY.md +961 -0
  166. package/src/__tests__/adversarial/attachChild-performance.test.ts +216 -0
  167. package/src/__tests__/adversarial/circular-reference.test.ts +101 -0
  168. package/src/__tests__/adversarial/complex-circular-reference.test.ts +139 -0
  169. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +571 -0
  170. package/src/__tests__/adversarial/deep-analysis.test.ts +729 -0
  171. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +213 -0
  172. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +448 -0
  173. package/src/__tests__/adversarial/edge-case.test.ts +703 -0
  174. package/src/__tests__/adversarial/error-merge-strategy.test.ts +760 -0
  175. package/src/__tests__/adversarial/incremental-performance.test.ts +140 -0
  176. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +457 -0
  177. package/src/__tests__/adversarial/observer-propagation.test.ts +487 -0
  178. package/src/__tests__/adversarial/parent-validation.test.ts +143 -0
  179. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +611 -0
  180. package/src/__tests__/adversarial/prd-compliance.test.ts +731 -0
  181. package/src/__tests__/compatibility/backward-compatibility.test.ts +1572 -0
  182. package/src/__tests__/helpers/index.ts +18 -0
  183. package/src/__tests__/helpers/tree-verification.ts +257 -0
  184. package/src/__tests__/integration/bidirectional-consistency.test.ts +847 -0
  185. package/src/__tests__/integration/observer-logging.test.ts +643 -0
  186. package/src/__tests__/integration/tree-mirroring.test.ts +37 -0
  187. package/src/__tests__/integration/workflow-reparenting.test.ts +303 -0
  188. package/src/__tests__/unit/context.test.ts +79 -0
  189. package/src/__tests__/unit/logger.test.ts +293 -0
  190. package/src/__tests__/unit/observable.test.ts +321 -0
  191. package/src/__tests__/unit/tree-debugger-incremental.test.ts +170 -0
  192. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +209 -0
  193. package/src/__tests__/unit/workflow-detachChild.test.ts +100 -0
  194. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +153 -0
  195. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +180 -0
  196. package/src/__tests__/unit/workflow.test.ts +277 -1
  197. package/src/core/agent.ts +21 -1
  198. package/src/core/logger.ts +27 -2
  199. package/src/core/workflow-context.ts +6 -4
  200. package/src/core/workflow.ts +252 -14
  201. package/src/debugger/tree-debugger.ts +52 -7
  202. package/src/decorators/task.ts +65 -2
  203. package/src/index.ts +4 -2
  204. package/src/types/decorators.ts +8 -1
  205. package/src/types/events.ts +1 -0
  206. package/src/utils/index.ts +1 -0
  207. package/src/utils/observable.ts +32 -3
  208. package/src/utils/workflow-error-utils.ts +56 -0
  209. package/tsconfig.json +1 -1
  210. package/llms_full.txt +0 -5890
  211. package/tasks.json +0 -0
  212. /package/plan/{backlog.json → 001_d3bb02af4886/backlog.json} +0 -0
  213. /package/plan/{P1P2/PRP.md → 001_d3bb02af4886/docs/PRP/P1P2-PRP.md} +0 -0
  214. /package/plan/{P3P4/PRP.md → 001_d3bb02af4886/docs/PRP/P3P4-PRP.md} +0 -0
  215. /package/plan/{P4P5/PRP.md → 001_d3bb02af4886/docs/PRP/P4P5-PRP.md} +0 -0
  216. /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/external_deps.md +0 -0
  217. /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/system_context.md +0 -0
  218. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_BEST_PRACTICES.md +0 -0
  219. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_CODE_PATTERNS.md +0 -0
  220. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_INTEGRATION_GUIDE.md +0 -0
  221. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_RESEARCH_INDEX.md +0 -0
  222. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_INDEX.md +0 -0
  223. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_RESEARCH_REPORT.md +0 -0
  224. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/RESEARCH_SUMMARY.md +0 -0
  225. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/anthropic-sdk.md +0 -0
  226. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/async-local-storage.md +0 -0
  227. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-code-patterns.md +0 -0
  228. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-decision-matrix.md +0 -0
  229. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-implementation-guide.md +0 -0
  230. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-integration-guide.md +0 -0
  231. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-patterns.md +0 -0
  232. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-quick-reference.md +0 -0
  233. /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/zod-schema.md +0 -0
  234. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/caching-lru.md +0 -0
  235. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/introspection-tools.md +0 -0
  236. /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/reflection-patterns.md +0 -0
  237. /package/plan/{P4P5/research → 001_d3bb02af4886/docs/research/P4P5}/RESEARCH_SUMMARY.md +0 -0
  238. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/INTROSPECTION_RESEARCH_SUMMARY.md +0 -0
  239. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/README-INTROSPECTION.md +0 -0
  240. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/agent-introspection-patterns.md +0 -0
  241. /package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-tool-examples.md +0 -0
  242. /package/{PRPs/PRDs/001-hierarchical-workflow-engine.md → plan/001_d3bb02af4886/prd_snapshot.md} +0 -0
@@ -0,0 +1,706 @@
1
+ # Quick Reference: Test Templates & Helper Functions
2
+
3
+ **Purpose:** Copy-paste templates for error aggregation testing
4
+ **Task:** P1.M2.T2.S2 - Implement error aggregation logic
5
+ **Last Updated:** 2026-01-12
6
+
7
+ ---
8
+
9
+ ## Helper Functions (Copy to Test File)
10
+
11
+ ### Type Guards
12
+
13
+ ```typescript
14
+ /**
15
+ * Type guard for WorkflowError
16
+ */
17
+ function isWorkflowError(error: unknown): error is WorkflowError {
18
+ return (
19
+ typeof error === 'object' &&
20
+ error !== null &&
21
+ 'message' in error &&
22
+ 'workflowId' in error &&
23
+ 'logs' in error
24
+ );
25
+ }
26
+
27
+ /**
28
+ * Type guard for rejected PromiseSettledResult
29
+ */
30
+ function isRejected(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult {
31
+ return result.status === 'rejected';
32
+ }
33
+
34
+ /**
35
+ * Type guard for fulfilled PromiseSettledResult
36
+ */
37
+ function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
38
+ return result.status === 'fulfilled';
39
+ }
40
+ ```
41
+
42
+ ### Error Creation
43
+
44
+ ```typescript
45
+ /**
46
+ * Create a mock WorkflowError
47
+ */
48
+ function createMockError(overrides?: Partial<WorkflowError>): WorkflowError {
49
+ return {
50
+ message: 'Mock error',
51
+ original: new Error('Mock'),
52
+ workflowId: 'mock-workflow',
53
+ state: {} as any,
54
+ logs: [],
55
+ stack: 'Error: Mock\n at mock.js:10:15',
56
+ ...overrides
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Create a failing child workflow
62
+ */
63
+ function createFailingWorkflow(parent: Workflow, name: string, errorMessage: string): Workflow {
64
+ return new (class extends Workflow {
65
+ constructor(n: string, p: Workflow) {
66
+ super(n, p);
67
+ }
68
+
69
+ async run() {
70
+ throw new Error(errorMessage);
71
+ }
72
+ })(name, parent);
73
+ }
74
+
75
+ /**
76
+ * Create a child workflow with configurable failure
77
+ */
78
+ function createChildWorkflow(
79
+ parent: Workflow,
80
+ name: string,
81
+ shouldFail: boolean = false
82
+ ): Workflow {
83
+ return new (class extends Workflow {
84
+ constructor(n: string, p: Workflow) {
85
+ super(n, p);
86
+ }
87
+
88
+ @Step()
89
+ async executeStep() {
90
+ if (shouldFail) {
91
+ throw new Error(`${name} failed`);
92
+ }
93
+ return `${name} succeeded`;
94
+ }
95
+
96
+ async run() {
97
+ return this.executeStep();
98
+ }
99
+ })(name, parent);
100
+ }
101
+ ```
102
+
103
+ ### Test Setup
104
+
105
+ ```typescript
106
+ /**
107
+ * Setup event observer for testing
108
+ */
109
+ function setupEventObserver(workflow: Workflow): WorkflowEvent[] {
110
+ const events: WorkflowEvent[] = [];
111
+ workflow.addObserver({
112
+ onLog: () => {},
113
+ onEvent: (e) => events.push(e),
114
+ onStateUpdated: () => {},
115
+ onTreeChanged: () => {},
116
+ });
117
+ return events;
118
+ }
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Test Templates
124
+
125
+ ### Template 1: Basic Error Aggregation
126
+
127
+ ```typescript
128
+ describe('Error Aggregation - Basic', () => {
129
+ it('should aggregate errors from multiple concurrent workflows', async () => {
130
+ // ARRANGE: Create parent workflow
131
+ class ParentWorkflow extends Workflow {
132
+ @Task({
133
+ concurrent: true,
134
+ errorMergeStrategy: { enabled: true }
135
+ })
136
+ async spawnChildren() {
137
+ return [
138
+ createFailingWorkflow(this, 'Child-1', 'Error 1'),
139
+ createFailingWorkflow(this, 'Child-2', 'Error 2'),
140
+ createFailingWorkflow(this, 'Child-3', 'Error 3'),
141
+ ];
142
+ }
143
+
144
+ async run() {
145
+ try {
146
+ await this.spawnChildren();
147
+ } catch (err) {
148
+ return err;
149
+ }
150
+ }
151
+ }
152
+
153
+ const parent = new ParentWorkflow('Parent');
154
+
155
+ // ACT: Run the workflow
156
+ const result = await parent.run();
157
+
158
+ // ASSERT: Verify error aggregation
159
+ expect(result.message).toContain('3 concurrent errors');
160
+ expect(result.message).toContain('[1] Error 1');
161
+ expect(result.message).toContain('[2] Error 2');
162
+ expect(result.message).toContain('[3] Error 3');
163
+ expect(result.logs).toHaveLength(3);
164
+ });
165
+ });
166
+ ```
167
+
168
+ ### Template 2: Custom Error Merger
169
+
170
+ ```typescript
171
+ describe('Error Aggregation - Custom Merger', () => {
172
+ it('should use custom error merge function', async () => {
173
+ // ARRANGE: Define custom merger
174
+ const customMerger = (errors: WorkflowError[]) => ({
175
+ message: `CUSTOM: ${errors.length} errors`,
176
+ original: errors,
177
+ workflowId: 'custom-merged',
178
+ state: {} as any,
179
+ logs: errors.flatMap(e => e.logs),
180
+ });
181
+
182
+ class ParentWorkflow extends Workflow {
183
+ @Task({
184
+ concurrent: true,
185
+ errorMergeStrategy: {
186
+ enabled: true,
187
+ combine: customMerger
188
+ }
189
+ })
190
+ async spawnChildren() {
191
+ return [
192
+ createFailingWorkflow(this, 'A', 'Error A'),
193
+ createFailingWorkflow(this, 'B', 'Error B'),
194
+ ];
195
+ }
196
+
197
+ async run() {
198
+ try {
199
+ await this.spawnChildren();
200
+ } catch (err) {
201
+ return err;
202
+ }
203
+ }
204
+ }
205
+
206
+ const parent = new ParentWorkflow('Parent');
207
+
208
+ // ACT
209
+ const result = await parent.run();
210
+
211
+ // ASSERT: Custom merger was used
212
+ expect(result.message).toBe('CUSTOM: 2 errors');
213
+ expect(result.workflowId).toBe('custom-merged');
214
+ });
215
+ });
216
+ ```
217
+
218
+ ### Template 3: Backward Compatibility
219
+
220
+ ```typescript
221
+ describe('Error Aggregation - Backward Compatibility', () => {
222
+ it('should throw first error when disabled', async () => {
223
+ // ARRANGE: Create parent without error merge strategy
224
+ class ParentWorkflow extends Workflow {
225
+ @Task({
226
+ concurrent: true,
227
+ errorMergeStrategy: { enabled: false } // Disabled
228
+ })
229
+ async spawnChildren() {
230
+ return [
231
+ createFailingWorkflow(this, 'First', 'First error'),
232
+ createFailingWorkflow(this, 'Second', 'Second error'),
233
+ createFailingWorkflow(this, 'Third', 'Third error'),
234
+ ];
235
+ }
236
+
237
+ async run() {
238
+ try {
239
+ await this.spawnChildren();
240
+ } catch (err) {
241
+ return err;
242
+ }
243
+ }
244
+ }
245
+
246
+ const parent = new ParentWorkflow('Parent');
247
+
248
+ // ACT
249
+ const result = await parent.run();
250
+
251
+ // ASSERT: Only first error thrown (backward compatible)
252
+ expect(result.message).toContain('First error');
253
+ expect(result.message).not.toContain('Second error');
254
+ expect(result.message).not.toContain('Third error');
255
+ });
256
+
257
+ it('should throw first error when errorMergeStrategy not provided', async () => {
258
+ // ARRANGE: No errorMergeStrategy at all
259
+ class ParentWorkflow extends Workflow {
260
+ @Task({ concurrent: true }) // No errorMergeStrategy
261
+ async spawnChildren() {
262
+ return [
263
+ createFailingWorkflow(this, 'First', 'First error'),
264
+ createFailingWorkflow(this, 'Second', 'Second error'),
265
+ ];
266
+ }
267
+
268
+ async run() {
269
+ try {
270
+ await this.spawnChildren();
271
+ } catch (err) {
272
+ return err;
273
+ }
274
+ }
275
+ }
276
+
277
+ const parent = new ParentWorkflow('Parent');
278
+
279
+ // ACT
280
+ const result = await parent.run();
281
+
282
+ // ASSERT: First error thrown (backward compatible default)
283
+ expect(result.message).toContain('First error');
284
+ });
285
+ });
286
+ ```
287
+
288
+ ### Template 4: Event Emission
289
+
290
+ ```typescript
291
+ describe('Error Aggregation - Event Emission', () => {
292
+ it('should emit error event with merged error', async () => {
293
+ // ARRANGE: Setup event collection
294
+ class ParentWorkflow extends Workflow {
295
+ @Task({
296
+ concurrent: true,
297
+ errorMergeStrategy: { enabled: true }
298
+ })
299
+ async spawnChildren() {
300
+ return [
301
+ createFailingWorkflow(this, 'Bad1', 'Error 1'),
302
+ createFailingWorkflow(this, 'Bad2', 'Error 2'),
303
+ ];
304
+ }
305
+
306
+ async run() {
307
+ try {
308
+ await this.spawnChildren();
309
+ } catch (err) {
310
+ // Expected
311
+ }
312
+ }
313
+ }
314
+
315
+ const parent = new ParentWorkflow('Parent');
316
+ const events = setupEventObserver(parent);
317
+
318
+ // ACT
319
+ await parent.run();
320
+
321
+ // ASSERT: Error events emitted
322
+ const errorEvents = events.filter(e => e.type === 'error');
323
+ expect(errorEvents.length).toBeGreaterThanOrEqual(2);
324
+
325
+ // ASSERT: Merged error event present
326
+ const mergedErrorEvent = errorEvents.find(e =>
327
+ e.type === 'error' && e.error.message.includes('2 concurrent errors')
328
+ );
329
+ expect(mergedErrorEvent).toBeDefined();
330
+ });
331
+ });
332
+ ```
333
+
334
+ ### Template 5: Edge Cases
335
+
336
+ ```typescript
337
+ describe('Error Aggregation - Edge Cases', () => {
338
+ it('should handle empty error array', () => {
339
+ // ARRANGE
340
+ const errors: WorkflowError[] = [];
341
+
342
+ // ACT & ASSERT
343
+ expect(() => mergeWorkflowErrors(errors)).toThrow('Cannot merge empty error array');
344
+ });
345
+
346
+ it('should handle single error', () => {
347
+ // ARRANGE
348
+ const singleError = createMockError({ message: 'Single error' });
349
+
350
+ // ACT
351
+ const result = mergeWorkflowErrors([singleError]);
352
+
353
+ // ASSERT: Returns same error object
354
+ expect(result).toBe(singleError);
355
+ expect(result.message).toBe('Single error');
356
+ });
357
+
358
+ it('should handle all workflows failing', async () => {
359
+ // ARRANGE: All children will fail
360
+ class ParentWorkflow extends Workflow {
361
+ @Task({
362
+ concurrent: true,
363
+ errorMergeStrategy: { enabled: true }
364
+ })
365
+ async spawnChildren() {
366
+ return Array.from({ length: 5 }, (_, i) =>
367
+ createFailingWorkflow(this, `FailChild-${i}`, `Error ${i}`)
368
+ );
369
+ }
370
+
371
+ async run() {
372
+ try {
373
+ await this.spawnChildren();
374
+ } catch (err) {
375
+ return err;
376
+ }
377
+ }
378
+ }
379
+
380
+ const parent = new ParentWorkflow('Parent');
381
+
382
+ // ACT
383
+ const result = await parent.run();
384
+
385
+ // ASSERT: All 5 errors aggregated
386
+ expect(result.message).toContain('5 concurrent errors');
387
+ for (let i = 0; i < 5; i++) {
388
+ expect(result.message).toContain(`Error ${i}`);
389
+ }
390
+ });
391
+ });
392
+ ```
393
+
394
+ ### Template 6: Promise.allSettled Patterns
395
+
396
+ ```typescript
397
+ describe('Promise.allSettled Patterns', () => {
398
+ it('should collect all errors from allSettled promises', async () => {
399
+ // ARRANGE: Create promises with mixed results
400
+ const promises = [
401
+ Promise.reject(new Error('Error 1')),
402
+ Promise.reject(new Error('Error 2')),
403
+ Promise.resolve('success'),
404
+ Promise.reject(new Error('Error 3')),
405
+ ];
406
+
407
+ // ACT: Use Promise.allSettled
408
+ const results = await Promise.allSettled(promises);
409
+
410
+ // ASSERT: Filter and verify errors
411
+ const rejected = results.filter(isRejected);
412
+
413
+ expect(rejected).toHaveLength(3);
414
+ expect(rejected[0].reason.message).toBe('Error 1');
415
+ expect(rejected[1].reason.message).toBe('Error 2');
416
+ expect(rejected[2].reason.message).toBe('Error 3');
417
+
418
+ // ASSERT: Verify fulfilled promises
419
+ const fulfilled = results.filter(isFulfilled);
420
+
421
+ expect(fulfilled).toHaveLength(1);
422
+ expect(fulfilled[0].value).toBe('success');
423
+ });
424
+
425
+ it('should complete all workflows despite failures', async () => {
426
+ // ARRANGE: Track all completions
427
+ const completedWorkflows = new Set<string>();
428
+
429
+ class ParentWorkflow extends Workflow {
430
+ @Task({ concurrent: true })
431
+ async spawnChildren() {
432
+ const children = [
433
+ createChildWorkflow(this, 'Success-1', false),
434
+ createChildWorkflow(this, 'Fail-1', true),
435
+ createChildWorkflow(this, 'Success-2', false),
436
+ createChildWorkflow(this, 'Fail-2', true),
437
+ createChildWorkflow(this, 'Success-3', false),
438
+ ];
439
+
440
+ // Track all completions
441
+ children.forEach(child => {
442
+ child.run().then(
443
+ () => completedWorkflows.add(child.id),
444
+ () => completedWorkflows.add(child.id)
445
+ );
446
+ });
447
+
448
+ return children;
449
+ }
450
+
451
+ async run() {
452
+ try {
453
+ await this.spawnChildren();
454
+ } catch (err) {
455
+ // Expected
456
+ }
457
+ }
458
+ }
459
+
460
+ const parent = new ParentWorkflow('Parent');
461
+
462
+ // ACT
463
+ await parent.run();
464
+
465
+ // ASSERT: All 5 workflows completed (no orphans)
466
+ expect(completedWorkflows.size).toBe(5);
467
+ expect(parent.children.length).toBe(5);
468
+ });
469
+ });
470
+ ```
471
+
472
+ ### Template 7: Performance Testing
473
+
474
+ ```typescript
475
+ describe('Error Aggregation - Performance', () => {
476
+ it('should handle large error counts efficiently', async () => {
477
+ // ARRANGE: Create 50 concurrent workflows
478
+ const workflowCount = 50;
479
+
480
+ class ParentWorkflow extends Workflow {
481
+ @Task({
482
+ concurrent: true,
483
+ errorMergeStrategy: { enabled: true }
484
+ })
485
+ async spawnManyChildren() {
486
+ return Array.from({ length: workflowCount }, (_, i) =>
487
+ createFailingWorkflow(this, `child-${i}`, `Error ${i}`)
488
+ );
489
+ }
490
+
491
+ async run() {
492
+ const startTime = performance.now();
493
+ try {
494
+ await this.spawnManyChildren();
495
+ } catch (err) {
496
+ const duration = performance.now() - startTime;
497
+ return { error: err, duration };
498
+ }
499
+ }
500
+ }
501
+
502
+ const parent = new ParentWorkflow('Parent');
503
+
504
+ // ACT
505
+ const { error, duration } = await parent.run();
506
+
507
+ // ASSERT: All errors aggregated
508
+ expect(error.message).toContain('50 concurrent errors');
509
+
510
+ // ASSERT: Completed in reasonable time (< 5 seconds)
511
+ expect(duration).toBeLessThan(5000);
512
+ });
513
+
514
+ it('should execute workflows concurrently not sequentially', async () => {
515
+ // ARRANGE: Track execution times
516
+ const startTimes = new Map<string, number>();
517
+
518
+ class TimedWorkflow extends Workflow {
519
+ async run() {
520
+ startTimes.set(this.id, Date.now());
521
+ await new Promise(resolve => setTimeout(resolve, 100));
522
+ return this.id;
523
+ }
524
+ }
525
+
526
+ class ParentWorkflow extends Workflow {
527
+ @Task({ concurrent: true })
528
+ async spawnChildren() {
529
+ return [
530
+ new TimedWorkflow('child-1', this),
531
+ new TimedWorkflow('child-2', this),
532
+ new TimedWorkflow('child-3', this),
533
+ ];
534
+ }
535
+
536
+ async run() {
537
+ const startTime = Date.now();
538
+ try {
539
+ await this.spawnChildren();
540
+ } catch (err) {
541
+ // Expected
542
+ }
543
+ return Date.now() - startTime;
544
+ }
545
+ }
546
+
547
+ const parent = new ParentWorkflow('Parent');
548
+
549
+ // ACT
550
+ const totalTime = await parent.run();
551
+
552
+ // ASSERT: Concurrent execution (total time < sequential time)
553
+ expect(totalTime).toBeLessThan(250); // Should be ~100ms, not 300ms
554
+
555
+ // ASSERT: All started around same time (within 50ms)
556
+ const times = Array.from(startTimes.values());
557
+ const maxDiff = Math.max(...times) - Math.min(...times);
558
+ expect(maxDiff).toBeLessThan(50);
559
+ });
560
+ });
561
+ ```
562
+
563
+ ---
564
+
565
+ ## Assertion Patterns
566
+
567
+ ### Message Assertions
568
+
569
+ ```typescript
570
+ // Contains substring
571
+ expect(result.message).toContain('concurrent errors');
572
+
573
+ // Matches regex
574
+ expect(result.message).toMatch(/\d+ concurrent errors/);
575
+
576
+ // Exact match
577
+ expect(result.message).toBe('3 concurrent errors: [1] Error 1; [2] Error 2; [3] Error 3');
578
+
579
+ // Multiple substrings
580
+ expect(result.message).toContain('Error 1');
581
+ expect(result.message).toContain('Error 2');
582
+ expect(result.message).toContain('Error 3');
583
+ ```
584
+
585
+ ### Object Matching
586
+
587
+ ```typescript
588
+ // Partial match
589
+ expect(result).toMatchObject({
590
+ message: expect.stringContaining('errors'),
591
+ workflowId: expect.any(String),
592
+ logs: expect.any(Array),
593
+ });
594
+
595
+ // Nested array matching
596
+ expect(result.logs).toEqual(
597
+ expect.arrayContaining([
598
+ expect.objectContaining({
599
+ workflowId: expect.any(String),
600
+ level: expect.any(String),
601
+ })
602
+ ])
603
+ );
604
+
605
+ // Exact array match
606
+ expect(result.original).toEqual([error1, error2, error3]);
607
+ ```
608
+
609
+ ### Type Assertions
610
+
611
+ ```typescript
612
+ // Type guard assertion
613
+ if (isWorkflowError(result)) {
614
+ expect(result.message).toBeDefined();
615
+ expect(result.workflowId).toBeDefined();
616
+ expect(Array.isArray(result.logs)).toBe(true);
617
+ } else {
618
+ fail('Result is not a WorkflowError');
619
+ }
620
+
621
+ // Instance check
622
+ expect(result).toBeInstanceOf(Error);
623
+ expect(result.original).toBeInstanceOf(Error);
624
+ ```
625
+
626
+ ### Error Assertions
627
+
628
+ ```typescript
629
+ // Async error with rejects
630
+ await expect(workflow.run()).rejects.toThrow('Expected error');
631
+
632
+ // Try-catch with assertion
633
+ try {
634
+ await workflow.run();
635
+ fail('Expected error to be thrown');
636
+ } catch (error) {
637
+ expect(error).toMatchObject({
638
+ message: expect.stringContaining('error'),
639
+ });
640
+ }
641
+
642
+ // Return error from try-catch
643
+ const error = await workflow.run().catch(err => err);
644
+ expect(error).toBeDefined();
645
+ expect(error.message).toContain('error');
646
+ ```
647
+
648
+ ---
649
+
650
+ ## Test Structure Template
651
+
652
+ ```typescript
653
+ describe('Feature Name', () => {
654
+ describe('Specific Scenario', () => {
655
+ it('should do something specific', async () => {
656
+ // ARRANGE: Setup test data and conditions
657
+ const workflow = new TestWorkflow('Test');
658
+
659
+ // ACT: Execute the code being tested
660
+ const result = await workflow.run();
661
+
662
+ // ASSERT: Verify expected outcomes
663
+ expect(result).toBeDefined();
664
+ expect(result.message).toContain('expected');
665
+ });
666
+ });
667
+ });
668
+ ```
669
+
670
+ ---
671
+
672
+ ## Import Statements
673
+
674
+ ```typescript
675
+ import { describe, it, expect, vi } from 'vitest';
676
+ import { Workflow, Task, Step } from '../../index.js';
677
+ import type { WorkflowError, WorkflowEvent } from '../../types/index.js';
678
+ import { mergeWorkflowErrors } from '../../utils/error-merger.js';
679
+ ```
680
+
681
+ ---
682
+
683
+ ## Common Test Scenarios Checklist
684
+
685
+ - [ ] Empty error array
686
+ - [ ] Single error
687
+ - [ ] Two errors
688
+ - [ ] Multiple errors (3, 5, 10+)
689
+ - [ ] All workflows succeed
690
+ - [ ] All workflows fail
691
+ - [ ] Mixed success/failure
692
+ - [ ] Custom merge function
693
+ - [ ] Disabled merge strategy (backward compat)
694
+ - [ ] No merge strategy provided (backward compat)
695
+ - [ ] Event emission
696
+ - [ ] Event propagation to parent
697
+ - [ ] Large error counts (50+)
698
+ - [ ] Performance/concurrency verification
699
+ - [ ] Orphan prevention
700
+ - [ ] Memory leaks (if applicable)
701
+
702
+ ---
703
+
704
+ **Quick Reference Version:** 1.0
705
+ **Last Updated:** 2026-01-12
706
+ **For:** P1.M2.T2.S2 Implementation