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
package/PRD.md
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
# **📘 PRODUCT REQUIREMENTS DOCUMENT (PRD)**
|
|
2
|
+
|
|
3
|
+
### **Hierarchical Workflow Engine with Full Observability & Tree Debugging**
|
|
4
|
+
|
|
5
|
+
Version: **1.0**
|
|
6
|
+
Status: **Implementation-ready**
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# **1. Overview**
|
|
11
|
+
|
|
12
|
+
This PRD defines a TypeScript workflow orchestration engine that provides:
|
|
13
|
+
|
|
14
|
+
* Hierarchical workflows with sequential + concurrent steps.
|
|
15
|
+
* Automatic parent/child attachment.
|
|
16
|
+
* High-resolution observability (logs, events, snapshots).
|
|
17
|
+
* Error introspection with full child state visibility.
|
|
18
|
+
* Restart logic handled at correct parent level.
|
|
19
|
+
* Real-time tree debugger API for terminal visualization.
|
|
20
|
+
|
|
21
|
+
All logs & events must form a **perfect 1:1 tree mirror** of the workflow execution tree in memory.
|
|
22
|
+
|
|
23
|
+
This PRD includes:
|
|
24
|
+
|
|
25
|
+
✔️ Full data model
|
|
26
|
+
✔️ All TypeScript interfaces
|
|
27
|
+
✔️ Decorator specs
|
|
28
|
+
✔️ Workflow base class skeleton
|
|
29
|
+
✔️ Logger implementation skeleton
|
|
30
|
+
✔️ Observer/event system skeleton
|
|
31
|
+
✔️ Snapshot system spec
|
|
32
|
+
✔️ Error/restart semantics
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# **2. Architecture**
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Workflow
|
|
40
|
+
├─ Steps (decorated methods)
|
|
41
|
+
├─ Tasks (decorated methods)
|
|
42
|
+
├─ Observed state (decorated fields)
|
|
43
|
+
├─ Children (other workflows)
|
|
44
|
+
├─ Logs
|
|
45
|
+
└─ Events
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The tree debugger subscribes to a root workflow and receives real-time events.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
# **3. Core Data Model (Interfaces)**
|
|
53
|
+
|
|
54
|
+
## **3.1 WorkflowNode**
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
export interface WorkflowNode {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
|
|
61
|
+
parent: WorkflowNode | null;
|
|
62
|
+
children: WorkflowNode[];
|
|
63
|
+
|
|
64
|
+
status: WorkflowStatus;
|
|
65
|
+
|
|
66
|
+
logs: LogEntry[];
|
|
67
|
+
events: WorkflowEvent[];
|
|
68
|
+
|
|
69
|
+
// optional state snapshot
|
|
70
|
+
stateSnapshot: SerializedWorkflowState | null;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## **3.2 WorkflowStatus**
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
export type WorkflowStatus =
|
|
78
|
+
| 'idle'
|
|
79
|
+
| 'running'
|
|
80
|
+
| 'completed'
|
|
81
|
+
| 'failed'
|
|
82
|
+
| 'cancelled';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
# **4. Logging & Events Model**
|
|
88
|
+
|
|
89
|
+
## **4.1 LogEntry**
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
93
|
+
|
|
94
|
+
export interface LogEntry {
|
|
95
|
+
id: string;
|
|
96
|
+
workflowId: string;
|
|
97
|
+
timestamp: number;
|
|
98
|
+
level: LogLevel;
|
|
99
|
+
message: string;
|
|
100
|
+
data?: unknown;
|
|
101
|
+
parentLogId?: string;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## **4.2 WorkflowEvent**
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
export type WorkflowEvent =
|
|
109
|
+
| { type: 'childAttached'; parentId: string; child: WorkflowNode }
|
|
110
|
+
| { type: 'stateSnapshot'; node: WorkflowNode }
|
|
111
|
+
| { type: 'stepStart'; node: WorkflowNode; step: string }
|
|
112
|
+
| { type: 'stepEnd'; node: WorkflowNode; step: string; duration: number }
|
|
113
|
+
| { type: 'error'; node: WorkflowNode; error: WorkflowError }
|
|
114
|
+
| { type: 'taskStart'; node: WorkflowNode; task: string }
|
|
115
|
+
| { type: 'taskEnd'; node: WorkflowNode; task: string }
|
|
116
|
+
| { type: 'treeUpdated'; root: WorkflowNode };
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
# **5. Error Model**
|
|
122
|
+
|
|
123
|
+
## **5.1 WorkflowError**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
export interface WorkflowError {
|
|
127
|
+
message: string;
|
|
128
|
+
original: unknown;
|
|
129
|
+
workflowId: string;
|
|
130
|
+
stack?: string;
|
|
131
|
+
|
|
132
|
+
state: SerializedWorkflowState; // a snapshot
|
|
133
|
+
logs: LogEntry[]; // logs from this node only
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
# **6. Snapshot System**
|
|
140
|
+
|
|
141
|
+
## **6.1 State Snapshot**
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
export type SerializedWorkflowState = Record<string, unknown>;
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## **6.2 ObservedState Metadata**
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
export interface StateFieldMetadata {
|
|
151
|
+
hidden?: boolean; // not shown in debugger
|
|
152
|
+
redact?: boolean; // shown as "***"
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
# **7. Observers**
|
|
159
|
+
|
|
160
|
+
## **7.1 WorkflowObserver**
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
export interface WorkflowObserver {
|
|
164
|
+
onLog(entry: LogEntry): void;
|
|
165
|
+
onEvent(event: WorkflowEvent): void;
|
|
166
|
+
onStateUpdated(node: WorkflowNode): void;
|
|
167
|
+
onTreeChanged(root: WorkflowNode): void;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Observers attach to the **root workflow** and receive all events.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
# **8. Decorators (Complete Technical Specification)**
|
|
176
|
+
|
|
177
|
+
## **8.1 @Step() Decorator**
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
export interface StepOptions {
|
|
181
|
+
name?: string;
|
|
182
|
+
snapshotState?: boolean;
|
|
183
|
+
trackTiming?: boolean; // Default: true - Track and emit step duration
|
|
184
|
+
logStart?: boolean;
|
|
185
|
+
logFinish?: boolean;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function Step(options: StepOptions = {}): MethodDecorator;
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Responsibilities:**
|
|
192
|
+
|
|
193
|
+
* Emit `stepStart` + `stepEnd`.
|
|
194
|
+
* Optionally snapshot state.
|
|
195
|
+
* Catch and wrap errors into `WorkflowError`.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## **8.2 @Task() Decorator**
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
export interface TaskOptions {
|
|
203
|
+
name?: string;
|
|
204
|
+
concurrent?: boolean;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function Task(options: TaskOptions = {}): MethodDecorator;
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Responsibilities:**
|
|
211
|
+
|
|
212
|
+
* Emit `taskStart` + `taskEnd`
|
|
213
|
+
* Attach returned workflow(s) as children.
|
|
214
|
+
* Enforce concurrency rules.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## **8.3 @ObservedState Decorator**
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
export function ObservedState(meta: StateFieldMetadata = {}): PropertyDecorator;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Fields marked with this decorator are included in snapshots.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
# **9. Restart Semantics**
|
|
229
|
+
|
|
230
|
+
* Descendant workflows never request restart upward.
|
|
231
|
+
* A parent step decides whether restart is needed by analyzing:
|
|
232
|
+
|
|
233
|
+
* all captured `WorkflowError`s
|
|
234
|
+
* descendant state snapshots
|
|
235
|
+
* logs from failing nodes
|
|
236
|
+
* Parent step may:
|
|
237
|
+
|
|
238
|
+
1. Retry the step
|
|
239
|
+
2. Abort the workflow
|
|
240
|
+
3. Rebuild the plan and continue
|
|
241
|
+
|
|
242
|
+
Restartability is **opt-in** at the step method level; not global.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
# **10. Optional Multi-Error Merging**
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
export interface ErrorMergeStrategy {
|
|
250
|
+
enabled: boolean;
|
|
251
|
+
maxMergeDepth?: number;
|
|
252
|
+
combine?(errors: WorkflowError[]): WorkflowError;
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Default: **disabled** → first error wins (race is preserved).
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
# **11. Tree Debugger API**
|
|
261
|
+
|
|
262
|
+
## **11.1 Tree Debugger Interface**
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
export interface WorkflowTreeDebugger {
|
|
266
|
+
getTree(): WorkflowNode;
|
|
267
|
+
getNode(id: string): WorkflowNode | undefined;
|
|
268
|
+
|
|
269
|
+
events: Observable<WorkflowEvent>;
|
|
270
|
+
|
|
271
|
+
toTreeString(node?: WorkflowNode): string;
|
|
272
|
+
toLogString(node?: WorkflowNode): string;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
This is consumed by the terminal UI.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
# **12. Base Classes (Class Skeletons)**
|
|
281
|
+
|
|
282
|
+
Below are implementation-ready class skeletons with exact method signatures.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
# **12.1 WorkflowLogger Skeleton**
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
export class WorkflowLogger {
|
|
290
|
+
constructor(private readonly node: WorkflowNode,
|
|
291
|
+
private readonly observers: WorkflowObserver[]) {}
|
|
292
|
+
|
|
293
|
+
private emit(entry: LogEntry) {
|
|
294
|
+
this.node.logs.push(entry);
|
|
295
|
+
for (const obs of this.observers) obs.onLog(entry);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
debug(message: string, data?: unknown) { /* ... */ }
|
|
299
|
+
info(message: string, data?: unknown) { /* ... */ }
|
|
300
|
+
warn(message: string, data?: unknown) { /* ... */ }
|
|
301
|
+
error(message: string, data?: unknown) { /* ... */ }
|
|
302
|
+
|
|
303
|
+
child(meta: Partial<LogEntry>): WorkflowLogger {
|
|
304
|
+
return new WorkflowLogger(this.node, this.observers);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
# **12.2 Workflow Base Class Skeleton**
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
export abstract class Workflow {
|
|
315
|
+
public readonly id: string;
|
|
316
|
+
public parent: Workflow | null = null;
|
|
317
|
+
public children: Workflow[] = [];
|
|
318
|
+
public status: WorkflowStatus = 'idle';
|
|
319
|
+
|
|
320
|
+
protected readonly logger: WorkflowLogger;
|
|
321
|
+
protected readonly node: WorkflowNode;
|
|
322
|
+
|
|
323
|
+
constructor(name?: string, parent?: Workflow) {
|
|
324
|
+
this.id = generateId();
|
|
325
|
+
this.parent = parent || null;
|
|
326
|
+
|
|
327
|
+
this.node = {
|
|
328
|
+
id: this.id,
|
|
329
|
+
name: name ?? this.constructor.name,
|
|
330
|
+
parent: parent?.node ?? null,
|
|
331
|
+
children: [],
|
|
332
|
+
logs: [],
|
|
333
|
+
events: [],
|
|
334
|
+
status: 'idle',
|
|
335
|
+
stateSnapshot: null,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
this.logger = new WorkflowLogger(this.node, this.getRootObservers());
|
|
339
|
+
if (parent) parent.attachChild(this);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private getRootObservers(): WorkflowObserver[] {
|
|
343
|
+
return this.parent ? this.parent.getRootObservers() : [];
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
attachChild(child: Workflow) {
|
|
347
|
+
this.children.push(child);
|
|
348
|
+
this.node.children.push(child.node);
|
|
349
|
+
this.emitEvent({ type: 'childAttached', parentId: this.id, child: child.node });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
protected emitEvent(event: WorkflowEvent) {
|
|
353
|
+
this.node.events.push(event);
|
|
354
|
+
for (const obs of this.getRootObservers()) {
|
|
355
|
+
obs.onEvent(event);
|
|
356
|
+
if (event.type === 'treeUpdated') obs.onTreeChanged(this.node);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
snapshotState() {
|
|
361
|
+
const snapshot = createStateSnapshot(this);
|
|
362
|
+
this.node.stateSnapshot = snapshot;
|
|
363
|
+
for (const obs of this.getRootObservers()) obs.onStateUpdated(this.node);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
abstract run(...args: any[]): Promise<any>;
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
# **12.3 Decorator Skeletons**
|
|
373
|
+
|
|
374
|
+
These are implementation-level scaffolds.
|
|
375
|
+
|
|
376
|
+
### **@ObservedState**
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
const OBSERVED_STATE_FIELDS = new WeakMap<object, Map<string, StateFieldMetadata>>();
|
|
380
|
+
|
|
381
|
+
export function ObservedState(meta: StateFieldMetadata = {}): PropertyDecorator {
|
|
382
|
+
return (target, propertyKey) => {
|
|
383
|
+
let map = OBSERVED_STATE_FIELDS.get(target);
|
|
384
|
+
if (!map) {
|
|
385
|
+
map = new Map();
|
|
386
|
+
OBSERVED_STATE_FIELDS.set(target, map);
|
|
387
|
+
}
|
|
388
|
+
map.set(propertyKey.toString(), meta);
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export function getObservedState(obj: any): SerializedWorkflowState {
|
|
393
|
+
const map = OBSERVED_STATE_FIELDS.get(Object.getPrototypeOf(obj));
|
|
394
|
+
if (!map) return {};
|
|
395
|
+
const result: SerializedWorkflowState = {};
|
|
396
|
+
for (const [key, meta] of map) {
|
|
397
|
+
let v = (obj as any)[key];
|
|
398
|
+
if (meta.redact) v = '***';
|
|
399
|
+
if (!meta.hidden) result[key] = v;
|
|
400
|
+
}
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
### **@Step**
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
export function Step(opts: StepOptions = {}): MethodDecorator {
|
|
411
|
+
return (target, prop, descriptor: PropertyDescriptor) => {
|
|
412
|
+
const original = descriptor.value;
|
|
413
|
+
|
|
414
|
+
descriptor.value = async function (...args: any[]) {
|
|
415
|
+
const wf = this as Workflow;
|
|
416
|
+
const stepName = opts.name ?? String(prop);
|
|
417
|
+
|
|
418
|
+
if (opts.logStart) wf.logger.info(`STEP START: ${stepName}`);
|
|
419
|
+
|
|
420
|
+
wf.emitEvent({ type: 'stepStart', node: wf.node, step: stepName });
|
|
421
|
+
|
|
422
|
+
let start = Date.now();
|
|
423
|
+
try {
|
|
424
|
+
const result = await original.apply(this, args);
|
|
425
|
+
|
|
426
|
+
if (opts.snapshotState) wf.snapshotState();
|
|
427
|
+
if (opts.trackTiming) {
|
|
428
|
+
const duration = Date.now() - start;
|
|
429
|
+
wf.emitEvent({ type: 'stepEnd', node: wf.node, step: stepName, duration });
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (opts.logFinish) wf.logger.info(`STEP END: ${stepName}`);
|
|
433
|
+
return result;
|
|
434
|
+
|
|
435
|
+
} catch (err: any) {
|
|
436
|
+
const snap = getObservedState(wf);
|
|
437
|
+
const wfError: WorkflowError = {
|
|
438
|
+
message: err?.message ?? 'error',
|
|
439
|
+
original: err,
|
|
440
|
+
workflowId: wf.id,
|
|
441
|
+
stack: err?.stack,
|
|
442
|
+
state: snap,
|
|
443
|
+
logs: [...wf.node.logs],
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
wf.emitEvent({ type: 'error', node: wf.node, error: wfError });
|
|
447
|
+
|
|
448
|
+
throw wfError;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
### **@Task**
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
export function Task(opts: TaskOptions = {}): MethodDecorator {
|
|
461
|
+
return (target, prop, descriptor: PropertyDescriptor) => {
|
|
462
|
+
const original = descriptor.value;
|
|
463
|
+
|
|
464
|
+
descriptor.value = async function (...args: any[]) {
|
|
465
|
+
const wf = this as Workflow;
|
|
466
|
+
const taskName = opts.name ?? String(prop);
|
|
467
|
+
|
|
468
|
+
wf.emitEvent({ type: 'taskStart', node: wf.node, task: taskName });
|
|
469
|
+
|
|
470
|
+
const result = await original.apply(this, args);
|
|
471
|
+
|
|
472
|
+
// must return Workflow or Workflow[]
|
|
473
|
+
const workflows = Array.isArray(result) ? result : [result];
|
|
474
|
+
for (const child of workflows) {
|
|
475
|
+
if (!(child instanceof Workflow)) {
|
|
476
|
+
throw new Error(`@Task method "${taskName}" did not return a Workflow.`);
|
|
477
|
+
}
|
|
478
|
+
child.parent = wf;
|
|
479
|
+
wf.attachChild(child);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
wf.emitEvent({ type: 'taskEnd', node: wf.node, task: taskName });
|
|
483
|
+
|
|
484
|
+
return result;
|
|
485
|
+
};
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
# **13. Example Workflow Using the System**
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
class TestCycleWorkflow extends Workflow {
|
|
496
|
+
@ObservedState() currentTest!: string;
|
|
497
|
+
|
|
498
|
+
@Step({ snapshotState: true })
|
|
499
|
+
async generateTest() { /* ... */ }
|
|
500
|
+
|
|
501
|
+
@Step()
|
|
502
|
+
async runTest() { /* ... may throw ... */ }
|
|
503
|
+
|
|
504
|
+
@Step()
|
|
505
|
+
async updateImplementation() { /* ... */ }
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
class TDDOrchestrator extends Workflow {
|
|
509
|
+
@Step({ logStart: true })
|
|
510
|
+
async setupEnvironment() { /* ... */ }
|
|
511
|
+
|
|
512
|
+
@Task()
|
|
513
|
+
async runCycle() {
|
|
514
|
+
return new TestCycleWorkflow('Cycle', this);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
async run() {
|
|
518
|
+
try {
|
|
519
|
+
await this.setupEnvironment();
|
|
520
|
+
await this.runCycle();
|
|
521
|
+
} catch (err) {
|
|
522
|
+
/* analyze & restart logic here */
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
# **14. Acceptance Criteria (Updated)**
|
|
531
|
+
|
|
532
|
+
This PRD now includes:
|
|
533
|
+
|
|
534
|
+
* explicit interfaces
|
|
535
|
+
* complete decorators
|
|
536
|
+
* class skeletons
|
|
537
|
+
* logger skeleton
|
|
538
|
+
* observer system
|
|
539
|
+
* real-time debugger interface
|
|
540
|
+
* error/restart models
|
|
541
|
+
* snapshot system
|
|
542
|
+
|
|
543
|
+
A senior engineer should be able to implement the full engine from this PRD.
|
package/README.md
CHANGED
|
@@ -113,16 +113,110 @@ Immutable value objects defining what to send to an agent and how to validate th
|
|
|
113
113
|
|
|
114
114
|
## Decorators
|
|
115
115
|
|
|
116
|
+
### @Step
|
|
117
|
+
|
|
118
|
+
Emit lifecycle events and track step execution timing.
|
|
119
|
+
|
|
120
|
+
**Default Behavior**: Without any options, `@Step()` automatically tracks timing information.
|
|
121
|
+
|
|
116
122
|
```typescript
|
|
117
|
-
//
|
|
118
|
-
@Step({ trackTiming: true, snapshotState: true })
|
|
123
|
+
@Step() // Timing tracked by default
|
|
119
124
|
async processData(): Promise<void> { }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Configuration Options**:
|
|
128
|
+
|
|
129
|
+
| Option | Type | Default | Description |
|
|
130
|
+
|--------|------|---------|-------------|
|
|
131
|
+
| `name` | `string` | method name | Custom step name |
|
|
132
|
+
| `trackTiming` | `boolean` | `true` | Include duration in `stepEnd` event. Set to `false` to eliminate timing overhead. |
|
|
133
|
+
| `snapshotState` | `boolean` | `false` | Capture state snapshot after step completion |
|
|
134
|
+
| `logStart` | `boolean` | `false` | Log message at step start |
|
|
135
|
+
| `logFinish` | `boolean` | `false` | Log message at step end (includes duration) |
|
|
136
|
+
|
|
137
|
+
**Examples**:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Default behavior - timing tracked automatically
|
|
141
|
+
@Step()
|
|
142
|
+
async basicStep(): Promise<void> { }
|
|
143
|
+
|
|
144
|
+
// Disable timing for performance-critical code
|
|
145
|
+
@Step({ trackTiming: false })
|
|
146
|
+
async highFrequencyStep(): Promise<void> { }
|
|
147
|
+
|
|
148
|
+
// Full configuration
|
|
149
|
+
@Step({ trackTiming: true, snapshotState: true, logStart: true })
|
|
150
|
+
async monitoredStep(): Promise<void> { }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Performance Note**: Timing tracking has minimal overhead. Disable `trackTiming` only in performance-critical code paths with high-frequency execution.
|
|
154
|
+
|
|
155
|
+
### @Task
|
|
156
|
+
|
|
157
|
+
Spawn and manage child workflows.
|
|
158
|
+
|
|
159
|
+
**Validation Behavior**: The decorator performs lenient validation - methods returning non-Workflow objects are silently skipped rather than throwing errors. This enables flexible method designs and duck-typing.
|
|
160
|
+
|
|
161
|
+
**Configuration Options**:
|
|
120
162
|
|
|
121
|
-
|
|
163
|
+
| Option | Type | Default | Description |
|
|
164
|
+
|--------|------|---------|-------------|
|
|
165
|
+
| `name` | `string` | method name | Custom task name |
|
|
166
|
+
| `concurrent` | `boolean` | `false` | If `true`, automatically run returned workflows in parallel using `Promise.all()` |
|
|
167
|
+
|
|
168
|
+
**How It Works**:
|
|
169
|
+
- Workflow objects (with `id` property) are automatically attached as children
|
|
170
|
+
- Non-workflow objects are silently skipped (not attached)
|
|
171
|
+
- The original return value is always preserved
|
|
172
|
+
- Duck-typing is used: any object with an `id` property is treated as workflow-like
|
|
173
|
+
|
|
174
|
+
**Examples**:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Standard usage - return single workflow
|
|
178
|
+
@Task()
|
|
179
|
+
async createChild(): Promise<ChildWorkflow> {
|
|
180
|
+
return new ChildWorkflow('child1', this); // Attached as child
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return multiple workflows
|
|
122
184
|
@Task({ concurrent: true })
|
|
123
|
-
async createWorkers(): Promise<WorkerWorkflow[]> {
|
|
185
|
+
async createWorkers(): Promise<WorkerWorkflow[]> {
|
|
186
|
+
return [
|
|
187
|
+
new WorkerWorkflow('worker1', 100, this), // Attached
|
|
188
|
+
new WorkerWorkflow('worker2', 150, this), // Attached
|
|
189
|
+
]; // Both run concurrently
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Mixed return - only workflows are attached
|
|
193
|
+
@Task()
|
|
194
|
+
async mixedReturn(): Promise<(Workflow | string)[]> {
|
|
195
|
+
return [
|
|
196
|
+
new ChildWorkflow('child1', this), // Attached
|
|
197
|
+
'some string', // Skipped (not a workflow)
|
|
198
|
+
new ChildWorkflow('child2', this), // Attached
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Non-workflow return - handled gracefully
|
|
203
|
+
@Task()
|
|
204
|
+
async returnsData(): Promise<string> {
|
|
205
|
+
return 'just some data'; // Returned as-is, no attachment attempted
|
|
206
|
+
}
|
|
207
|
+
```
|
|
124
208
|
|
|
125
|
-
|
|
209
|
+
**Important Notes**:
|
|
210
|
+
- The decorator uses structural typing (duck-typing) via the `id` property check
|
|
211
|
+
- This enables working with workflow-like objects, not just `Workflow` class instances
|
|
212
|
+
- TypeScript compile-time type checking still catches obvious errors
|
|
213
|
+
- Use `concurrent: true` for automatic parallel execution of returned workflows
|
|
214
|
+
|
|
215
|
+
### @ObservedState
|
|
216
|
+
|
|
217
|
+
Mark fields for state snapshots.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
126
220
|
@ObservedState()
|
|
127
221
|
progress: number = 0;
|
|
128
222
|
|
package/examples/README.md
CHANGED
|
@@ -25,6 +25,7 @@ npm run start:agent-loops
|
|
|
25
25
|
npm run start:sdk-features
|
|
26
26
|
npm run start:reflection
|
|
27
27
|
npm run start:introspection
|
|
28
|
+
npm run start:reparenting
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
## Examples Overview
|
|
@@ -137,6 +138,18 @@ Agent self-awareness and hierarchy navigation:
|
|
|
137
138
|
- inspect_cache_status - "Is this cached?"
|
|
138
139
|
- request_spawn_workflow - "Can I create children?"
|
|
139
140
|
|
|
141
|
+
### 11. Reparenting Workflows (`11-reparenting-workflows.ts`)
|
|
142
|
+
|
|
143
|
+
Run: `npx tsx examples/examples/11-reparenting-workflows.ts`
|
|
144
|
+
|
|
145
|
+
Workflow reparenting with detach-then-attach pattern:
|
|
146
|
+
- WRONG way: Direct attachChild() throws error (single-parent invariant)
|
|
147
|
+
- RIGHT way: detachChild() then attachChild() pattern
|
|
148
|
+
- Tree structure verification before/after reparenting
|
|
149
|
+
- Observer propagation updates after reparenting
|
|
150
|
+
- Dual-tree synchronization (workflow tree + node tree)
|
|
151
|
+
- Error handling for invalid reparenting operations
|
|
152
|
+
|
|
140
153
|
## Project Structure
|
|
141
154
|
|
|
142
155
|
```
|
|
@@ -151,7 +164,8 @@ examples/
|
|
|
151
164
|
│ ├── 07-agent-loops.ts
|
|
152
165
|
│ ├── 08-sdk-features.ts
|
|
153
166
|
│ ├── 09-reflection.ts
|
|
154
|
-
│
|
|
167
|
+
│ ├── 10-introspection.ts
|
|
168
|
+
│ └── 11-reparenting-workflows.ts
|
|
155
169
|
├── utils/
|
|
156
170
|
│ └── helpers.ts
|
|
157
171
|
├── index.ts
|