@cleocode/core 2026.3.58 → 2026.3.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agent-registry.d.ts +206 -0
- package/dist/agents/agent-registry.d.ts.map +1 -0
- package/dist/agents/health-monitor.d.ts +161 -0
- package/dist/agents/health-monitor.d.ts.map +1 -0
- package/dist/agents/index.d.ts +3 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/retry.d.ts +57 -4
- package/dist/agents/retry.d.ts.map +1 -1
- package/dist/backfill/index.d.ts +27 -0
- package/dist/backfill/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +880 -506
- package/dist/index.js.map +4 -4
- package/dist/intelligence/impact.d.ts +34 -1
- package/dist/intelligence/impact.d.ts.map +1 -1
- package/dist/intelligence/index.d.ts +2 -2
- package/dist/intelligence/index.d.ts.map +1 -1
- package/dist/intelligence/types.d.ts +60 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/internal.d.ts +5 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/retry.d.ts +128 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/nexus/sharing/index.d.ts +48 -2
- package/dist/nexus/sharing/index.d.ts.map +1 -1
- package/dist/stats/workflow-telemetry.d.ts +15 -0
- package/dist/stats/workflow-telemetry.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +35 -0
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/enforcement.d.ts.map +1 -1
- package/dist/tasks/epic-enforcement.d.ts +61 -0
- package/dist/tasks/epic-enforcement.d.ts.map +1 -1
- package/dist/tasks/pipeline-stage.d.ts +70 -1
- package/dist/tasks/pipeline-stage.d.ts.map +1 -1
- package/package.json +5 -5
- package/schemas/config.schema.json +37 -1547
- package/src/__tests__/sharing.test.ts +24 -0
- package/src/agents/__tests__/agent-registry.test.ts +351 -0
- package/src/agents/__tests__/health-monitor.test.ts +332 -0
- package/src/agents/agent-registry.ts +394 -0
- package/src/agents/health-monitor.ts +279 -0
- package/src/agents/index.ts +24 -1
- package/src/agents/retry.ts +57 -4
- package/src/backfill/index.ts +27 -0
- package/src/config.ts +3 -3
- package/src/index.ts +1 -0
- package/src/intelligence/__tests__/impact.test.ts +165 -1
- package/src/intelligence/impact.ts +203 -0
- package/src/intelligence/index.ts +3 -0
- package/src/intelligence/types.ts +76 -0
- package/src/internal.ts +20 -0
- package/src/lib/__tests__/retry.test.ts +321 -0
- package/src/lib/index.ts +16 -0
- package/src/lib/retry.ts +224 -0
- package/src/nexus/sharing/index.ts +142 -2
- package/src/stats/workflow-telemetry.ts +15 -0
- package/src/store/__tests__/session-store.test.ts +43 -7
- package/src/store/__tests__/task-store.test.ts +1 -1
- package/src/store/__tests__/test-db-helper.ts +7 -3
- package/src/store/cross-db-cleanup.ts +35 -0
- package/src/tasks/__tests__/epic-enforcement.test.ts +9 -4
- package/src/tasks/__tests__/minimal-test.test.ts +2 -2
- package/src/tasks/__tests__/update.test.ts +25 -25
- package/src/tasks/complete.ts +11 -6
- package/src/tasks/enforcement.ts +6 -3
- package/src/tasks/epic-enforcement.ts +61 -0
- package/src/tasks/pipeline-stage.ts +70 -1
- package/templates/config.template.json +5 -116
- package/templates/global-config.template.json +2 -44
- package/dist/adapters/adapter-registry.js +0 -64
- package/dist/adapters/adapter-registry.js.map +0 -1
- package/dist/adapters/discovery.js +0 -83
- package/dist/adapters/discovery.js.map +0 -1
- package/dist/adapters/index.js +0 -9
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/manager.js +0 -260
- package/dist/adapters/manager.js.map +0 -1
- package/dist/admin/export-tasks.js +0 -171
- package/dist/admin/export-tasks.js.map +0 -1
- package/dist/admin/export.js +0 -103
- package/dist/admin/export.js.map +0 -1
- package/dist/admin/help.js +0 -106
- package/dist/admin/help.js.map +0 -1
- package/dist/admin/import-tasks.js +0 -182
- package/dist/admin/import-tasks.js.map +0 -1
- package/dist/admin/import.js +0 -129
- package/dist/admin/import.js.map +0 -1
- package/dist/admin/index.js +0 -13
- package/dist/admin/index.js.map +0 -1
- package/dist/adrs/find.js +0 -134
- package/dist/adrs/find.js.map +0 -1
- package/dist/adrs/index.js +0 -15
- package/dist/adrs/index.js.map +0 -1
- package/dist/adrs/link-pipeline.js +0 -160
- package/dist/adrs/link-pipeline.js.map +0 -1
- package/dist/adrs/list.js +0 -43
- package/dist/adrs/list.js.map +0 -1
- package/dist/adrs/parse.js +0 -51
- package/dist/adrs/parse.js.map +0 -1
- package/dist/adrs/show.js +0 -22
- package/dist/adrs/show.js.map +0 -1
- package/dist/adrs/sync.js +0 -188
- package/dist/adrs/sync.js.map +0 -1
- package/dist/adrs/types.js +0 -9
- package/dist/adrs/types.js.map +0 -1
- package/dist/adrs/validate.js +0 -57
- package/dist/adrs/validate.js.map +0 -1
- package/dist/agents/agent-schema.js +0 -80
- package/dist/agents/agent-schema.js.map +0 -1
- package/dist/agents/capacity.js +0 -116
- package/dist/agents/capacity.js.map +0 -1
- package/dist/agents/index.js +0 -21
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/registry.js +0 -314
- package/dist/agents/registry.js.map +0 -1
- package/dist/agents/retry.js +0 -176
- package/dist/agents/retry.js.map +0 -1
- package/dist/audit-prune.js +0 -94
- package/dist/audit-prune.js.map +0 -1
- package/dist/audit.js +0 -68
- package/dist/audit.js.map +0 -1
- package/dist/bootstrap.js +0 -260
- package/dist/bootstrap.js.map +0 -1
- package/dist/caamp/adapter.js +0 -434
- package/dist/caamp/adapter.js.map +0 -1
- package/dist/caamp/capability-check.js +0 -38
- package/dist/caamp/capability-check.js.map +0 -1
- package/dist/caamp/index.js +0 -23
- package/dist/caamp/index.js.map +0 -1
- package/dist/caamp-init.js +0 -16
- package/dist/caamp-init.js.map +0 -1
- package/dist/cleo.js +0 -267
- package/dist/cleo.js.map +0 -1
- package/dist/codebase-map/analyzers/architecture.js +0 -130
- package/dist/codebase-map/analyzers/architecture.js.map +0 -1
- package/dist/codebase-map/analyzers/concerns.js +0 -122
- package/dist/codebase-map/analyzers/concerns.js.map +0 -1
- package/dist/codebase-map/analyzers/conventions.js +0 -149
- package/dist/codebase-map/analyzers/conventions.js.map +0 -1
- package/dist/codebase-map/analyzers/integrations.js +0 -108
- package/dist/codebase-map/analyzers/integrations.js.map +0 -1
- package/dist/codebase-map/analyzers/stack.js +0 -117
- package/dist/codebase-map/analyzers/stack.js.map +0 -1
- package/dist/codebase-map/analyzers/structure.js +0 -137
- package/dist/codebase-map/analyzers/structure.js.map +0 -1
- package/dist/codebase-map/analyzers/testing.js +0 -118
- package/dist/codebase-map/analyzers/testing.js.map +0 -1
- package/dist/codebase-map/index.js +0 -57
- package/dist/codebase-map/index.js.map +0 -1
- package/dist/codebase-map/store.js +0 -122
- package/dist/codebase-map/store.js.map +0 -1
- package/dist/codebase-map/summary.js +0 -152
- package/dist/codebase-map/summary.js.map +0 -1
- package/dist/compliance/index.js +0 -288
- package/dist/compliance/index.js.map +0 -1
- package/dist/compliance/protocol-enforcement.js +0 -332
- package/dist/compliance/protocol-enforcement.js.map +0 -1
- package/dist/compliance/protocol-rules.js +0 -786
- package/dist/compliance/protocol-rules.js.map +0 -1
- package/dist/compliance/protocol-types.js +0 -80
- package/dist/compliance/protocol-types.js.map +0 -1
- package/dist/compliance/store.js +0 -53
- package/dist/compliance/store.js.map +0 -1
- package/dist/config/build-config.js +0 -29
- package/dist/config/build-config.js.map +0 -1
- package/dist/config.js +0 -287
- package/dist/config.js.map +0 -1
- package/dist/constants.js +0 -18
- package/dist/constants.js.map +0 -1
- package/dist/context/index.js +0 -137
- package/dist/context/index.js.map +0 -1
- package/dist/engine-result.js +0 -12
- package/dist/engine-result.js.map +0 -1
- package/dist/error-catalog.js +0 -404
- package/dist/error-catalog.js.map +0 -1
- package/dist/error-registry.js +0 -393
- package/dist/error-registry.js.map +0 -1
- package/dist/errors.js +0 -167
- package/dist/errors.js.map +0 -1
- package/dist/hooks/handlers/error-hooks.js +0 -43
- package/dist/hooks/handlers/error-hooks.js.map +0 -1
- package/dist/hooks/handlers/file-hooks.js +0 -80
- package/dist/hooks/handlers/file-hooks.js.map +0 -1
- package/dist/hooks/handlers/index.js +0 -19
- package/dist/hooks/handlers/index.js.map +0 -1
- package/dist/hooks/handlers/mcp-hooks.js +0 -80
- package/dist/hooks/handlers/mcp-hooks.js.map +0 -1
- package/dist/hooks/handlers/session-hooks.js +0 -73
- package/dist/hooks/handlers/session-hooks.js.map +0 -1
- package/dist/hooks/handlers/task-hooks.js +0 -63
- package/dist/hooks/handlers/task-hooks.js.map +0 -1
- package/dist/hooks/index.js +0 -13
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/payload-schemas.js +0 -163
- package/dist/hooks/payload-schemas.js.map +0 -1
- package/dist/hooks/provider-hooks.js +0 -34
- package/dist/hooks/provider-hooks.js.map +0 -1
- package/dist/hooks/registry.js +0 -176
- package/dist/hooks/registry.js.map +0 -1
- package/dist/hooks/types.js +0 -62
- package/dist/hooks/types.js.map +0 -1
- package/dist/hooks.js +0 -136
- package/dist/hooks.js.map +0 -1
- package/dist/init.js +0 -711
- package/dist/init.js.map +0 -1
- package/dist/inject/index.js +0 -82
- package/dist/inject/index.js.map +0 -1
- package/dist/injection.js +0 -343
- package/dist/injection.js.map +0 -1
- package/dist/intelligence/impact.js +0 -499
- package/dist/intelligence/impact.js.map +0 -1
- package/dist/intelligence/index.js +0 -17
- package/dist/intelligence/index.js.map +0 -1
- package/dist/intelligence/patterns.js +0 -492
- package/dist/intelligence/patterns.js.map +0 -1
- package/dist/intelligence/prediction.js +0 -499
- package/dist/intelligence/prediction.js.map +0 -1
- package/dist/intelligence/types.js +0 -13
- package/dist/intelligence/types.js.map +0 -1
- package/dist/internal.js +0 -258
- package/dist/internal.js.map +0 -1
- package/dist/issue/create.js +0 -121
- package/dist/issue/create.js.map +0 -1
- package/dist/issue/diagnostics.js +0 -59
- package/dist/issue/diagnostics.js.map +0 -1
- package/dist/issue/index.js +0 -10
- package/dist/issue/index.js.map +0 -1
- package/dist/issue/template-parser.js +0 -267
- package/dist/issue/template-parser.js.map +0 -1
- package/dist/json-schema-validator.js +0 -76
- package/dist/json-schema-validator.js.map +0 -1
- package/dist/lifecycle/chain-composition.js +0 -152
- package/dist/lifecycle/chain-composition.js.map +0 -1
- package/dist/lifecycle/chain-store.js +0 -246
- package/dist/lifecycle/chain-store.js.map +0 -1
- package/dist/lifecycle/consolidate-rcasd.js +0 -352
- package/dist/lifecycle/consolidate-rcasd.js.map +0 -1
- package/dist/lifecycle/default-chain.js +0 -167
- package/dist/lifecycle/default-chain.js.map +0 -1
- package/dist/lifecycle/evidence.js +0 -180
- package/dist/lifecycle/evidence.js.map +0 -1
- package/dist/lifecycle/frontmatter.js +0 -363
- package/dist/lifecycle/frontmatter.js.map +0 -1
- package/dist/lifecycle/index.js +0 -753
- package/dist/lifecycle/index.js.map +0 -1
- package/dist/lifecycle/pipeline.js +0 -656
- package/dist/lifecycle/pipeline.js.map +0 -1
- package/dist/lifecycle/rcasd-index.js +0 -326
- package/dist/lifecycle/rcasd-index.js.map +0 -1
- package/dist/lifecycle/rcasd-paths.js +0 -220
- package/dist/lifecycle/rcasd-paths.js.map +0 -1
- package/dist/lifecycle/resume.js +0 -864
- package/dist/lifecycle/resume.js.map +0 -1
- package/dist/lifecycle/stage-artifacts.js +0 -94
- package/dist/lifecycle/stage-artifacts.js.map +0 -1
- package/dist/lifecycle/stages.js +0 -534
- package/dist/lifecycle/stages.js.map +0 -1
- package/dist/lifecycle/state-machine.js +0 -516
- package/dist/lifecycle/state-machine.js.map +0 -1
- package/dist/lifecycle/tessera-engine.js +0 -249
- package/dist/lifecycle/tessera-engine.js.map +0 -1
- package/dist/logger.js +0 -140
- package/dist/logger.js.map +0 -1
- package/dist/mcp/index.js +0 -146
- package/dist/mcp/index.js.map +0 -1
- package/dist/memory/auto-extract.js +0 -143
- package/dist/memory/auto-extract.js.map +0 -1
- package/dist/memory/brain-embedding.js +0 -49
- package/dist/memory/brain-embedding.js.map +0 -1
- package/dist/memory/brain-lifecycle.js +0 -298
- package/dist/memory/brain-lifecycle.js.map +0 -1
- package/dist/memory/brain-links.js +0 -148
- package/dist/memory/brain-links.js.map +0 -1
- package/dist/memory/brain-migration.js +0 -149
- package/dist/memory/brain-migration.js.map +0 -1
- package/dist/memory/brain-reasoning.js +0 -215
- package/dist/memory/brain-reasoning.js.map +0 -1
- package/dist/memory/brain-retrieval.js +0 -474
- package/dist/memory/brain-retrieval.js.map +0 -1
- package/dist/memory/brain-row-types.js +0 -10
- package/dist/memory/brain-row-types.js.map +0 -1
- package/dist/memory/brain-search.js +0 -519
- package/dist/memory/brain-search.js.map +0 -1
- package/dist/memory/brain-similarity.js +0 -145
- package/dist/memory/brain-similarity.js.map +0 -1
- package/dist/memory/claude-mem-migration.js +0 -277
- package/dist/memory/claude-mem-migration.js.map +0 -1
- package/dist/memory/decisions.js +0 -148
- package/dist/memory/decisions.js.map +0 -1
- package/dist/memory/engine-compat.js +0 -1030
- package/dist/memory/engine-compat.js.map +0 -1
- package/dist/memory/index.js +0 -773
- package/dist/memory/index.js.map +0 -1
- package/dist/memory/learnings.js +0 -121
- package/dist/memory/learnings.js.map +0 -1
- package/dist/memory/memory-bridge.js +0 -289
- package/dist/memory/memory-bridge.js.map +0 -1
- package/dist/memory/patterns.js +0 -122
- package/dist/memory/patterns.js.map +0 -1
- package/dist/memory/pipeline-manifest-sqlite.js +0 -975
- package/dist/memory/pipeline-manifest-sqlite.js.map +0 -1
- package/dist/memory/session-memory.js +0 -226
- package/dist/memory/session-memory.js.map +0 -1
- package/dist/metrics/ab-test.js +0 -260
- package/dist/metrics/ab-test.js.map +0 -1
- package/dist/metrics/aggregation.js +0 -363
- package/dist/metrics/aggregation.js.map +0 -1
- package/dist/metrics/common.js +0 -64
- package/dist/metrics/common.js.map +0 -1
- package/dist/metrics/enums.js +0 -78
- package/dist/metrics/enums.js.map +0 -1
- package/dist/metrics/index.js +0 -19
- package/dist/metrics/index.js.map +0 -1
- package/dist/metrics/model-provider-registry.js +0 -88
- package/dist/metrics/model-provider-registry.js.map +0 -1
- package/dist/metrics/otel-integration.js +0 -263
- package/dist/metrics/otel-integration.js.map +0 -1
- package/dist/metrics/provider-detection.js +0 -103
- package/dist/metrics/provider-detection.js.map +0 -1
- package/dist/metrics/token-estimation.js +0 -253
- package/dist/metrics/token-estimation.js.map +0 -1
- package/dist/metrics/token-service.js +0 -450
- package/dist/metrics/token-service.js.map +0 -1
- package/dist/migration/agent-outputs.js +0 -316
- package/dist/migration/agent-outputs.js.map +0 -1
- package/dist/migration/checksum.js +0 -92
- package/dist/migration/checksum.js.map +0 -1
- package/dist/migration/index.js +0 -282
- package/dist/migration/index.js.map +0 -1
- package/dist/migration/logger.js +0 -360
- package/dist/migration/logger.js.map +0 -1
- package/dist/migration/preflight.js +0 -9
- package/dist/migration/preflight.js.map +0 -1
- package/dist/migration/state.js +0 -421
- package/dist/migration/state.js.map +0 -1
- package/dist/migration/validate.js +0 -241
- package/dist/migration/validate.js.map +0 -1
- package/dist/nexus/deps.js +0 -375
- package/dist/nexus/deps.js.map +0 -1
- package/dist/nexus/discover.js +0 -288
- package/dist/nexus/discover.js.map +0 -1
- package/dist/nexus/hash.js +0 -10
- package/dist/nexus/hash.js.map +0 -1
- package/dist/nexus/index.js +0 -38
- package/dist/nexus/index.js.map +0 -1
- package/dist/nexus/migrate-json-to-sqlite.js +0 -115
- package/dist/nexus/migrate-json-to-sqlite.js.map +0 -1
- package/dist/nexus/permissions.js +0 -105
- package/dist/nexus/permissions.js.map +0 -1
- package/dist/nexus/query.js +0 -175
- package/dist/nexus/query.js.map +0 -1
- package/dist/nexus/registry.js +0 -584
- package/dist/nexus/registry.js.map +0 -1
- package/dist/nexus/sharing/index.js +0 -179
- package/dist/nexus/sharing/index.js.map +0 -1
- package/dist/nexus/transfer-types.js +0 -8
- package/dist/nexus/transfer-types.js.map +0 -1
- package/dist/nexus/transfer.js +0 -263
- package/dist/nexus/transfer.js.map +0 -1
- package/dist/observability/index.js +0 -103
- package/dist/observability/index.js.map +0 -1
- package/dist/observability/log-filter.js +0 -63
- package/dist/observability/log-filter.js.map +0 -1
- package/dist/observability/log-parser.js +0 -99
- package/dist/observability/log-parser.js.map +0 -1
- package/dist/observability/log-reader.js +0 -139
- package/dist/observability/log-reader.js.map +0 -1
- package/dist/observability/types.js +0 -19
- package/dist/observability/types.js.map +0 -1
- package/dist/orchestration/analyze.js +0 -107
- package/dist/orchestration/analyze.js.map +0 -1
- package/dist/orchestration/bootstrap.js +0 -132
- package/dist/orchestration/bootstrap.js.map +0 -1
- package/dist/orchestration/context.js +0 -56
- package/dist/orchestration/context.js.map +0 -1
- package/dist/orchestration/critical-path.js +0 -100
- package/dist/orchestration/critical-path.js.map +0 -1
- package/dist/orchestration/index.js +0 -286
- package/dist/orchestration/index.js.map +0 -1
- package/dist/orchestration/parallel.js +0 -89
- package/dist/orchestration/parallel.js.map +0 -1
- package/dist/orchestration/protocol-validators.js +0 -524
- package/dist/orchestration/protocol-validators.js.map +0 -1
- package/dist/orchestration/skill-ops.js +0 -98
- package/dist/orchestration/skill-ops.js.map +0 -1
- package/dist/orchestration/status.js +0 -107
- package/dist/orchestration/status.js.map +0 -1
- package/dist/orchestration/unblock.js +0 -103
- package/dist/orchestration/unblock.js.map +0 -1
- package/dist/orchestration/validate-spawn.js +0 -67
- package/dist/orchestration/validate-spawn.js.map +0 -1
- package/dist/orchestration/waves.js +0 -86
- package/dist/orchestration/waves.js.map +0 -1
- package/dist/otel/index.js +0 -163
- package/dist/otel/index.js.map +0 -1
- package/dist/output.js +0 -132
- package/dist/output.js.map +0 -1
- package/dist/pagination.js +0 -61
- package/dist/pagination.js.map +0 -1
- package/dist/paths.js +0 -337
- package/dist/paths.js.map +0 -1
- package/dist/phases/deps.js +0 -369
- package/dist/phases/deps.js.map +0 -1
- package/dist/phases/index.js +0 -349
- package/dist/phases/index.js.map +0 -1
- package/dist/pipeline/index.js +0 -10
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/phase.js +0 -45
- package/dist/pipeline/phase.js.map +0 -1
- package/dist/platform.js +0 -211
- package/dist/platform.js.map +0 -1
- package/dist/project-info.js +0 -84
- package/dist/project-info.js.map +0 -1
- package/dist/reconciliation/index.js +0 -10
- package/dist/reconciliation/index.js.map +0 -1
- package/dist/reconciliation/link-store.js +0 -129
- package/dist/reconciliation/link-store.js.map +0 -1
- package/dist/reconciliation/reconciliation-engine.js +0 -298
- package/dist/reconciliation/reconciliation-engine.js.map +0 -1
- package/dist/release/artifacts.js +0 -427
- package/dist/release/artifacts.js.map +0 -1
- package/dist/release/changelog-writer.js +0 -151
- package/dist/release/changelog-writer.js.map +0 -1
- package/dist/release/channel.js +0 -144
- package/dist/release/channel.js.map +0 -1
- package/dist/release/ci.js +0 -166
- package/dist/release/ci.js.map +0 -1
- package/dist/release/github-pr.js +0 -225
- package/dist/release/github-pr.js.map +0 -1
- package/dist/release/guards.js +0 -116
- package/dist/release/guards.js.map +0 -1
- package/dist/release/index.js +0 -22
- package/dist/release/index.js.map +0 -1
- package/dist/release/release-config.js +0 -158
- package/dist/release/release-config.js.map +0 -1
- package/dist/release/release-manifest.js +0 -1019
- package/dist/release/release-manifest.js.map +0 -1
- package/dist/release/version-bump.js +0 -255
- package/dist/release/version-bump.js.map +0 -1
- package/dist/remote/index.js +0 -257
- package/dist/remote/index.js.map +0 -1
- package/dist/repair.js +0 -89
- package/dist/repair.js.map +0 -1
- package/dist/research/index.js +0 -2
- package/dist/research/index.js.map +0 -1
- package/dist/roadmap/index.js +0 -59
- package/dist/roadmap/index.js.map +0 -1
- package/dist/routing/capability-matrix.js +0 -1550
- package/dist/routing/capability-matrix.js.map +0 -1
- package/dist/routing/index.js +0 -9
- package/dist/routing/index.js.map +0 -1
- package/dist/scaffold.js +0 -1158
- package/dist/scaffold.js.map +0 -1
- package/dist/schema-management.js +0 -295
- package/dist/schema-management.js.map +0 -1
- package/dist/security/index.js +0 -9
- package/dist/security/index.js.map +0 -1
- package/dist/security/input-sanitization.js +0 -321
- package/dist/security/input-sanitization.js.map +0 -1
- package/dist/sequence/index.js +0 -295
- package/dist/sequence/index.js.map +0 -1
- package/dist/sessions/assumptions.js +0 -54
- package/dist/sessions/assumptions.js.map +0 -1
- package/dist/sessions/briefing.js +0 -377
- package/dist/sessions/briefing.js.map +0 -1
- package/dist/sessions/context-alert.js +0 -222
- package/dist/sessions/context-alert.js.map +0 -1
- package/dist/sessions/context-inject.js +0 -61
- package/dist/sessions/context-inject.js.map +0 -1
- package/dist/sessions/context-monitor.js +0 -98
- package/dist/sessions/context-monitor.js.map +0 -1
- package/dist/sessions/decisions.js +0 -65
- package/dist/sessions/decisions.js.map +0 -1
- package/dist/sessions/find.js +0 -63
- package/dist/sessions/find.js.map +0 -1
- package/dist/sessions/handoff.js +0 -328
- package/dist/sessions/handoff.js.map +0 -1
- package/dist/sessions/hitl-warnings.js +0 -254
- package/dist/sessions/hitl-warnings.js.map +0 -1
- package/dist/sessions/index.js +0 -318
- package/dist/sessions/index.js.map +0 -1
- package/dist/sessions/session-archive.js +0 -40
- package/dist/sessions/session-archive.js.map +0 -1
- package/dist/sessions/session-cleanup.js +0 -59
- package/dist/sessions/session-cleanup.js.map +0 -1
- package/dist/sessions/session-drift.js +0 -134
- package/dist/sessions/session-drift.js.map +0 -1
- package/dist/sessions/session-enforcement.js +0 -140
- package/dist/sessions/session-enforcement.js.map +0 -1
- package/dist/sessions/session-grade.js +0 -253
- package/dist/sessions/session-grade.js.map +0 -1
- package/dist/sessions/session-history.js +0 -42
- package/dist/sessions/session-history.js.map +0 -1
- package/dist/sessions/session-id.js +0 -81
- package/dist/sessions/session-id.js.map +0 -1
- package/dist/sessions/session-memory-bridge.js +0 -52
- package/dist/sessions/session-memory-bridge.js.map +0 -1
- package/dist/sessions/session-show.js +0 -24
- package/dist/sessions/session-show.js.map +0 -1
- package/dist/sessions/session-stats.js +0 -69
- package/dist/sessions/session-stats.js.map +0 -1
- package/dist/sessions/session-suspend.js +0 -39
- package/dist/sessions/session-suspend.js.map +0 -1
- package/dist/sessions/session-switch.js +0 -51
- package/dist/sessions/session-switch.js.map +0 -1
- package/dist/sessions/session-view.js +0 -76
- package/dist/sessions/session-view.js.map +0 -1
- package/dist/sessions/statusline-setup.js +0 -85
- package/dist/sessions/statusline-setup.js.map +0 -1
- package/dist/sessions/types.js +0 -8
- package/dist/sessions/types.js.map +0 -1
- package/dist/signaldock/claude-code-transport.js +0 -107
- package/dist/signaldock/claude-code-transport.js.map +0 -1
- package/dist/signaldock/factory.js +0 -25
- package/dist/signaldock/factory.js.map +0 -1
- package/dist/signaldock/index.js +0 -9
- package/dist/signaldock/index.js.map +0 -1
- package/dist/signaldock/signaldock-transport.js +0 -122
- package/dist/signaldock/signaldock-transport.js.map +0 -1
- package/dist/signaldock/transport.js +0 -11
- package/dist/signaldock/transport.js.map +0 -1
- package/dist/signaldock/types.js +0 -11
- package/dist/signaldock/types.js.map +0 -1
- package/dist/skills/agents/config.js +0 -94
- package/dist/skills/agents/config.js.map +0 -1
- package/dist/skills/agents/install.js +0 -116
- package/dist/skills/agents/install.js.map +0 -1
- package/dist/skills/agents/registry.js +0 -161
- package/dist/skills/agents/registry.js.map +0 -1
- package/dist/skills/discovery.js +0 -333
- package/dist/skills/discovery.js.map +0 -1
- package/dist/skills/dispatch.js +0 -347
- package/dist/skills/dispatch.js.map +0 -1
- package/dist/skills/dynamic-skill-generator.js +0 -100
- package/dist/skills/dynamic-skill-generator.js.map +0 -1
- package/dist/skills/index.js +0 -44
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/injection/subagent.js +0 -195
- package/dist/skills/injection/subagent.js.map +0 -1
- package/dist/skills/injection/token.js +0 -260
- package/dist/skills/injection/token.js.map +0 -1
- package/dist/skills/install.js +0 -40
- package/dist/skills/install.js.map +0 -1
- package/dist/skills/manifests/contribution.js +0 -175
- package/dist/skills/manifests/contribution.js.map +0 -1
- package/dist/skills/manifests/research.js +0 -281
- package/dist/skills/manifests/research.js.map +0 -1
- package/dist/skills/manifests/resolver.js +0 -146
- package/dist/skills/manifests/resolver.js.map +0 -1
- package/dist/skills/marketplace.js +0 -90
- package/dist/skills/marketplace.js.map +0 -1
- package/dist/skills/orchestrator/spawn.js +0 -178
- package/dist/skills/orchestrator/spawn.js.map +0 -1
- package/dist/skills/orchestrator/startup.js +0 -451
- package/dist/skills/orchestrator/startup.js.map +0 -1
- package/dist/skills/orchestrator/validator.js +0 -301
- package/dist/skills/orchestrator/validator.js.map +0 -1
- package/dist/skills/precedence-integration.js +0 -73
- package/dist/skills/precedence-integration.js.map +0 -1
- package/dist/skills/precedence-types.js +0 -16
- package/dist/skills/precedence-types.js.map +0 -1
- package/dist/skills/routing-table.js +0 -63
- package/dist/skills/routing-table.js.map +0 -1
- package/dist/skills/skill-paths.js +0 -220
- package/dist/skills/skill-paths.js.map +0 -1
- package/dist/skills/test-utility.js +0 -55
- package/dist/skills/test-utility.js.map +0 -1
- package/dist/skills/types.js +0 -118
- package/dist/skills/types.js.map +0 -1
- package/dist/skills/validation.js +0 -183
- package/dist/skills/validation.js.map +0 -1
- package/dist/skills/version.js +0 -57
- package/dist/skills/version.js.map +0 -1
- package/dist/snapshot/index.js +0 -188
- package/dist/snapshot/index.js.map +0 -1
- package/dist/spawn/adapter-registry.js +0 -246
- package/dist/spawn/adapter-registry.js.map +0 -1
- package/dist/spawn/index.js +0 -10
- package/dist/spawn/index.js.map +0 -1
- package/dist/stats/index.js +0 -339
- package/dist/stats/index.js.map +0 -1
- package/dist/sticky/archive.js +0 -47
- package/dist/sticky/archive.js.map +0 -1
- package/dist/sticky/convert.js +0 -235
- package/dist/sticky/convert.js.map +0 -1
- package/dist/sticky/create.js +0 -48
- package/dist/sticky/create.js.map +0 -1
- package/dist/sticky/id.js +0 -35
- package/dist/sticky/id.js.map +0 -1
- package/dist/sticky/index.js +0 -16
- package/dist/sticky/index.js.map +0 -1
- package/dist/sticky/list.js +0 -44
- package/dist/sticky/list.js.map +0 -1
- package/dist/sticky/purge.js +0 -45
- package/dist/sticky/purge.js.map +0 -1
- package/dist/sticky/show.js +0 -42
- package/dist/sticky/show.js.map +0 -1
- package/dist/sticky/types.js +0 -10
- package/dist/sticky/types.js.map +0 -1
- package/dist/store/atomic.js +0 -167
- package/dist/store/atomic.js.map +0 -1
- package/dist/store/backup.js +0 -94
- package/dist/store/backup.js.map +0 -1
- package/dist/store/brain-accessor.js +0 -397
- package/dist/store/brain-accessor.js.map +0 -1
- package/dist/store/brain-schema.js +0 -212
- package/dist/store/brain-schema.js.map +0 -1
- package/dist/store/brain-sqlite.js +0 -271
- package/dist/store/brain-sqlite.js.map +0 -1
- package/dist/store/cache.js +0 -168
- package/dist/store/cache.js.map +0 -1
- package/dist/store/chain-schema.js +0 -51
- package/dist/store/chain-schema.js.map +0 -1
- package/dist/store/converters.js +0 -120
- package/dist/store/converters.js.map +0 -1
- package/dist/store/data-accessor.js +0 -26
- package/dist/store/data-accessor.js.map +0 -1
- package/dist/store/data-safety-central.js +0 -269
- package/dist/store/data-safety-central.js.map +0 -1
- package/dist/store/data-safety.js +0 -274
- package/dist/store/data-safety.js.map +0 -1
- package/dist/store/db-helpers.js +0 -221
- package/dist/store/db-helpers.js.map +0 -1
- package/dist/store/export.js +0 -155
- package/dist/store/export.js.map +0 -1
- package/dist/store/file-utils.js +0 -270
- package/dist/store/file-utils.js.map +0 -1
- package/dist/store/git-checkpoint.js +0 -365
- package/dist/store/git-checkpoint.js.map +0 -1
- package/dist/store/import-logging.js +0 -139
- package/dist/store/import-logging.js.map +0 -1
- package/dist/store/import-remap.js +0 -145
- package/dist/store/import-remap.js.map +0 -1
- package/dist/store/import-sort.js +0 -121
- package/dist/store/import-sort.js.map +0 -1
- package/dist/store/index.js +0 -28
- package/dist/store/index.js.map +0 -1
- package/dist/store/json.js +0 -208
- package/dist/store/json.js.map +0 -1
- package/dist/store/lifecycle-store.js +0 -249
- package/dist/store/lifecycle-store.js.map +0 -1
- package/dist/store/lock.js +0 -70
- package/dist/store/lock.js.map +0 -1
- package/dist/store/migration-sqlite.js +0 -671
- package/dist/store/migration-sqlite.js.map +0 -1
- package/dist/store/nexus-schema.js +0 -62
- package/dist/store/nexus-schema.js.map +0 -1
- package/dist/store/nexus-sqlite.js +0 -217
- package/dist/store/nexus-sqlite.js.map +0 -1
- package/dist/store/nexus-validation-schemas.js +0 -40
- package/dist/store/nexus-validation-schemas.js.map +0 -1
- package/dist/store/parsers.js +0 -37
- package/dist/store/parsers.js.map +0 -1
- package/dist/store/project-detect.js +0 -457
- package/dist/store/project-detect.js.map +0 -1
- package/dist/store/provider.js +0 -101
- package/dist/store/provider.js.map +0 -1
- package/dist/store/safety-data-accessor.js +0 -243
- package/dist/store/safety-data-accessor.js.map +0 -1
- package/dist/store/schema.js +0 -7
- package/dist/store/schema.js.map +0 -1
- package/dist/store/session-store.js +0 -219
- package/dist/store/session-store.js.map +0 -1
- package/dist/store/sqlite-backup.js +0 -105
- package/dist/store/sqlite-backup.js.map +0 -1
- package/dist/store/sqlite-data-accessor.js +0 -742
- package/dist/store/sqlite-data-accessor.js.map +0 -1
- package/dist/store/sqlite.js +0 -489
- package/dist/store/sqlite.js.map +0 -1
- package/dist/store/status-registry.js +0 -8
- package/dist/store/status-registry.js.map +0 -1
- package/dist/store/task-store.js +0 -344
- package/dist/store/task-store.js.map +0 -1
- package/dist/store/tasks-schema.js +0 -574
- package/dist/store/tasks-schema.js.map +0 -1
- package/dist/store/typed-query.js +0 -15
- package/dist/store/typed-query.js.map +0 -1
- package/dist/store/validation-schemas.js +0 -278
- package/dist/store/validation-schemas.js.map +0 -1
- package/dist/system/archive-analytics.js +0 -277
- package/dist/system/archive-analytics.js.map +0 -1
- package/dist/system/archive-stats.js +0 -64
- package/dist/system/archive-stats.js.map +0 -1
- package/dist/system/audit.js +0 -145
- package/dist/system/audit.js.map +0 -1
- package/dist/system/backup.js +0 -99
- package/dist/system/backup.js.map +0 -1
- package/dist/system/cleanup.js +0 -134
- package/dist/system/cleanup.js.map +0 -1
- package/dist/system/health.js +0 -1054
- package/dist/system/health.js.map +0 -1
- package/dist/system/index.js +0 -18
- package/dist/system/index.js.map +0 -1
- package/dist/system/inject-generate.js +0 -122
- package/dist/system/inject-generate.js.map +0 -1
- package/dist/system/labels.js +0 -38
- package/dist/system/labels.js.map +0 -1
- package/dist/system/metrics.js +0 -61
- package/dist/system/metrics.js.map +0 -1
- package/dist/system/migrate.js +0 -43
- package/dist/system/migrate.js.map +0 -1
- package/dist/system/platform-paths.js +0 -80
- package/dist/system/platform-paths.js.map +0 -1
- package/dist/system/runtime.js +0 -161
- package/dist/system/runtime.js.map +0 -1
- package/dist/system/safestop.js +0 -99
- package/dist/system/safestop.js.map +0 -1
- package/dist/system/storage-preflight.js +0 -123
- package/dist/system/storage-preflight.js.map +0 -1
- package/dist/task-work/index.js +0 -155
- package/dist/task-work/index.js.map +0 -1
- package/dist/tasks/add.js +0 -510
- package/dist/tasks/add.js.map +0 -1
- package/dist/tasks/analyze.js +0 -85
- package/dist/tasks/analyze.js.map +0 -1
- package/dist/tasks/archive.js +0 -90
- package/dist/tasks/archive.js.map +0 -1
- package/dist/tasks/atomicity.js +0 -83
- package/dist/tasks/atomicity.js.map +0 -1
- package/dist/tasks/cancel-ops.js +0 -83
- package/dist/tasks/cancel-ops.js.map +0 -1
- package/dist/tasks/complete.js +0 -224
- package/dist/tasks/complete.js.map +0 -1
- package/dist/tasks/crossref-extract.js +0 -73
- package/dist/tasks/crossref-extract.js.map +0 -1
- package/dist/tasks/delete-preview.js +0 -192
- package/dist/tasks/delete-preview.js.map +0 -1
- package/dist/tasks/delete.js +0 -120
- package/dist/tasks/delete.js.map +0 -1
- package/dist/tasks/deletion-strategy.js +0 -200
- package/dist/tasks/deletion-strategy.js.map +0 -1
- package/dist/tasks/dependency-check.js +0 -278
- package/dist/tasks/dependency-check.js.map +0 -1
- package/dist/tasks/deps-ready.js +0 -32
- package/dist/tasks/deps-ready.js.map +0 -1
- package/dist/tasks/enforcement.js +0 -82
- package/dist/tasks/enforcement.js.map +0 -1
- package/dist/tasks/find.js +0 -148
- package/dist/tasks/find.js.map +0 -1
- package/dist/tasks/graph-cache.js +0 -127
- package/dist/tasks/graph-cache.js.map +0 -1
- package/dist/tasks/graph-ops.js +0 -171
- package/dist/tasks/graph-ops.js.map +0 -1
- package/dist/tasks/graph-rag.js +0 -328
- package/dist/tasks/graph-rag.js.map +0 -1
- package/dist/tasks/hierarchy-policy.js +0 -149
- package/dist/tasks/hierarchy-policy.js.map +0 -1
- package/dist/tasks/hierarchy.js +0 -185
- package/dist/tasks/hierarchy.js.map +0 -1
- package/dist/tasks/id-generator.js +0 -65
- package/dist/tasks/id-generator.js.map +0 -1
- package/dist/tasks/index.js +0 -14
- package/dist/tasks/index.js.map +0 -1
- package/dist/tasks/labels.js +0 -52
- package/dist/tasks/labels.js.map +0 -1
- package/dist/tasks/list.js +0 -68
- package/dist/tasks/list.js.map +0 -1
- package/dist/tasks/phase-tracking.js +0 -133
- package/dist/tasks/phase-tracking.js.map +0 -1
- package/dist/tasks/plan.js +0 -268
- package/dist/tasks/plan.js.map +0 -1
- package/dist/tasks/relates.js +0 -89
- package/dist/tasks/relates.js.map +0 -1
- package/dist/tasks/reparent.d.ts +0 -38
- package/dist/tasks/reparent.d.ts.map +0 -1
- package/dist/tasks/show.js +0 -78
- package/dist/tasks/show.js.map +0 -1
- package/dist/tasks/size-weighting.js +0 -86
- package/dist/tasks/size-weighting.js.map +0 -1
- package/dist/tasks/staleness.js +0 -86
- package/dist/tasks/staleness.js.map +0 -1
- package/dist/tasks/task-ops.js +0 -1340
- package/dist/tasks/task-ops.js.map +0 -1
- package/dist/tasks/update.js +0 -243
- package/dist/tasks/update.js.map +0 -1
- package/dist/templates/index.js +0 -10
- package/dist/templates/index.js.map +0 -1
- package/dist/templates/parser.js +0 -254
- package/dist/templates/parser.js.map +0 -1
- package/dist/ui/aliases.js +0 -153
- package/dist/ui/aliases.js.map +0 -1
- package/dist/ui/changelog.js +0 -184
- package/dist/ui/changelog.js.map +0 -1
- package/dist/ui/command-registry.js +0 -168
- package/dist/ui/command-registry.js.map +0 -1
- package/dist/ui/flags.js +0 -94
- package/dist/ui/flags.js.map +0 -1
- package/dist/ui/index.js +0 -24
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/injection-legacy.d.ts +0 -26
- package/dist/ui/injection-legacy.d.ts.map +0 -1
- package/dist/ui/injection-legacy.js +0 -42
- package/dist/ui/injection-legacy.js.map +0 -1
- package/dist/upgrade.js +0 -901
- package/dist/upgrade.js.map +0 -1
- package/dist/validation/chain-validation.js +0 -146
- package/dist/validation/chain-validation.js.map +0 -1
- package/dist/validation/compliance.js +0 -155
- package/dist/validation/compliance.js.map +0 -1
- package/dist/validation/docs-sync.js +0 -212
- package/dist/validation/docs-sync.js.map +0 -1
- package/dist/validation/doctor/checks.js +0 -1069
- package/dist/validation/doctor/checks.js.map +0 -1
- package/dist/validation/doctor/index.js +0 -9
- package/dist/validation/doctor/index.js.map +0 -1
- package/dist/validation/doctor/project-cache.js +0 -160
- package/dist/validation/doctor/project-cache.js.map +0 -1
- package/dist/validation/doctor/utils.js +0 -155
- package/dist/validation/doctor/utils.js.map +0 -1
- package/dist/validation/engine.js +0 -902
- package/dist/validation/engine.js.map +0 -1
- package/dist/validation/gap-check.js +0 -175
- package/dist/validation/gap-check.js.map +0 -1
- package/dist/validation/index.js +0 -40
- package/dist/validation/index.js.map +0 -1
- package/dist/validation/manifest.js +0 -237
- package/dist/validation/manifest.js.map +0 -1
- package/dist/validation/operation-gate-validators.js +0 -724
- package/dist/validation/operation-gate-validators.js.map +0 -1
- package/dist/validation/operation-verification-gates.js +0 -532
- package/dist/validation/operation-verification-gates.js.map +0 -1
- package/dist/validation/param-utils.js +0 -139
- package/dist/validation/param-utils.js.map +0 -1
- package/dist/validation/protocol-common.js +0 -300
- package/dist/validation/protocol-common.js.map +0 -1
- package/dist/validation/protocols/consensus.js +0 -71
- package/dist/validation/protocols/consensus.js.map +0 -1
- package/dist/validation/protocols/contribution.js +0 -59
- package/dist/validation/protocols/contribution.js.map +0 -1
- package/dist/validation/protocols/decomposition.js +0 -59
- package/dist/validation/protocols/decomposition.js.map +0 -1
- package/dist/validation/protocols/implementation.js +0 -59
- package/dist/validation/protocols/implementation.js.map +0 -1
- package/dist/validation/protocols/release-protocol.js +0 -60
- package/dist/validation/protocols/release-protocol.js.map +0 -1
- package/dist/validation/protocols/research.js +0 -77
- package/dist/validation/protocols/research.js.map +0 -1
- package/dist/validation/protocols/specification.js +0 -84
- package/dist/validation/protocols/specification.js.map +0 -1
- package/dist/validation/protocols/testing-protocol.js +0 -70
- package/dist/validation/protocols/testing-protocol.js.map +0 -1
- package/dist/validation/protocols/validation-protocol.js +0 -70
- package/dist/validation/protocols/validation-protocol.js.map +0 -1
- package/dist/validation/schema-integrity.js +0 -170
- package/dist/validation/schema-integrity.js.map +0 -1
- package/dist/validation/schema-validator.js +0 -176
- package/dist/validation/schema-validator.js.map +0 -1
- package/dist/validation/validate-ops.js +0 -937
- package/dist/validation/validate-ops.js.map +0 -1
- package/dist/validation/validation-rules.js +0 -226
- package/dist/validation/validation-rules.js.map +0 -1
- package/dist/validation/verification.js +0 -321
- package/dist/validation/verification.js.map +0 -1
package/src/lib/retry.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* General-purpose retry utility with exponential backoff.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a shared, dependency-free retry primitive for use
|
|
5
|
+
* anywhere in the CLEO core. Unlike the agent-specific retry in
|
|
6
|
+
* `agents/retry.ts`, this utility has no database coupling and is safe to
|
|
7
|
+
* import from any layer.
|
|
8
|
+
*
|
|
9
|
+
* Default schedule (3 attempts, task T040 spec):
|
|
10
|
+
* - Attempt 1: immediate (0 ms delay before retry)
|
|
11
|
+
* - Attempt 2: 2 000 ms delay before retry
|
|
12
|
+
* - Attempt 3: 4 000 ms delay before retry
|
|
13
|
+
* - After attempt 3: throw last error
|
|
14
|
+
*
|
|
15
|
+
* @module lib/retry
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Types
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A predicate or pattern used to decide whether an error is retryable.
|
|
24
|
+
*
|
|
25
|
+
* - `RegExp` — matched against `error.message` (or `String(error)`)
|
|
26
|
+
* - `(error: unknown) => boolean` — arbitrary predicate function
|
|
27
|
+
*/
|
|
28
|
+
export type RetryablePredicate = RegExp | ((error: unknown) => boolean);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options that control retry behavior for {@link withRetry}.
|
|
32
|
+
*/
|
|
33
|
+
export interface RetryOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Maximum total number of attempts (initial + retries).
|
|
36
|
+
*
|
|
37
|
+
* @default 3
|
|
38
|
+
*/
|
|
39
|
+
maxAttempts?: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Delay before the second attempt in milliseconds.
|
|
43
|
+
* Each subsequent delay is `baseDelayMs * 2^(attempt - 1)`.
|
|
44
|
+
*
|
|
45
|
+
* @default 2000
|
|
46
|
+
*/
|
|
47
|
+
baseDelayMs?: number;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Upper bound on computed delay in milliseconds.
|
|
51
|
+
* Prevents unbounded growth with many retries.
|
|
52
|
+
*
|
|
53
|
+
* @default 30000
|
|
54
|
+
*/
|
|
55
|
+
maxDelayMs?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Explicit list of patterns or predicates that identify retryable errors.
|
|
59
|
+
*
|
|
60
|
+
* When provided, ONLY errors matching at least one entry are retried.
|
|
61
|
+
* Errors that match none of the entries cause immediate failure.
|
|
62
|
+
*
|
|
63
|
+
* When omitted, all errors are treated as retryable (up to `maxAttempts`).
|
|
64
|
+
*/
|
|
65
|
+
retryableErrors?: ReadonlyArray<RetryablePredicate>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Metadata attached to errors thrown after all retry attempts are exhausted.
|
|
70
|
+
*
|
|
71
|
+
* The last error from the final attempt is augmented with these fields so
|
|
72
|
+
* callers can distinguish a retry-exhausted failure from a first-attempt one.
|
|
73
|
+
*/
|
|
74
|
+
export interface RetryContext {
|
|
75
|
+
/** Total number of attempts made (always equal to `maxAttempts`). */
|
|
76
|
+
attempts: number;
|
|
77
|
+
/** Cumulative delay applied across all retry waits in milliseconds. */
|
|
78
|
+
totalDelayMs: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Public API
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Execute an async function with automatic retry and exponential backoff.
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* The function is called up to `maxAttempts` times. After the first failure,
|
|
90
|
+
* the utility waits `baseDelayMs` milliseconds, then retries. Each subsequent
|
|
91
|
+
* wait doubles: `baseDelayMs * 2^(attempt - 1)`, capped at `maxDelayMs`.
|
|
92
|
+
*
|
|
93
|
+
* If `retryableErrors` is supplied, only errors matching at least one entry
|
|
94
|
+
* are retried; other errors cause immediate re-throw.
|
|
95
|
+
*
|
|
96
|
+
* On final failure the original error is re-thrown. Use {@link RetryContext}
|
|
97
|
+
* fields (attached to the error) to inspect retry metadata.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* // Basic usage — 3 attempts with 0 ms / 2 000 ms / 4 000 ms delays
|
|
102
|
+
* const data = await withRetry(() => fetchFromApi());
|
|
103
|
+
*
|
|
104
|
+
* // Custom retry window — only on network errors
|
|
105
|
+
* const result = await withRetry(
|
|
106
|
+
* () => db.query(sql),
|
|
107
|
+
* {
|
|
108
|
+
* maxAttempts: 5,
|
|
109
|
+
* baseDelayMs: 500,
|
|
110
|
+
* retryableErrors: [/SQLITE_BUSY/, /database is locked/i],
|
|
111
|
+
* },
|
|
112
|
+
* );
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @typeParam T - The resolved type of the async function
|
|
116
|
+
* @param fn - Async factory that is called on each attempt.
|
|
117
|
+
* @param options - Optional retry configuration.
|
|
118
|
+
* @returns Resolved value of `fn` on success.
|
|
119
|
+
* @throws The last error thrown by `fn`, augmented with {@link RetryContext}
|
|
120
|
+
* fields (`attempts`, `totalDelayMs`).
|
|
121
|
+
*/
|
|
122
|
+
export async function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {
|
|
123
|
+
const maxAttempts = options?.maxAttempts ?? 3;
|
|
124
|
+
const baseDelayMs = options?.baseDelayMs ?? 2_000;
|
|
125
|
+
const maxDelayMs = options?.maxDelayMs ?? 30_000;
|
|
126
|
+
const retryableErrors = options?.retryableErrors;
|
|
127
|
+
|
|
128
|
+
let lastError: unknown;
|
|
129
|
+
let totalDelayMs = 0;
|
|
130
|
+
|
|
131
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
132
|
+
try {
|
|
133
|
+
return await fn();
|
|
134
|
+
} catch (err) {
|
|
135
|
+
lastError = err;
|
|
136
|
+
|
|
137
|
+
const isLastAttempt = attempt === maxAttempts;
|
|
138
|
+
if (isLastAttempt) break;
|
|
139
|
+
|
|
140
|
+
// If a filter list is provided, only retry matching errors.
|
|
141
|
+
if (retryableErrors !== undefined && !isRetryable(err, retryableErrors)) break;
|
|
142
|
+
|
|
143
|
+
const delay = computeDelay(attempt, baseDelayMs, maxDelayMs);
|
|
144
|
+
totalDelayMs += delay;
|
|
145
|
+
await sleep(delay);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Augment last error with retry context before re-throwing.
|
|
150
|
+
const context: RetryContext = { attempts: maxAttempts, totalDelayMs };
|
|
151
|
+
augmentError(lastError, context);
|
|
152
|
+
throw lastError;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ============================================================================
|
|
156
|
+
// Delay helpers (exported for unit testing)
|
|
157
|
+
// ============================================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Compute the wait time before the next attempt.
|
|
161
|
+
*
|
|
162
|
+
* @remarks
|
|
163
|
+
* Formula: `min(baseDelayMs * 2^(attempt - 1), maxDelayMs)`.
|
|
164
|
+
* On the first retry (`attempt === 1`) the delay is `baseDelayMs * 1 = baseDelayMs`.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* computeDelay(1, 2000, 30000); // 2000
|
|
169
|
+
* computeDelay(2, 2000, 30000); // 4000
|
|
170
|
+
* computeDelay(3, 2000, 30000); // 8000
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @param attempt - The 1-based attempt number that just failed.
|
|
174
|
+
* @param baseDelayMs - Base delay in milliseconds.
|
|
175
|
+
* @param maxDelayMs - Maximum allowed delay in milliseconds.
|
|
176
|
+
* @returns Delay in milliseconds before the next attempt.
|
|
177
|
+
*/
|
|
178
|
+
export function computeDelay(attempt: number, baseDelayMs: number, maxDelayMs: number): number {
|
|
179
|
+
const exponential = baseDelayMs * 2 ** (attempt - 1);
|
|
180
|
+
return Math.min(exponential, maxDelayMs);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Internal helpers
|
|
185
|
+
// ============================================================================
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Test whether an error matches at least one retryable predicate.
|
|
189
|
+
*
|
|
190
|
+
* @param err - The caught error.
|
|
191
|
+
* @param predicates - List of `RegExp` or predicate functions.
|
|
192
|
+
* @returns `true` if the error is retryable.
|
|
193
|
+
*/
|
|
194
|
+
function isRetryable(err: unknown, predicates: ReadonlyArray<RetryablePredicate>): boolean {
|
|
195
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
196
|
+
return predicates.some((predicate) => {
|
|
197
|
+
if (predicate instanceof RegExp) return predicate.test(message);
|
|
198
|
+
return predicate(err);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Attach `RetryContext` fields to an error value in-place when possible.
|
|
204
|
+
* Falls back gracefully for non-Error thrown values.
|
|
205
|
+
*
|
|
206
|
+
* @param err - The value to augment.
|
|
207
|
+
* @param context - Retry metadata to attach.
|
|
208
|
+
*/
|
|
209
|
+
function augmentError(err: unknown, context: RetryContext): void {
|
|
210
|
+
if (err instanceof Error) {
|
|
211
|
+
const mutableErr = err as Error & Partial<RetryContext>;
|
|
212
|
+
mutableErr.attempts = context.attempts;
|
|
213
|
+
mutableErr.totalDelayMs = context.totalDelayMs;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Promisified `setTimeout` for testability.
|
|
219
|
+
*
|
|
220
|
+
* @param ms - Duration in milliseconds.
|
|
221
|
+
*/
|
|
222
|
+
function sleep(ms: number): Promise<void> {
|
|
223
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
224
|
+
}
|
|
@@ -14,14 +14,42 @@ import { join, relative } from 'node:path';
|
|
|
14
14
|
import type { SharingConfig } from '@cleocode/contracts';
|
|
15
15
|
import { loadConfig } from '../../config.js';
|
|
16
16
|
import { getCleoDirAbsolute, getProjectRoot } from '../../paths.js';
|
|
17
|
+
import { cleoGitCommand, isCleoGitInitialized } from '../../store/git-checkpoint.js';
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Result of a sharing status check.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Provides a complete view of which `.cleo/` files are tracked vs ignored under
|
|
24
|
+
* the current sharing config, plus git sync state for Nexus multi-project visibility.
|
|
25
|
+
* The `hasGit`, `remotes`, `pendingChanges`, and `lastSync` fields are populated
|
|
26
|
+
* only when a `.cleo/.git` repo exists; otherwise they carry safe defaults.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const status = await getSharingStatus();
|
|
31
|
+
* if (status.hasGit && status.pendingChanges) {
|
|
32
|
+
* console.log('Uncommitted changes in .cleo/ — run: cleo checkpoint');
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
19
36
|
export interface SharingStatus {
|
|
20
37
|
mode: string;
|
|
21
38
|
allowlist: string[];
|
|
22
39
|
denylist: string[];
|
|
23
40
|
tracked: string[];
|
|
24
41
|
ignored: string[];
|
|
42
|
+
/** Whether the `.cleo/.git` isolated repo exists and is initialized. */
|
|
43
|
+
hasGit: boolean;
|
|
44
|
+
/** Git remote names configured in `.cleo/.git` (e.g. `['origin']`). */
|
|
45
|
+
remotes: string[];
|
|
46
|
+
/** Whether the `.cleo/.git` working tree has uncommitted changes. */
|
|
47
|
+
pendingChanges: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* ISO 8601 timestamp of the last push or pull to/from a remote, or `null`
|
|
50
|
+
* if no remote sync has ever occurred.
|
|
51
|
+
*/
|
|
52
|
+
lastSync: string | null;
|
|
25
53
|
}
|
|
26
54
|
|
|
27
55
|
/** Markers for the managed section in .gitignore. */
|
|
@@ -104,8 +132,102 @@ function collectCleoFiles(cleoDir: string): string[] {
|
|
|
104
132
|
}
|
|
105
133
|
|
|
106
134
|
/**
|
|
107
|
-
*
|
|
135
|
+
* Retrieve the names of git remotes configured in the `.cleo/.git` repo.
|
|
136
|
+
*
|
|
137
|
+
* @remarks
|
|
138
|
+
* Returns an empty array if the repo is not initialized or has no remotes.
|
|
139
|
+
* Errors are suppressed — callers should treat an empty array as "no remotes known".
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const remotes = await getCleoGitRemotes('/path/to/project/.cleo');
|
|
144
|
+
* // ['origin']
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
async function getCleoGitRemotes(cleoDir: string): Promise<string[]> {
|
|
148
|
+
const result = await cleoGitCommand(['remote'], cleoDir);
|
|
149
|
+
if (!result.success || !result.stdout) return [];
|
|
150
|
+
return result.stdout
|
|
151
|
+
.split('\n')
|
|
152
|
+
.map((r) => r.trim())
|
|
153
|
+
.filter(Boolean);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Determine whether the `.cleo/.git` working tree has any uncommitted changes.
|
|
158
|
+
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* Uses `git status --porcelain`. A non-empty output means pending changes exist.
|
|
161
|
+
* Returns `false` if the repo is not initialized or the command fails.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const dirty = await hasCleoGitPendingChanges('/path/to/project/.cleo');
|
|
166
|
+
* // true if any files are modified/untracked
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
async function hasCleoGitPendingChanges(cleoDir: string): Promise<boolean> {
|
|
170
|
+
const result = await cleoGitCommand(['status', '--porcelain'], cleoDir);
|
|
171
|
+
if (!result.success) return false;
|
|
172
|
+
return result.stdout.length > 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Read the ISO 8601 timestamp of the last push or pull recorded in the reflog.
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* Scans the git reflog for `fetch` or `push` entries and returns the committer
|
|
180
|
+
* date of the most recent one. Returns `null` if no push/pull has occurred or
|
|
181
|
+
* if the repo has no commits yet.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const lastSync = await getLastSyncTimestamp('/path/to/project/.cleo');
|
|
186
|
+
* // '2026-03-21T18:00:00.000Z' or null
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
async function getLastSyncTimestamp(cleoDir: string): Promise<string | null> {
|
|
190
|
+
// The reflog format: `%gd %gs %ci` — reflog selector, subject, committer ISO date
|
|
191
|
+
const result = await cleoGitCommand(['reflog', '--format=%gs %ci', 'HEAD'], cleoDir);
|
|
192
|
+
if (!result.success || !result.stdout) return null;
|
|
193
|
+
|
|
194
|
+
for (const line of result.stdout.split('\n')) {
|
|
195
|
+
const trimmed = line.trim();
|
|
196
|
+
// Match lines describing a fetch or push action (e.g. "fetch origin: fast-forward")
|
|
197
|
+
if (/^(fetch|push|pull)\b/i.test(trimmed)) {
|
|
198
|
+
// The date is everything after the action description — last ISO-like token
|
|
199
|
+
const isoMatch = trimmed.match(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4})$/);
|
|
200
|
+
if (isoMatch?.[1]) {
|
|
201
|
+
return new Date(isoMatch[1]).toISOString();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get the sharing status: which .cleo/ files are tracked vs ignored,
|
|
211
|
+
* plus git sync state for Nexus multi-project visibility.
|
|
212
|
+
*
|
|
213
|
+
* @remarks
|
|
214
|
+
* Populates `hasGit`, `remotes`, `pendingChanges`, and `lastSync` by inspecting
|
|
215
|
+
* the `.cleo/.git` isolated repo when it exists. All git operations are
|
|
216
|
+
* non-fatal — if the repo is absent or a command fails, the fields carry safe
|
|
217
|
+
* defaults (`false`, `[]`, `null`).
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* const status = await getSharingStatus('/path/to/project');
|
|
222
|
+
* console.log(status.mode); // 'project'
|
|
223
|
+
* console.log(status.hasGit); // true
|
|
224
|
+
* console.log(status.remotes); // ['origin']
|
|
225
|
+
* console.log(status.pendingChanges); // false
|
|
226
|
+
* console.log(status.lastSync); // '2026-03-21T18:00:00.000Z'
|
|
227
|
+
* ```
|
|
228
|
+
*
|
|
108
229
|
* @task T4883
|
|
230
|
+
* @task T110
|
|
109
231
|
*/
|
|
110
232
|
export async function getSharingStatus(cwd?: string): Promise<SharingStatus> {
|
|
111
233
|
const config = await loadConfig(cwd);
|
|
@@ -126,12 +248,30 @@ export async function getSharingStatus(cwd?: string): Promise<SharingStatus> {
|
|
|
126
248
|
}
|
|
127
249
|
}
|
|
128
250
|
|
|
251
|
+
// Populate git sync fields
|
|
252
|
+
const hasGit = isCleoGitInitialized(cleoDir);
|
|
253
|
+
let remotes: string[] = [];
|
|
254
|
+
let pendingChanges = false;
|
|
255
|
+
let lastSync: string | null = null;
|
|
256
|
+
|
|
257
|
+
if (hasGit) {
|
|
258
|
+
[remotes, pendingChanges, lastSync] = await Promise.all([
|
|
259
|
+
getCleoGitRemotes(cleoDir),
|
|
260
|
+
hasCleoGitPendingChanges(cleoDir),
|
|
261
|
+
getLastSyncTimestamp(cleoDir),
|
|
262
|
+
]);
|
|
263
|
+
}
|
|
264
|
+
|
|
129
265
|
return {
|
|
130
266
|
mode: sharing.mode,
|
|
131
267
|
allowlist: sharing.commitAllowlist,
|
|
132
268
|
denylist: sharing.denylist,
|
|
133
269
|
tracked,
|
|
134
270
|
ignored,
|
|
271
|
+
hasGit,
|
|
272
|
+
remotes,
|
|
273
|
+
pendingChanges,
|
|
274
|
+
lastSync,
|
|
135
275
|
};
|
|
136
276
|
}
|
|
137
277
|
|
|
@@ -229,6 +229,21 @@ function gradeFromScore(score: number): string {
|
|
|
229
229
|
* WF-003: Completed tasks SHOULD have verification gates set (T061)
|
|
230
230
|
* WF-004: Tasks with verification SHOULD have all 3 gates set
|
|
231
231
|
* WF-005: Tasks MUST have session binding on creation (non-epic)
|
|
232
|
+
*
|
|
233
|
+
* @remarks
|
|
234
|
+
* Derives all metrics from existing audit_log and tasks tables — no new
|
|
235
|
+
* tracking infrastructure is required.
|
|
236
|
+
*
|
|
237
|
+
* @param opts - Report options
|
|
238
|
+
* @param opts.since - ISO 8601 date string to filter metrics from
|
|
239
|
+
* @param opts.cwd - Working directory for database resolution
|
|
240
|
+
* @returns Compliance report with per-rule pass/fail counts and overall rate
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```ts
|
|
244
|
+
* const report = await getWorkflowComplianceReport({ cwd: '/my/project' });
|
|
245
|
+
* console.log(report.overall.passRate); // e.g. 0.85
|
|
246
|
+
* ```
|
|
232
247
|
*/
|
|
233
248
|
export async function getWorkflowComplianceReport(opts: {
|
|
234
249
|
since?: string;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @epic T4638
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import type { Session } from '@cleocode/contracts';
|
|
@@ -404,9 +404,27 @@ describe('SQLite session-store', () => {
|
|
|
404
404
|
const db = await getDb();
|
|
405
405
|
db.insert(tasksTable)
|
|
406
406
|
.values([
|
|
407
|
-
{
|
|
408
|
-
|
|
409
|
-
|
|
407
|
+
{
|
|
408
|
+
id: 'T001',
|
|
409
|
+
title: 'Task T001',
|
|
410
|
+
status: 'pending',
|
|
411
|
+
priority: 'medium',
|
|
412
|
+
createdAt: new Date().toISOString(),
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
id: 'T002',
|
|
416
|
+
title: 'Task T002',
|
|
417
|
+
status: 'pending',
|
|
418
|
+
priority: 'medium',
|
|
419
|
+
createdAt: new Date().toISOString(),
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
id: 'T003',
|
|
423
|
+
title: 'Task T003',
|
|
424
|
+
status: 'pending',
|
|
425
|
+
priority: 'medium',
|
|
426
|
+
createdAt: new Date().toISOString(),
|
|
427
|
+
},
|
|
410
428
|
])
|
|
411
429
|
.run();
|
|
412
430
|
await createSession(makeSession({ id: 'sess-001' }));
|
|
@@ -430,9 +448,27 @@ describe('SQLite session-store', () => {
|
|
|
430
448
|
const db = await getDb();
|
|
431
449
|
db.insert(tasksTable)
|
|
432
450
|
.values([
|
|
433
|
-
{
|
|
434
|
-
|
|
435
|
-
|
|
451
|
+
{
|
|
452
|
+
id: 'T001',
|
|
453
|
+
title: 'Task T001',
|
|
454
|
+
status: 'pending',
|
|
455
|
+
priority: 'medium',
|
|
456
|
+
createdAt: new Date().toISOString(),
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
id: 'T002',
|
|
460
|
+
title: 'Task T002',
|
|
461
|
+
status: 'pending',
|
|
462
|
+
priority: 'medium',
|
|
463
|
+
createdAt: new Date().toISOString(),
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
id: 'T003',
|
|
467
|
+
title: 'Task T003',
|
|
468
|
+
status: 'pending',
|
|
469
|
+
priority: 'medium',
|
|
470
|
+
createdAt: new Date().toISOString(),
|
|
471
|
+
},
|
|
436
472
|
])
|
|
437
473
|
.run();
|
|
438
474
|
await createSession(makeSession({ id: 'sess-001' }));
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @epic T4638
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import type { Task } from '@cleocode/contracts';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @task T5244
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import type { Task } from '@cleocode/contracts';
|
|
@@ -57,7 +57,9 @@ export async function createTestDb(): Promise<TestDbEnv> {
|
|
|
57
57
|
const { readdirSync } = await import('node:fs');
|
|
58
58
|
const contents = readdirSync(cleoDir);
|
|
59
59
|
if (!contents.includes('config.json')) {
|
|
60
|
-
throw new Error(
|
|
60
|
+
throw new Error(
|
|
61
|
+
`createTestDb: config.json not found in ${cleoDir} after write (contents: ${JSON.stringify(contents)})`,
|
|
62
|
+
);
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
const accessor = await createSqliteDataAccessor(tempDir);
|
|
@@ -66,7 +68,9 @@ export async function createTestDb(): Promise<TestDbEnv> {
|
|
|
66
68
|
const { readdirSync: readdirSync2 } = await import('node:fs');
|
|
67
69
|
const contentsAfterDb = readdirSync2(cleoDir);
|
|
68
70
|
if (!contentsAfterDb.includes('config.json')) {
|
|
69
|
-
throw new Error(
|
|
71
|
+
throw new Error(
|
|
72
|
+
`createTestDb: config.json DELETED by createSqliteDataAccessor! ${cleoDir}: ${JSON.stringify(contentsAfterDb)}`,
|
|
73
|
+
);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
return {
|
|
@@ -26,8 +26,17 @@ import { getBrainDb } from './brain-sqlite.js';
|
|
|
26
26
|
* This is a best-effort cleanup — brain.db is a cognitive store and minor
|
|
27
27
|
* staleness is preferable to failing task deletions due to brain.db errors.
|
|
28
28
|
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* Best-effort: failures in brain.db cleanup do not propagate to the caller.
|
|
31
|
+
* A background reconciliation pass can clean up any residual stale refs.
|
|
32
|
+
*
|
|
29
33
|
* @param taskId - The ID of the task being deleted from tasks.db
|
|
30
34
|
* @param cwd - Optional working directory
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* await cleanupBrainRefsOnTaskDelete('T042');
|
|
39
|
+
* ```
|
|
31
40
|
*/
|
|
32
41
|
export async function cleanupBrainRefsOnTaskDelete(taskId: string, cwd?: string): Promise<void> {
|
|
33
42
|
let brainDb: Awaited<ReturnType<typeof getBrainDb>> | null = null;
|
|
@@ -84,8 +93,16 @@ export async function cleanupBrainRefsOnTaskDelete(taskId: string, cwd?: string)
|
|
|
84
93
|
* Handles:
|
|
85
94
|
* - XFKB-004: Nullify brain_observations.source_session_id where it matches
|
|
86
95
|
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* Best-effort: failures do not propagate. brain.db may not be initialised.
|
|
98
|
+
*
|
|
87
99
|
* @param sessionId - The ID of the session being deleted from tasks.db
|
|
88
100
|
* @param cwd - Optional working directory
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* await cleanupBrainRefsOnSessionDelete('ses_20260321_abc');
|
|
105
|
+
* ```
|
|
89
106
|
*/
|
|
90
107
|
export async function cleanupBrainRefsOnSessionDelete(
|
|
91
108
|
sessionId: string,
|
|
@@ -116,8 +133,17 @@ export async function cleanupBrainRefsOnSessionDelete(
|
|
|
116
133
|
*
|
|
117
134
|
* Provides write-guard for XFKB-001/002/003 on brain.db insert.
|
|
118
135
|
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* Used as a write-guard before inserting cross-DB references into brain.db.
|
|
138
|
+
*
|
|
119
139
|
* @param taskId - Task ID to verify
|
|
120
140
|
* @param tasksDb - The tasks.db drizzle instance
|
|
141
|
+
* @returns True if the task exists in tasks.db
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* if (await taskExistsInTasksDb('T042', db)) { /* safe to reference *\/ }
|
|
146
|
+
* ```
|
|
121
147
|
*/
|
|
122
148
|
export async function taskExistsInTasksDb(
|
|
123
149
|
taskId: string,
|
|
@@ -139,8 +165,17 @@ export async function taskExistsInTasksDb(
|
|
|
139
165
|
*
|
|
140
166
|
* Provides write-guard for XFKB-004 on brain.db insert.
|
|
141
167
|
*
|
|
168
|
+
* @remarks
|
|
169
|
+
* Used as a write-guard before inserting cross-DB references into brain.db.
|
|
170
|
+
*
|
|
142
171
|
* @param sessionId - Session ID to verify
|
|
143
172
|
* @param tasksDb - The tasks.db drizzle instance
|
|
173
|
+
* @returns True if the session exists in tasks.db
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* if (await sessionExistsInTasksDb('ses_abc', db)) { /* safe to reference *\/ }
|
|
178
|
+
* ```
|
|
144
179
|
*/
|
|
145
180
|
export async function sessionExistsInTasksDb(
|
|
146
181
|
sessionId: string,
|
|
@@ -19,8 +19,13 @@ import { createTestDb, type TestDbEnv } from '../../store/__tests__/test-db-help
|
|
|
19
19
|
|
|
20
20
|
// Epic enforcement tests NEED enforcement active — temporarily clear VITEST
|
|
21
21
|
const savedVitest = process.env.VITEST;
|
|
22
|
-
beforeAll(() => {
|
|
23
|
-
|
|
22
|
+
beforeAll(() => {
|
|
23
|
+
delete process.env.VITEST;
|
|
24
|
+
});
|
|
25
|
+
afterAll(() => {
|
|
26
|
+
if (savedVitest) process.env.VITEST = savedVitest;
|
|
27
|
+
});
|
|
28
|
+
|
|
24
29
|
import type { DataAccessor } from '../../store/data-accessor.js';
|
|
25
30
|
import { addTask } from '../add.js';
|
|
26
31
|
import {
|
|
@@ -380,7 +385,7 @@ describe('validateEpicStageAdvancement (strict)', () => {
|
|
|
380
385
|
id: 'T002',
|
|
381
386
|
title: 'Child',
|
|
382
387
|
description: 'Child',
|
|
383
|
-
status: '
|
|
388
|
+
status: 'active',
|
|
384
389
|
priority: 'medium',
|
|
385
390
|
type: 'task',
|
|
386
391
|
parentId: 'T001',
|
|
@@ -416,7 +421,7 @@ describe('validateEpicStageAdvancement (strict)', () => {
|
|
|
416
421
|
id: 'T002',
|
|
417
422
|
title: 'Child',
|
|
418
423
|
description: 'Child',
|
|
419
|
-
status: '
|
|
424
|
+
status: 'active',
|
|
420
425
|
priority: 'medium',
|
|
421
426
|
type: 'task',
|
|
422
427
|
parentId: 'T001',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, mkdtempSync, readdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import {
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
5
|
|
|
6
6
|
describe('minimal repro', () => {
|
|
7
7
|
let tempDir: string;
|