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,729 @@
1
+ /**
2
+ * Deep Analysis Tests
3
+ * These tests probe deeper into edge cases, error scenarios, and potential bugs
4
+ */
5
+
6
+ import { describe, it, expect, beforeEach } from 'vitest';
7
+ import { Workflow, Step, Task, ObservedState } from '../../index.js';
8
+ import { WorkflowTreeDebugger } from '../../debugger/tree-debugger.js';
9
+
10
+ describe('Deep Analysis Tests', () => {
11
+ describe('Observable Edge Cases', () => {
12
+ it('should handle Observable.subscribe with empty observer object', async () => {
13
+ class TestWorkflow extends Workflow {
14
+ async run() {
15
+ this.emitEvent({ type: 'stepStart', node: this.node, step: 'test' });
16
+ }
17
+ }
18
+
19
+ const workflow = new TestWorkflow();
20
+ const debuggerInstance = new WorkflowTreeDebugger(workflow);
21
+
22
+ // Subscribe with empty observer - should not crash
23
+ debuggerInstance.events.subscribe({});
24
+
25
+ await workflow.run();
26
+ });
27
+
28
+ it('should handle Observable.unsubscribe during event emission', async () => {
29
+ class TestWorkflow extends Workflow {
30
+ async run() {
31
+ for (let i = 0; i < 10; i++) {
32
+ this.emitEvent({ type: 'stepStart', node: this.node, step: `step-${i}` });
33
+ }
34
+ }
35
+ }
36
+
37
+ const workflow = new TestWorkflow();
38
+ const debuggerInstance = new WorkflowTreeDebugger(workflow);
39
+
40
+ let count = 0;
41
+ const subscription = debuggerInstance.events.subscribe({
42
+ next: () => {
43
+ count++;
44
+ if (count === 5) {
45
+ subscription.unsubscribe();
46
+ }
47
+ },
48
+ });
49
+
50
+ await workflow.run();
51
+
52
+ // Should have received 5 events before unsubscribing
53
+ expect(count).toBe(5);
54
+ });
55
+ });
56
+
57
+ describe('WorkflowLogger Edge Cases', () => {
58
+ it('should handle logger.child() with empty parentLogId', async () => {
59
+ class TestWorkflow extends Workflow {
60
+ async run() {
61
+ const childLogger = this.logger.child('');
62
+ childLogger.info('Child log with empty parent');
63
+ }
64
+ }
65
+
66
+ const workflow = new TestWorkflow();
67
+ await workflow.run();
68
+
69
+ expect(workflow.node.logs.length).toBe(1);
70
+ // Empty string is passed through as parentLogId
71
+ expect(workflow.node.logs[0].parentLogId).toBeUndefined();
72
+ });
73
+
74
+ it('should handle logger with very long messages', async () => {
75
+ class TestWorkflow extends Workflow {
76
+ async run() {
77
+ const longMessage = 'A'.repeat(10000);
78
+ this.logger.info(longMessage);
79
+ }
80
+ }
81
+
82
+ const workflow = new TestWorkflow();
83
+ await workflow.run();
84
+
85
+ expect(workflow.node.logs[0].message.length).toBe(10000);
86
+ });
87
+
88
+ it('should handle logger with special characters in data', async () => {
89
+ class TestWorkflow extends Workflow {
90
+ async run() {
91
+ this.logger.info('Test', {
92
+ null: null,
93
+ undefined: undefined,
94
+ circular: { self: null as any },
95
+ function: () => {},
96
+ symbol: Symbol('test'),
97
+ });
98
+ }
99
+ }
100
+
101
+ const workflow = new TestWorkflow();
102
+ // Should not throw
103
+ await workflow.run();
104
+ });
105
+ });
106
+
107
+ describe('Step Decorator Edge Cases', () => {
108
+ it('should handle @Step on synchronous method that returns Promise', async () => {
109
+ class TestWorkflow extends Workflow {
110
+ @Step()
111
+ async testStep() {
112
+ return Promise.resolve('done');
113
+ }
114
+
115
+ async run() {
116
+ return this.testStep();
117
+ }
118
+ }
119
+
120
+ const workflow = new TestWorkflow();
121
+ const result = await workflow.run();
122
+ expect(result).toBe('done');
123
+ });
124
+
125
+ it('should handle @Step that returns undefined', async () => {
126
+ class TestWorkflow extends Workflow {
127
+ @Step()
128
+ async testStep() {
129
+ // No return
130
+ }
131
+
132
+ async run() {
133
+ return this.testStep();
134
+ }
135
+ }
136
+
137
+ const workflow = new TestWorkflow();
138
+ const result = await workflow.run();
139
+ expect(result).toBeUndefined();
140
+ });
141
+
142
+ it('should handle @Step that throws non-Error', async () => {
143
+ class TestWorkflow extends Workflow {
144
+ @Step()
145
+ async testStep() {
146
+ throw 'string error';
147
+ }
148
+
149
+ async run() {
150
+ try {
151
+ await this.testStep();
152
+ } catch (err) {
153
+ // Non-Error throws get wrapped with 'Unknown error' message
154
+ // but the original is preserved
155
+ expect((err as any).message).toBe('Unknown error');
156
+ expect((err as any).original).toBe('string error');
157
+ }
158
+ }
159
+ }
160
+
161
+ const workflow = new TestWorkflow();
162
+ await workflow.run();
163
+ });
164
+
165
+ it('should handle @Step that throws null', async () => {
166
+ class TestWorkflow extends Workflow {
167
+ @Step()
168
+ async testStep() {
169
+ throw null;
170
+ }
171
+
172
+ async run() {
173
+ try {
174
+ await this.testStep();
175
+ } catch (err) {
176
+ expect(err).not.toBeNull();
177
+ }
178
+ }
179
+ }
180
+
181
+ const workflow = new TestWorkflow();
182
+ await workflow.run();
183
+ });
184
+ });
185
+
186
+ describe('Task Decorator Edge Cases', () => {
187
+ it('should handle @Task that returns primitive value', async () => {
188
+ class TestWorkflow extends Workflow {
189
+ @Task()
190
+ async returnsString() {
191
+ return 'not a workflow';
192
+ }
193
+
194
+ async run() {
195
+ return this.returnsString();
196
+ }
197
+ }
198
+
199
+ const workflow = new TestWorkflow();
200
+ const result = await workflow.run();
201
+ expect(result).toBe('not a workflow');
202
+ expect(workflow.children.length).toBe(0);
203
+ });
204
+
205
+ it('should handle @Task that returns number', async () => {
206
+ class TestWorkflow extends Workflow {
207
+ @Task()
208
+ async returnsNumber() {
209
+ return 42;
210
+ }
211
+
212
+ async run() {
213
+ return this.returnsNumber();
214
+ }
215
+ }
216
+
217
+ const workflow = new TestWorkflow();
218
+ const result = await workflow.run();
219
+ expect(result).toBe(42);
220
+ });
221
+
222
+ it('should handle @Task that returns object with id property (duck typing)', async () => {
223
+ class TestWorkflow extends Workflow {
224
+ @Task()
225
+ async returnsDuck() {
226
+ return { id: 'duck-123', name: 'Duck' };
227
+ }
228
+
229
+ async run() {
230
+ return this.returnsDuck();
231
+ }
232
+ }
233
+
234
+ const workflow = new TestWorkflow();
235
+ const result = await workflow.run();
236
+ // Duck typing - objects with 'id' property get parent attached
237
+ // The returned object is mutated to have a parent property
238
+ expect(result.id).toBe('duck-123');
239
+ expect(result.name).toBe('Duck');
240
+ expect((result as { parent?: unknown }).parent).toBeDefined();
241
+ // Duck typing treats it as a workflow and attaches it
242
+ expect(workflow.children.length).toBe(1);
243
+ });
244
+
245
+ it('should handle @Task with concurrent on single non-workflow', async () => {
246
+ class TestWorkflow extends Workflow {
247
+ @Task({ concurrent: true })
248
+ async returnsString() {
249
+ return 'not a workflow';
250
+ }
251
+
252
+ async run() {
253
+ return this.returnsString();
254
+ }
255
+ }
256
+
257
+ const workflow = new TestWorkflow();
258
+ const result = await workflow.run();
259
+ expect(result).toBe('not a workflow');
260
+ });
261
+
262
+ it('should handle @Task with concurrent: true but no run method', async () => {
263
+ class ChildWorkflow extends Workflow {
264
+ // No run method - will throw
265
+ }
266
+
267
+ class ParentWorkflow extends Workflow {
268
+ @Task({ concurrent: true })
269
+ async spawnChild() {
270
+ return new ChildWorkflow('Child', this);
271
+ }
272
+
273
+ async run() {
274
+ // Child will be attached but running it will throw
275
+ return this.spawnChild();
276
+ }
277
+ }
278
+
279
+ const workflow = new ParentWorkflow();
280
+ await workflow.run();
281
+
282
+ // Child should still be attached
283
+ expect(workflow.children.length).toBe(1);
284
+ });
285
+ });
286
+
287
+ describe('ObservedState Edge Cases', () => {
288
+ it('should handle undefined value in observed state', async () => {
289
+ class TestWorkflow extends Workflow {
290
+ @ObservedState()
291
+ undefinedField: string | undefined = undefined;
292
+
293
+ async run() {
294
+ this.snapshotState();
295
+ return this.node.stateSnapshot;
296
+ }
297
+ }
298
+
299
+ const workflow = new TestWorkflow();
300
+ const snapshot = await workflow.run();
301
+
302
+ expect(snapshot?.undefinedField).toBeUndefined();
303
+ });
304
+
305
+ it('should handle circular reference in observed state', async () => {
306
+ class TestWorkflow extends Workflow {
307
+ @ObservedState()
308
+ circular: any = {};
309
+
310
+ async run() {
311
+ this.circular.self = this.circular;
312
+ this.snapshotState();
313
+ return this.node.stateSnapshot;
314
+ }
315
+ }
316
+
317
+ const workflow = new TestWorkflow();
318
+ // Should not crash
319
+ await workflow.run();
320
+ });
321
+
322
+ it('should handle deeply nested object in observed state', async () => {
323
+ class TestWorkflow extends Workflow {
324
+ @ObservedState()
325
+ nested: any = { level: 1 };
326
+
327
+ async run() {
328
+ for (let i = 2; i <= 100; i++) {
329
+ this.nested = { level: i, child: this.nested };
330
+ }
331
+ this.snapshotState();
332
+ return this.node.stateSnapshot;
333
+ }
334
+ }
335
+
336
+ const workflow = new TestWorkflow();
337
+ const snapshot = await workflow.run();
338
+
339
+ expect(snapshot?.nested).toBeDefined();
340
+ });
341
+ });
342
+
343
+ describe('Workflow Construction Edge Cases', () => {
344
+ it('should handle Workflow with no arguments', async () => {
345
+ class TestWorkflow extends Workflow {
346
+ async run() {
347
+ return 'done';
348
+ }
349
+ }
350
+
351
+ const workflow = new TestWorkflow();
352
+ expect(workflow.node.name).toBe('TestWorkflow');
353
+ expect(workflow.parent).toBeNull();
354
+ });
355
+
356
+ it('should handle Workflow with only parent argument', async () => {
357
+ class ChildWorkflow extends Workflow {
358
+ async run() {
359
+ return 'done';
360
+ }
361
+ }
362
+
363
+ class ParentWorkflow extends Workflow {
364
+ async run() {
365
+ const child = new ChildWorkflow(undefined as any, this);
366
+ expect(child.parent).toBe(this);
367
+ }
368
+ }
369
+
370
+ const workflow = new ParentWorkflow();
371
+ await workflow.run();
372
+ });
373
+
374
+ it('should handle functional workflow pattern', async () => {
375
+ const workflow = new Workflow({ name: 'FunctionalWorkflow' }, async (ctx) => {
376
+ await ctx.step('test', async () => {
377
+ return 'done';
378
+ });
379
+ });
380
+
381
+ const result = await workflow.run();
382
+ expect(result).toBeDefined();
383
+ });
384
+ });
385
+
386
+ describe('Tree Debugger Edge Cases', () => {
387
+ it('should handle toTreeString on deep hierarchy', async () => {
388
+ // Create a root workflow with deep children
389
+ class RootWorkflow extends Workflow {
390
+ async run() {
391
+ return 'done';
392
+ }
393
+ }
394
+
395
+ const root = new RootWorkflow();
396
+ let lastWorkflow: any = root;
397
+
398
+ // Build deep hierarchy
399
+ for (let i = 0; i < 20; i++) {
400
+ const ChildWorkflow = class extends Workflow {
401
+ async run() {
402
+ return 'done';
403
+ }
404
+ };
405
+ const child = new ChildWorkflow(`Workflow-${i}`, lastWorkflow);
406
+ await child.run();
407
+ lastWorkflow = child;
408
+ }
409
+
410
+ // Create debugger on the root
411
+ const debuggerInstance = new WorkflowTreeDebugger(root);
412
+ const treeString = debuggerInstance.toTreeString();
413
+
414
+ expect(treeString.length).toBeGreaterThan(0);
415
+ expect(treeString.split('\n').length).toBeGreaterThan(20);
416
+ });
417
+
418
+ it('should handle toLogString on workflow with no logs', async () => {
419
+ class TestWorkflow extends Workflow {
420
+ async run() {
421
+ // No logs
422
+ }
423
+ }
424
+
425
+ const workflow = new TestWorkflow();
426
+ await workflow.run();
427
+
428
+ const debuggerInstance = new WorkflowTreeDebugger(workflow);
429
+ const logString = debuggerInstance.toLogString();
430
+
431
+ expect(typeof logString).toBe('string');
432
+ });
433
+
434
+ it('should handle getNode on non-existent ID', async () => {
435
+ class TestWorkflow extends Workflow {
436
+ async run() {
437
+ return 'done';
438
+ }
439
+ }
440
+
441
+ const workflow = new TestWorkflow();
442
+ const debuggerInstance = new WorkflowTreeDebugger(workflow);
443
+
444
+ const node = debuggerInstance.getNode('non-existent-id');
445
+ expect(node).toBeUndefined();
446
+ });
447
+
448
+ it('should handle getStats on complex tree', async () => {
449
+ class ChildWorkflow extends Workflow {
450
+ @Step()
451
+ async step() {
452
+ this.logger.info('Child log');
453
+ return 'done';
454
+ }
455
+
456
+ async run() {
457
+ return this.step();
458
+ }
459
+ }
460
+
461
+ class ParentWorkflow extends Workflow {
462
+ @Task({ concurrent: true })
463
+ async spawnChildren() {
464
+ return [
465
+ new ChildWorkflow('Child1', this),
466
+ new ChildWorkflow('Child2', this),
467
+ new ChildWorkflow('Child3', this),
468
+ ];
469
+ }
470
+
471
+ async run() {
472
+ await this.spawnChildren();
473
+ await Promise.all(this.children.map(c => c.run()));
474
+ }
475
+ }
476
+
477
+ const workflow = new ParentWorkflow();
478
+ await workflow.run();
479
+
480
+ const debuggerInstance = new WorkflowTreeDebugger(workflow);
481
+ const stats = debuggerInstance.getStats();
482
+
483
+ expect(stats.totalNodes).toBe(4); // 1 parent + 3 children
484
+ expect(stats.totalLogs).toBeGreaterThan(0);
485
+ expect(stats.totalEvents).toBeGreaterThan(0);
486
+ expect(stats.byStatus).toBeDefined();
487
+ });
488
+ });
489
+
490
+ describe('Event Propagation Edge Cases', () => {
491
+ it('should handle events emitted during observer callback', async () => {
492
+ class TestWorkflow extends Workflow {
493
+ async run() {
494
+ let callCount = 0;
495
+
496
+ this.addObserver({
497
+ onLog: () => {},
498
+ onEvent: () => {
499
+ callCount++;
500
+ // Emit another event during callback
501
+ if (callCount === 1) {
502
+ this.emitEvent({ type: 'stepStart', node: this.node, step: 'nested' });
503
+ }
504
+ },
505
+ onStateUpdated: () => {},
506
+ onTreeChanged: () => {},
507
+ });
508
+
509
+ this.emitEvent({ type: 'stepStart', node: this.node, step: 'initial' });
510
+
511
+ expect(callCount).toBeGreaterThanOrEqual(1);
512
+ }
513
+ }
514
+
515
+ const workflow = new TestWorkflow();
516
+ await workflow.run();
517
+ });
518
+
519
+ it('should handle multiple observers with different behaviors', async () => {
520
+ class TestWorkflow extends Workflow {
521
+ async run() {
522
+ const results: { [key: string]: number } = {};
523
+
524
+ this.addObserver({
525
+ onLog: () => { results.observer1 = (results.observer1 || 0) + 1; },
526
+ onEvent: () => { results.observer1 = (results.observer1 || 0) + 1; },
527
+ onStateUpdated: () => {},
528
+ onTreeChanged: () => {},
529
+ });
530
+
531
+ this.addObserver({
532
+ onLog: () => { results.observer2 = (results.observer2 || 0) + 1; },
533
+ onEvent: () => { results.observer2 = (results.observer2 || 0) + 1; },
534
+ onStateUpdated: () => {},
535
+ onTreeChanged: () => {},
536
+ });
537
+
538
+ this.emitEvent({ type: 'stepStart', node: this.node, step: 'test' });
539
+
540
+ expect(results.observer1).toBeGreaterThan(0);
541
+ expect(results.observer2).toBeGreaterThan(0);
542
+ }
543
+ }
544
+
545
+ const workflow = new TestWorkflow();
546
+ await workflow.run();
547
+ });
548
+ });
549
+
550
+ describe('State Transition Edge Cases', () => {
551
+ it('should handle status changes during execution', async () => {
552
+ class TestWorkflow extends Workflow {
553
+ async run() {
554
+ expect(this.status).toBe('idle');
555
+ this.setStatus('running');
556
+ expect(this.status).toBe('running');
557
+ this.setStatus('completed');
558
+ expect(this.status).toBe('completed');
559
+ }
560
+ }
561
+
562
+ const workflow = new TestWorkflow();
563
+ await workflow.run();
564
+ });
565
+
566
+ it('should handle invalid status values', async () => {
567
+ class TestWorkflow extends Workflow {
568
+ async run() {
569
+ // TypeScript should prevent this at compile time, but let's test runtime
570
+ this.setStatus('invalid' as any);
571
+ // Status should be set (no validation at runtime)
572
+ expect(this.status).toBe('invalid');
573
+ }
574
+ }
575
+
576
+ const workflow = new TestWorkflow();
577
+ await workflow.run();
578
+ });
579
+ });
580
+
581
+ describe('Child Attachment Edge Cases', () => {
582
+ it('should prevent attaching the same child twice', async () => {
583
+ class ChildWorkflow extends Workflow {
584
+ async run() {
585
+ return 'done';
586
+ }
587
+ }
588
+
589
+ class ParentWorkflow extends Workflow {
590
+ async run() {
591
+ const child = new ChildWorkflow('Child', this);
592
+ // Try to attach again
593
+ expect(() => {
594
+ this.attachChild(child);
595
+ }).toThrow('Child already attached');
596
+ }
597
+ }
598
+
599
+ const workflow = new ParentWorkflow();
600
+ await workflow.run();
601
+ });
602
+
603
+ it('should handle child with parent set in constructor', async () => {
604
+ class ChildWorkflow extends Workflow {
605
+ async run() {
606
+ return 'done';
607
+ }
608
+ }
609
+
610
+ class ParentWorkflow extends Workflow {
611
+ async run() {
612
+ const child = new ChildWorkflow('Child', this);
613
+ // Child should already be attached
614
+ expect(this.children.length).toBe(1);
615
+ expect(this.children[0]).toBe(child);
616
+ }
617
+ }
618
+
619
+ const workflow = new ParentWorkflow();
620
+ await workflow.run();
621
+ });
622
+ });
623
+
624
+ describe('Memory and Resource Edge Cases', () => {
625
+ it('should handle rapid workflow creation and destruction', async () => {
626
+ class TestWorkflow extends Workflow {
627
+ async run() {
628
+ return 'done';
629
+ }
630
+ }
631
+
632
+ for (let i = 0; i < 100; i++) {
633
+ const workflow = new TestWorkflow(`Workflow-${i}`);
634
+ await workflow.run();
635
+ }
636
+
637
+ // If we got here without crashing, memory management is reasonable
638
+ expect(true).toBe(true);
639
+ });
640
+
641
+ it('should handle many observers on single workflow', async () => {
642
+ class TestWorkflow extends Workflow {
643
+ async run() {
644
+ this.emitEvent({ type: 'stepStart', node: this.node, step: 'test' });
645
+ }
646
+ }
647
+
648
+ const workflow = new TestWorkflow();
649
+
650
+ // Add 100 observers
651
+ for (let i = 0; i < 100; i++) {
652
+ workflow.addObserver({
653
+ onLog: () => {},
654
+ onEvent: () => {},
655
+ onStateUpdated: () => {},
656
+ onTreeChanged: () => {},
657
+ });
658
+ }
659
+
660
+ await workflow.run();
661
+
662
+ // Should complete without issues
663
+ expect(true).toBe(true);
664
+ });
665
+ });
666
+
667
+ describe('Error Recovery Edge Cases', () => {
668
+ it('should handle error in @Step followed by another @Step', async () => {
669
+ class TestWorkflow extends Workflow {
670
+ @Step()
671
+ async failingStep() {
672
+ throw new Error('Failed');
673
+ }
674
+
675
+ @Step()
676
+ async successStep() {
677
+ return 'success';
678
+ }
679
+
680
+ async run() {
681
+ try {
682
+ await this.failingStep();
683
+ } catch (err) {
684
+ // Expected
685
+ }
686
+ return await this.successStep();
687
+ }
688
+ }
689
+
690
+ const workflow = new TestWorkflow();
691
+ const result = await workflow.run();
692
+ expect(result).toBe('success');
693
+ });
694
+
695
+ it('should handle multiple sequential errors', async () => {
696
+ class TestWorkflow extends Workflow {
697
+ @Step()
698
+ async errorStep1() {
699
+ throw new Error('Error 1');
700
+ }
701
+
702
+ @Step()
703
+ async errorStep2() {
704
+ throw new Error('Error 2');
705
+ }
706
+
707
+ async run() {
708
+ try {
709
+ await this.errorStep1();
710
+ } catch (err) {
711
+ // Expected
712
+ }
713
+ try {
714
+ await this.errorStep2();
715
+ } catch (err) {
716
+ // Expected
717
+ }
718
+ }
719
+ }
720
+
721
+ const workflow = new TestWorkflow();
722
+ await workflow.run();
723
+
724
+ // Should have multiple error events
725
+ const errorEvents = workflow.node.events.filter(e => e.type === 'error');
726
+ expect(errorEvents.length).toBe(2);
727
+ });
728
+ });
729
+ });