groundswell 0.0.1 → 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/CHANGELOG.md +188 -0
- package/README.md +99 -5
- 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/dist/__tests__/helpers/index.js +10 -0
- 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} +2 -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 +7 -2
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -100
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/001-hierarchical-workflow-engine.md +0 -543
- 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 -244
- 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/index.ts +0 -143
- package/examples/utils/helpers.ts +0 -57
- package/llms_full.txt +0 -5890
- package/plan/P1P2/PRP.md +0 -527
- package/plan/P1P2/research/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/P1P2/research/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/P1P2/research/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/P1P2/research/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/P1P2/research/REFLECTION_INDEX.md +0 -291
- package/plan/P1P2/research/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/P1P2/research/RESEARCH_SUMMARY.md +0 -342
- package/plan/P1P2/research/anthropic-sdk.md +0 -174
- package/plan/P1P2/research/async-local-storage.md +0 -200
- package/plan/P1P2/research/reflection-code-patterns.md +0 -1205
- package/plan/P1P2/research/reflection-decision-matrix.md +0 -421
- package/plan/P1P2/research/reflection-implementation-guide.md +0 -1341
- package/plan/P1P2/research/reflection-integration-guide.md +0 -834
- package/plan/P1P2/research/reflection-patterns.md +0 -1468
- package/plan/P1P2/research/reflection-quick-reference.md +0 -558
- package/plan/P1P2/research/zod-schema.md +0 -152
- package/plan/P3P4/PRP.md +0 -1388
- package/plan/P3P4/research/caching-lru.md +0 -116
- package/plan/P3P4/research/introspection-tools.md +0 -177
- package/plan/P3P4/research/reflection-patterns.md +0 -117
- package/plan/P4P5/PRP.md +0 -1136
- package/plan/P4P5/research/RESEARCH_SUMMARY.md +0 -151
- package/plan/architecture/external_deps.md +0 -358
- package/plan/architecture/system_context.md +0 -242
- package/plan/backlog.json +0 -867
- package/plan/research/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/research/README-INTROSPECTION.md +0 -352
- package/plan/research/agent-introspection-patterns.md +0 -1085
- package/plan/research/introspection-security-guide.md +0 -928
- package/plan/research/introspection-tool-examples.md +0 -875
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -114
- 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 -138
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/workflow.test.ts +0 -81
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -573
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -87
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -349
- package/src/core/workflow.ts +0 -302
- package/src/debugger/tree-debugger.ts +0 -210
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -96
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -140
- 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 -25
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -74
- 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 -77
- package/tasks.json +0 -0
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.0.3] - 2026-01-12
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **WorkflowLogger.child() signature** (Critical): Updated to accept `Partial<LogEntry>` parameter matching PRD specification, while maintaining backward compatibility with string-based API via function overloads.
|
|
13
|
+
- Implementation: [src/core/logger.ts:98-111](src/core/logger.ts#L98-L111)
|
|
14
|
+
- **Promise.allSettled for concurrent tasks** (Major): Replaced `Promise.all()` with `Promise.allSettled()` for comprehensive error collection when multiple concurrent workflows fail, enabling aggregate error reporting.
|
|
15
|
+
- Implementation: [src/decorators/task.ts:112-142](src/decorators/task.ts#L112-L142)
|
|
16
|
+
- **ErrorMergeStrategy implementation** (Major): Added error merge strategy for concurrent task failures with configurable custom combinators, enabling aggregation of all concurrent errors into a single WorkflowError.
|
|
17
|
+
- Implementation: [src/types/decorators.ts:25-32](src/types/decorators.ts#L25-L32), [src/utils/workflow-error-utils.ts:23-56](src/utils/workflow-error-utils.ts#L23-L56)
|
|
18
|
+
- **Console.error to logger replacement** (Minor): Replaced `console.error()` with workflow logger for observer error handling, ensuring consistent structured logging throughout the codebase.
|
|
19
|
+
- Implementation: [src/core/workflow.ts:426, 444](src/core/workflow.ts#L426)
|
|
20
|
+
- **Tree debugger optimization** (Minor): Implemented incremental node map updates for childDetached events using BFS traversal, avoiding O(n) full map rebuilds and improving performance on large workflow trees.
|
|
21
|
+
- Implementation: [src/debugger/tree-debugger.ts:65-84, 92-117](src/debugger/tree-debugger.ts#L65-L84)
|
|
22
|
+
- **Workflow name validation** (Minor): Added validation for empty, whitespace-only, and overly long (>100 chars) workflow names to prevent invalid configurations.
|
|
23
|
+
- Implementation: [src/core/workflow.ts:98-107](src/core/workflow.ts#L98-L107)
|
|
24
|
+
- **trackTiming default documentation** (Major): Clarified documentation that `trackTiming` in `@Step` decorator defaults to `true` via `!== false` check, improving API discoverability.
|
|
25
|
+
- Implementation: [src/decorators/step.ts:94-101](src/decorators/step.ts#L94-L101)
|
|
26
|
+
- **isDescendantOf public API** (Minor): Made previously private `isDescendantOf()` helper method public with comprehensive JSDoc documentation, enabling workflow hierarchy validation and topology checking.
|
|
27
|
+
- Implementation: [src/core/workflow.ts:201-219](src/core/workflow.ts#L201-L219)
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **Public isDescendantOf() method**: Made the previously private `isDescendantOf()` helper method public for workflow hierarchy validation, circular reference prevention, and topology checking.
|
|
32
|
+
- Implementation: [src/core/workflow.ts:201-219](src/core/workflow.ts#L201-L219)
|
|
33
|
+
|
|
34
|
+
### Test Coverage
|
|
35
|
+
|
|
36
|
+
**New Test Files Added** (12 files):
|
|
37
|
+
- `src/__tests__/unit/logger.test.ts` - WorkflowLogger.child() signature tests (294 lines)
|
|
38
|
+
- `src/__tests__/adversarial/concurrent-task-failures.test.ts` - Concurrent task failure scenarios
|
|
39
|
+
- `src/__tests__/adversarial/error-merge-strategy.test.ts` - Error merge strategy functionality
|
|
40
|
+
- `src/__tests__/unit/tree-debugger-incremental.test.ts` - Incremental node map updates
|
|
41
|
+
- `src/__tests__/adversarial/node-map-update-benchmarks.test.ts` - Performance benchmarks
|
|
42
|
+
- `src/__tests__/integration/observer-logging.test.ts` - Observer logging tests
|
|
43
|
+
- `src/__tests__/unit/workflow.test.ts` - Workflow name validation
|
|
44
|
+
- `src/__tests__/unit/workflow-isDescendantOf.test.ts` - Public isDescendantOf API
|
|
45
|
+
- `src/__tests__/adversarial/parent-validation.test.ts` - Parent validation edge cases
|
|
46
|
+
- `src/__tests__/adversarial/circular-reference.test.ts` - Circular reference detection
|
|
47
|
+
- `src/__tests__/adversarial/complex-circular-reference.test.ts` - Deep circular reference scenarios
|
|
48
|
+
- `src/__tests__/integration/workflow-reparenting.test.ts` - Reparenting workflow tests
|
|
49
|
+
|
|
50
|
+
**Test Count Increase**: +50+ new test cases
|
|
51
|
+
**Regression Tests**: All existing tests continue to pass (100% pass rate maintained)
|
|
52
|
+
|
|
53
|
+
### Implementation Details
|
|
54
|
+
|
|
55
|
+
- **WorkflowLogger.child() signature fix**: [src/core/logger.ts:98-111](src/core/logger.ts#L98-L111)
|
|
56
|
+
- Function overloads for type safety with both string and Partial<LogEntry> parameters
|
|
57
|
+
- Backward compatible with existing string-based API
|
|
58
|
+
- Follows PRD specification exactly
|
|
59
|
+
- **Promise.allSettled for concurrent tasks**: [src/decorators/task.ts:112-142](src/decorators/task.ts#L112-L142)
|
|
60
|
+
- Captures all concurrent errors using Promise.allSettled()
|
|
61
|
+
- Optional error merge strategy for aggregate error reporting
|
|
62
|
+
- Backward compatible: throws first error by default
|
|
63
|
+
- **ErrorMergeStrategy implementation**: [src/types/decorators.ts:25-32](src/types/decorators.ts#L25-L32), [src/utils/workflow-error-utils.ts:23-56](src/utils/workflow-error-utils.ts#L23-L56)
|
|
64
|
+
- New TaskOptions.errorMergeStrategy property
|
|
65
|
+
- Default merger aggregates all error messages, logs, and workflow IDs
|
|
66
|
+
- Custom combine function support for specialized error handling
|
|
67
|
+
- **Console.error to logger replacement**: [src/core/workflow.ts:426, 444](src/core/workflow.ts#L426)
|
|
68
|
+
- Observer onEvent errors now logged with structured context
|
|
69
|
+
- Observer onStateUpdated errors now logged with node context
|
|
70
|
+
- **Tree debugger optimization**: [src/debugger/tree-debugger.ts:65-84, 92-117](src/debugger/tree-debugger.ts#L65-L84)
|
|
71
|
+
- Incremental subtree removal using BFS traversal
|
|
72
|
+
- O(k) complexity for subtree operations instead of O(n)
|
|
73
|
+
- Prevents stack overflow on deep trees with iterative BFS
|
|
74
|
+
- **Workflow name validation**: [src/core/workflow.ts:98-107](src/core/workflow.ts#L98-L107)
|
|
75
|
+
- Rejects empty and whitespace-only names
|
|
76
|
+
- Rejects names exceeding 100 characters
|
|
77
|
+
- Fail-fast validation during construction
|
|
78
|
+
- **trackTiming default documentation**: [src/decorators/step.ts:94-101](src/decorators/step.ts#L94-L101)
|
|
79
|
+
- Clarified that trackTiming defaults to true via !== false check
|
|
80
|
+
- Explicit false disables timing, undefined/true enables timing
|
|
81
|
+
- **isDescendantOf public API**: [src/core/workflow.ts:201-219](src/core/workflow.ts#L201-L219)
|
|
82
|
+
- Cycle detection during parent chain traversal
|
|
83
|
+
- Comprehensive JSDoc with security warning and usage examples
|
|
84
|
+
- Time/space complexity documentation
|
|
85
|
+
|
|
86
|
+
## [0.0.2] - 2026-01-12
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- **attachChild() parent validation**: `attachChild()` now throws an Error if you attempt to attach a child that already has a different parent. Previously, this would silently create an inconsistent tree state where the child appeared in multiple parents' `children` arrays while only linking to one parent via its `parent` property.
|
|
91
|
+
- **Circular reference detection**: `attachChild()` now detects and prevents attaching an ancestor as a child, which would create a circular reference in the tree.
|
|
92
|
+
- **Observer event propagation**: Observer events now propagate correctly after reparenting operations. Previously, events from a shared child would only reach the original parent's observers, not any new parents.
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
|
|
96
|
+
- **New `detachChild()` method**: Enables proper reparenting workflow by removing a child from both the workflow tree (`this.children`) and the node tree (`this.node.children`), clearing the child's parent reference, and emitting a `childDetached` event.
|
|
97
|
+
- Implementation: [src/core/workflow.ts:329-358](src/core/workflow.ts#L329-L358)
|
|
98
|
+
- **New `childDetached` event type**: Discriminated union member for detachment notifications, following the existing event pattern with `type`, `parentId`, and `childId` properties.
|
|
99
|
+
- Implementation: [src/types/events.ts:11](src/types/events.ts#L11)
|
|
100
|
+
- **New `isDescendantOf()` helper**: Private method for circular reference detection that traverses the parent chain upward with cycle detection.
|
|
101
|
+
- Implementation: [src/core/workflow.ts:151-169](src/core/workflow.ts#L151-L169)
|
|
102
|
+
|
|
103
|
+
### Migration Guide for attachChild() Behavior Change
|
|
104
|
+
|
|
105
|
+
**What Changed**:
|
|
106
|
+
The `attachChild()` method now throws an Error if you attempt to attach a child that already has a different parent. Previously, this would silently create an inconsistent tree state that broke observer propagation and violated the PRD's single-parent requirement.
|
|
107
|
+
|
|
108
|
+
**Before (Buggy Pattern)**:
|
|
109
|
+
```typescript
|
|
110
|
+
// This would silently create inconsistent state
|
|
111
|
+
const parent1 = new Workflow({ name: 'parent1' });
|
|
112
|
+
const parent2 = new Workflow({ name: 'parent2' });
|
|
113
|
+
const child = new Workflow({ name: 'child' });
|
|
114
|
+
|
|
115
|
+
parent1.attachChild(child); // child.parent = parent1
|
|
116
|
+
parent2.attachChild(child); // BUG: child still has parent1, but parent2 thinks it's attached
|
|
117
|
+
// Result: child.parent === parent1, but parent2.children.includes(child) === true
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**After (Correct Pattern)**:
|
|
121
|
+
```typescript
|
|
122
|
+
// Use detachChild() before reattaching
|
|
123
|
+
const parent1 = new Workflow({ name: 'parent1' });
|
|
124
|
+
const parent2 = new Workflow({ name: 'parent2' });
|
|
125
|
+
const child = new Workflow({ name: 'child' });
|
|
126
|
+
|
|
127
|
+
parent1.attachChild(child);
|
|
128
|
+
parent1.detachChild(child); // Explicitly detach first
|
|
129
|
+
parent2.attachChild(child); // Now works correctly
|
|
130
|
+
// Result: child.parent === parent2, parent1.children does NOT include child
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Migration Steps**:
|
|
134
|
+
1. Search your code for patterns of attaching the same child to multiple parents
|
|
135
|
+
2. Add `detachChild()` calls before reattaching to a new parent
|
|
136
|
+
3. Test that your workflow tree operations complete without errors
|
|
137
|
+
4. Verify observer events propagate correctly after reparenting
|
|
138
|
+
|
|
139
|
+
### Test Coverage
|
|
140
|
+
|
|
141
|
+
**New Test Files Added** (12 files):
|
|
142
|
+
- `src/__tests__/unit/workflow-detachChild.test.ts` - `detachChild()` method tests
|
|
143
|
+
- `src/__tests__/unit/workflow-emitEvent-childDetached.test.ts` - `childDetached` event tests
|
|
144
|
+
- `src/__tests__/adversarial/parent-validation.test.ts` - Parent validation edge cases
|
|
145
|
+
- `src/__tests__/adversarial/circular-reference.test.ts` - Circular reference detection
|
|
146
|
+
- `src/__tests__/adversarial/complex-circular-reference.test.ts` - Deep circular reference scenarios
|
|
147
|
+
- `src/__tests__/adversarial/attachChild-performance.test.ts` - Performance validation
|
|
148
|
+
- `src/__tests__/adversarial/deep-hierarchy-stress.test.ts` - Deep nesting tests (1000+ levels)
|
|
149
|
+
- `src/__tests__/adversarial/bidirectional-consistency.test.ts` - Tree consistency tests
|
|
150
|
+
- `src/__tests__/adversarial/edge-case.test.ts` - Edge case coverage
|
|
151
|
+
- `src/__tests__/adversarial/observer-propagation.test.ts` - Observer propagation validation
|
|
152
|
+
- `src/__tests__/adversarial/deep-analysis.test.ts` - Comprehensive deep tree analysis
|
|
153
|
+
- `src/__tests__/integration/workflow-reparenting.test.ts` - Reparenting workflow tests
|
|
154
|
+
|
|
155
|
+
**Test Count Increase**: +25 new test cases
|
|
156
|
+
**Regression Tests**: All existing tests continue to pass (100% pass rate maintained)
|
|
157
|
+
|
|
158
|
+
### Implementation Details
|
|
159
|
+
|
|
160
|
+
- **attachChild() validation**: [src/core/workflow.ts:266-305](src/core/workflow.ts#L266-L305)
|
|
161
|
+
- Validates child is not already attached to this workflow
|
|
162
|
+
- Validates child does not have a different parent (throws with helpful error message)
|
|
163
|
+
- Validates child is not an ancestor of this parent (circular reference detection)
|
|
164
|
+
- **detachChild() method**: [src/core/workflow.ts:329-358](src/core/workflow.ts#L329-L358)
|
|
165
|
+
- Removes child from both workflow and node trees
|
|
166
|
+
- Clears child's parent reference
|
|
167
|
+
- Emits childDetached event for observer notification
|
|
168
|
+
- **isDescendantOf() helper**: [src/core/workflow.ts:151-169](src/core/workflow.ts#L151-L169)
|
|
169
|
+
- Private helper method for circular reference detection
|
|
170
|
+
- Traverses parent chain with Set-based cycle detection
|
|
171
|
+
- **childDetached event**: [src/types/events.ts:11](src/types/events.ts#L11)
|
|
172
|
+
- Follows existing discriminated union pattern
|
|
173
|
+
- Uses `childId` (string) instead of `child` (WorkflowNode) since child is no longer in tree
|
|
174
|
+
|
|
175
|
+
## [0.0.1] - 2025-01-10
|
|
176
|
+
|
|
177
|
+
### Added
|
|
178
|
+
- Initial release with hierarchical workflow engine
|
|
179
|
+
- `Workflow` base class with parent/child relationships
|
|
180
|
+
- Observer pattern for event propagation
|
|
181
|
+
- `WorkflowTreeDebugger` for real-time tree visualization
|
|
182
|
+
- `@Step`, `@Task`, and `@ObservedState` decorators
|
|
183
|
+
- Full TypeScript type definitions
|
|
184
|
+
|
|
185
|
+
[Unreleased]: https://github.com/dustin/groundswell/compare/v0.0.3...HEAD
|
|
186
|
+
[0.0.3]: https://github.com/dustin/groundswell/compare/v0.0.2...v0.0.3
|
|
187
|
+
[0.0.2]: https://github.com/dustin/groundswell/compare/v0.0.1...v0.0.2
|
|
188
|
+
[0.0.1]: https://github.com/dustin/groundswell/releases/tag/v0.0.1
|
package/README.md
CHANGED
|
@@ -113,16 +113,110 @@ Immutable value objects defining what to send to an agent and how to validate th
|
|
|
113
113
|
|
|
114
114
|
## Decorators
|
|
115
115
|
|
|
116
|
+
### @Step
|
|
117
|
+
|
|
118
|
+
Emit lifecycle events and track step execution timing.
|
|
119
|
+
|
|
120
|
+
**Default Behavior**: Without any options, `@Step()` automatically tracks timing information.
|
|
121
|
+
|
|
116
122
|
```typescript
|
|
117
|
-
//
|
|
118
|
-
@Step({ trackTiming: true, snapshotState: true })
|
|
123
|
+
@Step() // Timing tracked by default
|
|
119
124
|
async processData(): Promise<void> { }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Configuration Options**:
|
|
128
|
+
|
|
129
|
+
| Option | Type | Default | Description |
|
|
130
|
+
|--------|------|---------|-------------|
|
|
131
|
+
| `name` | `string` | method name | Custom step name |
|
|
132
|
+
| `trackTiming` | `boolean` | `true` | Include duration in `stepEnd` event. Set to `false` to eliminate timing overhead. |
|
|
133
|
+
| `snapshotState` | `boolean` | `false` | Capture state snapshot after step completion |
|
|
134
|
+
| `logStart` | `boolean` | `false` | Log message at step start |
|
|
135
|
+
| `logFinish` | `boolean` | `false` | Log message at step end (includes duration) |
|
|
136
|
+
|
|
137
|
+
**Examples**:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Default behavior - timing tracked automatically
|
|
141
|
+
@Step()
|
|
142
|
+
async basicStep(): Promise<void> { }
|
|
143
|
+
|
|
144
|
+
// Disable timing for performance-critical code
|
|
145
|
+
@Step({ trackTiming: false })
|
|
146
|
+
async highFrequencyStep(): Promise<void> { }
|
|
147
|
+
|
|
148
|
+
// Full configuration
|
|
149
|
+
@Step({ trackTiming: true, snapshotState: true, logStart: true })
|
|
150
|
+
async monitoredStep(): Promise<void> { }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Performance Note**: Timing tracking has minimal overhead. Disable `trackTiming` only in performance-critical code paths with high-frequency execution.
|
|
154
|
+
|
|
155
|
+
### @Task
|
|
156
|
+
|
|
157
|
+
Spawn and manage child workflows.
|
|
158
|
+
|
|
159
|
+
**Validation Behavior**: The decorator performs lenient validation - methods returning non-Workflow objects are silently skipped rather than throwing errors. This enables flexible method designs and duck-typing.
|
|
160
|
+
|
|
161
|
+
**Configuration Options**:
|
|
120
162
|
|
|
121
|
-
|
|
163
|
+
| Option | Type | Default | Description |
|
|
164
|
+
|--------|------|---------|-------------|
|
|
165
|
+
| `name` | `string` | method name | Custom task name |
|
|
166
|
+
| `concurrent` | `boolean` | `false` | If `true`, automatically run returned workflows in parallel using `Promise.all()` |
|
|
167
|
+
|
|
168
|
+
**How It Works**:
|
|
169
|
+
- Workflow objects (with `id` property) are automatically attached as children
|
|
170
|
+
- Non-workflow objects are silently skipped (not attached)
|
|
171
|
+
- The original return value is always preserved
|
|
172
|
+
- Duck-typing is used: any object with an `id` property is treated as workflow-like
|
|
173
|
+
|
|
174
|
+
**Examples**:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Standard usage - return single workflow
|
|
178
|
+
@Task()
|
|
179
|
+
async createChild(): Promise<ChildWorkflow> {
|
|
180
|
+
return new ChildWorkflow('child1', this); // Attached as child
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return multiple workflows
|
|
122
184
|
@Task({ concurrent: true })
|
|
123
|
-
async createWorkers(): Promise<WorkerWorkflow[]> {
|
|
185
|
+
async createWorkers(): Promise<WorkerWorkflow[]> {
|
|
186
|
+
return [
|
|
187
|
+
new WorkerWorkflow('worker1', 100, this), // Attached
|
|
188
|
+
new WorkerWorkflow('worker2', 150, this), // Attached
|
|
189
|
+
]; // Both run concurrently
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Mixed return - only workflows are attached
|
|
193
|
+
@Task()
|
|
194
|
+
async mixedReturn(): Promise<(Workflow | string)[]> {
|
|
195
|
+
return [
|
|
196
|
+
new ChildWorkflow('child1', this), // Attached
|
|
197
|
+
'some string', // Skipped (not a workflow)
|
|
198
|
+
new ChildWorkflow('child2', this), // Attached
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Non-workflow return - handled gracefully
|
|
203
|
+
@Task()
|
|
204
|
+
async returnsData(): Promise<string> {
|
|
205
|
+
return 'just some data'; // Returned as-is, no attachment attempted
|
|
206
|
+
}
|
|
207
|
+
```
|
|
124
208
|
|
|
125
|
-
|
|
209
|
+
**Important Notes**:
|
|
210
|
+
- The decorator uses structural typing (duck-typing) via the `id` property check
|
|
211
|
+
- This enables working with workflow-like objects, not just `Workflow` class instances
|
|
212
|
+
- TypeScript compile-time type checking still catches obvious errors
|
|
213
|
+
- Use `concurrent: true` for automatic parallel execution of returned workflows
|
|
214
|
+
|
|
215
|
+
### @ObservedState
|
|
216
|
+
|
|
217
|
+
Mark fields for state snapshots.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
126
220
|
@ObservedState()
|
|
127
221
|
progress: number = 0;
|
|
128
222
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Test: attachChild() with isDescendantOf() validation
|
|
3
|
+
*
|
|
4
|
+
* Validates that the isDescendantOf() method (added in P1.M1.T2.S2)
|
|
5
|
+
* does not cause significant performance degradation in attachChild()
|
|
6
|
+
* operations across various tree sizes and configurations.
|
|
7
|
+
*
|
|
8
|
+
* Performance Thresholds (from deep-hierarchy-stress.test.ts):
|
|
9
|
+
* - Single operation: < 100ms
|
|
10
|
+
* - Bulk operations (100 iterations): < 1000ms
|
|
11
|
+
* - isDescendantOf() complexity: O(d) where d = tree depth
|
|
12
|
+
*
|
|
13
|
+
* Related: plan/bugfix/P1M4T2S2/PRP.md
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=attachChild-performance.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachChild-performance.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/adversarial/attachChild-performance.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Test: attachChild() with isDescendantOf() validation
|
|
3
|
+
*
|
|
4
|
+
* Validates that the isDescendantOf() method (added in P1.M1.T2.S2)
|
|
5
|
+
* does not cause significant performance degradation in attachChild()
|
|
6
|
+
* operations across various tree sizes and configurations.
|
|
7
|
+
*
|
|
8
|
+
* Performance Thresholds (from deep-hierarchy-stress.test.ts):
|
|
9
|
+
* - Single operation: < 100ms
|
|
10
|
+
* - Bulk operations (100 iterations): < 1000ms
|
|
11
|
+
* - isDescendantOf() complexity: O(d) where d = tree depth
|
|
12
|
+
*
|
|
13
|
+
* Related: plan/bugfix/P1M4T2S2/PRP.md
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
16
|
+
import { Workflow } from '../../index.js';
|
|
17
|
+
import { validateTreeConsistency, verifyBidirectionalLink } from '../helpers/tree-verification.js';
|
|
18
|
+
/**
|
|
19
|
+
* SimpleWorkflow class for performance testing
|
|
20
|
+
* Pattern from: src/__tests__/adversarial/deep-hierarchy-stress.test.ts:20-26
|
|
21
|
+
*/
|
|
22
|
+
class SimpleWorkflow extends Workflow {
|
|
23
|
+
async run() {
|
|
24
|
+
this.setStatus('running');
|
|
25
|
+
this.setStatus('completed');
|
|
26
|
+
return 'done';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
describe('attachChild Performance Regression Tests', () => {
|
|
30
|
+
/**
|
|
31
|
+
* Setup: Mock console methods to capture error messages
|
|
32
|
+
* Pattern from: src/__tests__/adversarial/deep-hierarchy-stress.test.ts:33-37
|
|
33
|
+
*/
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
36
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
37
|
+
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Teardown: Restore all mocks to prevent test pollution
|
|
41
|
+
* CRITICAL: Always use vi.restoreAllMocks() in afterEach
|
|
42
|
+
*/
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
vi.restoreAllMocks();
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Test 1: Shallow tree performance (depth 10)
|
|
48
|
+
*
|
|
49
|
+
* Validates that attachChild() performs very fast on shallow trees
|
|
50
|
+
* where isDescendantOf() only needs to traverse a short parent chain.
|
|
51
|
+
*
|
|
52
|
+
* Threshold: < 10ms (should be very fast for shallow trees)
|
|
53
|
+
*/
|
|
54
|
+
it('should attach child in shallow tree within acceptable time', () => {
|
|
55
|
+
// ARRANGE: Create shallow tree (depth 10)
|
|
56
|
+
const DEPTH = 10;
|
|
57
|
+
const root = new SimpleWorkflow('Root');
|
|
58
|
+
let current = root;
|
|
59
|
+
for (let i = 0; i < DEPTH; i++) {
|
|
60
|
+
current = new SimpleWorkflow(`Level-${i}`, current);
|
|
61
|
+
}
|
|
62
|
+
// ACT: Measure attachChild() time for new child at depth 10
|
|
63
|
+
const startTime = performance.now();
|
|
64
|
+
const newChild = new SimpleWorkflow('NewChild', current);
|
|
65
|
+
const attachDuration = performance.now() - startTime;
|
|
66
|
+
// ASSERT: Verify functional correctness
|
|
67
|
+
expect(newChild.parent).toBe(current);
|
|
68
|
+
expect(current.children).toContain(newChild);
|
|
69
|
+
verifyBidirectionalLink(current, newChild);
|
|
70
|
+
// ASSERT: Verify performance threshold (< 10ms for shallow tree)
|
|
71
|
+
expect(attachDuration).toBeLessThan(10);
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* Test 2: Deep tree performance (depth 100)
|
|
75
|
+
*
|
|
76
|
+
* Validates that attachChild() scales linearly with tree depth.
|
|
77
|
+
* isDescendantOf() must traverse 100 parent references, which should
|
|
78
|
+
* complete in < 50ms given the O(d) iterative implementation.
|
|
79
|
+
*
|
|
80
|
+
* Threshold: < 50ms (linear scaling with depth)
|
|
81
|
+
*/
|
|
82
|
+
it('should attach child in deep tree (depth 100) within acceptable time', () => {
|
|
83
|
+
// ARRANGE: Create deep tree
|
|
84
|
+
const DEPTH = 100;
|
|
85
|
+
const root = new SimpleWorkflow('Root');
|
|
86
|
+
let current = root;
|
|
87
|
+
for (let i = 0; i < DEPTH; i++) {
|
|
88
|
+
current = new SimpleWorkflow(`Child-${i}`, current);
|
|
89
|
+
}
|
|
90
|
+
// ACT: Measure attachChild() at deepest level
|
|
91
|
+
const startTime = performance.now();
|
|
92
|
+
const newChild = new SimpleWorkflow('NewChild', current);
|
|
93
|
+
const attachDuration = performance.now() - startTime;
|
|
94
|
+
// ASSERT: Functional correctness
|
|
95
|
+
verifyBidirectionalLink(current, newChild);
|
|
96
|
+
// ASSERT: Performance threshold (< 50ms for depth 100)
|
|
97
|
+
expect(attachDuration).toBeLessThan(50);
|
|
98
|
+
// ASSERT: Validate overall tree consistency
|
|
99
|
+
const errors = validateTreeConsistency(root);
|
|
100
|
+
expect(errors).toHaveLength(0);
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* Test 3: Extreme deep tree (depth 1000)
|
|
104
|
+
*
|
|
105
|
+
* Validates that attachChild() handles extreme depth without stack overflow
|
|
106
|
+
* and completes within acceptable time. This tests the O(d) complexity
|
|
107
|
+
* at the upper bound of typical workflow tree depths.
|
|
108
|
+
*
|
|
109
|
+
* Threshold: < 100ms (from deep-hierarchy-stress.test.ts:169)
|
|
110
|
+
*/
|
|
111
|
+
it('should attach child in extreme deep tree (depth 1000) without stack overflow', () => {
|
|
112
|
+
const DEPTH = 1000;
|
|
113
|
+
const root = new SimpleWorkflow('Root');
|
|
114
|
+
let current = root;
|
|
115
|
+
for (let i = 0; i < DEPTH; i++) {
|
|
116
|
+
current = new SimpleWorkflow(`Child-${i}`, current);
|
|
117
|
+
}
|
|
118
|
+
// ACT: Measure attachChild() at depth 1000
|
|
119
|
+
const startTime = performance.now();
|
|
120
|
+
const newChild = new SimpleWorkflow('NewChild', current);
|
|
121
|
+
const attachDuration = performance.now() - startTime;
|
|
122
|
+
// ASSERT: Functional correctness
|
|
123
|
+
verifyBidirectionalLink(current, newChild);
|
|
124
|
+
// ASSERT: Performance threshold (< 100ms from deep-hierarchy-stress.test.ts:169)
|
|
125
|
+
expect(attachDuration).toBeLessThan(100);
|
|
126
|
+
// ASSERT: Validate tree consistency at extreme depth
|
|
127
|
+
const errors = validateTreeConsistency(root);
|
|
128
|
+
expect(errors).toHaveLength(0);
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* Test 4: Wide tree performance (100 children)
|
|
132
|
+
*
|
|
133
|
+
* Validates that attachChild() performs efficiently when attaching
|
|
134
|
+
* multiple children to a single parent. Each attachment only requires
|
|
135
|
+
* checking immediate parent chain, so performance should be excellent.
|
|
136
|
+
*
|
|
137
|
+
* Threshold: < 100ms total, < 1ms average per attachment
|
|
138
|
+
*/
|
|
139
|
+
it('should attach 100 children to single parent efficiently', () => {
|
|
140
|
+
// ARRANGE: Create parent
|
|
141
|
+
const parent = new SimpleWorkflow('Parent');
|
|
142
|
+
const NUM_CHILDREN = 100;
|
|
143
|
+
// ACT: Measure time to attach all children
|
|
144
|
+
const startTime = performance.now();
|
|
145
|
+
for (let i = 0; i < NUM_CHILDREN; i++) {
|
|
146
|
+
const child = new SimpleWorkflow(`Child-${i}`, parent);
|
|
147
|
+
}
|
|
148
|
+
const totalDuration = performance.now() - startTime;
|
|
149
|
+
// ASSERT: Verify all children attached
|
|
150
|
+
expect(parent.children).toHaveLength(NUM_CHILDREN);
|
|
151
|
+
parent.children.forEach(child => {
|
|
152
|
+
verifyBidirectionalLink(parent, child);
|
|
153
|
+
});
|
|
154
|
+
// ASSERT: Performance (< 100ms total, < 1ms average)
|
|
155
|
+
expect(totalDuration).toBeLessThan(100);
|
|
156
|
+
const avgTime = totalDuration / NUM_CHILDREN;
|
|
157
|
+
expect(avgTime).toBeLessThan(1); // < 1ms per attachment
|
|
158
|
+
});
|
|
159
|
+
/**
|
|
160
|
+
* Test 5: Bulk attachment performance (100 operations)
|
|
161
|
+
*
|
|
162
|
+
* Validates that sequential attachChild() operations complete within
|
|
163
|
+
* acceptable time. This measures cumulative overhead of isDescendantOf()
|
|
164
|
+
* validation across multiple operations.
|
|
165
|
+
*
|
|
166
|
+
* Threshold: < 1000ms (from deep-hierarchy-stress.test.ts:186)
|
|
167
|
+
*/
|
|
168
|
+
it('should complete 100 sequential attachChild operations within acceptable time', () => {
|
|
169
|
+
// ARRANGE: Create root workflow
|
|
170
|
+
const root = new SimpleWorkflow('Root');
|
|
171
|
+
const ITERATIONS = 100;
|
|
172
|
+
// ACT: Measure cumulative time for 100 attachments
|
|
173
|
+
const totalStartTime = performance.now();
|
|
174
|
+
for (let i = 0; i < ITERATIONS; i++) {
|
|
175
|
+
const child = new SimpleWorkflow(`Child-${i}`, root);
|
|
176
|
+
}
|
|
177
|
+
const totalDuration = performance.now() - totalStartTime;
|
|
178
|
+
// ASSERT: Verify functional correctness
|
|
179
|
+
expect(root.children).toHaveLength(ITERATIONS);
|
|
180
|
+
// ASSERT: Performance threshold (< 1000ms from deep-hierarchy-stress.test.ts:186)
|
|
181
|
+
expect(totalDuration).toBeLessThan(1000);
|
|
182
|
+
// ASSERT: Average time per operation
|
|
183
|
+
const avgTime = totalDuration / ITERATIONS;
|
|
184
|
+
expect(avgTime).toBeLessThan(10); // < 10ms average
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=attachChild-performance.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachChild-performance.test.js","sourceRoot":"","sources":["../../../src/__tests__/adversarial/attachChild-performance.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circular Reference Tests (TDD Red Phase)
|
|
3
|
+
*
|
|
4
|
+
* These tests validate the attachChild() method properly prevents
|
|
5
|
+
* attaching an ancestor workflow as a child (which would create a circular reference).
|
|
6
|
+
*
|
|
7
|
+
* This is the RED phase of TDD - tests are written to FAIL initially,
|
|
8
|
+
* documenting the expected behavior before implementation.
|
|
9
|
+
*
|
|
10
|
+
* Related: plan/docs/bugfix-architecture/bug_analysis.md
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=circular-reference.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circular-reference.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/adversarial/circular-reference.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circular Reference Tests (TDD Red Phase)
|
|
3
|
+
*
|
|
4
|
+
* These tests validate the attachChild() method properly prevents
|
|
5
|
+
* attaching an ancestor workflow as a child (which would create a circular reference).
|
|
6
|
+
*
|
|
7
|
+
* This is the RED phase of TDD - tests are written to FAIL initially,
|
|
8
|
+
* documenting the expected behavior before implementation.
|
|
9
|
+
*
|
|
10
|
+
* Related: plan/docs/bugfix-architecture/bug_analysis.md
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
13
|
+
import { Workflow } from '../../index.js';
|
|
14
|
+
/**
|
|
15
|
+
* SimpleWorkflow class for testing
|
|
16
|
+
* Pattern from: src/__tests__/unit/workflow.test.ts:4-11
|
|
17
|
+
*/
|
|
18
|
+
class SimpleWorkflow extends Workflow {
|
|
19
|
+
async run() {
|
|
20
|
+
this.setStatus('running');
|
|
21
|
+
this.setStatus('completed');
|
|
22
|
+
return 'done';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
describe('Adversarial: Circular Reference Detection', () => {
|
|
26
|
+
/**
|
|
27
|
+
* Setup: Mock console methods to capture error messages
|
|
28
|
+
* Pattern from: research/console-mocking.md "Basic Spying Patterns"
|
|
29
|
+
*/
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
32
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
33
|
+
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Teardown: Restore all mocks to prevent test pollution
|
|
37
|
+
* CRITICAL: Always use vi.restoreAllMocks() in afterEach
|
|
38
|
+
*/
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
vi.restoreAllMocks();
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Test 1: Immediate Circular Reference
|
|
44
|
+
*
|
|
45
|
+
* Bug: attachChild() does NOT check if the child being attached is actually
|
|
46
|
+
* an ancestor of this workflow (would create a circular reference)
|
|
47
|
+
*
|
|
48
|
+
* Expected: Error thrown with message containing 'circular' OR 'cycle' OR 'ancestor'
|
|
49
|
+
* Actual: No error thrown, circular reference created
|
|
50
|
+
*
|
|
51
|
+
* Pattern from: plan/docs/bugfix-architecture/implementation_patterns.md "Pattern 2"
|
|
52
|
+
*/
|
|
53
|
+
it('should throw when attaching immediate parent as child', () => {
|
|
54
|
+
// ARRANGE: Create parent and child workflows
|
|
55
|
+
const parent = new SimpleWorkflow('Parent');
|
|
56
|
+
const child = new SimpleWorkflow('Child', parent);
|
|
57
|
+
// Verify initial state
|
|
58
|
+
// CRITICAL: Constructor auto-attaches child to parent at workflow.ts:113-116
|
|
59
|
+
expect(child.parent).toBe(parent);
|
|
60
|
+
expect(parent.children).toContain(child);
|
|
61
|
+
// ACT & ASSERT: Attempting to attach parent as child should throw
|
|
62
|
+
// This test FAILS because attachChild() doesn't call this.isDescendantOf(child)
|
|
63
|
+
expect(() => child.attachChild(parent)).toThrow(/circular|cycle|ancestor/i);
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* Test 2: Ancestor Circular Reference (Multi-level)
|
|
67
|
+
*
|
|
68
|
+
* Bug: attachChild() does NOT check if the child being attached is an ancestor
|
|
69
|
+
* anywhere up the parent chain (would create a circular reference)
|
|
70
|
+
*
|
|
71
|
+
* Expected: Error thrown with message containing 'circular' OR 'cycle' OR 'ancestor'
|
|
72
|
+
* Actual: No error thrown, circular reference created
|
|
73
|
+
*
|
|
74
|
+
* Pattern from: plan/docs/bugfix-architecture/implementation_patterns.md "Pattern 2"
|
|
75
|
+
*/
|
|
76
|
+
it('should throw when attaching ancestor as child', () => {
|
|
77
|
+
// ARRANGE: Create 3-level hierarchy
|
|
78
|
+
const root = new SimpleWorkflow('Root');
|
|
79
|
+
const child1 = new SimpleWorkflow('Child1', root);
|
|
80
|
+
const child2 = new SimpleWorkflow('Child2', child1);
|
|
81
|
+
// Verify initial state
|
|
82
|
+
// CRITICAL: Constructor auto-attaches at workflow.ts:113-116
|
|
83
|
+
expect(child2.parent).toBe(child1);
|
|
84
|
+
expect(child1.parent).toBe(root);
|
|
85
|
+
expect(root.children).toContain(child1);
|
|
86
|
+
expect(child1.children).toContain(child2);
|
|
87
|
+
// ACT & ASSERT: Attempting to attach root as child of child2 should throw
|
|
88
|
+
// This test FAILS because attachChild() doesn't call this.isDescendantOf(child)
|
|
89
|
+
expect(() => child2.attachChild(root)).toThrow(/circular|cycle|ancestor/i);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=circular-reference.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circular-reference.test.js","sourceRoot":"","sources":["../../../src/__tests__/adversarial/circular-reference.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;GAGG;AACH,MAAM,cAAe,SAAQ,QAAQ;IACnC,KAAK,CAAC,GAAG;QACP,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC1B,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtD,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACxD,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH;;;;;;;;;;OAUG;IACH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,6CAA6C;QAC7C,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAElD,uBAAuB;QACvB,6EAA6E;QAC7E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAEzC,kEAAkE;QAClE,gFAAgF;QAChF,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH;;;;;;;;;;OAUG;IACH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,oCAAoC;QACpC,MAAM,IAAI,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEpD,uBAAuB;QACvB,6DAA6D;QAC7D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE1C,0EAA0E;QAC1E,gFAAgF;QAChF,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complex Circular Reference Tests
|
|
3
|
+
*
|
|
4
|
+
* These tests validate that isDescendantOf() correctly detects circular
|
|
5
|
+
* references at various depths in the workflow tree.
|
|
6
|
+
*
|
|
7
|
+
* Test Cases:
|
|
8
|
+
* 1. Immediate circular reference (depth 1): child.attachChild(parent)
|
|
9
|
+
* 2. Two-level circular reference (depth 2): grandchild.attachChild(root)
|
|
10
|
+
* 3. Three-level circular reference (depth 3): great-grandchild.attachChild(root)
|
|
11
|
+
*
|
|
12
|
+
* Pattern from: plan/docs/bugfix-architecture/implementation_patterns.md Pattern 8
|
|
13
|
+
* Related: plan/bugfix/P1M3T1S3/PRP.md
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=complex-circular-reference.test.d.ts.map
|