@paths.design/caws-cli 10.2.0 → 11.0.0
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/README.md +125 -374
- package/dist/index.js +43 -785
- package/dist/shell/binding/resolve-binding.d.ts +4 -0
- package/dist/shell/binding/resolve-binding.d.ts.map +1 -0
- package/dist/shell/binding/resolve-binding.js +228 -0
- package/dist/shell/binding/resolve-binding.js.map +1 -0
- package/dist/shell/binding/types.d.ts +42 -0
- package/dist/shell/binding/types.d.ts.map +1 -0
- package/dist/shell/binding/types.js +21 -0
- package/dist/shell/binding/types.js.map +1 -0
- package/dist/shell/commands/claim.d.ts +14 -0
- package/dist/shell/commands/claim.d.ts.map +1 -0
- package/dist/shell/commands/claim.js +197 -0
- package/dist/shell/commands/claim.js.map +1 -0
- package/dist/shell/commands/doctor.d.ts +13 -0
- package/dist/shell/commands/doctor.d.ts.map +1 -0
- package/dist/shell/commands/doctor.js +97 -0
- package/dist/shell/commands/doctor.js.map +1 -0
- package/dist/shell/commands/evidence.d.ts +28 -0
- package/dist/shell/commands/evidence.d.ts.map +1 -0
- package/dist/shell/commands/evidence.js +166 -0
- package/dist/shell/commands/evidence.js.map +1 -0
- package/dist/shell/commands/gates.d.ts +19 -0
- package/dist/shell/commands/gates.d.ts.map +1 -0
- package/dist/shell/commands/gates.js +181 -0
- package/dist/shell/commands/gates.js.map +1 -0
- package/dist/shell/commands/init.d.ts +8 -0
- package/dist/shell/commands/init.d.ts.map +1 -0
- package/dist/shell/commands/init.js +64 -0
- package/dist/shell/commands/init.js.map +1 -0
- package/dist/shell/commands/scope.d.ts +11 -0
- package/dist/shell/commands/scope.d.ts.map +1 -0
- package/dist/shell/commands/scope.js +92 -0
- package/dist/shell/commands/scope.js.map +1 -0
- package/dist/shell/commands/status.d.ts +15 -0
- package/dist/shell/commands/status.d.ts.map +1 -0
- package/dist/shell/commands/status.js +106 -0
- package/dist/shell/commands/status.js.map +1 -0
- package/dist/shell/commands/waiver.d.ts +38 -0
- package/dist/shell/commands/waiver.d.ts.map +1 -0
- package/dist/shell/commands/waiver.js +240 -0
- package/dist/shell/commands/waiver.js.map +1 -0
- package/dist/shell/gates/disposition.d.ts +23 -0
- package/dist/shell/gates/disposition.d.ts.map +1 -0
- package/dist/shell/gates/disposition.js +87 -0
- package/dist/shell/gates/disposition.js.map +1 -0
- package/dist/shell/gates/gate-result-contract.d.ts +39 -0
- package/dist/shell/gates/gate-result-contract.d.ts.map +1 -0
- package/dist/shell/gates/gate-result-contract.js +150 -0
- package/dist/shell/gates/gate-result-contract.js.map +1 -0
- package/dist/shell/gates/quality-gates-adapter.d.ts +55 -0
- package/dist/shell/gates/quality-gates-adapter.d.ts.map +1 -0
- package/dist/shell/gates/quality-gates-adapter.js +161 -0
- package/dist/shell/gates/quality-gates-adapter.js.map +1 -0
- package/dist/shell/gates/waiver-filter.d.ts +58 -0
- package/dist/shell/gates/waiver-filter.d.ts.map +1 -0
- package/dist/shell/gates/waiver-filter.js +119 -0
- package/dist/shell/gates/waiver-filter.js.map +1 -0
- package/dist/shell/index.d.ts +50 -0
- package/dist/shell/index.d.ts.map +1 -0
- package/dist/shell/index.js +73 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/shell/register.d.ts +11 -0
- package/dist/shell/register.d.ts.map +1 -0
- package/dist/shell/register.js +274 -0
- package/dist/shell/register.js.map +1 -0
- package/dist/shell/render/claim.d.ts +22 -0
- package/dist/shell/render/claim.d.ts.map +1 -0
- package/dist/shell/render/claim.js +75 -0
- package/dist/shell/render/claim.js.map +1 -0
- package/dist/shell/render/decision.d.ts +15 -0
- package/dist/shell/render/decision.d.ts.map +1 -0
- package/dist/shell/render/decision.js +66 -0
- package/dist/shell/render/decision.js.map +1 -0
- package/dist/shell/render/diagnostic.d.ts +19 -0
- package/dist/shell/render/diagnostic.d.ts.map +1 -0
- package/dist/shell/render/diagnostic.js +76 -0
- package/dist/shell/render/diagnostic.js.map +1 -0
- package/dist/shell/render/finding.d.ts +15 -0
- package/dist/shell/render/finding.d.ts.map +1 -0
- package/dist/shell/render/finding.js +57 -0
- package/dist/shell/render/finding.js.map +1 -0
- package/dist/shell/render/gates.d.ts +3 -0
- package/dist/shell/render/gates.d.ts.map +1 -0
- package/dist/shell/render/gates.js +56 -0
- package/dist/shell/render/gates.js.map +1 -0
- package/dist/shell/render/init.d.ts +11 -0
- package/dist/shell/render/init.d.ts.map +1 -0
- package/dist/shell/render/init.js +32 -0
- package/dist/shell/render/init.js.map +1 -0
- package/dist/shell/render/status.d.ts +26 -0
- package/dist/shell/render/status.d.ts.map +1 -0
- package/dist/shell/render/status.js +143 -0
- package/dist/shell/render/status.js.map +1 -0
- package/dist/shell/render/waiver.d.ts +21 -0
- package/dist/shell/render/waiver.d.ts.map +1 -0
- package/dist/shell/render/waiver.js +94 -0
- package/dist/shell/render/waiver.js.map +1 -0
- package/dist/shell/rules.d.ts +37 -0
- package/dist/shell/rules.d.ts.map +1 -0
- package/dist/shell/rules.js +51 -0
- package/dist/shell/rules.js.map +1 -0
- package/dist/shell/session/actor.d.ts +14 -0
- package/dist/shell/session/actor.d.ts.map +1 -0
- package/dist/shell/session/actor.js +34 -0
- package/dist/shell/session/actor.js.map +1 -0
- package/dist/shell/session/resolve-session.d.ts +5 -0
- package/dist/shell/session/resolve-session.d.ts.map +1 -0
- package/dist/shell/session/resolve-session.js +239 -0
- package/dist/shell/session/resolve-session.js.map +1 -0
- package/dist/shell/session/types.d.ts +56 -0
- package/dist/shell/session/types.d.ts.map +1 -0
- package/dist/shell/session/types.js +15 -0
- package/dist/shell/session/types.js.map +1 -0
- package/dist/store/agents-store.d.ts +3 -0
- package/dist/store/agents-store.d.ts.map +1 -0
- package/dist/store/agents-store.js +63 -0
- package/dist/store/agents-store.js.map +1 -0
- package/dist/store/apply-patch.d.ts +16 -0
- package/dist/store/apply-patch.d.ts.map +1 -0
- package/dist/store/apply-patch.js +191 -0
- package/dist/store/apply-patch.js.map +1 -0
- package/dist/store/atomic-write.d.ts +16 -0
- package/dist/store/atomic-write.d.ts.map +1 -0
- package/dist/store/atomic-write.js +132 -0
- package/dist/store/atomic-write.js.map +1 -0
- package/dist/store/doctor-snapshot.d.ts +20 -0
- package/dist/store/doctor-snapshot.d.ts.map +1 -0
- package/dist/store/doctor-snapshot.js +176 -0
- package/dist/store/doctor-snapshot.js.map +1 -0
- package/dist/store/events-store.d.ts +33 -0
- package/dist/store/events-store.d.ts.map +1 -0
- package/dist/store/events-store.js +297 -0
- package/dist/store/events-store.js.map +1 -0
- package/dist/store/index.d.ts +21 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +47 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/init-store.d.ts +21 -0
- package/dist/store/init-store.d.ts.map +1 -0
- package/dist/store/init-store.js +295 -0
- package/dist/store/init-store.js.map +1 -0
- package/dist/store/json-store.d.ts +3 -0
- package/dist/store/json-store.d.ts.map +1 -0
- package/dist/store/json-store.js +65 -0
- package/dist/store/json-store.js.map +1 -0
- package/dist/store/policy-store.d.ts +3 -0
- package/dist/store/policy-store.d.ts.map +1 -0
- package/dist/store/policy-store.js +65 -0
- package/dist/store/policy-store.js.map +1 -0
- package/dist/store/repo-root.d.ts +46 -0
- package/dist/store/repo-root.d.ts.map +1 -0
- package/dist/store/repo-root.js +145 -0
- package/dist/store/repo-root.js.map +1 -0
- package/dist/store/rules.d.ts +53 -0
- package/dist/store/rules.d.ts.map +1 -0
- package/dist/store/rules.js +78 -0
- package/dist/store/rules.js.map +1 -0
- package/dist/store/specs-store.d.ts +3 -0
- package/dist/store/specs-store.d.ts.map +1 -0
- package/dist/store/specs-store.js +131 -0
- package/dist/store/specs-store.js.map +1 -0
- package/dist/store/types.d.ts +84 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +14 -0
- package/dist/store/types.js.map +1 -0
- package/dist/store/waivers-store.d.ts +25 -0
- package/dist/store/waivers-store.d.ts.map +1 -0
- package/dist/store/waivers-store.js +232 -0
- package/dist/store/waivers-store.js.map +1 -0
- package/dist/store/worktrees-store.d.ts +3 -0
- package/dist/store/worktrees-store.d.ts.map +1 -0
- package/dist/store/worktrees-store.js +62 -0
- package/dist/store/worktrees-store.js.map +1 -0
- package/dist/store/yaml-store.d.ts +9 -0
- package/dist/store/yaml-store.d.ts.map +1 -0
- package/dist/store/yaml-store.js +121 -0
- package/dist/store/yaml-store.js.map +1 -0
- package/package.json +15 -13
- package/dist/budget-derivation.js +0 -751
- package/dist/cicd-optimizer.js +0 -504
- package/dist/commands/agents.js +0 -124
- package/dist/commands/archive.js +0 -500
- package/dist/commands/burnup.js +0 -198
- package/dist/commands/diagnose.js +0 -525
- package/dist/commands/evaluate.js +0 -314
- package/dist/commands/gates.js +0 -149
- package/dist/commands/init.js +0 -857
- package/dist/commands/iterate.js +0 -417
- package/dist/commands/mode.js +0 -269
- package/dist/commands/parallel.js +0 -242
- package/dist/commands/plan.js +0 -438
- package/dist/commands/provenance.js +0 -1143
- package/dist/commands/quality-monitor.js +0 -284
- package/dist/commands/scope.js +0 -264
- package/dist/commands/session.js +0 -312
- package/dist/commands/sidecar.js +0 -74
- package/dist/commands/specs.js +0 -1656
- package/dist/commands/status.js +0 -1172
- package/dist/commands/templates.js +0 -237
- package/dist/commands/tool.js +0 -136
- package/dist/commands/tutorial.js +0 -480
- package/dist/commands/validate.js +0 -357
- package/dist/commands/verify-acs.js +0 -443
- package/dist/commands/waivers.js +0 -599
- package/dist/commands/workflow.js +0 -243
- package/dist/commands/worktree.js +0 -502
- package/dist/config/lite-scope.js +0 -158
- package/dist/config/modes.js +0 -347
- package/dist/constants/spec-types.js +0 -65
- package/dist/gates/budget-limit.js +0 -121
- package/dist/gates/feedback.js +0 -260
- package/dist/gates/format.js +0 -179
- package/dist/gates/god-object.js +0 -117
- package/dist/gates/pipeline.js +0 -167
- package/dist/gates/scope-boundary.js +0 -112
- package/dist/gates/spec-completeness.js +0 -109
- package/dist/gates/todo-detection.js +0 -205
- package/dist/generators/jest-config-generator.js +0 -242
- package/dist/generators/working-spec.js +0 -237
- package/dist/minimal-cli.js +0 -88
- package/dist/parallel/parallel-manager.js +0 -433
- package/dist/policy/PolicyManager.js +0 -470
- package/dist/scaffold/claude-hooks.js +0 -443
- package/dist/scaffold/cursor-hooks.js +0 -177
- package/dist/scaffold/git-hooks.js +0 -928
- package/dist/scaffold/index.js +0 -794
- package/dist/session/session-manager.js +0 -653
- package/dist/sidecars/index.js +0 -33
- package/dist/sidecars/listeners.js +0 -40
- package/dist/sidecars/provenance-summary.js +0 -238
- package/dist/sidecars/quality-gaps.js +0 -258
- package/dist/sidecars/schema.js +0 -149
- package/dist/sidecars/spec-drift.js +0 -151
- package/dist/sidecars/waiver-draft.js +0 -176
- package/dist/spec/SpecFileManager.js +0 -419
- package/dist/templates/.caws/schemas/policy.schema.json +0 -117
- package/dist/templates/.caws/schemas/scope.schema.json +0 -52
- package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
- package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
- package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
- package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
- package/dist/templates/.caws/tools/README.md +0 -18
- package/dist/templates/.caws/tools/scope-guard.js +0 -203
- package/dist/templates/.caws/tools-allow.json +0 -331
- package/dist/templates/.caws/waivers.yml +0 -19
- package/dist/templates/.claude/README.md +0 -190
- package/dist/templates/.claude/hooks/audit.sh +0 -121
- package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
- package/dist/templates/.claude/hooks/classify_command.py +0 -592
- package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
- package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
- package/dist/templates/.claude/hooks/naming-check.sh +0 -100
- package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
- package/dist/templates/.claude/hooks/quality-check.sh +0 -81
- package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
- package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
- package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
- package/dist/templates/.claude/hooks/session-log.sh +0 -634
- package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
- package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
- package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
- package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
- package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
- package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
- package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
- package/dist/templates/.claude/rules/git-safety.md +0 -26
- package/dist/templates/.claude/rules/worktree-isolation.md +0 -101
- package/dist/templates/.claude/settings.json +0 -141
- package/dist/templates/.cursor/README.md +0 -299
- package/dist/templates/.cursor/hooks/audit.sh +0 -55
- package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
- package/dist/templates/.cursor/hooks/format.sh +0 -38
- package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
- package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
- package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
- package/dist/templates/.cursor/hooks/session-log.sh +0 -924
- package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
- package/dist/templates/.cursor/hooks.json +0 -76
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
- package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
- package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
- package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
- package/dist/templates/.cursor/rules/README.md +0 -148
- package/dist/templates/.github/copilot-instructions.md +0 -82
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
- package/dist/templates/.junie/guidelines.md +0 -73
- package/dist/templates/.vscode/launch.json +0 -17
- package/dist/templates/.vscode/settings.json +0 -95
- package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
- package/dist/templates/CLAUDE.md +0 -196
- package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
- package/dist/templates/OIDC_SETUP.md +0 -300
- package/dist/templates/agents.md +0 -171
- package/dist/templates/codemod/README.md +0 -1
- package/dist/templates/codemod/test.js +0 -93
- package/dist/templates/docs/README.md +0 -151
- package/dist/templates/scripts/new_feature.sh +0 -80
- package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
- package/dist/test-analysis.js +0 -786
- package/dist/tool-interface.js +0 -314
- package/dist/tool-loader.js +0 -303
- package/dist/tool-validator.js +0 -393
- package/dist/utils/agent-display.js +0 -210
- package/dist/utils/agent-session.js +0 -344
- package/dist/utils/async-utils.js +0 -188
- package/dist/utils/command-wrapper.js +0 -200
- package/dist/utils/event-log.js +0 -584
- package/dist/utils/event-renderer.js +0 -521
- package/dist/utils/finalization.js +0 -230
- package/dist/utils/git-lock.js +0 -119
- package/dist/utils/gitignore-updater.js +0 -158
- package/dist/utils/ide-detection.js +0 -133
- package/dist/utils/lifecycle-events.js +0 -94
- package/dist/utils/project-analysis.js +0 -367
- package/dist/utils/promise-utils.js +0 -72
- package/dist/utils/quality-gates-errors.js +0 -520
- package/dist/utils/quality-gates-utils.js +0 -387
- package/dist/utils/schema-validator.js +0 -50
- package/dist/utils/spec-resolver.js +0 -711
- package/dist/utils/typescript-detector.js +0 -369
- package/dist/utils/working-state.js +0 -530
- package/dist/utils/yaml-validation.js +0 -156
- package/dist/validation/spec-validation.js +0 -924
- package/dist/waivers-manager.js +0 -732
- package/dist/worktree/worktree-manager.js +0 -1735
- package/templates/.caws/schemas/policy.schema.json +0 -117
- package/templates/.caws/schemas/scope.schema.json +0 -52
- package/templates/.caws/schemas/waivers.schema.json +0 -106
- package/templates/.caws/schemas/working-spec.schema.json +0 -340
- package/templates/.caws/schemas/worktrees.schema.json +0 -38
- package/templates/.caws/templates/working-spec.template.yml +0 -80
- package/templates/.caws/tools/README.md +0 -18
- package/templates/.caws/tools/scope-guard.js +0 -203
- package/templates/.caws/tools-allow.json +0 -331
- package/templates/.caws/waivers.yml +0 -19
- package/templates/.claude/README.md +0 -190
- package/templates/.claude/hooks/audit.sh +0 -121
- package/templates/.claude/hooks/block-dangerous.sh +0 -203
- package/templates/.claude/hooks/classify_command.py +0 -592
- package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
- package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
- package/templates/.claude/hooks/naming-check.sh +0 -100
- package/templates/.claude/hooks/protected-paths.sh +0 -39
- package/templates/.claude/hooks/quality-check.sh +0 -81
- package/templates/.claude/hooks/scan-secrets.sh +0 -85
- package/templates/.claude/hooks/scope-guard.sh +0 -381
- package/templates/.claude/hooks/session-caws-status.sh +0 -117
- package/templates/.claude/hooks/session-log.sh +0 -634
- package/templates/.claude/hooks/simplification-guard.sh +0 -92
- package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
- package/templates/.claude/hooks/test_classify_command.py +0 -370
- package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
- package/templates/.claude/hooks/validate-spec.sh +0 -76
- package/templates/.claude/hooks/worktree-guard.sh +0 -220
- package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
- package/templates/.claude/rules/git-safety.md +0 -26
- package/templates/.claude/rules/worktree-isolation.md +0 -101
- package/templates/.claude/settings.json +0 -141
- package/templates/.cursor/README.md +0 -299
- package/templates/.cursor/hooks/audit.sh +0 -55
- package/templates/.cursor/hooks/block-dangerous.sh +0 -84
- package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
- package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
- package/templates/.cursor/hooks/format.sh +0 -38
- package/templates/.cursor/hooks/naming-check.sh +0 -64
- package/templates/.cursor/hooks/scan-secrets.sh +0 -51
- package/templates/.cursor/hooks/scope-guard.sh +0 -52
- package/templates/.cursor/hooks/session-log.sh +0 -924
- package/templates/.cursor/hooks/validate-spec.sh +0 -83
- package/templates/.cursor/hooks.json +0 -76
- package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
- package/templates/.cursor/rules/01-working-style.mdc +0 -50
- package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
- package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
- package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
- package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
- package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
- package/templates/.cursor/rules/07-process-ops.mdc +0 -20
- package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
- package/templates/.cursor/rules/09-docstrings.mdc +0 -89
- package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
- package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
- package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
- package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
- package/templates/.cursor/rules/README.md +0 -148
- package/templates/.github/copilot-instructions.md +0 -82
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
- package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
- package/templates/.junie/guidelines.md +0 -73
- package/templates/.vscode/launch.json +0 -17
- package/templates/.vscode/settings.json +0 -95
- package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
- package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
- package/templates/CLAUDE.md +0 -196
- package/templates/COMMIT_CONVENTIONS.md +0 -86
- package/templates/OIDC_SETUP.md +0 -300
- package/templates/agents.md +0 -171
- package/templates/codemod/README.md +0 -1
- package/templates/codemod/test.js +0 -93
- package/templates/docs/README.md +0 -151
- package/templates/scripts/new_feature.sh +0 -80
- package/templates/scripts/quality-gates/check-god-objects.js +0 -146
- package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
- package/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Session Identity
|
|
3
|
-
*
|
|
4
|
-
* Provides a unified way to identify the current agent session across
|
|
5
|
-
* Claude Code, Cursor, and other IDE agent environments.
|
|
6
|
-
*
|
|
7
|
-
* Sources checked (first match wins):
|
|
8
|
-
* 1. CLAUDE_SESSION_ID — set by Claude Code automatically
|
|
9
|
-
* 2. .caws/agents.json — written by Cursor session-log hook (conversation_id)
|
|
10
|
-
* 3. CURSOR_TRACE_ID — set by Cursor (per-request, not stable, last resort)
|
|
11
|
-
*
|
|
12
|
-
* The agent registry (.caws/agents.json) also tracks active agents for
|
|
13
|
-
* multi-agent coordination. Entries expire after a configurable TTL.
|
|
14
|
-
*
|
|
15
|
-
* @author @darianrosebrook
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const fs = require('fs');
|
|
19
|
-
const path = require('path');
|
|
20
|
-
|
|
21
|
-
const AGENTS_REGISTRY = '.caws/agents.json';
|
|
22
|
-
const DEFAULT_TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get the current agent's session ID from the best available source.
|
|
26
|
-
* @param {string} [projectRoot] - Project root (for reading agent registry)
|
|
27
|
-
* @returns {string|null} Session ID or null if not in an agent context
|
|
28
|
-
*/
|
|
29
|
-
function getAgentSessionId(projectRoot) {
|
|
30
|
-
// 1. Claude Code — most reliable, set automatically
|
|
31
|
-
if (process.env.CLAUDE_SESSION_ID) {
|
|
32
|
-
return process.env.CLAUDE_SESSION_ID;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 2. Agent registry — written by Cursor session-log hook
|
|
36
|
-
if (projectRoot) {
|
|
37
|
-
const registry = loadAgentRegistry(projectRoot);
|
|
38
|
-
const active = findActiveAgent(registry);
|
|
39
|
-
if (active) {
|
|
40
|
-
return active.sessionId;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 3. Cursor trace ID — per-request, not stable, but better than nothing
|
|
45
|
-
if (process.env.CURSOR_TRACE_ID) {
|
|
46
|
-
return `cursor:${process.env.CURSOR_TRACE_ID}`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Get the agent platform name.
|
|
54
|
-
* @returns {string} 'claude-code' | 'cursor' | 'unknown'
|
|
55
|
-
*/
|
|
56
|
-
function getAgentPlatform() {
|
|
57
|
-
if (process.env.CLAUDE_SESSION_ID) return 'claude-code';
|
|
58
|
-
if (process.env.CURSOR_TRACE_ID) return 'cursor';
|
|
59
|
-
return 'unknown';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Load the agent registry, pruning stale entries.
|
|
64
|
-
* @param {string} root - Project root
|
|
65
|
-
* @returns {object} Registry with { agents: { [sessionId]: entry } }
|
|
66
|
-
*/
|
|
67
|
-
function loadAgentRegistry(root) {
|
|
68
|
-
const registryPath = path.join(root, AGENTS_REGISTRY);
|
|
69
|
-
let registry = { version: 1, agents: {} };
|
|
70
|
-
|
|
71
|
-
if (fs.existsSync(registryPath)) {
|
|
72
|
-
try {
|
|
73
|
-
registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
74
|
-
} catch {
|
|
75
|
-
// Corrupt file — start fresh
|
|
76
|
-
registry = { version: 1, agents: {} };
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Prune stale entries on every read
|
|
81
|
-
const now = Date.now();
|
|
82
|
-
let pruned = false;
|
|
83
|
-
for (const [id, entry] of Object.entries(registry.agents || {})) {
|
|
84
|
-
const ttl = entry.ttl || DEFAULT_TTL_MS;
|
|
85
|
-
const lastSeenTime = entry.lastSeen ? new Date(entry.lastSeen).getTime() : 0;
|
|
86
|
-
const lastSeen = isNaN(lastSeenTime) ? 0 : lastSeenTime;
|
|
87
|
-
if (now - lastSeen > ttl) {
|
|
88
|
-
delete registry.agents[id];
|
|
89
|
-
pruned = true;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (pruned) {
|
|
94
|
-
saveAgentRegistry(root, registry);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return registry;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Save the agent registry atomically (write-then-rename).
|
|
102
|
-
* @param {string} root - Project root
|
|
103
|
-
* @param {object} registry - Registry object
|
|
104
|
-
*/
|
|
105
|
-
function saveAgentRegistry(root, registry) {
|
|
106
|
-
const registryPath = path.join(root, AGENTS_REGISTRY);
|
|
107
|
-
const dir = path.dirname(registryPath);
|
|
108
|
-
if (!fs.existsSync(dir)) {
|
|
109
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
110
|
-
}
|
|
111
|
-
const tmpPath = registryPath + '.tmp.' + process.pid;
|
|
112
|
-
fs.writeFileSync(tmpPath, JSON.stringify(registry, null, 2));
|
|
113
|
-
fs.renameSync(tmpPath, registryPath);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Register or heartbeat an agent session.
|
|
118
|
-
* Called by session-log hooks to keep entries fresh.
|
|
119
|
-
* @param {string} root - Project root
|
|
120
|
-
* @param {object} agent - Agent info
|
|
121
|
-
* @param {string} agent.sessionId - Unique session/conversation ID
|
|
122
|
-
* @param {string} agent.platform - 'claude-code' | 'cursor' | 'unknown'
|
|
123
|
-
* @param {string} [agent.model] - Model name if known
|
|
124
|
-
* @param {string} [agent.specId] - Active spec ID if known
|
|
125
|
-
* @param {string|null} [agent.worktree] - Active worktree name if known
|
|
126
|
-
* @param {number} [agent.ttl] - Custom TTL in ms (default 30 min)
|
|
127
|
-
*/
|
|
128
|
-
function heartbeatAgent(root, agent) {
|
|
129
|
-
const registry = loadAgentRegistry(root);
|
|
130
|
-
const existing = registry.agents[agent.sessionId] || {};
|
|
131
|
-
|
|
132
|
-
// CAWSFIX-31: `worktree` is allowed to be set to null explicitly (e.g.,
|
|
133
|
-
// refreshing a spec-only operation). Distinguish "not provided" from
|
|
134
|
-
// "explicitly null" using `in` so the previous worktree binding isn't
|
|
135
|
-
// silently preserved when the caller intends to clear it.
|
|
136
|
-
const worktreeProvided = Object.prototype.hasOwnProperty.call(agent, 'worktree');
|
|
137
|
-
|
|
138
|
-
registry.agents[agent.sessionId] = {
|
|
139
|
-
...existing,
|
|
140
|
-
sessionId: agent.sessionId,
|
|
141
|
-
platform: agent.platform || existing.platform || 'unknown',
|
|
142
|
-
model: agent.model || existing.model || null,
|
|
143
|
-
specId: agent.specId || existing.specId || null,
|
|
144
|
-
worktree: worktreeProvided ? agent.worktree : (existing.worktree || null),
|
|
145
|
-
ttl: agent.ttl || existing.ttl || DEFAULT_TTL_MS,
|
|
146
|
-
firstSeen: existing.firstSeen || new Date().toISOString(),
|
|
147
|
-
lastSeen: new Date().toISOString(),
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
saveAgentRegistry(root, registry);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Refresh the current agent session's claim with the operation's specId
|
|
155
|
-
* and (optionally) worktree context.
|
|
156
|
-
*
|
|
157
|
-
* CAWSFIX-31: every CAWS lifecycle CLI op (specs create/close/archive/
|
|
158
|
-
* delete, worktree create/bind/merge) calls this so agents.json stays
|
|
159
|
-
* fresh even when the IDE session-log hook hasn't fired (e.g., between
|
|
160
|
-
* SessionStart and PreCompact, or in non-Claude-Code environments).
|
|
161
|
-
*
|
|
162
|
-
* Best-effort: silently no-ops when no session id can be determined or
|
|
163
|
-
* when the project root has no .caws/ directory. Never throws.
|
|
164
|
-
*
|
|
165
|
-
* @param {string} root - Project root
|
|
166
|
-
* @param {object} ctx - Refresh context
|
|
167
|
-
* @param {string|null} [ctx.specId] - Spec the operation touched
|
|
168
|
-
* @param {string|null} [ctx.worktree] - Worktree the operation touched
|
|
169
|
-
*/
|
|
170
|
-
function refreshAgentClaim(root, ctx = {}) {
|
|
171
|
-
try {
|
|
172
|
-
const sessionId = getAgentSessionId(root);
|
|
173
|
-
if (!sessionId) return;
|
|
174
|
-
const platform = getAgentPlatform();
|
|
175
|
-
heartbeatAgent(root, {
|
|
176
|
-
sessionId,
|
|
177
|
-
platform,
|
|
178
|
-
specId: ctx.specId || null,
|
|
179
|
-
worktree: ctx.worktree !== undefined ? ctx.worktree : null,
|
|
180
|
-
});
|
|
181
|
-
} catch {
|
|
182
|
-
// Best-effort: a failure here must never break the lifecycle op.
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Find session-log directories under `tmp/` whose `.meta.json` matches
|
|
188
|
-
* the given session id or branch.
|
|
189
|
-
*
|
|
190
|
-
* CAWSFIX-31: the CLI surfaces these paths as pointers when a foreign
|
|
191
|
-
* claim is detected. It does not interpret the contents — the agent
|
|
192
|
-
* reads them and decides whether to take over.
|
|
193
|
-
*
|
|
194
|
-
* Returns an array of `{ sessionId, path, branch, turnCount, lastTurn }`.
|
|
195
|
-
* Tolerates missing/malformed `.meta.json`. Refuses to follow symlinks
|
|
196
|
-
* outside `<root>/tmp/` for safety.
|
|
197
|
-
*
|
|
198
|
-
* @param {string} root - Project root
|
|
199
|
-
* @param {object} [filters] - Optional filters
|
|
200
|
-
* @param {string} [filters.sessionId] - Only return logs for this id
|
|
201
|
-
* @param {string} [filters.branch] - Only return logs whose meta.branch matches
|
|
202
|
-
* @returns {Array<object>}
|
|
203
|
-
*/
|
|
204
|
-
function findSessionLogs(root, filters = {}) {
|
|
205
|
-
const results = [];
|
|
206
|
-
const tmpDir = path.join(root, 'tmp');
|
|
207
|
-
if (!fs.existsSync(tmpDir)) return results;
|
|
208
|
-
|
|
209
|
-
let realTmp;
|
|
210
|
-
try {
|
|
211
|
-
realTmp = fs.realpathSync(tmpDir);
|
|
212
|
-
} catch {
|
|
213
|
-
return results;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
let entries;
|
|
217
|
-
try {
|
|
218
|
-
entries = fs.readdirSync(tmpDir, { withFileTypes: true });
|
|
219
|
-
} catch {
|
|
220
|
-
return results;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
for (const entry of entries) {
|
|
224
|
-
if (!entry.isDirectory()) continue;
|
|
225
|
-
const sid = entry.name;
|
|
226
|
-
if (filters.sessionId && sid !== filters.sessionId) continue;
|
|
227
|
-
|
|
228
|
-
const dirPath = path.join(tmpDir, sid);
|
|
229
|
-
let realDir;
|
|
230
|
-
try {
|
|
231
|
-
realDir = fs.realpathSync(dirPath);
|
|
232
|
-
} catch {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
// Symlink-escape guard: realpath must remain under realTmp.
|
|
236
|
-
if (!realDir.startsWith(realTmp + path.sep) && realDir !== realTmp) continue;
|
|
237
|
-
|
|
238
|
-
const metaPath = path.join(dirPath, '.meta.json');
|
|
239
|
-
if (!fs.existsSync(metaPath)) continue;
|
|
240
|
-
|
|
241
|
-
let meta = {};
|
|
242
|
-
try {
|
|
243
|
-
meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
|
|
244
|
-
} catch {
|
|
245
|
-
// Malformed .meta.json — skip but don't crash.
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (filters.branch && meta.branch !== filters.branch) continue;
|
|
250
|
-
|
|
251
|
-
// Count turn files and capture latest turn timestamp.
|
|
252
|
-
let turnCount = 0;
|
|
253
|
-
let lastTurn = null;
|
|
254
|
-
try {
|
|
255
|
-
const files = fs.readdirSync(dirPath);
|
|
256
|
-
const turnFiles = files
|
|
257
|
-
.filter((f) => /^turn-\d+\.json$/.test(f))
|
|
258
|
-
.sort();
|
|
259
|
-
turnCount = turnFiles.length;
|
|
260
|
-
if (turnFiles.length > 0) {
|
|
261
|
-
const latest = turnFiles[turnFiles.length - 1];
|
|
262
|
-
try {
|
|
263
|
-
const turnData = JSON.parse(fs.readFileSync(path.join(dirPath, latest), 'utf8'));
|
|
264
|
-
lastTurn = turnData.ts_end || turnData.ts_start || null;
|
|
265
|
-
} catch {
|
|
266
|
-
lastTurn = null;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
} catch {
|
|
270
|
-
// best-effort; leave defaults
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
results.push({
|
|
274
|
-
sessionId: sid,
|
|
275
|
-
path: dirPath,
|
|
276
|
-
branch: meta.branch || null,
|
|
277
|
-
turnCount,
|
|
278
|
-
lastTurn,
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return results;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Remove an agent session from the registry.
|
|
287
|
-
* Called on session stop.
|
|
288
|
-
* @param {string} root - Project root
|
|
289
|
-
* @param {string} sessionId - Session to remove
|
|
290
|
-
*/
|
|
291
|
-
function removeAgent(root, sessionId) {
|
|
292
|
-
const registry = loadAgentRegistry(root);
|
|
293
|
-
delete registry.agents[sessionId];
|
|
294
|
-
saveAgentRegistry(root, registry);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Find the most recently active agent for this terminal/process.
|
|
299
|
-
* Prefers agents that match the current environment.
|
|
300
|
-
* @param {object} registry - Loaded registry
|
|
301
|
-
* @returns {object|null} Agent entry or null
|
|
302
|
-
*/
|
|
303
|
-
function findActiveAgent(registry) {
|
|
304
|
-
const agents = Object.values(registry.agents || {});
|
|
305
|
-
if (agents.length === 0) return null;
|
|
306
|
-
|
|
307
|
-
// If we're in Cursor, prefer cursor agents
|
|
308
|
-
const isCursor = !!process.env.CURSOR_TRACE_ID;
|
|
309
|
-
const preferred = agents.filter(a => {
|
|
310
|
-
if (isCursor) return a.platform === 'cursor';
|
|
311
|
-
return a.platform === 'claude-code';
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
const pool = preferred.length > 0 ? preferred : agents;
|
|
315
|
-
|
|
316
|
-
// Return most recently seen
|
|
317
|
-
pool.sort((a, b) => new Date(b.lastSeen) - new Date(a.lastSeen));
|
|
318
|
-
return pool[0];
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* List all currently active (non-expired) agents.
|
|
323
|
-
* @param {string} root - Project root
|
|
324
|
-
* @returns {object[]} Array of agent entries
|
|
325
|
-
*/
|
|
326
|
-
function listActiveAgents(root) {
|
|
327
|
-
const registry = loadAgentRegistry(root);
|
|
328
|
-
return Object.values(registry.agents || {});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
module.exports = {
|
|
332
|
-
getAgentSessionId,
|
|
333
|
-
getAgentPlatform,
|
|
334
|
-
loadAgentRegistry,
|
|
335
|
-
saveAgentRegistry,
|
|
336
|
-
heartbeatAgent,
|
|
337
|
-
refreshAgentClaim,
|
|
338
|
-
findSessionLogs,
|
|
339
|
-
removeAgent,
|
|
340
|
-
findActiveAgent,
|
|
341
|
-
listActiveAgents,
|
|
342
|
-
AGENTS_REGISTRY,
|
|
343
|
-
DEFAULT_TTL_MS,
|
|
344
|
-
};
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Async Operation Utilities
|
|
3
|
-
* Provides consistent patterns for async operations, parallel execution, and resource cleanup
|
|
4
|
-
* @author @darianrosebrook
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Execute multiple async operations in parallel
|
|
9
|
-
* @param {Array<Promise>} promises - Array of promises to execute
|
|
10
|
-
* @param {Object} options - Options
|
|
11
|
-
* @param {boolean} [options.failFast=true] - Stop on first error
|
|
12
|
-
* @returns {Promise<Array>} Array of results
|
|
13
|
-
*/
|
|
14
|
-
async function parallel(promises, options = {}) {
|
|
15
|
-
const { failFast = true } = options;
|
|
16
|
-
|
|
17
|
-
if (failFast) {
|
|
18
|
-
return Promise.all(promises);
|
|
19
|
-
} else {
|
|
20
|
-
// Wait for all promises, collecting both successes and failures
|
|
21
|
-
return Promise.allSettled(promises).then((results) => {
|
|
22
|
-
return results.map((result) => {
|
|
23
|
-
if (result.status === 'fulfilled') {
|
|
24
|
-
return { success: true, value: result.value };
|
|
25
|
-
} else {
|
|
26
|
-
return { success: false, error: result.reason };
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Execute async operations sequentially
|
|
35
|
-
* @param {Array<Function>} operations - Array of async functions to execute
|
|
36
|
-
* @param {Object} options - Options
|
|
37
|
-
* @param {boolean} [options.stopOnError=true] - Stop on first error
|
|
38
|
-
* @returns {Promise<Array>} Array of results
|
|
39
|
-
*/
|
|
40
|
-
async function sequential(operations, options = {}) {
|
|
41
|
-
const { stopOnError = true } = options;
|
|
42
|
-
const results = [];
|
|
43
|
-
|
|
44
|
-
for (const operation of operations) {
|
|
45
|
-
try {
|
|
46
|
-
const result = await operation();
|
|
47
|
-
results.push({ success: true, value: result });
|
|
48
|
-
} catch (error) {
|
|
49
|
-
if (stopOnError) {
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
results.push({ success: false, error });
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return results;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Retry an async operation with exponential backoff
|
|
61
|
-
* @param {Function} operation - Async function to retry
|
|
62
|
-
* @param {Object} options - Retry options
|
|
63
|
-
* @param {number} [options.maxRetries=3] - Maximum number of retries
|
|
64
|
-
* @param {number} [options.initialDelay=1000] - Initial delay in ms
|
|
65
|
-
* @param {number} [options.maxDelay=10000] - Maximum delay in ms
|
|
66
|
-
* @param {Function} [options.shouldRetry] - Function to determine if error should be retried
|
|
67
|
-
* @returns {Promise<any>} Operation result
|
|
68
|
-
*/
|
|
69
|
-
async function retry(operation, options = {}) {
|
|
70
|
-
const {
|
|
71
|
-
maxRetries = 3,
|
|
72
|
-
initialDelay = 1000,
|
|
73
|
-
maxDelay = 10000,
|
|
74
|
-
shouldRetry = () => true,
|
|
75
|
-
} = options;
|
|
76
|
-
|
|
77
|
-
let lastError;
|
|
78
|
-
let delay = initialDelay;
|
|
79
|
-
|
|
80
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
81
|
-
try {
|
|
82
|
-
return await operation();
|
|
83
|
-
} catch (error) {
|
|
84
|
-
lastError = error;
|
|
85
|
-
|
|
86
|
-
if (attempt === maxRetries || !shouldRetry(error)) {
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Wait before retrying with exponential backoff
|
|
91
|
-
// eslint-disable-next-line no-undef
|
|
92
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
93
|
-
delay = Math.min(delay * 2, maxDelay);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
throw lastError;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Execute operation with timeout
|
|
102
|
-
* @param {Promise} promise - Promise to execute
|
|
103
|
-
* @param {number} timeoutMs - Timeout in milliseconds
|
|
104
|
-
* @param {string} [errorMessage] - Custom error message
|
|
105
|
-
* @returns {Promise<any>} Operation result
|
|
106
|
-
*/
|
|
107
|
-
async function withTimeout(promise, timeoutMs, errorMessage = 'Operation timed out') {
|
|
108
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
109
|
-
// eslint-disable-next-line no-undef
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
reject(new Error(`${errorMessage} (${timeoutMs}ms)`));
|
|
112
|
-
}, timeoutMs);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return Promise.race([promise, timeoutPromise]);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Execute operation with resource cleanup
|
|
120
|
-
* @param {Function} operation - Async operation to execute
|
|
121
|
-
* @param {Function} cleanup - Cleanup function (called in finally)
|
|
122
|
-
* @returns {Promise<any>} Operation result
|
|
123
|
-
*/
|
|
124
|
-
async function withCleanup(operation, cleanup) {
|
|
125
|
-
try {
|
|
126
|
-
return await operation();
|
|
127
|
-
} finally {
|
|
128
|
-
await cleanup();
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Execute multiple operations and collect all errors
|
|
134
|
-
* @param {Array<Function>} operations - Array of async functions
|
|
135
|
-
* @returns {Promise<{successes: Array, errors: Array}>} Results and errors
|
|
136
|
-
*/
|
|
137
|
-
async function collectResults(operations) {
|
|
138
|
-
const results = await Promise.allSettled(
|
|
139
|
-
operations.map((op) => op())
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
const successes = [];
|
|
143
|
-
const errors = [];
|
|
144
|
-
|
|
145
|
-
results.forEach((result, index) => {
|
|
146
|
-
if (result.status === 'fulfilled') {
|
|
147
|
-
successes.push({ index, value: result.value });
|
|
148
|
-
} else {
|
|
149
|
-
errors.push({ index, error: result.reason });
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
return { successes, errors };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Execute operation with cancellation support
|
|
158
|
-
* @param {Function} operation - Async operation to execute
|
|
159
|
-
* @param {AbortSignal} signal - Abort signal for cancellation
|
|
160
|
-
* @returns {Promise<any>} Operation result
|
|
161
|
-
*/
|
|
162
|
-
async function withCancellation(operation, signal) {
|
|
163
|
-
if (signal.aborted) {
|
|
164
|
-
throw new Error('Operation cancelled');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return new Promise((resolve, reject) => {
|
|
168
|
-
signal.addEventListener('abort', () => {
|
|
169
|
-
reject(new Error('Operation cancelled'));
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
operation()
|
|
173
|
-
.then(resolve)
|
|
174
|
-
.catch(reject);
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
module.exports = {
|
|
179
|
-
parallel,
|
|
180
|
-
sequential,
|
|
181
|
-
retry,
|
|
182
|
-
withTimeout,
|
|
183
|
-
withCleanup,
|
|
184
|
-
collectResults,
|
|
185
|
-
withCancellation,
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
|