groundswell 0.0.2 → 0.0.3
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/dist/__tests__/adversarial/attachChild-performance.test.d.ts +16 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.js +187 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.js.map +1 -0
- package/dist/__tests__/adversarial/circular-reference.test.d.ts +13 -0
- package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/circular-reference.test.js +92 -0
- package/dist/__tests__/adversarial/circular-reference.test.js.map +1 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +16 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.js +127 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +1 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +21 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js +667 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +1 -0
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts +6 -0
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/deep-analysis.test.js +877 -0
- package/dist/__tests__/adversarial/deep-analysis.test.js.map +1 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +13 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +186 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +1 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +6 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js +626 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +1 -0
- package/dist/__tests__/adversarial/edge-case.test.d.ts +6 -0
- package/dist/__tests__/adversarial/edge-case.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/edge-case.test.js +857 -0
- package/dist/__tests__/adversarial/edge-case.test.js.map +1 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +20 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.js +907 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +1 -0
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts +2 -0
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/incremental-performance.test.js +113 -0
- package/dist/__tests__/adversarial/incremental-performance.test.js.map +1 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +22 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +383 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +1 -0
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts +21 -0
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/observer-propagation.test.js +404 -0
- package/dist/__tests__/adversarial/observer-propagation.test.js.map +1 -0
- package/dist/__tests__/adversarial/parent-validation.test.d.ts +13 -0
- package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/parent-validation.test.js +128 -0
- package/dist/__tests__/adversarial/parent-validation.test.js.map +1 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +20 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +482 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +1 -0
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts +6 -0
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/prd-compliance.test.js +886 -0
- package/dist/__tests__/adversarial/prd-compliance.test.js.map +1 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +22 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +1 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.js +1843 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.js.map +1 -0
- package/dist/__tests__/helpers/index.d.ts +10 -0
- package/dist/__tests__/helpers/index.d.ts.map +1 -0
- package/{src/__tests__/helpers/index.ts → dist/__tests__/helpers/index.js} +2 -10
- package/dist/__tests__/helpers/index.js.map +1 -0
- package/dist/__tests__/helpers/tree-verification.d.ts +90 -0
- package/dist/__tests__/helpers/tree-verification.d.ts.map +1 -0
- package/dist/__tests__/helpers/tree-verification.js +202 -0
- package/dist/__tests__/helpers/tree-verification.js.map +1 -0
- package/dist/__tests__/integration/agent-workflow.test.d.ts +2 -0
- package/dist/__tests__/integration/agent-workflow.test.d.ts.map +1 -0
- package/dist/__tests__/integration/agent-workflow.test.js +256 -0
- package/dist/__tests__/integration/agent-workflow.test.js.map +1 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +14 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.js +668 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.js.map +1 -0
- package/dist/__tests__/integration/observer-logging.test.d.ts +2 -0
- package/dist/__tests__/integration/observer-logging.test.d.ts.map +1 -0
- package/dist/__tests__/integration/observer-logging.test.js +517 -0
- package/dist/__tests__/integration/observer-logging.test.js.map +1 -0
- package/dist/__tests__/integration/tree-mirroring.test.d.ts +2 -0
- package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +1 -0
- package/dist/__tests__/integration/tree-mirroring.test.js +117 -0
- package/dist/__tests__/integration/tree-mirroring.test.js.map +1 -0
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts +12 -0
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +1 -0
- package/dist/__tests__/integration/workflow-reparenting.test.js +239 -0
- package/dist/__tests__/integration/workflow-reparenting.test.js.map +1 -0
- package/dist/__tests__/unit/agent.test.d.ts +2 -0
- package/dist/__tests__/unit/agent.test.d.ts.map +1 -0
- package/dist/__tests__/unit/agent.test.js +143 -0
- package/dist/__tests__/unit/agent.test.js.map +1 -0
- package/dist/__tests__/unit/cache-key.test.d.ts +5 -0
- package/dist/__tests__/unit/cache-key.test.d.ts.map +1 -0
- package/dist/__tests__/unit/cache-key.test.js +145 -0
- package/dist/__tests__/unit/cache-key.test.js.map +1 -0
- package/dist/__tests__/unit/cache.test.d.ts +5 -0
- package/dist/__tests__/unit/cache.test.d.ts.map +1 -0
- package/dist/__tests__/unit/cache.test.js +132 -0
- package/dist/__tests__/unit/cache.test.js.map +1 -0
- package/dist/__tests__/unit/context.test.d.ts +2 -0
- package/dist/__tests__/unit/context.test.d.ts.map +1 -0
- package/dist/__tests__/unit/context.test.js +220 -0
- package/dist/__tests__/unit/context.test.js.map +1 -0
- package/dist/__tests__/unit/decorators.test.d.ts +2 -0
- package/dist/__tests__/unit/decorators.test.d.ts.map +1 -0
- package/dist/__tests__/unit/decorators.test.js +162 -0
- package/dist/__tests__/unit/decorators.test.js.map +1 -0
- package/dist/__tests__/unit/introspection-tools.test.d.ts +5 -0
- package/dist/__tests__/unit/introspection-tools.test.d.ts.map +1 -0
- package/dist/__tests__/unit/introspection-tools.test.js +191 -0
- package/dist/__tests__/unit/introspection-tools.test.js.map +1 -0
- package/dist/__tests__/unit/logger.test.d.ts +2 -0
- package/dist/__tests__/unit/logger.test.d.ts.map +1 -0
- package/dist/__tests__/unit/logger.test.js +241 -0
- package/dist/__tests__/unit/logger.test.js.map +1 -0
- package/dist/__tests__/unit/observable.test.d.ts +2 -0
- package/dist/__tests__/unit/observable.test.d.ts.map +1 -0
- package/dist/__tests__/unit/observable.test.js +251 -0
- package/dist/__tests__/unit/observable.test.js.map +1 -0
- package/dist/__tests__/unit/prompt.test.d.ts +2 -0
- package/dist/__tests__/unit/prompt.test.d.ts.map +1 -0
- package/dist/__tests__/unit/prompt.test.js +113 -0
- package/dist/__tests__/unit/prompt.test.js.map +1 -0
- package/dist/__tests__/unit/reflection.test.d.ts +5 -0
- package/dist/__tests__/unit/reflection.test.d.ts.map +1 -0
- package/dist/__tests__/unit/reflection.test.js +160 -0
- package/dist/__tests__/unit/reflection.test.js.map +1 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +2 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +1 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.js +136 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +1 -0
- package/dist/__tests__/unit/tree-debugger.test.d.ts +2 -0
- package/dist/__tests__/unit/tree-debugger.test.d.ts.map +1 -0
- package/dist/__tests__/unit/tree-debugger.test.js +69 -0
- package/dist/__tests__/unit/tree-debugger.test.js.map +1 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +2 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +1 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js +154 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-detachChild.test.js +76 -0
- package/dist/__tests__/unit/workflow-detachChild.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +122 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js +140 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +1 -0
- package/dist/__tests__/unit/workflow.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow.test.js +330 -0
- package/dist/__tests__/unit/workflow.test.js.map +1 -0
- package/dist/cache/cache-key.d.ts +66 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +195 -0
- package/dist/cache/cache-key.js.map +1 -0
- package/dist/cache/cache.d.ts +104 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +179 -0
- package/dist/cache/cache.js.map +1 -0
- package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/agent.d.ts +112 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +426 -0
- package/dist/core/agent.js.map +1 -0
- package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +80 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-tree.d.ts +72 -0
- package/dist/core/event-tree.d.ts.map +1 -0
- package/dist/core/event-tree.js +211 -0
- package/dist/core/event-tree.js.map +1 -0
- package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +110 -0
- package/dist/core/factory.js.map +1 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +50 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +91 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp-handler.d.ts +69 -0
- package/dist/core/mcp-handler.d.ts.map +1 -0
- package/dist/core/mcp-handler.js +143 -0
- package/dist/core/mcp-handler.js.map +1 -0
- package/dist/core/prompt.d.ts +80 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +120 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/workflow-context.d.ts +57 -0
- package/dist/core/workflow-context.d.ts.map +1 -0
- package/dist/core/workflow-context.js +263 -0
- package/dist/core/workflow-context.js.map +1 -0
- package/dist/core/workflow.d.ts +241 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +464 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/debugger/index.d.ts +2 -0
- package/dist/debugger/index.d.ts.map +1 -0
- package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
- package/dist/debugger/index.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +71 -0
- package/dist/debugger/tree-debugger.d.ts.map +1 -0
- package/dist/debugger/tree-debugger.js +198 -0
- package/dist/debugger/tree-debugger.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/observed-state.d.ts +32 -0
- package/dist/decorators/observed-state.d.ts.map +1 -0
- package/dist/decorators/observed-state.js +79 -0
- package/dist/decorators/observed-state.js.map +1 -0
- package/dist/decorators/step.d.ts +15 -0
- package/dist/decorators/step.d.ts.map +1 -0
- package/dist/decorators/step.js +110 -0
- package/dist/decorators/step.js.map +1 -0
- package/dist/decorators/task.d.ts +50 -0
- package/dist/decorators/task.d.ts.map +1 -0
- package/dist/decorators/task.js +118 -0
- package/dist/decorators/task.js.map +1 -0
- package/dist/examples/index.d.ts +3 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/{src/examples/index.ts → dist/examples/index.js} +1 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/tdd-orchestrator.d.ts +15 -0
- package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
- package/dist/examples/tdd-orchestrator.js +121 -0
- package/dist/examples/tdd-orchestrator.js.map +1 -0
- package/dist/examples/test-cycle-workflow.d.ts +14 -0
- package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
- package/dist/examples/test-cycle-workflow.js +116 -0
- package/dist/examples/test-cycle-workflow.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/reflection/index.d.ts +5 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/reflection.d.ts +84 -0
- package/dist/reflection/reflection.d.ts.map +1 -0
- package/dist/reflection/reflection.js +329 -0
- package/dist/reflection/reflection.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/introspection.d.ts +165 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js +324 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/types/agent.d.ts +66 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +6 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/decorators.d.ts +31 -0
- package/dist/types/decorators.d.ts.map +1 -0
- package/dist/types/decorators.js +2 -0
- package/dist/types/decorators.js.map +1 -0
- package/dist/types/error-strategy.d.ts +13 -0
- package/dist/types/error-strategy.d.ts.map +1 -0
- package/dist/types/error-strategy.js +2 -0
- package/dist/types/error-strategy.js.map +1 -0
- package/dist/types/error.d.ts +20 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +2 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/events.d.ts +87 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logging.d.ts +24 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/observer.d.ts +18 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +2 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/prompt.d.ts +31 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +6 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/reflection.d.ts +96 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +24 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/sdk-primitives.d.ts +118 -0
- package/dist/types/sdk-primitives.d.ts.map +1 -0
- package/dist/types/sdk-primitives.js +6 -0
- package/dist/types/sdk-primitives.js.map +1 -0
- package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/types/workflow-context.d.ts +139 -0
- package/dist/types/workflow-context.d.ts.map +1 -0
- package/dist/types/workflow-context.js +8 -0
- package/dist/types/workflow-context.js.map +1 -0
- package/dist/types/workflow.d.ts +30 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/id.d.ts +6 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -0
- package/{src/utils/index.ts → dist/utils/index.d.ts} +1 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/observable.d.ts +54 -0
- package/dist/utils/observable.d.ts.map +1 -0
- package/dist/utils/observable.js +82 -0
- package/dist/utils/observable.js.map +1 -0
- package/dist/utils/workflow-error-utils.d.ts +22 -0
- package/dist/utils/workflow-error-utils.d.ts.map +1 -0
- package/dist/utils/workflow-error-utils.js +45 -0
- package/dist/utils/workflow-error-utils.js.map +1 -0
- package/package.json +5 -2
- package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
- package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
- package/.claude/commands/task-breakdown.md +0 -94
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -101
- package/PRD.md +0 -543
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/002-agent-prompt.md +0 -390
- package/PRPs/PRDs/003-agent-prompt.md +0 -943
- package/PRPs/PRDs/004-agent-prompt.md +0 -1136
- package/PRPs/PRDs/tasks-001.json +0 -492
- package/PRPs/README.md +0 -83
- package/PRPs/templates/prp_base.md +0 -222
- package/docs/agent.md +0 -422
- package/docs/prompt.md +0 -419
- package/docs/workflow.md +0 -600
- package/examples/README.md +0 -258
- package/examples/examples/01-basic-workflow.ts +0 -100
- package/examples/examples/02-decorator-options.ts +0 -217
- package/examples/examples/03-parent-child.ts +0 -241
- package/examples/examples/04-observers-debugger.ts +0 -340
- package/examples/examples/05-error-handling.ts +0 -387
- package/examples/examples/06-concurrent-tasks.ts +0 -352
- package/examples/examples/07-agent-loops.ts +0 -432
- package/examples/examples/08-sdk-features.ts +0 -667
- package/examples/examples/09-reflection.ts +0 -573
- package/examples/examples/10-introspection.ts +0 -550
- package/examples/examples/11-reparenting-workflows.ts +0 -269
- package/examples/index.ts +0 -147
- package/examples/utils/helpers.ts +0 -57
- package/package-lock.json +0 -2398
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
- package/plan/001_d3bb02af4886/backlog.json +0 -867
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
- package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
- package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
- package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
- package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
- package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
- package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
- package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
- package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
- package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
- package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
- package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
- package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
- package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
- package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
- package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
- package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
- package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
- package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
- package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
- package/src/__tests__/adversarial/edge-case.test.ts +0 -703
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
- package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
- package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
- package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
- package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
- package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
- package/src/__tests__/helpers/tree-verification.ts +0 -257
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
- package/src/__tests__/integration/observer-logging.test.ts +0 -643
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
- package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
- package/src/__tests__/unit/agent.test.ts +0 -169
- package/src/__tests__/unit/cache-key.test.ts +0 -182
- package/src/__tests__/unit/cache.test.ts +0 -172
- package/src/__tests__/unit/context.test.ts +0 -217
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/logger.test.ts +0 -293
- package/src/__tests__/unit/observable.test.ts +0 -321
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
- package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
- package/src/__tests__/unit/workflow.test.ts +0 -357
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -593
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -112
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -351
- package/src/core/workflow.ts +0 -540
- package/src/debugger/tree-debugger.ts +0 -255
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -159
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -142
- package/src/reflection/reflection.ts +0 -407
- package/src/tools/index.ts +0 -36
- package/src/tools/introspection.ts +0 -464
- package/src/types/agent.ts +0 -90
- package/src/types/decorators.ts +0 -32
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -75
- package/src/types/index.ts +0 -55
- package/src/types/logging.ts +0 -24
- package/src/types/observer.ts +0 -18
- package/src/types/prompt.ts +0 -40
- package/src/types/reflection.ts +0 -117
- package/src/types/sdk-primitives.ts +0 -128
- package/src/types/workflow-context.ts +0 -163
- package/src/types/workflow.ts +0 -37
- package/src/utils/id.ts +0 -11
- package/src/utils/observable.ts +0 -106
- package/src/utils/workflow-error-utils.ts +0 -56
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
|
@@ -1,1572 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backward Compatibility Test Suite
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive tests that validate all existing API usage patterns continue to work
|
|
5
|
-
* after bug fixes, and ensures breaking changes fail with clear, actionable error
|
|
6
|
-
* messages directing users to the correct migration path.
|
|
7
|
-
*
|
|
8
|
-
* Related:
|
|
9
|
-
* - PRP: P1.M4.T3.S2 - Backward Compatibility Testing
|
|
10
|
-
* - Breaking Changes Audit: plan/.../P1M4T3S1/BREAKING_CHANGES_AUDIT.md
|
|
11
|
-
*
|
|
12
|
-
* Test Coverage:
|
|
13
|
-
* 1. Breaking Change: Workflow name validation (LOW severity)
|
|
14
|
-
* 2. Backward Compatible: WorkflowLogger.child() string API
|
|
15
|
-
* 3. Backward Compatible: Promise.allSettled default behavior
|
|
16
|
-
* 4. Documentation Examples: README quick start patterns
|
|
17
|
-
* 5. Example Files: All 11 runnable examples
|
|
18
|
-
* 6. Decorator Patterns: @Step, @Task, @ObservedState options
|
|
19
|
-
* 7. Parent-Child Patterns: Hierarchical workflow creation
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { describe, it, expect } from 'vitest';
|
|
23
|
-
import {
|
|
24
|
-
Workflow,
|
|
25
|
-
WorkflowLogger,
|
|
26
|
-
Step,
|
|
27
|
-
Task,
|
|
28
|
-
ObservedState,
|
|
29
|
-
getObservedState,
|
|
30
|
-
WorkflowTreeDebugger,
|
|
31
|
-
createWorkflow,
|
|
32
|
-
WorkflowObserver,
|
|
33
|
-
WorkflowEvent,
|
|
34
|
-
WorkflowError,
|
|
35
|
-
} from '../../index.js';
|
|
36
|
-
|
|
37
|
-
// ============================================================================
|
|
38
|
-
// Section 1: Breaking Changes - Workflow Name Validation
|
|
39
|
-
// ============================================================================
|
|
40
|
-
// Severity: LOW
|
|
41
|
-
// Impact: Constructor rejects empty/whitespace/long names
|
|
42
|
-
// Migration: Provide valid names (simple fix)
|
|
43
|
-
// ============================================================================
|
|
44
|
-
|
|
45
|
-
describe('Backward Compatibility Tests', () => {
|
|
46
|
-
describe('Breaking Changes - Workflow Name Validation', () => {
|
|
47
|
-
describe('Class-based constructor pattern', () => {
|
|
48
|
-
class TestWorkflow extends Workflow {
|
|
49
|
-
constructor(name?: string) {
|
|
50
|
-
super(name);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async run(): Promise<string> {
|
|
54
|
-
this.setStatus('running');
|
|
55
|
-
this.setStatus('completed');
|
|
56
|
-
return 'done';
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
it('should throw descriptive error for empty string name', () => {
|
|
61
|
-
expect(() => new TestWorkflow(''))
|
|
62
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should throw descriptive error for whitespace-only name (spaces)', () => {
|
|
66
|
-
expect(() => new TestWorkflow(' '))
|
|
67
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should throw descriptive error for whitespace-only name (tabs)', () => {
|
|
71
|
-
expect(() => new TestWorkflow('\t\t'))
|
|
72
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should throw descriptive error for whitespace-only name (newlines)', () => {
|
|
76
|
-
expect(() => new TestWorkflow('\n\n'))
|
|
77
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should throw descriptive error for whitespace-only name (mixed)', () => {
|
|
81
|
-
expect(() => new TestWorkflow(' \t\n '))
|
|
82
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should throw descriptive error for name exceeding 100 characters', () => {
|
|
86
|
-
const longName = 'a'.repeat(101);
|
|
87
|
-
expect(() => new TestWorkflow(longName))
|
|
88
|
-
.toThrow('Workflow name cannot exceed 100 characters');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should accept name with exactly 100 characters', () => {
|
|
92
|
-
const exactly100 = 'a'.repeat(100);
|
|
93
|
-
const wf = new TestWorkflow(exactly100);
|
|
94
|
-
expect(wf.getNode().name).toBe(exactly100);
|
|
95
|
-
expect(wf.getNode().name.length).toBe(100);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should accept valid names with leading/trailing whitespace', () => {
|
|
99
|
-
const wf1 = new TestWorkflow(' MyWorkflow ');
|
|
100
|
-
expect(wf1.getNode().name).toBe(' MyWorkflow ');
|
|
101
|
-
|
|
102
|
-
const wf2 = new TestWorkflow('\tValidName\t');
|
|
103
|
-
expect(wf2.getNode().name).toBe('\tValidName\t');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should use class name when name is undefined', () => {
|
|
107
|
-
const wf = new TestWorkflow();
|
|
108
|
-
expect(wf.getNode().name).toBe('TestWorkflow');
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('should use class name when name is null', () => {
|
|
112
|
-
const wf = new TestWorkflow(null as any);
|
|
113
|
-
expect(wf.getNode().name).toBe('TestWorkflow');
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe('Functional constructor pattern', () => {
|
|
118
|
-
it('should throw descriptive error for empty string name', () => {
|
|
119
|
-
expect(() => new Workflow({ name: '' }, async () => {}))
|
|
120
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should throw descriptive error for whitespace name', () => {
|
|
124
|
-
expect(() => new Workflow({ name: ' ' }, async () => {}))
|
|
125
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should throw descriptive error for name exceeding 100 characters', () => {
|
|
129
|
-
const longName = 'a'.repeat(101);
|
|
130
|
-
expect(() => new Workflow({ name: longName }, async () => {}))
|
|
131
|
-
.toThrow('Workflow name cannot exceed 100 characters');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should accept valid name in functional pattern', async () => {
|
|
135
|
-
const wf = new Workflow({ name: 'ValidFunctionalWorkflow' }, async () => 'done');
|
|
136
|
-
expect(wf.getNode().name).toBe('ValidFunctionalWorkflow');
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
describe('Error message clarity and actionability', () => {
|
|
141
|
-
it('should provide clear error message for empty name', () => {
|
|
142
|
-
expect(() => new Workflow({ name: '' }, async () => {}))
|
|
143
|
-
.toThrow('Workflow name cannot be empty or whitespace only');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should provide clear error message for long name', () => {
|
|
147
|
-
expect(() => new Workflow({ name: 'a'.repeat(101) }, async () => {}))
|
|
148
|
-
.toThrow('Workflow name cannot exceed 100 characters');
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// ============================================================================
|
|
154
|
-
// Section 2: Backward Compatible Changes - WorkflowLogger.child()
|
|
155
|
-
// ============================================================================
|
|
156
|
-
// Change: child() now accepts Partial<LogEntry> in addition to string
|
|
157
|
-
// Backward Compatibility: String-based API still works via function overloads
|
|
158
|
-
// ============================================================================
|
|
159
|
-
|
|
160
|
-
describe('Backward Compatible Changes - WorkflowLogger.child()', () => {
|
|
161
|
-
describe('String-based API (backward compatible)', () => {
|
|
162
|
-
it('should support string-based logger.child() with parentLogId', async () => {
|
|
163
|
-
class TestWorkflow extends Workflow {
|
|
164
|
-
async run() {
|
|
165
|
-
// Old API - should still work
|
|
166
|
-
const childLogger = this.logger.child('parent-log-id');
|
|
167
|
-
childLogger.info('Test message');
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const workflow = new TestWorkflow();
|
|
172
|
-
await workflow.run();
|
|
173
|
-
|
|
174
|
-
expect(workflow.getNode().logs[0].parentLogId).toBe('parent-log-id');
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('should support string-based logger.child() with all log levels', async () => {
|
|
178
|
-
class TestWorkflow extends Workflow {
|
|
179
|
-
async run() {
|
|
180
|
-
const childLogger = this.logger.child('test-parent');
|
|
181
|
-
childLogger.debug('Debug message');
|
|
182
|
-
childLogger.info('Info message');
|
|
183
|
-
childLogger.warn('Warn message');
|
|
184
|
-
childLogger.error('Error message');
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const workflow = new TestWorkflow();
|
|
189
|
-
await workflow.run();
|
|
190
|
-
|
|
191
|
-
expect(workflow.getNode().logs.length).toBe(4);
|
|
192
|
-
expect(workflow.getNode().logs[0].parentLogId).toBe('test-parent');
|
|
193
|
-
expect(workflow.getNode().logs[0].level).toBe('debug');
|
|
194
|
-
expect(workflow.getNode().logs[1].level).toBe('info');
|
|
195
|
-
expect(workflow.getNode().logs[2].level).toBe('warn');
|
|
196
|
-
expect(workflow.getNode().logs[3].level).toBe('error');
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should support string-based logger.child() with data parameter', async () => {
|
|
200
|
-
class TestWorkflow extends Workflow {
|
|
201
|
-
async run() {
|
|
202
|
-
const childLogger = this.logger.child('data-parent');
|
|
203
|
-
childLogger.info('Message with data', { key: 'value', count: 42 });
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const workflow = new TestWorkflow();
|
|
208
|
-
await workflow.run();
|
|
209
|
-
|
|
210
|
-
expect(workflow.getNode().logs[0].parentLogId).toBe('data-parent');
|
|
211
|
-
expect(workflow.getNode().logs[0].data).toEqual({ key: 'value', count: 42 });
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should handle empty string (results in undefined parentLogId)', async () => {
|
|
215
|
-
class TestWorkflow extends Workflow {
|
|
216
|
-
async run() {
|
|
217
|
-
const childLogger = this.logger.child('');
|
|
218
|
-
childLogger.info('Test message');
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const workflow = new TestWorkflow();
|
|
223
|
-
await workflow.run();
|
|
224
|
-
|
|
225
|
-
// Empty string is falsy, so parentLogId becomes undefined
|
|
226
|
-
expect(workflow.getNode().logs[0].parentLogId).toBeUndefined();
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
describe('New API - Partial<LogEntry> syntax (also backward compatible)', () => {
|
|
231
|
-
it('should support new object-based logger.child() API', async () => {
|
|
232
|
-
class TestWorkflow extends Workflow {
|
|
233
|
-
async run() {
|
|
234
|
-
// New API - should work alongside old API
|
|
235
|
-
const childLogger = this.logger.child({ parentLogId: 'parent-log-id' });
|
|
236
|
-
childLogger.info('Test message');
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const workflow = new TestWorkflow();
|
|
241
|
-
await workflow.run();
|
|
242
|
-
|
|
243
|
-
expect(workflow.getNode().logs[0].parentLogId).toBe('parent-log-id');
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
describe('Parent-child log hierarchy (backward compatible)', () => {
|
|
248
|
-
it('should support multi-level nesting with string-based child loggers', async () => {
|
|
249
|
-
class TestWorkflow extends Workflow {
|
|
250
|
-
async run() {
|
|
251
|
-
// Root log
|
|
252
|
-
this.logger.info('Root message');
|
|
253
|
-
const rootLogId = this.node.logs[0].id;
|
|
254
|
-
|
|
255
|
-
// First level child - using string API (backward compatible)
|
|
256
|
-
const child1 = this.logger.child(rootLogId);
|
|
257
|
-
child1.info('Level 1 child');
|
|
258
|
-
const level1LogId = this.node.logs[1].id;
|
|
259
|
-
|
|
260
|
-
// Second level child - using string API
|
|
261
|
-
const child2 = this.logger.child(level1LogId);
|
|
262
|
-
child2.info('Level 2 child');
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const workflow = new TestWorkflow();
|
|
267
|
-
await workflow.run();
|
|
268
|
-
|
|
269
|
-
expect(workflow.getNode().logs.length).toBe(3);
|
|
270
|
-
expect(workflow.getNode().logs[0].parentLogId).toBeUndefined();
|
|
271
|
-
expect(workflow.getNode().logs[1].parentLogId).toBe(workflow.getNode().logs[0].id);
|
|
272
|
-
expect(workflow.getNode().logs[2].parentLogId).toBe(workflow.getNode().logs[1].id);
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// ============================================================================
|
|
278
|
-
// Section 3: Backward Compatible Changes - Promise.allSettled Default Behavior
|
|
279
|
-
// ============================================================================
|
|
280
|
-
// Change: @Task with concurrent: true now uses Promise.allSettled()
|
|
281
|
-
// Backward Compatibility: Default behavior unchanged - throws first error
|
|
282
|
-
// ============================================================================
|
|
283
|
-
|
|
284
|
-
describe('Backward Compatible Changes - Promise.allSettled Default Behavior', () => {
|
|
285
|
-
// Helper to create a child workflow that may fail
|
|
286
|
-
function createChildWorkflow(
|
|
287
|
-
parent: Workflow,
|
|
288
|
-
name: string,
|
|
289
|
-
shouldFail: boolean = false
|
|
290
|
-
): Workflow {
|
|
291
|
-
return new (class extends Workflow {
|
|
292
|
-
constructor(n: string, p: Workflow) {
|
|
293
|
-
super(n, p);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
@Step()
|
|
297
|
-
async executeStep() {
|
|
298
|
-
if (shouldFail) {
|
|
299
|
-
throw new Error(`${name} failed`);
|
|
300
|
-
}
|
|
301
|
-
return `${name} succeeded`;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
async run() {
|
|
305
|
-
return this.executeStep();
|
|
306
|
-
}
|
|
307
|
-
})(name, parent);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
describe('Default behavior - throws first error (backward compatible)', () => {
|
|
311
|
-
it('should throw first error when concurrent task fails', async () => {
|
|
312
|
-
class ParentWorkflow extends Workflow {
|
|
313
|
-
@Task({ concurrent: true })
|
|
314
|
-
async spawnChildren() {
|
|
315
|
-
return [
|
|
316
|
-
createChildWorkflow(this, 'Child-0', false),
|
|
317
|
-
createChildWorkflow(this, 'Child-1', true), // Will fail
|
|
318
|
-
createChildWorkflow(this, 'Child-2', false),
|
|
319
|
-
createChildWorkflow(this, 'Child-3', false),
|
|
320
|
-
];
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
async run() {
|
|
324
|
-
await this.spawnChildren();
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const workflow = new ParentWorkflow('Parent');
|
|
329
|
-
|
|
330
|
-
// Should throw first error (backward compatible with Promise.all)
|
|
331
|
-
await expect(workflow.run()).rejects.toThrow('Child-1 failed');
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
it('should complete all workflows even when one fails', async () => {
|
|
335
|
-
class ParentWorkflow extends Workflow {
|
|
336
|
-
@Task({ concurrent: true })
|
|
337
|
-
async spawnChildren() {
|
|
338
|
-
return [
|
|
339
|
-
createChildWorkflow(this, 'Child-0', false),
|
|
340
|
-
createChildWorkflow(this, 'Child-1', true), // Will fail
|
|
341
|
-
createChildWorkflow(this, 'Child-2', false),
|
|
342
|
-
];
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
async run() {
|
|
346
|
-
try {
|
|
347
|
-
await this.spawnChildren();
|
|
348
|
-
} catch {
|
|
349
|
-
// Expected
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const workflow = new ParentWorkflow('Parent');
|
|
355
|
-
await workflow.run();
|
|
356
|
-
|
|
357
|
-
// All children should be attached (Promise.allSettled completed all)
|
|
358
|
-
expect(workflow.children.length).toBe(3);
|
|
359
|
-
|
|
360
|
-
const childNames = workflow.children.map((c) => c.getNode().name);
|
|
361
|
-
expect(childNames).toContain('Child-0');
|
|
362
|
-
expect(childNames).toContain('Child-1');
|
|
363
|
-
expect(childNames).toContain('Child-2');
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
describe('No error merge strategy - default behavior preserved', () => {
|
|
368
|
-
it('should not merge errors when errorMergeStrategy is not enabled', async () => {
|
|
369
|
-
class ParentWorkflow extends Workflow {
|
|
370
|
-
@Task({ concurrent: true })
|
|
371
|
-
async spawnChildren() {
|
|
372
|
-
return [
|
|
373
|
-
createChildWorkflow(this, 'Alpha', true),
|
|
374
|
-
createChildWorkflow(this, 'Beta', true),
|
|
375
|
-
createChildWorkflow(this, 'Gamma', false),
|
|
376
|
-
];
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async run() {
|
|
380
|
-
await this.spawnChildren();
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const workflow = new ParentWorkflow('Parent');
|
|
385
|
-
|
|
386
|
-
// Should throw first error only (backward compatible)
|
|
387
|
-
await expect(workflow.run()).rejects.toThrow('Alpha failed');
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
// ============================================================================
|
|
393
|
-
// Section 4: Documentation Examples - README Quick Start
|
|
394
|
-
// ============================================================================
|
|
395
|
-
// Tests that all README documentation examples execute without modification
|
|
396
|
-
// ============================================================================
|
|
397
|
-
|
|
398
|
-
describe('Documentation Examples - README Quick Start', () => {
|
|
399
|
-
describe('Class-based workflow from README', () => {
|
|
400
|
-
it('should execute README class-based workflow example', async () => {
|
|
401
|
-
// From README.md lines 22-42 (approximately)
|
|
402
|
-
class DataProcessor extends Workflow {
|
|
403
|
-
@ObservedState()
|
|
404
|
-
progress = 0;
|
|
405
|
-
|
|
406
|
-
@Step({ trackTiming: true, snapshotState: true })
|
|
407
|
-
async process(): Promise<string[]> {
|
|
408
|
-
this.progress = 100;
|
|
409
|
-
return ['item1', 'item2', 'item3'];
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
async run(): Promise<string[]> {
|
|
413
|
-
this.setStatus('running');
|
|
414
|
-
const result = await this.process();
|
|
415
|
-
this.setStatus('completed');
|
|
416
|
-
return result;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const workflow = new DataProcessor('DataProcessor');
|
|
421
|
-
const result = await workflow.run();
|
|
422
|
-
|
|
423
|
-
expect(result).toEqual(['item1', 'item2', 'item3']);
|
|
424
|
-
expect(workflow.status).toBe('completed');
|
|
425
|
-
expect(workflow.progress).toBe(100);
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
describe('Functional workflow from README', () => {
|
|
430
|
-
it('should execute README functional workflow example', async () => {
|
|
431
|
-
// From README.md lines 44-57 (approximately)
|
|
432
|
-
const fetchData = async () => ['data1', 'data2'];
|
|
433
|
-
const transform = async (data: string[]) => data.map(x => x.toUpperCase());
|
|
434
|
-
|
|
435
|
-
const workflow = createWorkflow(
|
|
436
|
-
{ name: 'DataPipeline' },
|
|
437
|
-
async (ctx) => {
|
|
438
|
-
const loaded = await ctx.step('load', async () => fetchData());
|
|
439
|
-
const processed = await ctx.step('process', async () => transform(loaded));
|
|
440
|
-
return processed;
|
|
441
|
-
}
|
|
442
|
-
);
|
|
443
|
-
|
|
444
|
-
const result = await workflow.run();
|
|
445
|
-
|
|
446
|
-
// Result can be either direct value or WorkflowResult object
|
|
447
|
-
if (typeof result === 'object' && result !== null && 'data' in result) {
|
|
448
|
-
expect(result.data).toEqual(['DATA1', 'DATA2']);
|
|
449
|
-
} else {
|
|
450
|
-
expect(result).toEqual(['DATA1', 'DATA2']);
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
describe('Basic workflow creation pattern', () => {
|
|
456
|
-
it('should support basic class extension pattern', async () => {
|
|
457
|
-
// From README basic usage
|
|
458
|
-
class DataProcessor extends Workflow {
|
|
459
|
-
async run(): Promise<string[]> {
|
|
460
|
-
this.setStatus('running');
|
|
461
|
-
this.logger.info('Processing started');
|
|
462
|
-
|
|
463
|
-
const result = await this.processData();
|
|
464
|
-
|
|
465
|
-
this.setStatus('completed');
|
|
466
|
-
return result;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
private async processData(): Promise<string[]> {
|
|
470
|
-
return ['item1', 'item2'];
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const workflow = new DataProcessor('MyProcessor');
|
|
475
|
-
const result = await workflow.run();
|
|
476
|
-
|
|
477
|
-
expect(result).toEqual(['item1', 'item2']);
|
|
478
|
-
expect(workflow.status).toBe('completed');
|
|
479
|
-
});
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
describe('Logger usage from documentation', () => {
|
|
483
|
-
it('should support all logger methods from documentation', async () => {
|
|
484
|
-
class LoggingWorkflow extends Workflow {
|
|
485
|
-
async run(): Promise<void> {
|
|
486
|
-
this.setStatus('running');
|
|
487
|
-
|
|
488
|
-
// All logger methods from docs
|
|
489
|
-
this.logger.debug('Debug message', { data: 'test' });
|
|
490
|
-
this.logger.info('Info message');
|
|
491
|
-
this.logger.warn('Warning message');
|
|
492
|
-
this.logger.error('Error message', { error: new Error('test') });
|
|
493
|
-
|
|
494
|
-
this.setStatus('completed');
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const workflow = new LoggingWorkflow('LoggerTest');
|
|
499
|
-
await workflow.run();
|
|
500
|
-
|
|
501
|
-
expect(workflow.getNode().logs.length).toBe(4);
|
|
502
|
-
expect(workflow.getNode().logs[0].level).toBe('debug');
|
|
503
|
-
expect(workflow.getNode().logs[1].level).toBe('info');
|
|
504
|
-
expect(workflow.getNode().logs[2].level).toBe('warn');
|
|
505
|
-
expect(workflow.getNode().logs[3].level).toBe('error');
|
|
506
|
-
});
|
|
507
|
-
});
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
// ============================================================================
|
|
511
|
-
// Section 5: Example Files - Core Patterns
|
|
512
|
-
// ============================================================================
|
|
513
|
-
// Tests that verify example file patterns work correctly
|
|
514
|
-
// ============================================================================
|
|
515
|
-
|
|
516
|
-
describe('Example Files - Core Patterns', () => {
|
|
517
|
-
describe('01-basic-workflow.ts patterns', () => {
|
|
518
|
-
it('should support basic workflow with status management', async () => {
|
|
519
|
-
// Pattern from examples/examples/01-basic-workflow.ts
|
|
520
|
-
class DataProcessingWorkflow extends Workflow {
|
|
521
|
-
private data: string[] = [];
|
|
522
|
-
|
|
523
|
-
async run(): Promise<string[]> {
|
|
524
|
-
this.setStatus('running');
|
|
525
|
-
this.logger.info('Starting data processing workflow');
|
|
526
|
-
|
|
527
|
-
try {
|
|
528
|
-
// Simulate data processing
|
|
529
|
-
this.data = ['item1', 'item2', 'item3'];
|
|
530
|
-
|
|
531
|
-
this.setStatus('completed');
|
|
532
|
-
this.logger.info('Workflow completed successfully');
|
|
533
|
-
return this.data;
|
|
534
|
-
} catch (error) {
|
|
535
|
-
this.setStatus('failed');
|
|
536
|
-
this.logger.error('Workflow failed', { error });
|
|
537
|
-
throw error;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
const workflow = new DataProcessingWorkflow('DataProcessor');
|
|
543
|
-
const result = await workflow.run();
|
|
544
|
-
|
|
545
|
-
expect(result).toEqual(['item1', 'item2', 'item3']);
|
|
546
|
-
expect(workflow.status).toBe('completed');
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
it('should support WorkflowTreeDebugger', async () => {
|
|
550
|
-
class SimpleWorkflow extends Workflow {
|
|
551
|
-
async run(): Promise<string> {
|
|
552
|
-
this.setStatus('running');
|
|
553
|
-
this.logger.info('Running');
|
|
554
|
-
this.setStatus('completed');
|
|
555
|
-
return 'done';
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
const workflow = new SimpleWorkflow();
|
|
560
|
-
const debugger_ = new WorkflowTreeDebugger(workflow);
|
|
561
|
-
|
|
562
|
-
await workflow.run();
|
|
563
|
-
|
|
564
|
-
// Debugger should produce valid tree output
|
|
565
|
-
const treeString = debugger_.toTreeString();
|
|
566
|
-
expect(treeString).toContain('SimpleWorkflow');
|
|
567
|
-
});
|
|
568
|
-
});
|
|
569
|
-
|
|
570
|
-
describe('02-decorator-options.ts patterns', () => {
|
|
571
|
-
it('should support @Step with all options', async () => {
|
|
572
|
-
// Pattern from examples/examples/02-decorator-options.ts
|
|
573
|
-
class StepOptionsWorkflow extends Workflow {
|
|
574
|
-
@ObservedState()
|
|
575
|
-
currentPhase: string = 'init';
|
|
576
|
-
|
|
577
|
-
// Default step - minimal configuration
|
|
578
|
-
@Step()
|
|
579
|
-
async defaultStep(): Promise<void> {
|
|
580
|
-
this.currentPhase = 'default';
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Step with custom name
|
|
584
|
-
@Step({ name: 'CustomNamedStep' })
|
|
585
|
-
async stepWithCustomName(): Promise<void> {
|
|
586
|
-
this.currentPhase = 'custom-named';
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// Step with state snapshot
|
|
590
|
-
@Step({ snapshotState: true })
|
|
591
|
-
async stepWithSnapshot(): Promise<void> {
|
|
592
|
-
this.currentPhase = 'snapshot';
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
// Step with timing tracking
|
|
596
|
-
@Step({ trackTiming: true })
|
|
597
|
-
async stepWithTiming(): Promise<void> {
|
|
598
|
-
this.currentPhase = 'timed';
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Step with start/finish logging
|
|
602
|
-
@Step({ logStart: true, logFinish: true })
|
|
603
|
-
async stepWithLogging(): Promise<void> {
|
|
604
|
-
this.currentPhase = 'logged';
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
async run(): Promise<void> {
|
|
608
|
-
this.setStatus('running');
|
|
609
|
-
await this.defaultStep();
|
|
610
|
-
await this.stepWithCustomName();
|
|
611
|
-
await this.stepWithSnapshot();
|
|
612
|
-
await this.stepWithTiming();
|
|
613
|
-
await this.stepWithLogging();
|
|
614
|
-
this.setStatus('completed');
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
const workflow = new StepOptionsWorkflow();
|
|
619
|
-
await workflow.run();
|
|
620
|
-
|
|
621
|
-
expect(workflow.status).toBe('completed');
|
|
622
|
-
expect(workflow.currentPhase).toBe('logged');
|
|
623
|
-
});
|
|
624
|
-
|
|
625
|
-
it('should support @ObservedState with redact option', async () => {
|
|
626
|
-
// Pattern from examples/examples/02-decorator-options.ts
|
|
627
|
-
class StateOptionsWorkflow extends Workflow {
|
|
628
|
-
@ObservedState()
|
|
629
|
-
publicData: string = 'visible-value';
|
|
630
|
-
|
|
631
|
-
@ObservedState({ redact: true })
|
|
632
|
-
apiKey: string = 'super-secret-api-key-12345';
|
|
633
|
-
|
|
634
|
-
@ObservedState({ hidden: true })
|
|
635
|
-
internalCounter: number = 999;
|
|
636
|
-
|
|
637
|
-
async run(): Promise<void> {
|
|
638
|
-
this.setStatus('running');
|
|
639
|
-
this.setStatus('completed');
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
const workflow = new StateOptionsWorkflow();
|
|
644
|
-
await workflow.run();
|
|
645
|
-
|
|
646
|
-
const snapshot = getObservedState(workflow);
|
|
647
|
-
|
|
648
|
-
// Public data should be visible
|
|
649
|
-
expect(snapshot.publicData).toBe('visible-value');
|
|
650
|
-
|
|
651
|
-
// API key should be redacted
|
|
652
|
-
expect(snapshot.apiKey).toBe('***');
|
|
653
|
-
|
|
654
|
-
// Hidden field should not be present
|
|
655
|
-
expect('internalCounter' in snapshot).toBe(false);
|
|
656
|
-
});
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
describe('03-parent-child.ts patterns', () => {
|
|
660
|
-
it('should support hierarchical workflow creation', async () => {
|
|
661
|
-
// Pattern from examples/examples/03-parent-child.ts
|
|
662
|
-
class LeafWorkflow extends Workflow {
|
|
663
|
-
@ObservedState()
|
|
664
|
-
processed: boolean = false;
|
|
665
|
-
|
|
666
|
-
constructor(name: string, parent?: Workflow) {
|
|
667
|
-
super(name, parent);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
@Step({ trackTiming: true })
|
|
671
|
-
async process(): Promise<void> {
|
|
672
|
-
this.logger.info(`Processing ${this.getNode().name}`);
|
|
673
|
-
this.processed = true;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
async run(): Promise<void> {
|
|
677
|
-
this.setStatus('running');
|
|
678
|
-
await this.process();
|
|
679
|
-
this.setStatus('completed');
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
class ParentWorkflow extends Workflow {
|
|
684
|
-
@ObservedState()
|
|
685
|
-
itemCount: number = 0;
|
|
686
|
-
|
|
687
|
-
@Task()
|
|
688
|
-
async spawnChild(name: string): Promise<LeafWorkflow> {
|
|
689
|
-
return new LeafWorkflow(name, this);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
async run(): Promise<void> {
|
|
693
|
-
this.setStatus('running');
|
|
694
|
-
this.itemCount = 2;
|
|
695
|
-
|
|
696
|
-
const child1 = await this.spawnChild('Child-1');
|
|
697
|
-
await child1.run();
|
|
698
|
-
|
|
699
|
-
const child2 = await this.spawnChild('Child-2');
|
|
700
|
-
await child2.run();
|
|
701
|
-
|
|
702
|
-
this.setStatus('completed');
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
const parent = new ParentWorkflow('Parent');
|
|
707
|
-
await parent.run();
|
|
708
|
-
|
|
709
|
-
expect(parent.status).toBe('completed');
|
|
710
|
-
expect(parent.children.length).toBe(2);
|
|
711
|
-
expect(parent.itemCount).toBe(2);
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
it('should support parent parameter in constructor', async () => {
|
|
715
|
-
class ChildWorkflow extends Workflow {
|
|
716
|
-
constructor(name: string, parent?: Workflow) {
|
|
717
|
-
super(name, parent);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
async run(): Promise<string> {
|
|
721
|
-
this.setStatus('running');
|
|
722
|
-
this.setStatus('completed');
|
|
723
|
-
return 'child-result';
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
class ParentWorkflow extends Workflow {
|
|
728
|
-
@Task()
|
|
729
|
-
async createChild(): Promise<ChildWorkflow> {
|
|
730
|
-
return new ChildWorkflow('Child', this);
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
async run(): Promise<void> {
|
|
734
|
-
this.setStatus('running');
|
|
735
|
-
const child = await this.createChild();
|
|
736
|
-
await child.run();
|
|
737
|
-
this.setStatus('completed');
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
const parent = new ParentWorkflow('Parent');
|
|
742
|
-
await parent.run();
|
|
743
|
-
|
|
744
|
-
expect(parent.children.length).toBe(1);
|
|
745
|
-
expect(parent.children[0].getNode().name).toBe('Child');
|
|
746
|
-
expect(parent.children[0].parent).toBe(parent);
|
|
747
|
-
});
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
describe('05-error-handling.ts patterns', () => {
|
|
751
|
-
it('should support @Step with error wrapping', async () => {
|
|
752
|
-
// Pattern from examples/examples/05-error-handling.ts
|
|
753
|
-
class ErrorDemoWorkflow extends Workflow {
|
|
754
|
-
@ObservedState()
|
|
755
|
-
currentStep: string = 'init';
|
|
756
|
-
|
|
757
|
-
@Step({ snapshotState: true })
|
|
758
|
-
async step1(): Promise<void> {
|
|
759
|
-
this.currentStep = 'step1';
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
@Step({ snapshotState: true })
|
|
763
|
-
async failingStep(): Promise<void> {
|
|
764
|
-
this.currentStep = 'failing';
|
|
765
|
-
throw new Error('Something went wrong in failingStep!');
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
async run(): Promise<void> {
|
|
769
|
-
this.setStatus('running');
|
|
770
|
-
await this.step1();
|
|
771
|
-
await this.failingStep();
|
|
772
|
-
this.setStatus('completed');
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
const workflow = new ErrorDemoWorkflow();
|
|
777
|
-
let capturedError: WorkflowError | null = null;
|
|
778
|
-
|
|
779
|
-
try {
|
|
780
|
-
await workflow.run();
|
|
781
|
-
} catch (error) {
|
|
782
|
-
capturedError = error as WorkflowError;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
expect(capturedError).not.toBeNull();
|
|
786
|
-
expect(capturedError?.message).toBe('Something went wrong in failingStep!');
|
|
787
|
-
expect(capturedError?.state.currentStep).toBe('failing');
|
|
788
|
-
expect(capturedError?.workflowId).toBe(workflow.id);
|
|
789
|
-
});
|
|
790
|
-
|
|
791
|
-
it('should support WorkflowError structure', async () => {
|
|
792
|
-
class FailingWorkflow extends Workflow {
|
|
793
|
-
@ObservedState()
|
|
794
|
-
attempt: number = 1;
|
|
795
|
-
|
|
796
|
-
@Step()
|
|
797
|
-
async fail(): Promise<void> {
|
|
798
|
-
throw new Error('Test failure');
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
async run(): Promise<void> {
|
|
802
|
-
this.setStatus('running');
|
|
803
|
-
await this.fail();
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
const workflow = new FailingWorkflow();
|
|
808
|
-
let wfError: WorkflowError | null = null;
|
|
809
|
-
|
|
810
|
-
try {
|
|
811
|
-
await workflow.run();
|
|
812
|
-
} catch (error) {
|
|
813
|
-
wfError = error as WorkflowError;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
expect(wfError).toBeDefined();
|
|
817
|
-
expect(wfError?.message).toBe('Test failure');
|
|
818
|
-
expect(wfError?.workflowId).toBe(workflow.id);
|
|
819
|
-
expect(wfError?.state.attempt).toBe(1);
|
|
820
|
-
expect(Array.isArray(wfError?.logs)).toBe(true);
|
|
821
|
-
expect(wfError?.stack).toBeDefined();
|
|
822
|
-
});
|
|
823
|
-
});
|
|
824
|
-
|
|
825
|
-
describe('06-concurrent-tasks.ts patterns', () => {
|
|
826
|
-
it('should support @Task with concurrent option', async () => {
|
|
827
|
-
// Pattern from examples/examples/06-concurrent-tasks.ts
|
|
828
|
-
class WorkerWorkflow extends Workflow {
|
|
829
|
-
@ObservedState()
|
|
830
|
-
result: string = '';
|
|
831
|
-
|
|
832
|
-
constructor(id: string, parent?: Workflow) {
|
|
833
|
-
super(`Worker-${id}`, parent);
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
@Step({ trackTiming: true })
|
|
837
|
-
async process(): Promise<string> {
|
|
838
|
-
this.result = `Result from ${this.getNode().name}`;
|
|
839
|
-
return this.result;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
async run(): Promise<string> {
|
|
843
|
-
this.setStatus('running');
|
|
844
|
-
const result = await this.process();
|
|
845
|
-
this.setStatus('completed');
|
|
846
|
-
return result;
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
class ConcurrentWorkflow extends Workflow {
|
|
851
|
-
@ObservedState()
|
|
852
|
-
workerCount: number = 0;
|
|
853
|
-
|
|
854
|
-
@Task({ concurrent: true })
|
|
855
|
-
async createAllWorkers(): Promise<WorkerWorkflow[]> {
|
|
856
|
-
this.workerCount = 3;
|
|
857
|
-
return [
|
|
858
|
-
new WorkerWorkflow('1', this),
|
|
859
|
-
new WorkerWorkflow('2', this),
|
|
860
|
-
new WorkerWorkflow('3', this),
|
|
861
|
-
];
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
async run(): Promise<void> {
|
|
865
|
-
this.setStatus('running');
|
|
866
|
-
await this.createAllWorkers();
|
|
867
|
-
this.setStatus('completed');
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
const workflow = new ConcurrentWorkflow();
|
|
872
|
-
await workflow.run();
|
|
873
|
-
|
|
874
|
-
expect(workflow.status).toBe('completed');
|
|
875
|
-
expect(workflow.children.length).toBe(3);
|
|
876
|
-
expect(workflow.workerCount).toBe(3);
|
|
877
|
-
});
|
|
878
|
-
|
|
879
|
-
it('should support manual parallel execution pattern', async () => {
|
|
880
|
-
// Manual parallel execution (Promise.all) should still work
|
|
881
|
-
class WorkerWorkflow extends Workflow {
|
|
882
|
-
async run(): Promise<string> {
|
|
883
|
-
this.setStatus('running');
|
|
884
|
-
this.setStatus('completed');
|
|
885
|
-
return 'worker-result';
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
class ManualParallelWorkflow extends Workflow {
|
|
890
|
-
@Task()
|
|
891
|
-
async createWorker(): Promise<WorkerWorkflow> {
|
|
892
|
-
return new WorkerWorkflow('Worker', this);
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
async run(): Promise<string[]> {
|
|
896
|
-
this.setStatus('running');
|
|
897
|
-
|
|
898
|
-
// Manual parallel execution
|
|
899
|
-
const workers = await Promise.all([
|
|
900
|
-
this.createWorker(),
|
|
901
|
-
this.createWorker(),
|
|
902
|
-
this.createWorker(),
|
|
903
|
-
]);
|
|
904
|
-
|
|
905
|
-
const results = await Promise.all(
|
|
906
|
-
workers.map(w => w.run())
|
|
907
|
-
);
|
|
908
|
-
|
|
909
|
-
this.setStatus('completed');
|
|
910
|
-
return results;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
const workflow = new ManualParallelWorkflow();
|
|
915
|
-
const results = await workflow.run();
|
|
916
|
-
|
|
917
|
-
expect(results).toEqual(['worker-result', 'worker-result', 'worker-result']);
|
|
918
|
-
expect(workflow.children.length).toBe(3);
|
|
919
|
-
});
|
|
920
|
-
});
|
|
921
|
-
});
|
|
922
|
-
|
|
923
|
-
// ============================================================================
|
|
924
|
-
// Section 6: Decorator Patterns - Comprehensive Coverage
|
|
925
|
-
// ============================================================================
|
|
926
|
-
// Tests for all decorator option combinations
|
|
927
|
-
// ============================================================================
|
|
928
|
-
|
|
929
|
-
describe('Decorator Patterns - Comprehensive Coverage', () => {
|
|
930
|
-
describe('@Step decorator variations', () => {
|
|
931
|
-
it('should support @Step with no options', async () => {
|
|
932
|
-
class TestWorkflow extends Workflow {
|
|
933
|
-
@Step()
|
|
934
|
-
async basicStep(): Promise<void> {
|
|
935
|
-
this.logger.info('Basic step');
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
async run(): Promise<void> {
|
|
939
|
-
await this.basicStep();
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
const workflow = new TestWorkflow();
|
|
944
|
-
await workflow.run();
|
|
945
|
-
|
|
946
|
-
expect(workflow.getNode().logs.some(l => l.message === 'Basic step')).toBe(true);
|
|
947
|
-
});
|
|
948
|
-
|
|
949
|
-
it('should support @Step with trackTiming option', async () => {
|
|
950
|
-
const events: WorkflowEvent[] = [];
|
|
951
|
-
|
|
952
|
-
class TestWorkflow extends Workflow {
|
|
953
|
-
@Step({ trackTiming: true })
|
|
954
|
-
async timedStep(): Promise<void> {
|
|
955
|
-
// Do nothing
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
async run(): Promise<void> {
|
|
959
|
-
await this.timedStep();
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
const workflow = new TestWorkflow();
|
|
964
|
-
workflow.addObserver({
|
|
965
|
-
onLog: () => {},
|
|
966
|
-
onEvent: (e) => events.push(e),
|
|
967
|
-
onStateUpdated: () => {},
|
|
968
|
-
onTreeChanged: () => {},
|
|
969
|
-
});
|
|
970
|
-
|
|
971
|
-
await workflow.run();
|
|
972
|
-
|
|
973
|
-
const stepEndEvents = events.filter(e => e.type === 'stepEnd');
|
|
974
|
-
expect(stepEndEvents.length).toBeGreaterThan(0);
|
|
975
|
-
if (stepEndEvents[0].type === 'stepEnd') {
|
|
976
|
-
expect(stepEndEvents[0].duration).toBeDefined();
|
|
977
|
-
}
|
|
978
|
-
});
|
|
979
|
-
|
|
980
|
-
it('should support @Step with snapshotState option', async () => {
|
|
981
|
-
class TestWorkflow extends Workflow {
|
|
982
|
-
@ObservedState()
|
|
983
|
-
value: number = 0;
|
|
984
|
-
|
|
985
|
-
@Step({ snapshotState: true })
|
|
986
|
-
async updateStep(): Promise<void> {
|
|
987
|
-
this.value = 42;
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
async run(): Promise<void> {
|
|
991
|
-
await this.updateStep();
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
const workflow = new TestWorkflow();
|
|
996
|
-
await workflow.run();
|
|
997
|
-
|
|
998
|
-
expect(workflow.value).toBe(42);
|
|
999
|
-
});
|
|
1000
|
-
|
|
1001
|
-
it('should support @Step with logStart and logFinish options', async () => {
|
|
1002
|
-
class TestWorkflow extends Workflow {
|
|
1003
|
-
@Step({ logStart: true, logFinish: true })
|
|
1004
|
-
async loggedStep(): Promise<void> {
|
|
1005
|
-
this.logger.info('Inside step');
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
async run(): Promise<void> {
|
|
1009
|
-
await this.loggedStep();
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
const workflow = new TestWorkflow();
|
|
1014
|
-
await workflow.run();
|
|
1015
|
-
|
|
1016
|
-
const logs = workflow.getNode().logs;
|
|
1017
|
-
expect(logs.some(l => l.message.includes('STEP START'))).toBe(true);
|
|
1018
|
-
expect(logs.some(l => l.message.includes('Inside step'))).toBe(true);
|
|
1019
|
-
expect(logs.some(l => l.message.includes('STEP END'))).toBe(true);
|
|
1020
|
-
});
|
|
1021
|
-
|
|
1022
|
-
it('should support @Step with all options combined', async () => {
|
|
1023
|
-
class TestWorkflow extends Workflow {
|
|
1024
|
-
@ObservedState()
|
|
1025
|
-
phase: string = 'init';
|
|
1026
|
-
|
|
1027
|
-
@Step({
|
|
1028
|
-
name: 'FullyConfigured',
|
|
1029
|
-
trackTiming: true,
|
|
1030
|
-
snapshotState: true,
|
|
1031
|
-
logStart: true,
|
|
1032
|
-
logFinish: true,
|
|
1033
|
-
})
|
|
1034
|
-
async fullStep(): Promise<void> {
|
|
1035
|
-
this.phase = 'complete';
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
async run(): Promise<void> {
|
|
1039
|
-
await this.fullStep();
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
const workflow = new TestWorkflow();
|
|
1044
|
-
await workflow.run();
|
|
1045
|
-
|
|
1046
|
-
expect(workflow.phase).toBe('complete');
|
|
1047
|
-
});
|
|
1048
|
-
});
|
|
1049
|
-
|
|
1050
|
-
describe('@Task decorator variations', () => {
|
|
1051
|
-
it('should support @Task with no options', async () => {
|
|
1052
|
-
class ChildWorkflow extends Workflow {
|
|
1053
|
-
async run(): Promise<string> {
|
|
1054
|
-
return 'child-result';
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
class ParentWorkflow extends Workflow {
|
|
1059
|
-
@Task()
|
|
1060
|
-
async createChild(): Promise<ChildWorkflow> {
|
|
1061
|
-
return new ChildWorkflow('Child', this);
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
async run(): Promise<void> {
|
|
1065
|
-
const child = await this.createChild();
|
|
1066
|
-
await child.run();
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
const workflow = new ParentWorkflow();
|
|
1071
|
-
await workflow.run();
|
|
1072
|
-
|
|
1073
|
-
expect(workflow.children.length).toBe(1);
|
|
1074
|
-
});
|
|
1075
|
-
|
|
1076
|
-
it('should support @Task with custom name', async () => {
|
|
1077
|
-
class ChildWorkflow extends Workflow {
|
|
1078
|
-
async run(): Promise<string> {
|
|
1079
|
-
return 'result';
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
class ParentWorkflow extends Workflow {
|
|
1084
|
-
@Task({ name: 'CustomTaskName' })
|
|
1085
|
-
async createChild(): Promise<ChildWorkflow> {
|
|
1086
|
-
return new ChildWorkflow('Child', this);
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
async run(): Promise<void> {
|
|
1090
|
-
await this.createChild();
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
const workflow = new ParentWorkflow();
|
|
1095
|
-
const events: WorkflowEvent[] = [];
|
|
1096
|
-
|
|
1097
|
-
workflow.addObserver({
|
|
1098
|
-
onLog: () => {},
|
|
1099
|
-
onEvent: (e) => events.push(e),
|
|
1100
|
-
onStateUpdated: () => {},
|
|
1101
|
-
onTreeChanged: () => {},
|
|
1102
|
-
});
|
|
1103
|
-
|
|
1104
|
-
await workflow.run();
|
|
1105
|
-
|
|
1106
|
-
const taskEvents = events.filter(e => e.type === 'taskStart' || e.type === 'taskEnd');
|
|
1107
|
-
expect(taskEvents.length).toBeGreaterThan(0);
|
|
1108
|
-
});
|
|
1109
|
-
|
|
1110
|
-
it('should support @Task with concurrent option', async () => {
|
|
1111
|
-
class ChildWorkflow extends Workflow {
|
|
1112
|
-
async run(): Promise<string> {
|
|
1113
|
-
return 'result';
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
class ParentWorkflow extends Workflow {
|
|
1118
|
-
@Task({ concurrent: true })
|
|
1119
|
-
async createChildren(): Promise<ChildWorkflow[]> {
|
|
1120
|
-
return [
|
|
1121
|
-
new ChildWorkflow('Child-1', this),
|
|
1122
|
-
new ChildWorkflow('Child-2', this),
|
|
1123
|
-
new ChildWorkflow('Child-3', this),
|
|
1124
|
-
];
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
async run(): Promise<void> {
|
|
1128
|
-
await this.createChildren();
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
const workflow = new ParentWorkflow();
|
|
1133
|
-
await workflow.run();
|
|
1134
|
-
|
|
1135
|
-
expect(workflow.children.length).toBe(3);
|
|
1136
|
-
});
|
|
1137
|
-
});
|
|
1138
|
-
|
|
1139
|
-
describe('@ObservedState decorator variations', () => {
|
|
1140
|
-
it('should support @ObservedState with no options', async () => {
|
|
1141
|
-
class TestWorkflow extends Workflow {
|
|
1142
|
-
@ObservedState()
|
|
1143
|
-
value: number = 0;
|
|
1144
|
-
|
|
1145
|
-
async run(): Promise<void> {
|
|
1146
|
-
this.value = 42;
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
const workflow = new TestWorkflow();
|
|
1151
|
-
await workflow.run();
|
|
1152
|
-
|
|
1153
|
-
const snapshot = getObservedState(workflow);
|
|
1154
|
-
expect(snapshot.value).toBe(42);
|
|
1155
|
-
});
|
|
1156
|
-
|
|
1157
|
-
it('should support @ObservedState with redact option', async () => {
|
|
1158
|
-
class TestWorkflow extends Workflow {
|
|
1159
|
-
@ObservedState({ redact: true })
|
|
1160
|
-
apiKey: string = 'secret-key';
|
|
1161
|
-
|
|
1162
|
-
async run(): Promise<void> {
|
|
1163
|
-
// Do nothing
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
const workflow = new TestWorkflow();
|
|
1168
|
-
await workflow.run();
|
|
1169
|
-
|
|
1170
|
-
const snapshot = getObservedState(workflow);
|
|
1171
|
-
expect(snapshot.apiKey).toBe('***');
|
|
1172
|
-
});
|
|
1173
|
-
|
|
1174
|
-
it('should support @ObservedState with hidden option', async () => {
|
|
1175
|
-
class TestWorkflow extends Workflow {
|
|
1176
|
-
@ObservedState({ hidden: true })
|
|
1177
|
-
internalId: string = 'internal-123';
|
|
1178
|
-
|
|
1179
|
-
async run(): Promise<void> {
|
|
1180
|
-
// Do nothing
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
const workflow = new TestWorkflow();
|
|
1185
|
-
await workflow.run();
|
|
1186
|
-
|
|
1187
|
-
const snapshot = getObservedState(workflow);
|
|
1188
|
-
expect('internalId' in snapshot).toBe(false);
|
|
1189
|
-
});
|
|
1190
|
-
|
|
1191
|
-
it('should support multiple @ObservedState fields', async () => {
|
|
1192
|
-
class TestWorkflow extends Workflow {
|
|
1193
|
-
@ObservedState()
|
|
1194
|
-
field1: string = 'value1';
|
|
1195
|
-
|
|
1196
|
-
@ObservedState()
|
|
1197
|
-
field2: number = 42;
|
|
1198
|
-
|
|
1199
|
-
@ObservedState({ redact: true })
|
|
1200
|
-
secret: string = 'hidden';
|
|
1201
|
-
|
|
1202
|
-
@ObservedState({ hidden: true })
|
|
1203
|
-
internal: string = 'not-visible';
|
|
1204
|
-
|
|
1205
|
-
async run(): Promise<void> {
|
|
1206
|
-
// Do nothing
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
const workflow = new TestWorkflow();
|
|
1211
|
-
await workflow.run();
|
|
1212
|
-
|
|
1213
|
-
const snapshot = getObservedState(workflow);
|
|
1214
|
-
expect(snapshot.field1).toBe('value1');
|
|
1215
|
-
expect(snapshot.field2).toBe(42);
|
|
1216
|
-
expect(snapshot.secret).toBe('***');
|
|
1217
|
-
expect('internal' in snapshot).toBe(false);
|
|
1218
|
-
});
|
|
1219
|
-
});
|
|
1220
|
-
});
|
|
1221
|
-
|
|
1222
|
-
// ============================================================================
|
|
1223
|
-
// Section 7: Parent-Child Patterns - Hierarchical Workflows
|
|
1224
|
-
// ============================================================================
|
|
1225
|
-
// Tests for parent-child relationship patterns
|
|
1226
|
-
// ============================================================================
|
|
1227
|
-
|
|
1228
|
-
describe('Parent-Child Patterns - Hierarchical Workflows', () => {
|
|
1229
|
-
describe('Constructor-based parent attachment', () => {
|
|
1230
|
-
it('should attach child via constructor parent parameter', async () => {
|
|
1231
|
-
class ChildWorkflow extends Workflow {
|
|
1232
|
-
constructor(name: string, parent?: Workflow) {
|
|
1233
|
-
super(name, parent);
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
async run(): Promise<string> {
|
|
1237
|
-
this.setStatus('running');
|
|
1238
|
-
this.setStatus('completed');
|
|
1239
|
-
return 'child-done';
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
class ParentWorkflow extends Workflow {
|
|
1244
|
-
async run(): Promise<void> {
|
|
1245
|
-
this.setStatus('running');
|
|
1246
|
-
|
|
1247
|
-
const child1 = new ChildWorkflow('Child1', this);
|
|
1248
|
-
await child1.run();
|
|
1249
|
-
|
|
1250
|
-
const child2 = new ChildWorkflow('Child2', this);
|
|
1251
|
-
await child2.run();
|
|
1252
|
-
|
|
1253
|
-
this.setStatus('completed');
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
const parent = new ParentWorkflow('Parent');
|
|
1258
|
-
await parent.run();
|
|
1259
|
-
|
|
1260
|
-
expect(parent.children.length).toBe(2);
|
|
1261
|
-
expect(parent.children[0].parent).toBe(parent);
|
|
1262
|
-
expect(parent.children[1].parent).toBe(parent);
|
|
1263
|
-
});
|
|
1264
|
-
|
|
1265
|
-
it('should establish bidirectional parent-child relationship', async () => {
|
|
1266
|
-
class ChildWorkflow extends Workflow {
|
|
1267
|
-
constructor(name: string, parent?: Workflow) {
|
|
1268
|
-
super(name, parent);
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
async run(): Promise<string> {
|
|
1272
|
-
return 'done';
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
class ParentWorkflow extends Workflow {
|
|
1277
|
-
@Task()
|
|
1278
|
-
async spawnChild(): Promise<ChildWorkflow> {
|
|
1279
|
-
return new ChildWorkflow('Child', this);
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
async run(): Promise<void> {
|
|
1283
|
-
const child = await this.spawnChild();
|
|
1284
|
-
await child.run();
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
const parent = new ParentWorkflow('Parent');
|
|
1289
|
-
await parent.run();
|
|
1290
|
-
|
|
1291
|
-
const child = parent.children[0];
|
|
1292
|
-
|
|
1293
|
-
expect(child.parent).toBe(parent);
|
|
1294
|
-
expect(parent.children).toContain(child);
|
|
1295
|
-
expect(parent.getNode().children).toContain(child.getNode());
|
|
1296
|
-
});
|
|
1297
|
-
});
|
|
1298
|
-
|
|
1299
|
-
describe('Deep hierarchies', () => {
|
|
1300
|
-
it('should support multi-level parent-child chains', async () => {
|
|
1301
|
-
class Level3Workflow extends Workflow {
|
|
1302
|
-
constructor(name: string, parent?: Workflow) {
|
|
1303
|
-
super(name, parent);
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
async run(): Promise<string> {
|
|
1307
|
-
this.setStatus('running');
|
|
1308
|
-
this.setStatus('completed');
|
|
1309
|
-
return 'level3';
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
class Level2Workflow extends Workflow {
|
|
1314
|
-
constructor(name: string, parent?: Workflow) {
|
|
1315
|
-
super(name, parent);
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
@Task()
|
|
1319
|
-
async spawnLevel3(): Promise<Level3Workflow> {
|
|
1320
|
-
return new Level3Workflow('Level3', this);
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
async run(): Promise<string> {
|
|
1324
|
-
this.setStatus('running');
|
|
1325
|
-
const child = await this.spawnLevel3();
|
|
1326
|
-
await child.run();
|
|
1327
|
-
this.setStatus('completed');
|
|
1328
|
-
return 'level2';
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
class Level1Workflow extends Workflow {
|
|
1333
|
-
@Task()
|
|
1334
|
-
async spawnLevel2(): Promise<Level2Workflow> {
|
|
1335
|
-
return new Level2Workflow('Level2', this);
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
async run(): Promise<void> {
|
|
1339
|
-
this.setStatus('running');
|
|
1340
|
-
const child = await this.spawnLevel2();
|
|
1341
|
-
await child.run();
|
|
1342
|
-
this.setStatus('completed');
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
const root = new Level1Workflow('Level1');
|
|
1347
|
-
await root.run();
|
|
1348
|
-
|
|
1349
|
-
expect(root.children.length).toBe(1);
|
|
1350
|
-
const level2 = root.children[0];
|
|
1351
|
-
expect(level2.children.length).toBe(1);
|
|
1352
|
-
const level3 = level2.children[0];
|
|
1353
|
-
|
|
1354
|
-
expect(level3.parent).toBe(level2);
|
|
1355
|
-
expect(level2.parent).toBe(root);
|
|
1356
|
-
});
|
|
1357
|
-
});
|
|
1358
|
-
|
|
1359
|
-
describe('Sibling workflows', () => {
|
|
1360
|
-
it('should support multiple children of same parent', async () => {
|
|
1361
|
-
class ChildWorkflow extends Workflow {
|
|
1362
|
-
constructor(name: string, parent?: Workflow) {
|
|
1363
|
-
super(name, parent);
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
async run(): Promise<string> {
|
|
1367
|
-
return 'done';
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
class ParentWorkflow extends Workflow {
|
|
1372
|
-
@ObservedState()
|
|
1373
|
-
childCount: number = 0;
|
|
1374
|
-
|
|
1375
|
-
async run(): Promise<void> {
|
|
1376
|
-
this.childCount = 3;
|
|
1377
|
-
|
|
1378
|
-
for (let i = 1; i <= 3; i++) {
|
|
1379
|
-
const child = new ChildWorkflow(`Child${i}`, this);
|
|
1380
|
-
await child.run();
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
const parent = new ParentWorkflow('Parent');
|
|
1386
|
-
await parent.run();
|
|
1387
|
-
|
|
1388
|
-
expect(parent.children.length).toBe(3);
|
|
1389
|
-
expect(parent.childCount).toBe(3);
|
|
1390
|
-
|
|
1391
|
-
const childNames = parent.children.map(c => c.getNode().name);
|
|
1392
|
-
expect(childNames).toEqual(['Child1', 'Child2', 'Child3']);
|
|
1393
|
-
});
|
|
1394
|
-
});
|
|
1395
|
-
});
|
|
1396
|
-
|
|
1397
|
-
// ============================================================================
|
|
1398
|
-
// Section 8: Additional Backward Compatibility Validations
|
|
1399
|
-
// ============================================================================
|
|
1400
|
-
// Additional tests for comprehensive backward compatibility coverage
|
|
1401
|
-
// ============================================================================
|
|
1402
|
-
|
|
1403
|
-
describe('Additional Backward Compatibility Validations', () => {
|
|
1404
|
-
describe('Workflow status transitions', () => {
|
|
1405
|
-
it('should support all status transitions from examples', async () => {
|
|
1406
|
-
class StatusWorkflow extends Workflow {
|
|
1407
|
-
async run(): Promise<void> {
|
|
1408
|
-
// idle -> running -> completed
|
|
1409
|
-
expect(this.status).toBe('idle');
|
|
1410
|
-
this.setStatus('running');
|
|
1411
|
-
expect(this.status).toBe('running');
|
|
1412
|
-
this.setStatus('completed');
|
|
1413
|
-
expect(this.status).toBe('completed');
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
const workflow = new StatusWorkflow();
|
|
1418
|
-
await workflow.run();
|
|
1419
|
-
|
|
1420
|
-
expect(workflow.status).toBe('completed');
|
|
1421
|
-
});
|
|
1422
|
-
|
|
1423
|
-
it('should support failed status transition', async () => {
|
|
1424
|
-
class FailingWorkflow extends Workflow {
|
|
1425
|
-
async run(): Promise<void> {
|
|
1426
|
-
this.setStatus('running');
|
|
1427
|
-
this.setStatus('failed');
|
|
1428
|
-
throw new Error('Intentional failure');
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
const workflow = new FailingWorkflow();
|
|
1433
|
-
|
|
1434
|
-
try {
|
|
1435
|
-
await workflow.run();
|
|
1436
|
-
} catch {
|
|
1437
|
-
// Expected
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
expect(workflow.status).toBe('failed');
|
|
1441
|
-
});
|
|
1442
|
-
});
|
|
1443
|
-
|
|
1444
|
-
describe('Workflow ID generation', () => {
|
|
1445
|
-
it('should generate unique IDs for each workflow instance', () => {
|
|
1446
|
-
class TestWorkflow extends Workflow {}
|
|
1447
|
-
|
|
1448
|
-
const wf1 = new TestWorkflow();
|
|
1449
|
-
const wf2 = new TestWorkflow();
|
|
1450
|
-
const wf3 = new TestWorkflow();
|
|
1451
|
-
|
|
1452
|
-
expect(wf1.id).not.toBe(wf2.id);
|
|
1453
|
-
expect(wf2.id).not.toBe(wf3.id);
|
|
1454
|
-
expect(wf1.id).not.toBe(wf3.id);
|
|
1455
|
-
});
|
|
1456
|
-
});
|
|
1457
|
-
|
|
1458
|
-
describe('Workflow name defaults', () => {
|
|
1459
|
-
it('should use class name as default when no name provided', () => {
|
|
1460
|
-
class MyCustomWorkflow extends Workflow {}
|
|
1461
|
-
|
|
1462
|
-
const wf = new MyCustomWorkflow();
|
|
1463
|
-
expect(wf.getNode().name).toBe('MyCustomWorkflow');
|
|
1464
|
-
});
|
|
1465
|
-
});
|
|
1466
|
-
|
|
1467
|
-
describe('Logger child with both APIs', () => {
|
|
1468
|
-
it('should support mixing old and new logger.child() APIs', async () => {
|
|
1469
|
-
class TestWorkflow extends Workflow {
|
|
1470
|
-
async run() {
|
|
1471
|
-
// Old API
|
|
1472
|
-
const child1 = this.logger.child('log-1');
|
|
1473
|
-
child1.info('Message 1');
|
|
1474
|
-
|
|
1475
|
-
// New API
|
|
1476
|
-
const child2 = this.logger.child({ parentLogId: 'log-2' });
|
|
1477
|
-
child2.info('Message 2');
|
|
1478
|
-
|
|
1479
|
-
// Old API again
|
|
1480
|
-
const child3 = this.logger.child('log-3');
|
|
1481
|
-
child3.info('Message 3');
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
const workflow = new TestWorkflow();
|
|
1486
|
-
await workflow.run();
|
|
1487
|
-
|
|
1488
|
-
expect(workflow.getNode().logs[0].parentLogId).toBe('log-1');
|
|
1489
|
-
expect(workflow.getNode().logs[1].parentLogId).toBe('log-2');
|
|
1490
|
-
expect(workflow.getNode().logs[2].parentLogId).toBe('log-3');
|
|
1491
|
-
});
|
|
1492
|
-
});
|
|
1493
|
-
|
|
1494
|
-
describe('WorkflowTreeDebugger compatibility', () => {
|
|
1495
|
-
it('should work with WorkflowTreeDebugger', async () => {
|
|
1496
|
-
class TestWorkflow extends Workflow {
|
|
1497
|
-
@ObservedState()
|
|
1498
|
-
value: number = 42;
|
|
1499
|
-
|
|
1500
|
-
@Step()
|
|
1501
|
-
async testStep(): Promise<void> {
|
|
1502
|
-
this.logger.info('Test log');
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
async run(): Promise<void> {
|
|
1506
|
-
this.setStatus('running');
|
|
1507
|
-
await this.testStep();
|
|
1508
|
-
this.setStatus('completed');
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
|
|
1512
|
-
const workflow = new TestWorkflow();
|
|
1513
|
-
const debugger_ = new WorkflowTreeDebugger(workflow);
|
|
1514
|
-
|
|
1515
|
-
await workflow.run();
|
|
1516
|
-
|
|
1517
|
-
// All debugger methods should work
|
|
1518
|
-
const tree = debugger_.toTreeString();
|
|
1519
|
-
const logs = debugger_.toLogString();
|
|
1520
|
-
const stats = debugger_.getStats();
|
|
1521
|
-
|
|
1522
|
-
expect(tree).toContain('TestWorkflow');
|
|
1523
|
-
expect(typeof logs).toBe('string');
|
|
1524
|
-
expect(stats.totalNodes).toBeGreaterThanOrEqual(1);
|
|
1525
|
-
});
|
|
1526
|
-
});
|
|
1527
|
-
|
|
1528
|
-
describe('Observer pattern compatibility', () => {
|
|
1529
|
-
it('should support WorkflowObserver with all callbacks', async () => {
|
|
1530
|
-
const logs: string[] = [];
|
|
1531
|
-
const events: WorkflowEvent[] = [];
|
|
1532
|
-
const stateUpdates: number[] = [];
|
|
1533
|
-
const treeUpdates: number[] = [];
|
|
1534
|
-
|
|
1535
|
-
class TestWorkflow extends Workflow {
|
|
1536
|
-
@ObservedState()
|
|
1537
|
-
counter: number = 0;
|
|
1538
|
-
|
|
1539
|
-
@Step({ snapshotState: true })
|
|
1540
|
-
async testStep(): Promise<void> {
|
|
1541
|
-
this.counter = 1;
|
|
1542
|
-
this.logger.info('Test message');
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
async run(): Promise<void> {
|
|
1546
|
-
this.setStatus('running');
|
|
1547
|
-
await this.testStep();
|
|
1548
|
-
this.setStatus('completed');
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
const workflow = new TestWorkflow();
|
|
1553
|
-
|
|
1554
|
-
const observer: WorkflowObserver = {
|
|
1555
|
-
onLog: (entry) => logs.push(entry.message),
|
|
1556
|
-
onEvent: (event) => events.push(event),
|
|
1557
|
-
onStateUpdated: () => stateUpdates.push(1),
|
|
1558
|
-
onTreeChanged: () => treeUpdates.push(1),
|
|
1559
|
-
};
|
|
1560
|
-
|
|
1561
|
-
workflow.addObserver(observer);
|
|
1562
|
-
await workflow.run();
|
|
1563
|
-
|
|
1564
|
-
expect(logs.length).toBeGreaterThan(0);
|
|
1565
|
-
expect(logs.some(l => l === 'Test message')).toBe(true);
|
|
1566
|
-
expect(events.length).toBeGreaterThan(0);
|
|
1567
|
-
expect(stateUpdates.length).toBeGreaterThan(0);
|
|
1568
|
-
expect(treeUpdates.length).toBeGreaterThan(0);
|
|
1569
|
-
});
|
|
1570
|
-
});
|
|
1571
|
-
});
|
|
1572
|
-
});
|