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
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { Workflow, WorkflowObserver, WorkflowNode, LogEntry, WorkflowEvent } from '../../index.js';
2
+ import { Workflow, WorkflowObserver, WorkflowNode, LogEntry, WorkflowEvent, ObservedState, getObservedState } from '../../index.js';
3
3
 
4
4
  class SimpleWorkflow extends Workflow {
5
5
  async run(): Promise<string> {
@@ -10,6 +10,80 @@ class SimpleWorkflow extends Workflow {
10
10
  }
11
11
  }
12
12
 
13
+ describe('Workflow Name Validation', () => {
14
+ it('should reject empty string name', () => {
15
+ expect(() => new SimpleWorkflow('')).toThrow('Workflow name cannot be empty or whitespace only');
16
+ });
17
+
18
+ it('should reject whitespace-only name (spaces)', () => {
19
+ expect(() => new SimpleWorkflow(' ')).toThrow('Workflow name cannot be empty or whitespace only');
20
+ });
21
+
22
+ it('should reject whitespace-only name (tabs)', () => {
23
+ expect(() => new SimpleWorkflow('\t\t')).toThrow('Workflow name cannot be empty or whitespace only');
24
+ });
25
+
26
+ it('should reject whitespace-only name (newlines)', () => {
27
+ expect(() => new SimpleWorkflow('\n\n')).toThrow('Workflow name cannot be empty or whitespace only');
28
+ });
29
+
30
+ it('should reject whitespace-only name (mixed whitespace)', () => {
31
+ expect(() => new SimpleWorkflow(' \t\n ')).toThrow('Workflow name cannot be empty or whitespace only');
32
+ });
33
+
34
+ it('should reject name exceeding 100 characters', () => {
35
+ const longName = 'a'.repeat(101);
36
+ expect(() => new SimpleWorkflow(longName)).toThrow('Workflow name cannot exceed 100 characters');
37
+ });
38
+
39
+ it('should accept name with exactly 100 characters', () => {
40
+ const exactly100 = 'a'.repeat(100);
41
+ const wf = new SimpleWorkflow(exactly100);
42
+ expect(wf.getNode().name).toBe(exactly100);
43
+ expect(wf.getNode().name.length).toBe(100);
44
+ });
45
+
46
+ it('should accept valid names with leading/trailing whitespace', () => {
47
+ const wf1 = new SimpleWorkflow(' MyWorkflow ');
48
+ expect(wf1.getNode().name).toBe(' MyWorkflow ');
49
+
50
+ const wf2 = new SimpleWorkflow('\tValidName\t');
51
+ expect(wf2.getNode().name).toBe('\tValidName\t');
52
+ });
53
+
54
+ it('should use class name when name is undefined', () => {
55
+ const wf = new SimpleWorkflow();
56
+ expect(wf.getNode().name).toBe('SimpleWorkflow');
57
+ });
58
+
59
+ it('should use class name when name is null', () => {
60
+ const wf = new SimpleWorkflow(null as any);
61
+ expect(wf.getNode().name).toBe('SimpleWorkflow');
62
+ });
63
+
64
+ it('should validate both constructor patterns - class-based with empty name', () => {
65
+ expect(() => new SimpleWorkflow('')).toThrow('Workflow name cannot be empty or whitespace only');
66
+ });
67
+
68
+ it('should validate both constructor patterns - functional with empty name', () => {
69
+ expect(() => new Workflow({ name: '' }, async () => {})).toThrow('Workflow name cannot be empty or whitespace only');
70
+ });
71
+
72
+ it('should validate both constructor patterns - functional with whitespace name', () => {
73
+ expect(() => new Workflow({ name: ' ' }, async () => {})).toThrow('Workflow name cannot be empty or whitespace only');
74
+ });
75
+
76
+ it('should validate both constructor patterns - functional with name exceeding 100 characters', () => {
77
+ const longName = 'a'.repeat(101);
78
+ expect(() => new Workflow({ name: longName }, async () => {})).toThrow('Workflow name cannot exceed 100 characters');
79
+ });
80
+
81
+ it('should accept valid name in functional pattern', () => {
82
+ const wf = new Workflow({ name: 'ValidFunctionalWorkflow' }, async () => 'done');
83
+ expect(wf.getNode().name).toBe('ValidFunctionalWorkflow');
84
+ });
85
+ });
86
+
13
87
  describe('Workflow', () => {
14
88
  it('should create with unique id', () => {
15
89
  const wf1 = new SimpleWorkflow();
@@ -78,4 +152,206 @@ describe('Workflow', () => {
78
152
  expect(attachEvent).toBeDefined();
79
153
  expect(attachEvent?.type === 'childAttached' && attachEvent.parentId).toBe(parent.id);
80
154
  });
155
+
156
+ it('should capture state and logs in functional workflow error', async () => {
157
+ // Arrange: Create observer to capture events
158
+ const events: WorkflowEvent[] = [];
159
+
160
+ const observer: WorkflowObserver = {
161
+ onLog: () => {},
162
+ onEvent: (event) => events.push(event),
163
+ onStateUpdated: () => {},
164
+ onTreeChanged: () => {},
165
+ };
166
+
167
+ // Arrange: Create functional workflow with a step that throws an error
168
+ const workflow = new Workflow<void>(
169
+ { name: 'ErrorCaptureTest' },
170
+ async (ctx) => {
171
+ // Execute a step that will fail
172
+ await ctx.step('failing-step', async () => {
173
+ throw new Error('Test error from step');
174
+ });
175
+ }
176
+ );
177
+
178
+ // Act: Attach observer and run workflow
179
+ workflow.addObserver(observer);
180
+ await expect(workflow.run()).rejects.toThrow('Test error from step');
181
+
182
+ // Assert: Verify error event was emitted
183
+ const errorEvents = events.filter((e) => e.type === 'error');
184
+ expect(errorEvents.length).toBeGreaterThanOrEqual(1);
185
+
186
+ // Assert: Verify error structure
187
+ const errorEvent = errorEvents[0];
188
+ expect(errorEvent.error).toBeDefined();
189
+ expect(errorEvent.error.message).toBe('Test error from step');
190
+
191
+ // Assert: Verify logs array was captured (even if empty for step errors)
192
+ expect(errorEvent.error.logs).toBeDefined();
193
+ expect(Array.isArray(errorEvent.error.logs)).toBe(true);
194
+
195
+ // Assert: Verify state was captured (may be empty object for pure functional workflows)
196
+ expect(errorEvent.error.state).toBeDefined();
197
+ expect(typeof errorEvent.error.state).toBe('object');
198
+
199
+ // Assert: Verify workflow status
200
+ expect(workflow.status).toBe('failed');
201
+
202
+ // Assert: Verify workflowId is captured
203
+ expect(errorEvent.error.workflowId).toBe(workflow.id);
204
+ });
205
+
206
+ it('should capture @ObservedState fields in workflow error state', async () => {
207
+ // Test workflow class with @ObservedState decorated fields
208
+ // Using functional pattern (executor) so error events are emitted via runFunctional()
209
+ class StatefulWorkflowClass extends Workflow {
210
+ @ObservedState()
211
+ stepCount: number = 0;
212
+
213
+ @ObservedState({ redact: true })
214
+ apiKey: string = 'secret-key-123';
215
+
216
+ @ObservedState({ hidden: true })
217
+ internalCounter: number = 42;
218
+ }
219
+
220
+ // Arrange: Create observer to capture error events
221
+ const events: WorkflowEvent[] = [];
222
+
223
+ const observer: WorkflowObserver = {
224
+ onLog: () => {},
225
+ onEvent: (event) => events.push(event),
226
+ onStateUpdated: () => {},
227
+ onTreeChanged: () => {},
228
+ };
229
+
230
+ // Arrange: Create workflow with @ObservedState fields using functional pattern
231
+ const workflow = new StatefulWorkflowClass(
232
+ { name: 'StatefulErrorTest' },
233
+ async (ctx) => {
234
+ // Modify @ObservedState fields on the workflow instance
235
+ (workflow as any).stepCount = 5;
236
+ (workflow as any).apiKey = 'updated-key';
237
+ (workflow as any).internalCounter = 99;
238
+
239
+ // Execute a step that will fail
240
+ await ctx.step('failing-step', async () => {
241
+ throw new Error('Error after state update');
242
+ });
243
+ }
244
+ );
245
+
246
+ // Act: Attach observer and trigger error
247
+ workflow.addObserver(observer);
248
+ await expect(workflow.run()).rejects.toThrow('Error after state update');
249
+
250
+ // Assert: Verify error event was emitted
251
+ const errorEvents = events.filter((e) => e.type === 'error');
252
+ expect(errorEvents.length).toBeGreaterThanOrEqual(1);
253
+
254
+ // Assert: Verify error structure
255
+ const errorEvent = errorEvents[0];
256
+ expect(errorEvent.error).toBeDefined();
257
+ expect(errorEvent.error.message).toBe('Error after state update');
258
+
259
+ // Assert: Verify @ObservedState fields were captured
260
+ expect(errorEvent.error.state).toBeDefined();
261
+ expect(typeof errorEvent.error.state).toBe('object');
262
+
263
+ // Assert: Verify public field value is captured
264
+ expect(errorEvent.error.state.stepCount).toBe(5);
265
+
266
+ // Assert: Verify redacted field shows '***'
267
+ expect(errorEvent.error.state.apiKey).toBe('***');
268
+
269
+ // Assert: Verify hidden field is NOT in state
270
+ expect('internalCounter' in errorEvent.error.state).toBe(false);
271
+
272
+ // Assert: Verify logs array is present (may be empty)
273
+ expect(errorEvent.error.logs).toBeDefined();
274
+ expect(Array.isArray(errorEvent.error.logs)).toBe(true);
275
+
276
+ // Assert: Verify workflow status
277
+ expect(workflow.status).toBe('failed');
278
+
279
+ // Assert: Verify workflowId is captured
280
+ expect(errorEvent.error.workflowId).toBe(workflow.id);
281
+ });
282
+
283
+ it('should detect circular parent relationship', () => {
284
+ // Arrange: Create parent and child workflows
285
+ const parent = new SimpleWorkflow('Parent');
286
+ const child = new SimpleWorkflow('Child', parent);
287
+
288
+ // Act: Create circular reference manually
289
+ // This simulates a bug or malicious input that creates a cycle
290
+ parent.parent = child;
291
+
292
+ // Assert: getRoot() should throw error for circular reference
293
+ // Note: getRoot() is protected, so we cast to any to access it
294
+ expect(() => (parent as any).getRoot()).toThrow(
295
+ 'Circular parent-child relationship detected'
296
+ );
297
+ });
298
+
299
+ it('should detect circular relationship in getRootObservers', () => {
300
+ // Arrange: Create parent and child workflows
301
+ const parent = new SimpleWorkflow('Parent');
302
+ const child = new SimpleWorkflow('Child', parent);
303
+
304
+ // Act: Create circular reference manually
305
+ // This simulates a bug or malicious input that creates a cycle
306
+ parent.parent = child;
307
+
308
+ // Assert: getRootObservers() should throw error for circular reference
309
+ // Note: getRootObservers() is private, so we cast to any to access it
310
+ expect(() => (parent as any).getRootObservers()).toThrow(
311
+ 'Circular parent-child relationship detected'
312
+ );
313
+ });
314
+
315
+ it('should throw error when duplicate attachment attempted', () => {
316
+ // Arrange: Create parent and child workflows with first attachment
317
+ const parent = new SimpleWorkflow('Parent');
318
+ const child = new SimpleWorkflow('Child', parent);
319
+
320
+ // Act & Assert: Second attachment attempt should throw error
321
+ expect(() => parent.attachChild(child)).toThrow(
322
+ 'Child already attached to this workflow'
323
+ );
324
+ });
325
+
326
+ it('should emit treeUpdated event when status changes', () => {
327
+ // Arrange: Create workflow instance
328
+ const wf = new SimpleWorkflow();
329
+
330
+ // Arrange: Create arrays to track event emissions and callback invocations
331
+ const events: WorkflowEvent[] = [];
332
+ const treeChangedCalls: WorkflowNode[] = [];
333
+
334
+ // Arrange: Create observer with callbacks
335
+ const observer: WorkflowObserver = {
336
+ onLog: () => {}, // Empty - not testing logs
337
+ onEvent: (event) => events.push(event), // Capture events
338
+ onStateUpdated: () => {}, // Empty - not testing state updates
339
+ onTreeChanged: (root) => treeChangedCalls.push(root), // Capture tree changes
340
+ };
341
+
342
+ // Act: Attach observer and trigger status change
343
+ wf.addObserver(observer);
344
+ wf.setStatus('running');
345
+
346
+ // Assert: Verify treeUpdated event was emitted
347
+ const treeUpdatedEvent = events.find((e) => e.type === 'treeUpdated');
348
+ expect(treeUpdatedEvent).toBeDefined();
349
+
350
+ // Assert: Verify event payload contains root node (type narrowing for discriminated union)
351
+ expect(treeUpdatedEvent?.type === 'treeUpdated' && treeUpdatedEvent.root).toBe(wf.getNode());
352
+
353
+ // Assert: Verify onTreeChanged callback was invoked with root node
354
+ expect(treeChangedCalls).toHaveLength(1);
355
+ expect(treeChangedCalls[0]).toBe(wf.getNode());
356
+ });
81
357
  });
package/src/core/agent.ts CHANGED
@@ -63,6 +63,9 @@ export class Agent {
63
63
  /** MCP handler for tool management */
64
64
  private readonly mcpHandler: MCPHandler;
65
65
 
66
+ /** Direct MCPHandler instances for delegated execution */
67
+ private readonly mcpHandlers: MCPHandler[] = [];
68
+
66
69
  /** Default model to use */
67
70
  private readonly model: string;
68
71
 
@@ -87,6 +90,12 @@ export class Agent {
87
90
  // Register MCP servers
88
91
  if (config.mcps) {
89
92
  for (const mcp of config.mcps) {
93
+ // If the MCP is already an MCPHandler instance, store it directly
94
+ // for delegated tool execution (preserves registered executors)
95
+ if (mcp instanceof MCPHandler) {
96
+ this.mcpHandlers.push(mcp);
97
+ }
98
+ // Always register with main handler for tool discovery
90
99
  this.mcpHandler.registerServer(mcp);
91
100
  }
92
101
  }
@@ -463,7 +472,18 @@ export class Agent {
463
472
  * Execute a tool (either direct or via MCP)
464
473
  */
465
474
  private async executeTool(name: string, input: unknown): Promise<unknown> {
466
- // Check if it's an MCP tool
475
+ // First, check stored MCPHandler instances (they have registered executors)
476
+ for (const handler of this.mcpHandlers) {
477
+ if (handler.hasTool(name)) {
478
+ const result = await handler.executeTool(name, input);
479
+ if (result.is_error) {
480
+ throw new Error(result.content as string);
481
+ }
482
+ return result.content;
483
+ }
484
+ }
485
+
486
+ // Fall back to main mcpHandler (for non-MCPHandler MCPServers)
467
487
  if (this.mcpHandler.hasTool(name)) {
468
488
  const result = await this.mcpHandler.executeTool(name, input);
469
489
  if (result.is_error) {
@@ -15,6 +15,14 @@ export class WorkflowLogger {
15
15
  this.parentLogId = parentLogId;
16
16
  }
17
17
 
18
+ /**
19
+ * Emit a log entry directly to the node without notifying observers
20
+ * Used to avoid infinite recursion when observer.onLog() throws
21
+ */
22
+ private emitWithoutObserverNotification(entry: LogEntry): void {
23
+ this.node.logs.push(entry);
24
+ }
25
+
18
26
  /**
19
27
  * Emit a log entry to the node and all observers
20
28
  */
@@ -24,7 +32,16 @@ export class WorkflowLogger {
24
32
  try {
25
33
  obs.onLog(entry);
26
34
  } catch (err) {
27
- console.error('Observer onLog error:', err);
35
+ // Create error entry and emit without observer notification to avoid infinite recursion
36
+ const errorEntry: LogEntry = {
37
+ id: generateId(),
38
+ workflowId: this.node.id,
39
+ timestamp: Date.now(),
40
+ level: 'error',
41
+ message: 'Observer onLog error',
42
+ data: { error: err },
43
+ };
44
+ this.emitWithoutObserverNotification(errorEntry);
28
45
  }
29
46
  }
30
47
  }
@@ -80,8 +97,16 @@ export class WorkflowLogger {
80
97
 
81
98
  /**
82
99
  * Create a child logger that includes parentLogId
100
+ * @param parentLogId - ID of the parent log entry (legacy API)
101
+ */
102
+ child(parentLogId: string): WorkflowLogger;
103
+ /**
104
+ * Create a child logger with metadata
105
+ * @param meta - Partial log entry metadata (typically { parentLogId: string })
83
106
  */
84
- child(parentLogId: string): WorkflowLogger {
107
+ child(meta: Partial<LogEntry>): WorkflowLogger;
108
+ child(input: string | Partial<LogEntry>): WorkflowLogger {
109
+ const parentLogId = typeof input === 'string' ? input : input.parentLogId;
85
110
  return new WorkflowLogger(this.node, this.observers, parentLogId);
86
111
  }
87
112
  }
@@ -17,6 +17,7 @@ import type {
17
17
  WorkflowEvent,
18
18
  ReflectionConfig,
19
19
  ReflectionContext,
20
+ LogEntry,
20
21
  } from '../types/index.js';
21
22
  import { EventTreeHandleImpl, createEventTreeHandle } from './event-tree.js';
22
23
  import {
@@ -26,6 +27,7 @@ import {
26
27
  import { generateId } from '../utils/id.js';
27
28
  import { ReflectionManager } from '../reflection/reflection.js';
28
29
  import { createReflectionConfig } from '../types/index.js';
30
+ import { getObservedState } from '../decorators/observed-state.js';
29
31
 
30
32
  /**
31
33
  * Interface for workflow-like objects that can emit events
@@ -157,8 +159,8 @@ export class WorkflowContextImpl implements WorkflowContext {
157
159
  original: error,
158
160
  workflowId: this.workflowId,
159
161
  stack: error instanceof Error ? error.stack : undefined,
160
- state: {},
161
- logs: [],
162
+ state: getObservedState(this.workflow),
163
+ logs: [...this.workflow.node.logs] as LogEntry[],
162
164
  },
163
165
  });
164
166
 
@@ -321,8 +323,8 @@ export class WorkflowContextImpl implements WorkflowContext {
321
323
  original: error,
322
324
  workflowId: this.workflowId,
323
325
  stack: error instanceof Error ? error.stack : undefined,
324
- state: {},
325
- logs: [],
326
+ state: getObservedState(this.workflow),
327
+ logs: [...this.workflow.node.logs] as LogEntry[],
326
328
  },
327
329
  });
328
330