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.
- package/.claude/commands/subtask-planning/prp-base-create.md +120 -0
- package/.claude/commands/subtask-planning/prp-base-execute.md +65 -0
- package/.claude/commands/task-breakdown.md +94 -0
- package/.claude/system_prompts/task-breakdown.md +1 -0
- package/CHANGELOG.md +188 -0
- package/PRD.md +543 -0
- package/README.md +99 -5
- package/examples/README.md +15 -1
- package/examples/examples/11-reparenting-workflows.ts +269 -0
- package/examples/index.ts +4 -0
- package/package-lock.json +2398 -0
- package/package.json +3 -1
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +259 -0
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +484 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +488 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +581 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +687 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +492 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +932 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +1109 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +802 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +603 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +564 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +518 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +1252 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +364 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +114 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +205 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +199 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +134 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +495 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +435 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +506 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +612 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +558 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +788 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +460 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +454 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +520 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +417 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +760 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +245 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +792 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +535 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +190 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +654 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +227 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +345 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +193 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +1323 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +1011 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +927 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +505 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +401 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +142 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +112 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +159 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +549 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +368 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +172 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +175 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +696 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +860 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +1066 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +1103 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +789 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +1098 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +1037 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +916 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +1045 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +890 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +822 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +668 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +706 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +265 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +655 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +1103 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +426 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +506 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +114 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +316 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +754 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +612 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +719 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +215 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +765 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +718 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +149 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +470 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +332 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +167 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +265 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +273 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +760 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +434 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +717 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +472 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +125 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +301 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +1170 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +940 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +151 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +650 -0
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +259 -0
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +457 -0
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +346 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +311 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +1565 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +288 -0
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +741 -0
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +652 -0
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +527 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +415 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +378 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +713 -0
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +370 -0
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +499 -0
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +230 -0
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +1134 -0
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +179 -0
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +629 -0
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +214 -0
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +629 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +529 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +142 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +304 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +558 -0
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +256 -0
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +346 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +415 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +489 -0
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +218 -0
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +380 -0
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +1923 -0
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +319 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +115 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +134 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +153 -0
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +132 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +716 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +186 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +604 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +213 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +30 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +56 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +53 -0
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +49 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +958 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +339 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +305 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +433 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +1574 -0
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +1014 -0
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +376 -0
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +1507 -0
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +949 -0
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +619 -0
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +723 -0
- package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-security-guide.md +56 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +460 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +324 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +175 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +499 -0
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +163 -0
- package/plan/bugfix/BUG_FIX_SUMMARY.md +961 -0
- package/src/__tests__/adversarial/attachChild-performance.test.ts +216 -0
- package/src/__tests__/adversarial/circular-reference.test.ts +101 -0
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +139 -0
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +571 -0
- package/src/__tests__/adversarial/deep-analysis.test.ts +729 -0
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +213 -0
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +448 -0
- package/src/__tests__/adversarial/edge-case.test.ts +703 -0
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +760 -0
- package/src/__tests__/adversarial/incremental-performance.test.ts +140 -0
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +457 -0
- package/src/__tests__/adversarial/observer-propagation.test.ts +487 -0
- package/src/__tests__/adversarial/parent-validation.test.ts +143 -0
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +611 -0
- package/src/__tests__/adversarial/prd-compliance.test.ts +731 -0
- package/src/__tests__/compatibility/backward-compatibility.test.ts +1572 -0
- package/src/__tests__/helpers/index.ts +18 -0
- package/src/__tests__/helpers/tree-verification.ts +257 -0
- package/src/__tests__/integration/bidirectional-consistency.test.ts +847 -0
- package/src/__tests__/integration/observer-logging.test.ts +643 -0
- package/src/__tests__/integration/tree-mirroring.test.ts +37 -0
- package/src/__tests__/integration/workflow-reparenting.test.ts +303 -0
- package/src/__tests__/unit/context.test.ts +79 -0
- package/src/__tests__/unit/logger.test.ts +293 -0
- package/src/__tests__/unit/observable.test.ts +321 -0
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +170 -0
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +209 -0
- package/src/__tests__/unit/workflow-detachChild.test.ts +100 -0
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +153 -0
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +180 -0
- package/src/__tests__/unit/workflow.test.ts +277 -1
- package/src/core/agent.ts +21 -1
- package/src/core/logger.ts +27 -2
- package/src/core/workflow-context.ts +6 -4
- package/src/core/workflow.ts +252 -14
- package/src/debugger/tree-debugger.ts +52 -7
- package/src/decorators/task.ts +65 -2
- package/src/index.ts +4 -2
- package/src/types/decorators.ts +8 -1
- package/src/types/events.ts +1 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/observable.ts +32 -3
- package/src/utils/workflow-error-utils.ts +56 -0
- package/tsconfig.json +1 -1
- package/llms_full.txt +0 -5890
- package/tasks.json +0 -0
- /package/plan/{backlog.json → 001_d3bb02af4886/backlog.json} +0 -0
- /package/plan/{P1P2/PRP.md → 001_d3bb02af4886/docs/PRP/P1P2-PRP.md} +0 -0
- /package/plan/{P3P4/PRP.md → 001_d3bb02af4886/docs/PRP/P3P4-PRP.md} +0 -0
- /package/plan/{P4P5/PRP.md → 001_d3bb02af4886/docs/PRP/P4P5-PRP.md} +0 -0
- /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/external_deps.md +0 -0
- /package/plan/{architecture → 001_d3bb02af4886/docs/architecture}/system_context.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_BEST_PRACTICES.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_CODE_PATTERNS.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_INTEGRATION_GUIDE.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/LRU_CACHE_RESEARCH_INDEX.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_INDEX.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/REFLECTION_RESEARCH_REPORT.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/RESEARCH_SUMMARY.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/anthropic-sdk.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/async-local-storage.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-code-patterns.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-decision-matrix.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-implementation-guide.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-integration-guide.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-patterns.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/reflection-quick-reference.md +0 -0
- /package/plan/{P1P2/research → 001_d3bb02af4886/docs/research/P1P2}/zod-schema.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/caching-lru.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/introspection-tools.md +0 -0
- /package/plan/{P3P4/research → 001_d3bb02af4886/docs/research/P3P4}/reflection-patterns.md +0 -0
- /package/plan/{P4P5/research → 001_d3bb02af4886/docs/research/P4P5}/RESEARCH_SUMMARY.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/INTROSPECTION_RESEARCH_SUMMARY.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/README-INTROSPECTION.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/agent-introspection-patterns.md +0 -0
- /package/plan/{research → 001_d3bb02af4886/docs/research/general}/introspection-tool-examples.md +0 -0
- /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
|
-
//
|
|
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) {
|
package/src/core/logger.ts
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
|