@cleocode/core 2026.4.7 → 2026.4.11
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/adapters/adapter-registry.js +64 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/discovery.js +83 -0
- package/dist/adapters/discovery.js.map +1 -0
- package/dist/adapters/index.js +9 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/manager.js +260 -0
- package/dist/adapters/manager.js.map +1 -0
- package/dist/admin/export-tasks.js +171 -0
- package/dist/admin/export-tasks.js.map +1 -0
- package/dist/admin/export.js +103 -0
- package/dist/admin/export.js.map +1 -0
- package/dist/admin/help.js +106 -0
- package/dist/admin/help.js.map +1 -0
- package/dist/admin/import-tasks.js +182 -0
- package/dist/admin/import-tasks.js.map +1 -0
- package/dist/admin/import.js +129 -0
- package/dist/admin/import.js.map +1 -0
- package/dist/admin/index.js +13 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/adrs/find.js +134 -0
- package/dist/adrs/find.js.map +1 -0
- package/dist/adrs/index.js +15 -0
- package/dist/adrs/index.js.map +1 -0
- package/dist/adrs/link-pipeline.js +160 -0
- package/dist/adrs/link-pipeline.js.map +1 -0
- package/dist/adrs/list.js +43 -0
- package/dist/adrs/list.js.map +1 -0
- package/dist/adrs/parse.js +51 -0
- package/dist/adrs/parse.js.map +1 -0
- package/dist/adrs/show.js +22 -0
- package/dist/adrs/show.js.map +1 -0
- package/dist/adrs/sync.js +188 -0
- package/dist/adrs/sync.js.map +1 -0
- package/dist/adrs/types.js +9 -0
- package/dist/adrs/types.js.map +1 -0
- package/dist/adrs/validate.js +57 -0
- package/dist/adrs/validate.js.map +1 -0
- package/dist/agents/agent-registry.js +288 -0
- package/dist/agents/agent-registry.js.map +1 -0
- package/dist/agents/agent-schema.d.ts +2 -2
- package/dist/agents/agent-schema.js +82 -0
- package/dist/agents/agent-schema.js.map +1 -0
- package/dist/agents/capacity.js +116 -0
- package/dist/agents/capacity.js.map +1 -0
- package/dist/agents/execution-learning.js +474 -0
- package/dist/agents/execution-learning.js.map +1 -0
- package/dist/agents/health-monitor.js +217 -0
- package/dist/agents/health-monitor.js.map +1 -0
- package/dist/agents/index.js +29 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/registry.js +314 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/retry.js +215 -0
- package/dist/agents/retry.js.map +1 -0
- package/dist/audit-prune.js +94 -0
- package/dist/audit-prune.js.map +1 -0
- package/dist/audit.js +68 -0
- package/dist/audit.js.map +1 -0
- package/dist/backfill/index.js +229 -0
- package/dist/backfill/index.js.map +1 -0
- package/dist/bootstrap.js +344 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/caamp/adapter.js +259 -0
- package/dist/caamp/adapter.js.map +1 -0
- package/dist/caamp/capability-check.js +38 -0
- package/dist/caamp/capability-check.js.map +1 -0
- package/dist/caamp/index.js +21 -0
- package/dist/caamp/index.js.map +1 -0
- package/dist/caamp-init.js +16 -0
- package/dist/caamp-init.js.map +1 -0
- package/dist/cleo.js +322 -0
- package/dist/cleo.js.map +1 -0
- package/dist/code/index.js +10 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code/outline.js +165 -0
- package/dist/code/outline.js.map +1 -0
- package/dist/code/parser.js +295 -0
- package/dist/code/parser.js.map +1 -0
- package/dist/code/search.js +135 -0
- package/dist/code/search.js.map +1 -0
- package/dist/code/unfold.js +155 -0
- package/dist/code/unfold.js.map +1 -0
- package/dist/codebase-map/analyzers/architecture.js +130 -0
- package/dist/codebase-map/analyzers/architecture.js.map +1 -0
- package/dist/codebase-map/analyzers/concerns.js +122 -0
- package/dist/codebase-map/analyzers/concerns.js.map +1 -0
- package/dist/codebase-map/analyzers/conventions.js +149 -0
- package/dist/codebase-map/analyzers/conventions.js.map +1 -0
- package/dist/codebase-map/analyzers/integrations.js +108 -0
- package/dist/codebase-map/analyzers/integrations.js.map +1 -0
- package/dist/codebase-map/analyzers/stack.js +117 -0
- package/dist/codebase-map/analyzers/stack.js.map +1 -0
- package/dist/codebase-map/analyzers/structure.js +137 -0
- package/dist/codebase-map/analyzers/structure.js.map +1 -0
- package/dist/codebase-map/analyzers/testing.js +118 -0
- package/dist/codebase-map/analyzers/testing.js.map +1 -0
- package/dist/codebase-map/index.js +57 -0
- package/dist/codebase-map/index.js.map +1 -0
- package/dist/codebase-map/store.js +122 -0
- package/dist/codebase-map/store.js.map +1 -0
- package/dist/codebase-map/summary.js +152 -0
- package/dist/codebase-map/summary.js.map +1 -0
- package/dist/compliance/index.js +288 -0
- package/dist/compliance/index.js.map +1 -0
- package/dist/compliance/protocol-enforcement.js +332 -0
- package/dist/compliance/protocol-enforcement.js.map +1 -0
- package/dist/compliance/protocol-rules.js +786 -0
- package/dist/compliance/protocol-rules.js.map +1 -0
- package/dist/compliance/protocol-types.js +79 -0
- package/dist/compliance/protocol-types.js.map +1 -0
- package/dist/compliance/store.js +53 -0
- package/dist/compliance/store.js.map +1 -0
- package/dist/conduit/conduit-client.js +107 -0
- package/dist/conduit/conduit-client.js.map +1 -0
- package/dist/conduit/factory.js +52 -0
- package/dist/conduit/factory.js.map +1 -0
- package/dist/conduit/http-transport.js +155 -0
- package/dist/conduit/http-transport.js.map +1 -0
- package/dist/conduit/index.js +15 -0
- package/dist/conduit/index.js.map +1 -0
- package/dist/conduit/local-transport.js +245 -0
- package/dist/conduit/local-transport.js.map +1 -0
- package/dist/conduit/sse-transport.js +299 -0
- package/dist/conduit/sse-transport.js.map +1 -0
- package/dist/config/build-config.js +29 -0
- package/dist/config/build-config.js.map +1 -0
- package/dist/config.js +401 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -0
- package/dist/context/index.js +137 -0
- package/dist/context/index.js.map +1 -0
- package/dist/crypto/credentials.js +191 -0
- package/dist/crypto/credentials.js.map +1 -0
- package/dist/discovery.js +182 -0
- package/dist/discovery.js.map +1 -0
- package/dist/engine-result.js +12 -0
- package/dist/engine-result.js.map +1 -0
- package/dist/error-catalog.js +404 -0
- package/dist/error-catalog.js.map +1 -0
- package/dist/error-registry.js +393 -0
- package/dist/error-registry.js.map +1 -0
- package/dist/errors.js +167 -0
- package/dist/errors.js.map +1 -0
- package/dist/hooks/handlers/agent-hooks.js +106 -0
- package/dist/hooks/handlers/agent-hooks.js.map +1 -0
- package/dist/hooks/handlers/context-hooks.js +111 -0
- package/dist/hooks/handlers/context-hooks.js.map +1 -0
- package/dist/hooks/handlers/error-hooks.js +52 -0
- package/dist/hooks/handlers/error-hooks.js.map +1 -0
- package/dist/hooks/handlers/file-hooks.js +104 -0
- package/dist/hooks/handlers/file-hooks.js.map +1 -0
- package/dist/hooks/handlers/handler-helpers.js +61 -0
- package/dist/hooks/handlers/handler-helpers.js.map +1 -0
- package/dist/hooks/handlers/index.js +28 -0
- package/dist/hooks/handlers/index.js.map +1 -0
- package/dist/hooks/handlers/memory-bridge-refresh.js +42 -0
- package/dist/hooks/handlers/memory-bridge-refresh.js.map +1 -0
- package/dist/hooks/handlers/notification-hooks.js +62 -0
- package/dist/hooks/handlers/notification-hooks.js.map +1 -0
- package/dist/hooks/handlers/session-hooks.d.ts +21 -0
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.js +142 -0
- package/dist/hooks/handlers/session-hooks.js.map +1 -0
- package/dist/hooks/handlers/task-hooks.js +65 -0
- package/dist/hooks/handlers/task-hooks.js.map +1 -0
- package/dist/hooks/handlers/work-capture-hooks.js +165 -0
- package/dist/hooks/handlers/work-capture-hooks.js.map +1 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/payload-schemas.d.ts +2 -2
- package/dist/hooks/payload-schemas.js +220 -0
- package/dist/hooks/payload-schemas.js.map +1 -0
- package/dist/hooks/provider-hooks.js +66 -0
- package/dist/hooks/provider-hooks.js.map +1 -0
- package/dist/hooks/registry.js +229 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/types.js +66 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/hooks.js +136 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.js +3361 -3095
- package/dist/index.js.map +4 -4
- package/dist/init.js +852 -0
- package/dist/init.js.map +1 -0
- package/dist/inject/index.js +82 -0
- package/dist/inject/index.js.map +1 -0
- package/dist/injection.js +343 -0
- package/dist/injection.js.map +1 -0
- package/dist/intelligence/adaptive-validation.js +497 -0
- package/dist/intelligence/adaptive-validation.js.map +1 -0
- package/dist/intelligence/impact.js +675 -0
- package/dist/intelligence/impact.js.map +1 -0
- package/dist/intelligence/index.js +22 -0
- package/dist/intelligence/index.js.map +1 -0
- package/dist/intelligence/patterns.js +492 -0
- package/dist/intelligence/patterns.js.map +1 -0
- package/dist/intelligence/prediction.js +499 -0
- package/dist/intelligence/prediction.js.map +1 -0
- package/dist/intelligence/types.js +13 -0
- package/dist/intelligence/types.js.map +1 -0
- package/dist/internal.d.ts +7 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +299 -0
- package/dist/internal.js.map +1 -0
- package/dist/issue/create.js +121 -0
- package/dist/issue/create.js.map +1 -0
- package/dist/issue/diagnostics.js +59 -0
- package/dist/issue/diagnostics.js.map +1 -0
- package/dist/issue/index.js +10 -0
- package/dist/issue/index.js.map +1 -0
- package/dist/issue/template-parser.js +267 -0
- package/dist/issue/template-parser.js.map +1 -0
- package/dist/json-schema-validator.js +76 -0
- package/dist/json-schema-validator.js.map +1 -0
- package/dist/lib/index.js +11 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/retry.js +152 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/tree-sitter-languages.js +71 -0
- package/dist/lib/tree-sitter-languages.js.map +1 -0
- package/dist/lifecycle/chain-composition.js +152 -0
- package/dist/lifecycle/chain-composition.js.map +1 -0
- package/dist/lifecycle/chain-store.js +246 -0
- package/dist/lifecycle/chain-store.js.map +1 -0
- package/dist/lifecycle/consolidate-rcasd.js +352 -0
- package/dist/lifecycle/consolidate-rcasd.js.map +1 -0
- package/dist/lifecycle/default-chain.js +176 -0
- package/dist/lifecycle/default-chain.js.map +1 -0
- package/dist/lifecycle/evidence.js +180 -0
- package/dist/lifecycle/evidence.js.map +1 -0
- package/dist/lifecycle/frontmatter.js +363 -0
- package/dist/lifecycle/frontmatter.js.map +1 -0
- package/dist/lifecycle/index.js +756 -0
- package/dist/lifecycle/index.js.map +1 -0
- package/dist/lifecycle/pipeline.js +656 -0
- package/dist/lifecycle/pipeline.js.map +1 -0
- package/dist/lifecycle/rcasd-index.js +326 -0
- package/dist/lifecycle/rcasd-index.js.map +1 -0
- package/dist/lifecycle/rcasd-paths.js +220 -0
- package/dist/lifecycle/rcasd-paths.js.map +1 -0
- package/dist/lifecycle/resume.js +864 -0
- package/dist/lifecycle/resume.js.map +1 -0
- package/dist/lifecycle/stage-artifacts.js +94 -0
- package/dist/lifecycle/stage-artifacts.js.map +1 -0
- package/dist/lifecycle/stage-guidance.js +234 -0
- package/dist/lifecycle/stage-guidance.js.map +1 -0
- package/dist/lifecycle/stages.js +534 -0
- package/dist/lifecycle/stages.js.map +1 -0
- package/dist/lifecycle/state-machine.js +516 -0
- package/dist/lifecycle/state-machine.js.map +1 -0
- package/dist/lifecycle/tessera-engine.js +249 -0
- package/dist/lifecycle/tessera-engine.js.map +1 -0
- package/dist/logger.js +140 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/auto-extract.js +177 -0
- package/dist/memory/auto-extract.js.map +1 -0
- package/dist/memory/brain-embedding.js +66 -0
- package/dist/memory/brain-embedding.js.map +1 -0
- package/dist/memory/brain-lifecycle.js +298 -0
- package/dist/memory/brain-lifecycle.js.map +1 -0
- package/dist/memory/brain-links.js +161 -0
- package/dist/memory/brain-links.js.map +1 -0
- package/dist/memory/brain-maintenance.js +114 -0
- package/dist/memory/brain-maintenance.js.map +1 -0
- package/dist/memory/brain-migration.js +149 -0
- package/dist/memory/brain-migration.js.map +1 -0
- package/dist/memory/brain-reasoning.js +215 -0
- package/dist/memory/brain-reasoning.js.map +1 -0
- package/dist/memory/brain-retrieval.js +542 -0
- package/dist/memory/brain-retrieval.js.map +1 -0
- package/dist/memory/brain-row-types.js +10 -0
- package/dist/memory/brain-row-types.js.map +1 -0
- package/dist/memory/brain-search.js +519 -0
- package/dist/memory/brain-search.js.map +1 -0
- package/dist/memory/brain-similarity.js +145 -0
- package/dist/memory/brain-similarity.js.map +1 -0
- package/dist/memory/claude-mem-migration.js +277 -0
- package/dist/memory/claude-mem-migration.js.map +1 -0
- package/dist/memory/decisions.js +162 -0
- package/dist/memory/decisions.js.map +1 -0
- package/dist/memory/embedding-local.js +97 -0
- package/dist/memory/embedding-local.js.map +1 -0
- package/dist/memory/embedding-queue.js +271 -0
- package/dist/memory/embedding-queue.js.map +1 -0
- package/dist/memory/embedding-worker.js +58 -0
- package/dist/memory/embedding-worker.js.map +1 -0
- package/dist/memory/engine-compat.js +1397 -0
- package/dist/memory/engine-compat.js.map +1 -0
- package/dist/memory/index.js +1140 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/learnings.d.ts +4 -4
- package/dist/memory/learnings.js +121 -0
- package/dist/memory/learnings.js.map +1 -0
- package/dist/memory/memory-bridge.js +370 -0
- package/dist/memory/memory-bridge.js.map +1 -0
- package/dist/memory/patterns.d.ts +6 -6
- package/dist/memory/patterns.js +122 -0
- package/dist/memory/patterns.js.map +1 -0
- package/dist/memory/pipeline-manifest-sqlite.js +975 -0
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -0
- package/dist/memory/session-memory.js +331 -0
- package/dist/memory/session-memory.js.map +1 -0
- package/dist/metrics/ab-test.js +260 -0
- package/dist/metrics/ab-test.js.map +1 -0
- package/dist/metrics/aggregation.js +363 -0
- package/dist/metrics/aggregation.js.map +1 -0
- package/dist/metrics/common.js +64 -0
- package/dist/metrics/common.js.map +1 -0
- package/dist/metrics/enums.js +78 -0
- package/dist/metrics/enums.js.map +1 -0
- package/dist/metrics/index.js +19 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/model-provider-registry.js +88 -0
- package/dist/metrics/model-provider-registry.js.map +1 -0
- package/dist/metrics/otel-integration.js +263 -0
- package/dist/metrics/otel-integration.js.map +1 -0
- package/dist/metrics/provider-detection.js +103 -0
- package/dist/metrics/provider-detection.js.map +1 -0
- package/dist/metrics/token-estimation.js +253 -0
- package/dist/metrics/token-estimation.js.map +1 -0
- package/dist/metrics/token-service.js +450 -0
- package/dist/metrics/token-service.js.map +1 -0
- package/dist/migration/agent-outputs.js +316 -0
- package/dist/migration/agent-outputs.js.map +1 -0
- package/dist/migration/checksum.js +92 -0
- package/dist/migration/checksum.js.map +1 -0
- package/dist/migration/index.js +282 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/logger.js +360 -0
- package/dist/migration/logger.js.map +1 -0
- package/dist/migration/preflight.js +9 -0
- package/dist/migration/preflight.js.map +1 -0
- package/dist/migration/state.js +421 -0
- package/dist/migration/state.js.map +1 -0
- package/dist/migration/validate.js +241 -0
- package/dist/migration/validate.js.map +1 -0
- package/dist/mvi-helpers.js +74 -0
- package/dist/mvi-helpers.js.map +1 -0
- package/dist/nexus/deps.js +375 -0
- package/dist/nexus/deps.js.map +1 -0
- package/dist/nexus/discover.js +288 -0
- package/dist/nexus/discover.js.map +1 -0
- package/dist/nexus/hash.js +10 -0
- package/dist/nexus/hash.js.map +1 -0
- package/dist/nexus/index.js +40 -0
- package/dist/nexus/index.js.map +1 -0
- package/dist/nexus/migrate-json-to-sqlite.js +115 -0
- package/dist/nexus/migrate-json-to-sqlite.js.map +1 -0
- package/dist/nexus/permissions.js +105 -0
- package/dist/nexus/permissions.js.map +1 -0
- package/dist/nexus/query.js +175 -0
- package/dist/nexus/query.js.map +1 -0
- package/dist/nexus/registry.js +584 -0
- package/dist/nexus/registry.js.map +1 -0
- package/dist/nexus/sharing/index.js +288 -0
- package/dist/nexus/sharing/index.js.map +1 -0
- package/dist/nexus/transfer-types.js +8 -0
- package/dist/nexus/transfer-types.js.map +1 -0
- package/dist/nexus/transfer.js +263 -0
- package/dist/nexus/transfer.js.map +1 -0
- package/dist/nexus/workspace.js +355 -0
- package/dist/nexus/workspace.js.map +1 -0
- package/dist/observability/index.js +103 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/log-filter.js +63 -0
- package/dist/observability/log-filter.js.map +1 -0
- package/dist/observability/log-parser.js +99 -0
- package/dist/observability/log-parser.js.map +1 -0
- package/dist/observability/log-reader.js +139 -0
- package/dist/observability/log-reader.js.map +1 -0
- package/dist/observability/types.js +19 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/orchestration/analyze.js +107 -0
- package/dist/orchestration/analyze.js.map +1 -0
- package/dist/orchestration/bootstrap.js +132 -0
- package/dist/orchestration/bootstrap.js.map +1 -0
- package/dist/orchestration/context.js +56 -0
- package/dist/orchestration/context.js.map +1 -0
- package/dist/orchestration/critical-path.js +100 -0
- package/dist/orchestration/critical-path.js.map +1 -0
- package/dist/orchestration/hierarchy.js +183 -0
- package/dist/orchestration/hierarchy.js.map +1 -0
- package/dist/orchestration/index.js +287 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/parallel.js +89 -0
- package/dist/orchestration/parallel.js.map +1 -0
- package/dist/orchestration/protocol-validators.js +815 -0
- package/dist/orchestration/protocol-validators.js.map +1 -0
- package/dist/orchestration/skill-ops.js +98 -0
- package/dist/orchestration/skill-ops.js.map +1 -0
- package/dist/orchestration/status.js +107 -0
- package/dist/orchestration/status.js.map +1 -0
- package/dist/orchestration/unblock.js +103 -0
- package/dist/orchestration/unblock.js.map +1 -0
- package/dist/orchestration/validate-spawn.js +67 -0
- package/dist/orchestration/validate-spawn.js.map +1 -0
- package/dist/orchestration/waves.js +86 -0
- package/dist/orchestration/waves.js.map +1 -0
- package/dist/otel/index.js +163 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/output.js +164 -0
- package/dist/output.js.map +1 -0
- package/dist/pagination.js +64 -0
- package/dist/pagination.js.map +1 -0
- package/dist/paths.d.ts +39 -9
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +776 -0
- package/dist/paths.js.map +1 -0
- package/dist/phases/deps.js +372 -0
- package/dist/phases/deps.js.map +1 -0
- package/dist/phases/index.js +349 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/pipeline/index.js +10 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/phase.js +45 -0
- package/dist/pipeline/phase.js.map +1 -0
- package/dist/platform.js +211 -0
- package/dist/platform.js.map +1 -0
- package/dist/project-info.js +84 -0
- package/dist/project-info.js.map +1 -0
- package/dist/reconciliation/index.js +10 -0
- package/dist/reconciliation/index.js.map +1 -0
- package/dist/reconciliation/link-store.js +129 -0
- package/dist/reconciliation/link-store.js.map +1 -0
- package/dist/reconciliation/reconciliation-engine.js +298 -0
- package/dist/reconciliation/reconciliation-engine.js.map +1 -0
- package/dist/release/artifacts.js +427 -0
- package/dist/release/artifacts.js.map +1 -0
- package/dist/release/changelog-writer.js +151 -0
- package/dist/release/changelog-writer.js.map +1 -0
- package/dist/release/channel.js +144 -0
- package/dist/release/channel.js.map +1 -0
- package/dist/release/ci.js +166 -0
- package/dist/release/ci.js.map +1 -0
- package/dist/release/github-pr.js +225 -0
- package/dist/release/github-pr.js.map +1 -0
- package/dist/release/guards.js +116 -0
- package/dist/release/guards.js.map +1 -0
- package/dist/release/index.js +22 -0
- package/dist/release/index.js.map +1 -0
- package/dist/release/release-config.js +158 -0
- package/dist/release/release-config.js.map +1 -0
- package/dist/release/release-manifest.js +1019 -0
- package/dist/release/release-manifest.js.map +1 -0
- package/dist/release/version-bump.js +255 -0
- package/dist/release/version-bump.js.map +1 -0
- package/dist/remote/index.js +257 -0
- package/dist/remote/index.js.map +1 -0
- package/dist/repair.js +130 -0
- package/dist/repair.js.map +1 -0
- package/dist/research/index.js +2 -0
- package/dist/research/index.js.map +1 -0
- package/dist/roadmap/index.js +59 -0
- package/dist/roadmap/index.js.map +1 -0
- package/dist/routing/capability-matrix.js +1556 -0
- package/dist/routing/capability-matrix.js.map +1 -0
- package/dist/routing/index.js +9 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/scaffold.d.ts +15 -2
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +1759 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/schema-management.js +295 -0
- package/dist/schema-management.js.map +1 -0
- package/dist/security/index.js +9 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/input-sanitization.js +321 -0
- package/dist/security/input-sanitization.js.map +1 -0
- package/dist/sequence/index.js +295 -0
- package/dist/sequence/index.js.map +1 -0
- package/dist/sessions/assumptions.js +54 -0
- package/dist/sessions/assumptions.js.map +1 -0
- package/dist/sessions/briefing.js +377 -0
- package/dist/sessions/briefing.js.map +1 -0
- package/dist/sessions/context-alert.js +222 -0
- package/dist/sessions/context-alert.js.map +1 -0
- package/dist/sessions/context-inject.js +61 -0
- package/dist/sessions/context-inject.js.map +1 -0
- package/dist/sessions/context-monitor.js +98 -0
- package/dist/sessions/context-monitor.js.map +1 -0
- package/dist/sessions/decisions.js +65 -0
- package/dist/sessions/decisions.js.map +1 -0
- package/dist/sessions/find.js +65 -0
- package/dist/sessions/find.js.map +1 -0
- package/dist/sessions/handoff.js +328 -0
- package/dist/sessions/handoff.js.map +1 -0
- package/dist/sessions/hitl-warnings.js +254 -0
- package/dist/sessions/hitl-warnings.js.map +1 -0
- package/dist/sessions/index.js +327 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/session-archive.js +40 -0
- package/dist/sessions/session-archive.js.map +1 -0
- package/dist/sessions/session-cleanup.js +59 -0
- package/dist/sessions/session-cleanup.js.map +1 -0
- package/dist/sessions/session-drift.js +134 -0
- package/dist/sessions/session-drift.js.map +1 -0
- package/dist/sessions/session-enforcement.js +144 -0
- package/dist/sessions/session-enforcement.js.map +1 -0
- package/dist/sessions/session-grade.js +253 -0
- package/dist/sessions/session-grade.js.map +1 -0
- package/dist/sessions/session-history.js +42 -0
- package/dist/sessions/session-history.js.map +1 -0
- package/dist/sessions/session-id.js +81 -0
- package/dist/sessions/session-id.js.map +1 -0
- package/dist/sessions/session-memory-bridge.js +52 -0
- package/dist/sessions/session-memory-bridge.js.map +1 -0
- package/dist/sessions/session-show.js +24 -0
- package/dist/sessions/session-show.js.map +1 -0
- package/dist/sessions/session-stats.js +69 -0
- package/dist/sessions/session-stats.js.map +1 -0
- package/dist/sessions/session-suspend.js +39 -0
- package/dist/sessions/session-suspend.js.map +1 -0
- package/dist/sessions/session-switch.js +51 -0
- package/dist/sessions/session-switch.js.map +1 -0
- package/dist/sessions/session-view.js +76 -0
- package/dist/sessions/session-view.js.map +1 -0
- package/dist/sessions/snapshot.js +213 -0
- package/dist/sessions/snapshot.js.map +1 -0
- package/dist/sessions/statusline-setup.js +85 -0
- package/dist/sessions/statusline-setup.js.map +1 -0
- package/dist/sessions/types.js +8 -0
- package/dist/sessions/types.js.map +1 -0
- package/dist/skills/agents/config.js +94 -0
- package/dist/skills/agents/config.js.map +1 -0
- package/dist/skills/agents/install.js +116 -0
- package/dist/skills/agents/install.js.map +1 -0
- package/dist/skills/agents/registry.js +161 -0
- package/dist/skills/agents/registry.js.map +1 -0
- package/dist/skills/discovery.js +333 -0
- package/dist/skills/discovery.js.map +1 -0
- package/dist/skills/dispatch.js +347 -0
- package/dist/skills/dispatch.js.map +1 -0
- package/dist/skills/dynamic-skill-generator.js +87 -0
- package/dist/skills/dynamic-skill-generator.js.map +1 -0
- package/dist/skills/index.js +44 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/injection/subagent.js +195 -0
- package/dist/skills/injection/subagent.js.map +1 -0
- package/dist/skills/injection/token.js +260 -0
- package/dist/skills/injection/token.js.map +1 -0
- package/dist/skills/install.js +40 -0
- package/dist/skills/install.js.map +1 -0
- package/dist/skills/manifests/contribution.js +175 -0
- package/dist/skills/manifests/contribution.js.map +1 -0
- package/dist/skills/manifests/research.js +281 -0
- package/dist/skills/manifests/research.js.map +1 -0
- package/dist/skills/manifests/resolver.js +146 -0
- package/dist/skills/manifests/resolver.js.map +1 -0
- package/dist/skills/marketplace.js +90 -0
- package/dist/skills/marketplace.js.map +1 -0
- package/dist/skills/orchestrator/spawn.js +178 -0
- package/dist/skills/orchestrator/spawn.js.map +1 -0
- package/dist/skills/orchestrator/startup.js +451 -0
- package/dist/skills/orchestrator/startup.js.map +1 -0
- package/dist/skills/orchestrator/validator.js +301 -0
- package/dist/skills/orchestrator/validator.js.map +1 -0
- package/dist/skills/precedence-integration.js +73 -0
- package/dist/skills/precedence-integration.js.map +1 -0
- package/dist/skills/precedence-types.js +16 -0
- package/dist/skills/precedence-types.js.map +1 -0
- package/dist/skills/routing-table.js +63 -0
- package/dist/skills/routing-table.js.map +1 -0
- package/dist/skills/skill-paths.js +217 -0
- package/dist/skills/skill-paths.js.map +1 -0
- package/dist/skills/test-utility.js +55 -0
- package/dist/skills/test-utility.js.map +1 -0
- package/dist/skills/types.js +118 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/skills/validation.js +183 -0
- package/dist/skills/validation.js.map +1 -0
- package/dist/skills/version.js +57 -0
- package/dist/skills/version.js.map +1 -0
- package/dist/snapshot/index.js +188 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/spawn/adapter-registry.js +246 -0
- package/dist/spawn/adapter-registry.js.map +1 -0
- package/dist/spawn/index.js +10 -0
- package/dist/spawn/index.js.map +1 -0
- package/dist/stats/index.js +343 -0
- package/dist/stats/index.js.map +1 -0
- package/dist/stats/workflow-telemetry.js +400 -0
- package/dist/stats/workflow-telemetry.js.map +1 -0
- package/dist/sticky/archive.js +47 -0
- package/dist/sticky/archive.js.map +1 -0
- package/dist/sticky/convert.js +235 -0
- package/dist/sticky/convert.js.map +1 -0
- package/dist/sticky/create.js +48 -0
- package/dist/sticky/create.js.map +1 -0
- package/dist/sticky/id.js +35 -0
- package/dist/sticky/id.js.map +1 -0
- package/dist/sticky/index.js +16 -0
- package/dist/sticky/index.js.map +1 -0
- package/dist/sticky/list.js +44 -0
- package/dist/sticky/list.js.map +1 -0
- package/dist/sticky/purge.js +45 -0
- package/dist/sticky/purge.js.map +1 -0
- package/dist/sticky/show.js +42 -0
- package/dist/sticky/show.js.map +1 -0
- package/dist/sticky/types.js +10 -0
- package/dist/sticky/types.js.map +1 -0
- package/dist/store/agent-registry-accessor.js +265 -0
- package/dist/store/agent-registry-accessor.js.map +1 -0
- package/dist/store/atomic.js +167 -0
- package/dist/store/atomic.js.map +1 -0
- package/dist/store/backup.js +94 -0
- package/dist/store/backup.js.map +1 -0
- package/dist/store/brain-accessor.js +397 -0
- package/dist/store/brain-accessor.js.map +1 -0
- package/dist/store/brain-schema.d.ts +8 -8
- package/dist/store/brain-schema.js +215 -0
- package/dist/store/brain-schema.js.map +1 -0
- package/dist/store/brain-sqlite.js +222 -0
- package/dist/store/brain-sqlite.js.map +1 -0
- package/dist/store/cache.js +168 -0
- package/dist/store/cache.js.map +1 -0
- package/dist/store/chain-schema.js +51 -0
- package/dist/store/chain-schema.js.map +1 -0
- package/dist/store/cleanup-legacy.d.ts +128 -0
- package/dist/store/cleanup-legacy.d.ts.map +1 -0
- package/dist/store/converters.js +124 -0
- package/dist/store/converters.js.map +1 -0
- package/dist/store/cross-db-cleanup.js +319 -0
- package/dist/store/cross-db-cleanup.js.map +1 -0
- package/dist/store/data-accessor.js +26 -0
- package/dist/store/data-accessor.js.map +1 -0
- package/dist/store/data-safety-central.js +269 -0
- package/dist/store/data-safety-central.js.map +1 -0
- package/dist/store/data-safety.js +274 -0
- package/dist/store/data-safety.js.map +1 -0
- package/dist/store/db-helpers.js +224 -0
- package/dist/store/db-helpers.js.map +1 -0
- package/dist/store/export.js +155 -0
- package/dist/store/export.js.map +1 -0
- package/dist/store/file-utils.js +270 -0
- package/dist/store/file-utils.js.map +1 -0
- package/dist/store/git-checkpoint.js +365 -0
- package/dist/store/git-checkpoint.js.map +1 -0
- package/dist/store/import-logging.js +139 -0
- package/dist/store/import-logging.js.map +1 -0
- package/dist/store/import-remap.js +145 -0
- package/dist/store/import-remap.js.map +1 -0
- package/dist/store/import-sort.js +121 -0
- package/dist/store/import-sort.js.map +1 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +29 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/json.js +208 -0
- package/dist/store/json.js.map +1 -0
- package/dist/store/lifecycle-store.js +249 -0
- package/dist/store/lifecycle-store.js.map +1 -0
- package/dist/store/lock.js +70 -0
- package/dist/store/lock.js.map +1 -0
- package/dist/store/migration-manager.js +151 -0
- package/dist/store/migration-manager.js.map +1 -0
- package/dist/store/migration-sqlite.js +676 -0
- package/dist/store/migration-sqlite.js.map +1 -0
- package/dist/store/nexus-schema.js +62 -0
- package/dist/store/nexus-schema.js.map +1 -0
- package/dist/store/nexus-sqlite.d.ts +14 -2
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +217 -0
- package/dist/store/nexus-sqlite.js.map +1 -0
- package/dist/store/nexus-validation-schemas.js +40 -0
- package/dist/store/nexus-validation-schemas.js.map +1 -0
- package/dist/store/parsers.js +37 -0
- package/dist/store/parsers.js.map +1 -0
- package/dist/store/project-detect.js +457 -0
- package/dist/store/project-detect.js.map +1 -0
- package/dist/store/provider.js +101 -0
- package/dist/store/provider.js.map +1 -0
- package/dist/store/safety-data-accessor.js +257 -0
- package/dist/store/safety-data-accessor.js.map +1 -0
- package/dist/store/schema.js +7 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store/session-store.js +219 -0
- package/dist/store/session-store.js.map +1 -0
- package/dist/store/signaldock-sqlite.js +400 -0
- package/dist/store/signaldock-sqlite.js.map +1 -0
- package/dist/store/sqlite-backup.d.ts +121 -10
- package/dist/store/sqlite-backup.d.ts.map +1 -1
- package/dist/store/sqlite-backup.js +241 -0
- package/dist/store/sqlite-backup.js.map +1 -0
- package/dist/store/sqlite-data-accessor.js +787 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +481 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/status-registry.js +8 -0
- package/dist/store/status-registry.js.map +1 -0
- package/dist/store/task-store.js +358 -0
- package/dist/store/task-store.js.map +1 -0
- package/dist/store/tasks-schema.d.ts +8 -8
- package/dist/store/tasks-schema.js +610 -0
- package/dist/store/tasks-schema.js.map +1 -0
- package/dist/store/typed-query.js +15 -0
- package/dist/store/typed-query.js.map +1 -0
- package/dist/store/validation-schemas.d.ts +37 -37
- package/dist/store/validation-schemas.js +278 -0
- package/dist/store/validation-schemas.js.map +1 -0
- package/dist/system/archive-analytics.js +277 -0
- package/dist/system/archive-analytics.js.map +1 -0
- package/dist/system/archive-stats.js +64 -0
- package/dist/system/archive-stats.js.map +1 -0
- package/dist/system/audit.js +145 -0
- package/dist/system/audit.js.map +1 -0
- package/dist/system/backup.d.ts +91 -3
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +280 -0
- package/dist/system/backup.js.map +1 -0
- package/dist/system/cleanup.js +134 -0
- package/dist/system/cleanup.js.map +1 -0
- package/dist/system/health.js +1100 -0
- package/dist/system/health.js.map +1 -0
- package/dist/system/index.js +18 -0
- package/dist/system/index.js.map +1 -0
- package/dist/system/inject-generate.js +122 -0
- package/dist/system/inject-generate.js.map +1 -0
- package/dist/system/labels.js +38 -0
- package/dist/system/labels.js.map +1 -0
- package/dist/system/metrics.js +61 -0
- package/dist/system/metrics.js.map +1 -0
- package/dist/system/migrate.js +43 -0
- package/dist/system/migrate.js.map +1 -0
- package/dist/system/platform-paths.js +80 -0
- package/dist/system/platform-paths.js.map +1 -0
- package/dist/system/runtime.js +161 -0
- package/dist/system/runtime.js.map +1 -0
- package/dist/system/safestop.js +99 -0
- package/dist/system/safestop.js.map +1 -0
- package/dist/system/storage-preflight.js +123 -0
- package/dist/system/storage-preflight.js.map +1 -0
- package/dist/task-work/index.js +159 -0
- package/dist/task-work/index.js.map +1 -0
- package/dist/tasks/add.js +661 -0
- package/dist/tasks/add.js.map +1 -0
- package/dist/tasks/analyze.js +85 -0
- package/dist/tasks/analyze.js.map +1 -0
- package/dist/tasks/archive.js +90 -0
- package/dist/tasks/archive.js.map +1 -0
- package/dist/tasks/atomicity.js +83 -0
- package/dist/tasks/atomicity.js.map +1 -0
- package/dist/tasks/cancel-ops.js +83 -0
- package/dist/tasks/cancel-ops.js.map +1 -0
- package/dist/tasks/complete.js +211 -0
- package/dist/tasks/complete.js.map +1 -0
- package/dist/tasks/crossref-extract.js +73 -0
- package/dist/tasks/crossref-extract.js.map +1 -0
- package/dist/tasks/delete-preview.js +192 -0
- package/dist/tasks/delete-preview.js.map +1 -0
- package/dist/tasks/delete.js +120 -0
- package/dist/tasks/delete.js.map +1 -0
- package/dist/tasks/deletion-strategy.js +200 -0
- package/dist/tasks/deletion-strategy.js.map +1 -0
- package/dist/tasks/dependency-check.js +278 -0
- package/dist/tasks/dependency-check.js.map +1 -0
- package/dist/tasks/deps-ready.js +32 -0
- package/dist/tasks/deps-ready.js.map +1 -0
- package/dist/tasks/enforcement.js +86 -0
- package/dist/tasks/enforcement.js.map +1 -0
- package/dist/tasks/epic-enforcement.js +294 -0
- package/dist/tasks/epic-enforcement.js.map +1 -0
- package/dist/tasks/find.js +154 -0
- package/dist/tasks/find.js.map +1 -0
- package/dist/tasks/graph-cache.js +127 -0
- package/dist/tasks/graph-cache.js.map +1 -0
- package/dist/tasks/graph-ops.js +171 -0
- package/dist/tasks/graph-ops.js.map +1 -0
- package/dist/tasks/graph-rag.js +328 -0
- package/dist/tasks/graph-rag.js.map +1 -0
- package/dist/tasks/hierarchy-policy.js +149 -0
- package/dist/tasks/hierarchy-policy.js.map +1 -0
- package/dist/tasks/hierarchy.js +185 -0
- package/dist/tasks/hierarchy.js.map +1 -0
- package/dist/tasks/id-generator.js +65 -0
- package/dist/tasks/id-generator.js.map +1 -0
- package/dist/tasks/index.js +14 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/labels.js +52 -0
- package/dist/tasks/labels.js.map +1 -0
- package/dist/tasks/list.js +75 -0
- package/dist/tasks/list.js.map +1 -0
- package/dist/tasks/phase-tracking.js +133 -0
- package/dist/tasks/phase-tracking.js.map +1 -0
- package/dist/tasks/pipeline-stage.js +248 -0
- package/dist/tasks/pipeline-stage.js.map +1 -0
- package/dist/tasks/plan.js +268 -0
- package/dist/tasks/plan.js.map +1 -0
- package/dist/tasks/relates.js +89 -0
- package/dist/tasks/relates.js.map +1 -0
- package/dist/tasks/show.js +80 -0
- package/dist/tasks/show.js.map +1 -0
- package/dist/tasks/size-weighting.js +86 -0
- package/dist/tasks/size-weighting.js.map +1 -0
- package/dist/tasks/staleness.js +86 -0
- package/dist/tasks/staleness.js.map +1 -0
- package/dist/tasks/task-ops.js +1741 -0
- package/dist/tasks/task-ops.js.map +1 -0
- package/dist/tasks/update.js +277 -0
- package/dist/tasks/update.js.map +1 -0
- package/dist/templates/index.js +10 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/parser.js +254 -0
- package/dist/templates/parser.js.map +1 -0
- package/dist/ui/aliases.js +153 -0
- package/dist/ui/aliases.js.map +1 -0
- package/dist/ui/changelog.js +184 -0
- package/dist/ui/changelog.js.map +1 -0
- package/dist/ui/command-registry.js +168 -0
- package/dist/ui/command-registry.js.map +1 -0
- package/dist/ui/flags.js +94 -0
- package/dist/ui/flags.js.map +1 -0
- package/dist/ui/index.js +24 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/upgrade.js +1148 -0
- package/dist/upgrade.js.map +1 -0
- package/dist/validation/chain-validation.js +146 -0
- package/dist/validation/chain-validation.js.map +1 -0
- package/dist/validation/compliance.js +155 -0
- package/dist/validation/compliance.js.map +1 -0
- package/dist/validation/docs-sync.js +212 -0
- package/dist/validation/docs-sync.js.map +1 -0
- package/dist/validation/doctor/checks.js +1069 -0
- package/dist/validation/doctor/checks.js.map +1 -0
- package/dist/validation/doctor/index.js +9 -0
- package/dist/validation/doctor/index.js.map +1 -0
- package/dist/validation/doctor/project-cache.js +160 -0
- package/dist/validation/doctor/project-cache.js.map +1 -0
- package/dist/validation/doctor/utils.js +155 -0
- package/dist/validation/doctor/utils.js.map +1 -0
- package/dist/validation/engine.js +902 -0
- package/dist/validation/engine.js.map +1 -0
- package/dist/validation/gap-check.js +175 -0
- package/dist/validation/gap-check.js.map +1 -0
- package/dist/validation/index.js +40 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/manifest.js +237 -0
- package/dist/validation/manifest.js.map +1 -0
- package/dist/validation/operation-gate-validators.js +724 -0
- package/dist/validation/operation-gate-validators.js.map +1 -0
- package/dist/validation/operation-verification-gates.js +532 -0
- package/dist/validation/operation-verification-gates.js.map +1 -0
- package/dist/validation/param-utils.js +139 -0
- package/dist/validation/param-utils.js.map +1 -0
- package/dist/validation/protocol-common.js +300 -0
- package/dist/validation/protocol-common.js.map +1 -0
- package/dist/validation/protocols/_shared.js +75 -0
- package/dist/validation/protocols/_shared.js.map +1 -0
- package/dist/validation/protocols/architecture-decision.js +31 -0
- package/dist/validation/protocols/architecture-decision.js.map +1 -0
- package/dist/validation/protocols/artifact-publish.js +28 -0
- package/dist/validation/protocols/artifact-publish.js.map +1 -0
- package/dist/validation/protocols/consensus.js +41 -0
- package/dist/validation/protocols/consensus.js.map +1 -0
- package/dist/validation/protocols/contribution.js +27 -0
- package/dist/validation/protocols/contribution.js.map +1 -0
- package/dist/validation/protocols/decomposition.js +28 -0
- package/dist/validation/protocols/decomposition.js.map +1 -0
- package/dist/validation/protocols/implementation.js +24 -0
- package/dist/validation/protocols/implementation.js.map +1 -0
- package/dist/validation/protocols/provenance.js +29 -0
- package/dist/validation/protocols/provenance.js.map +1 -0
- package/dist/validation/protocols/release.js +29 -0
- package/dist/validation/protocols/release.js.map +1 -0
- package/dist/validation/protocols/research.js +24 -0
- package/dist/validation/protocols/research.js.map +1 -0
- package/dist/validation/protocols/specification.js +27 -0
- package/dist/validation/protocols/specification.js.map +1 -0
- package/dist/validation/protocols/testing.js +30 -0
- package/dist/validation/protocols/testing.js.map +1 -0
- package/dist/validation/protocols/validation.js +30 -0
- package/dist/validation/protocols/validation.js.map +1 -0
- package/dist/validation/schema-integrity.js +170 -0
- package/dist/validation/schema-integrity.js.map +1 -0
- package/dist/validation/schema-validator.js +176 -0
- package/dist/validation/schema-validator.js.map +1 -0
- package/dist/validation/validate-ops.js +937 -0
- package/dist/validation/validate-ops.js.map +1 -0
- package/dist/validation/validation-rules.js +226 -0
- package/dist/validation/validation-rules.js.map +1 -0
- package/dist/validation/verification.js +321 -0
- package/dist/validation/verification.js.map +1 -0
- package/package.json +10 -8
- package/src/__tests__/paths-walkup.test.ts +305 -0
- package/src/__tests__/paths.test.ts +61 -17
- package/src/hooks/handlers/session-hooks.ts +42 -0
- package/src/internal.ts +19 -2
- package/src/paths.ts +91 -14
- package/src/scaffold.ts +22 -3
- package/src/store/__tests__/cleanup-legacy.test.ts +268 -0
- package/src/store/__tests__/database-topology-integration.test.ts +504 -0
- package/src/store/__tests__/sqlite-backup-global.test.ts +281 -0
- package/src/store/__tests__/sqlite-backup.test.ts +118 -10
- package/src/store/cleanup-legacy.ts +208 -0
- package/src/store/index.ts +7 -0
- package/src/store/nexus-sqlite.ts +32 -3
- package/src/store/sqlite-backup.ts +368 -37
- package/src/store/sqlite.ts +19 -3
- package/src/system/__tests__/backup.test.ts +237 -0
- package/src/system/backup.ts +248 -28
- package/templates/cleo-gitignore +19 -3
|
@@ -37,11 +37,40 @@ let _nexusDbPath: string | null = null;
|
|
|
37
37
|
let _nexusInitPromise: Promise<NodeSQLiteDatabase<typeof nexusSchema>> | null = null;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
* Returns the global-tier nexus.db path. ALWAYS under `getCleoHome()`.
|
|
41
|
+
*
|
|
42
|
+
* nexus.db is a cross-project registry and must live in the global CLEO
|
|
43
|
+
* home directory (`~/.local/share/cleo/` on Linux via XDG). It is NEVER
|
|
44
|
+
* written to a per-project `.cleo/` directory.
|
|
45
|
+
*
|
|
46
|
+
* @task T307
|
|
47
|
+
* @epic T299
|
|
48
|
+
* @why ADR-036 §Decision/Global-Tier: nexus.db is global-only. This guard
|
|
49
|
+
* throws immediately if path resolution ever drifts outside getCleoHome(),
|
|
50
|
+
* preventing silent creation of project-tier stray nexus.db files.
|
|
51
|
+
* @throws {Error} If the resolved path is not under `getCleoHome()` — this
|
|
52
|
+
* indicates a code path that bypasses canonical path resolution and is a
|
|
53
|
+
* bug that must be fixed rather than silently tolerated.
|
|
42
54
|
*/
|
|
43
55
|
export function getNexusDbPath(): string {
|
|
44
|
-
|
|
56
|
+
const cleoHome = getCleoHome();
|
|
57
|
+
const nexusPath = join(cleoHome, DB_FILENAME);
|
|
58
|
+
|
|
59
|
+
// Guard: the resolved path MUST be under the global tier.
|
|
60
|
+
// Under normal operation this invariant is always satisfied because we
|
|
61
|
+
// build nexusPath from cleoHome above. The assertion catches hypothetical
|
|
62
|
+
// future regressions where getCleoHome() is monkey-patched or join()
|
|
63
|
+
// produces an unexpected result on exotic platforms.
|
|
64
|
+
if (!nexusPath.startsWith(cleoHome)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`BUG: getNexusDbPath() resolved to "${nexusPath}" which is NOT under ` +
|
|
67
|
+
`getCleoHome() ("${cleoHome}"). nexus.db is global-only per ADR-036. ` +
|
|
68
|
+
`This indicates a code path that bypasses canonical path resolution — ` +
|
|
69
|
+
`fix the caller, do not suppress this error.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return nexusPath;
|
|
45
74
|
}
|
|
46
75
|
|
|
47
76
|
/**
|
|
@@ -1,25 +1,64 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQLite backup via VACUUM INTO with snapshot rotation.
|
|
3
3
|
*
|
|
4
|
-
* Produces self-contained, WAL-free copies of
|
|
5
|
-
* .
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Produces self-contained, WAL-free copies of CLEO SQLite databases
|
|
5
|
+
* (tasks.db, brain.db at project tier; nexus.db at global tier) into
|
|
6
|
+
* `.cleo/backups/sqlite/` (project) or `$XDG_DATA_HOME/cleo/backups/sqlite/`
|
|
7
|
+
* (global) with a configurable rotation limit. All errors are swallowed —
|
|
8
|
+
* backup failure must never interrupt normal operation.
|
|
8
9
|
*
|
|
9
10
|
* @task T4873
|
|
11
|
+
* @task T5158 — extended to cover brain.db
|
|
12
|
+
* @task T306 — extended to cover global-tier nexus.db (epic T299)
|
|
10
13
|
* @epic T4867
|
|
11
14
|
*/
|
|
12
15
|
|
|
13
16
|
import { existsSync, mkdirSync, readdirSync, statSync, unlinkSync } from 'node:fs';
|
|
14
17
|
import { join } from 'node:path';
|
|
15
|
-
import { getCleoDir } from '../paths.js';
|
|
18
|
+
import { getCleoDir, getCleoHome } from '../paths.js';
|
|
19
|
+
import { getBrainNativeDb } from './brain-sqlite.js';
|
|
20
|
+
import { getNexusNativeDb } from './nexus-sqlite.js';
|
|
16
21
|
import { getNativeDb } from './sqlite.js';
|
|
17
22
|
|
|
23
|
+
/** Maximum number of snapshots retained per database (oldest rotated out). */
|
|
18
24
|
const MAX_SNAPSHOTS = 10;
|
|
25
|
+
/** Debounce window (ms) during which duplicate snapshot requests are suppressed. */
|
|
19
26
|
const DEBOUNCE_MS = 30_000; // 30 seconds
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Per-database snapshot book-keeping: last snapshot timestamp (epoch ms)
|
|
30
|
+
* keyed by the canonical snapshot prefix (e.g. `"tasks"` / `"brain"`).
|
|
31
|
+
*/
|
|
32
|
+
const _lastBackupEpoch: Record<string, number> = {};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Registered snapshot target — each one maps a logical key (prefix used in
|
|
36
|
+
* snapshot filenames) to a function returning the live {@link DatabaseSync}
|
|
37
|
+
* handle. `null` means the database has not been initialized in the current
|
|
38
|
+
* process and its snapshot step should be skipped.
|
|
39
|
+
*/
|
|
40
|
+
interface SnapshotTarget {
|
|
41
|
+
/** Canonical name used in snapshot filenames, e.g. `"tasks"` or `"brain"`. */
|
|
42
|
+
prefix: string;
|
|
43
|
+
/** Resolves the live native handle, or `null` if not yet initialized. */
|
|
44
|
+
getDb: () => { exec: (sql: string) => void } | null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Canonical list of snapshot targets. Ordering is insertion order — tasks.db
|
|
49
|
+
* snapshots first (highest-value operational state), then brain.db.
|
|
50
|
+
*/
|
|
51
|
+
const SNAPSHOT_TARGETS: SnapshotTarget[] = [
|
|
52
|
+
{ prefix: 'tasks', getDb: getNativeDb },
|
|
53
|
+
{ prefix: 'brain', getDb: getBrainNativeDb },
|
|
54
|
+
];
|
|
22
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Format a Date as `YYYYMMDD-HHmmss` (local time) for snapshot filenames.
|
|
58
|
+
*
|
|
59
|
+
* Matches the regex `/^(?:tasks|brain)-\d{8}-\d{6}\.db$/` used by the rotation
|
|
60
|
+
* and listing logic below.
|
|
61
|
+
*/
|
|
23
62
|
function formatTimestamp(d: Date): string {
|
|
24
63
|
const pad = (n: number, len = 2) => String(n).padStart(len, '0');
|
|
25
64
|
return (
|
|
@@ -28,10 +67,26 @@ function formatTimestamp(d: Date): string {
|
|
|
28
67
|
);
|
|
29
68
|
}
|
|
30
69
|
|
|
31
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Build the regex that matches snapshot filenames for the given prefix.
|
|
72
|
+
* Isolated so both {@link rotateSnapshots} and {@link listSqliteBackupsForPrefix}
|
|
73
|
+
* share a single source of truth.
|
|
74
|
+
*/
|
|
75
|
+
function snapshotPattern(prefix: string): RegExp {
|
|
76
|
+
// Escape the prefix in case it ever contains regex metacharacters.
|
|
77
|
+
const safe = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
78
|
+
return new RegExp(`^${safe}-\\d{8}-\\d{6}\\.db$`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Rotate snapshots for a single prefix: delete the oldest files until fewer
|
|
83
|
+
* than {@link MAX_SNAPSHOTS} remain. Non-fatal on any filesystem error.
|
|
84
|
+
*/
|
|
85
|
+
function rotateSnapshots(backupDir: string, prefix: string): void {
|
|
32
86
|
try {
|
|
87
|
+
const pattern = snapshotPattern(prefix);
|
|
33
88
|
const files = readdirSync(backupDir)
|
|
34
|
-
.filter((f) =>
|
|
89
|
+
.filter((f) => pattern.test(f))
|
|
35
90
|
.map((f) => ({
|
|
36
91
|
name: f,
|
|
37
92
|
path: join(backupDir, f),
|
|
@@ -40,7 +95,8 @@ function rotateSnapshots(backupDir: string): void {
|
|
|
40
95
|
.sort((a, b) => a.mtimeMs - b.mtimeMs); // oldest first
|
|
41
96
|
|
|
42
97
|
while (files.length >= MAX_SNAPSHOTS) {
|
|
43
|
-
const oldest = files.shift()
|
|
98
|
+
const oldest = files.shift();
|
|
99
|
+
if (!oldest) break;
|
|
44
100
|
unlinkSync(oldest.path);
|
|
45
101
|
}
|
|
46
102
|
} catch {
|
|
@@ -48,23 +104,73 @@ function rotateSnapshots(backupDir: string): void {
|
|
|
48
104
|
}
|
|
49
105
|
}
|
|
50
106
|
|
|
107
|
+
/** Options accepted by {@link vacuumIntoBackup} and {@link vacuumIntoBackupAll}. */
|
|
51
108
|
export interface VacuumOptions {
|
|
109
|
+
/**
|
|
110
|
+
* Working directory used to resolve the project-local `.cleo/backups/sqlite/`
|
|
111
|
+
* directory. Defaults to `process.cwd()` (delegated to {@link getCleoDir}).
|
|
112
|
+
*/
|
|
52
113
|
cwd?: string;
|
|
114
|
+
/** When true, bypass the {@link DEBOUNCE_MS} debounce window. */
|
|
53
115
|
force?: boolean;
|
|
54
116
|
}
|
|
55
117
|
|
|
56
118
|
/**
|
|
57
|
-
* Create a VACUUM INTO snapshot of
|
|
119
|
+
* Create a VACUUM INTO snapshot of a single SQLite database.
|
|
120
|
+
*
|
|
121
|
+
* Runs `PRAGMA wal_checkpoint(TRUNCATE)` first to flush the WAL for a
|
|
122
|
+
* consistent snapshot, then issues `VACUUM INTO '<dest>'` which SQLite
|
|
123
|
+
* implements as an atomic, fully defragmented clone.
|
|
124
|
+
*
|
|
125
|
+
* Non-fatal: all errors are swallowed via the outer try in
|
|
126
|
+
* {@link vacuumIntoBackupAll}; failures here must never block normal
|
|
127
|
+
* operation.
|
|
128
|
+
*
|
|
129
|
+
* @param target — snapshot target descriptor (prefix + native DB getter)
|
|
130
|
+
* @param backupDir — absolute path to `.cleo/backups/sqlite/`
|
|
131
|
+
* @param now — reference timestamp for the filename
|
|
132
|
+
*/
|
|
133
|
+
function snapshotOne(target: SnapshotTarget, backupDir: string, now: Date): void {
|
|
134
|
+
const db = target.getDb();
|
|
135
|
+
if (!db) return; // DB not initialized in this process — skip silently
|
|
136
|
+
|
|
137
|
+
const dest = join(backupDir, `${target.prefix}-${formatTimestamp(now)}.db`);
|
|
138
|
+
|
|
139
|
+
// TRUNCATE checkpoint: flushes all WAL frames to the main DB and truncates
|
|
140
|
+
// the WAL file to zero bytes, ensuring a consistent DB state before the
|
|
141
|
+
// VACUUM INTO snapshot (ADR-013, section 3 point 7). This is safe because
|
|
142
|
+
// the .db files are excluded from project git tracking (.gitignore + git
|
|
143
|
+
// rm --cached), so git operations cannot restore a stale WAL. The root
|
|
144
|
+
// cause of the 2026-02-25 data loss was that WAL files were still tracked
|
|
145
|
+
// in the project git index; that has been resolved (T4894, T5158).
|
|
146
|
+
db.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
147
|
+
|
|
148
|
+
rotateSnapshots(backupDir, target.prefix);
|
|
149
|
+
|
|
150
|
+
// Escape single quotes in path (path is programmatic, but be safe).
|
|
151
|
+
const safeDest = dest.replace(/'/g, "''");
|
|
152
|
+
db.exec(`VACUUM INTO '${safeDest}'`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create a VACUUM INTO snapshot of the primary SQLite database (tasks.db).
|
|
58
157
|
*
|
|
59
|
-
* Debounced by default (30s). Pass `force: true` to bypass debounce.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
158
|
+
* Debounced by default (30s). Pass `force: true` to bypass debounce. This
|
|
159
|
+
* function is retained for backward compatibility with existing call sites
|
|
160
|
+
* in `data-safety.ts` / `data-safety-central.ts` that only snapshot tasks.db.
|
|
62
161
|
*
|
|
63
|
-
*
|
|
162
|
+
* Prefer {@link vacuumIntoBackupAll} for new code — it snapshots every
|
|
163
|
+
* registered database (currently tasks.db + brain.db) and shares the same
|
|
164
|
+
* debounce + rotation guarantees.
|
|
165
|
+
*
|
|
166
|
+
* Non-fatal: all errors are swallowed — backup failure must never
|
|
167
|
+
* interrupt normal operation.
|
|
64
168
|
*/
|
|
65
169
|
export async function vacuumIntoBackup(opts: VacuumOptions = {}): Promise<void> {
|
|
66
170
|
const now = Date.now();
|
|
67
|
-
|
|
171
|
+
const prefix = 'tasks';
|
|
172
|
+
const last = _lastBackupEpoch[prefix] ?? 0;
|
|
173
|
+
if (!opts.force && now - last < DEBOUNCE_MS) {
|
|
68
174
|
return; // debounced
|
|
69
175
|
}
|
|
70
176
|
|
|
@@ -73,36 +179,61 @@ export async function vacuumIntoBackup(opts: VacuumOptions = {}): Promise<void>
|
|
|
73
179
|
const backupDir = join(cleoDir, 'backups', 'sqlite');
|
|
74
180
|
mkdirSync(backupDir, { recursive: true });
|
|
75
181
|
|
|
76
|
-
const
|
|
77
|
-
if (!
|
|
78
|
-
|
|
79
|
-
const dest = join(backupDir, `tasks-${formatTimestamp(new Date())}.db`);
|
|
182
|
+
const target = SNAPSHOT_TARGETS.find((t) => t.prefix === prefix);
|
|
183
|
+
if (!target) return;
|
|
80
184
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// still tracked in the project git index; that has been resolved (T4894).
|
|
88
|
-
db.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
89
|
-
|
|
90
|
-
rotateSnapshots(backupDir);
|
|
185
|
+
snapshotOne(target, backupDir, new Date());
|
|
186
|
+
_lastBackupEpoch[prefix] = Date.now();
|
|
187
|
+
} catch {
|
|
188
|
+
// non-fatal — backup failure must never interrupt normal operation
|
|
189
|
+
}
|
|
190
|
+
}
|
|
91
191
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Create VACUUM INTO snapshots of all registered CLEO SQLite databases
|
|
194
|
+
* (currently tasks.db + brain.db). Each database is debounced independently.
|
|
195
|
+
*
|
|
196
|
+
* This is the preferred entry point for session-lifecycle hooks and
|
|
197
|
+
* pre-destructive-operation snapshots — it guarantees that BRAIN memory is
|
|
198
|
+
* snapshotted alongside task state.
|
|
199
|
+
*
|
|
200
|
+
* Non-fatal: errors are swallowed per database so a brain.db failure cannot
|
|
201
|
+
* block a tasks.db snapshot (and vice versa).
|
|
202
|
+
*/
|
|
203
|
+
export async function vacuumIntoBackupAll(opts: VacuumOptions = {}): Promise<void> {
|
|
204
|
+
const nowMs = Date.now();
|
|
205
|
+
const now = new Date();
|
|
95
206
|
|
|
96
|
-
|
|
207
|
+
let backupDir: string;
|
|
208
|
+
try {
|
|
209
|
+
const cleoDir = getCleoDir(opts.cwd);
|
|
210
|
+
backupDir = join(cleoDir, 'backups', 'sqlite');
|
|
211
|
+
mkdirSync(backupDir, { recursive: true });
|
|
97
212
|
} catch {
|
|
98
|
-
//
|
|
213
|
+
return; // cannot resolve backup dir — abort silently
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
for (const target of SNAPSHOT_TARGETS) {
|
|
217
|
+
const last = _lastBackupEpoch[target.prefix] ?? 0;
|
|
218
|
+
if (!opts.force && nowMs - last < DEBOUNCE_MS) {
|
|
219
|
+
continue; // debounced — skip this target only
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
snapshotOne(target, backupDir, now);
|
|
223
|
+
_lastBackupEpoch[target.prefix] = Date.now();
|
|
224
|
+
} catch {
|
|
225
|
+
// non-fatal — continue with remaining targets
|
|
226
|
+
}
|
|
99
227
|
}
|
|
100
228
|
}
|
|
101
229
|
|
|
102
230
|
/**
|
|
103
|
-
* List existing
|
|
231
|
+
* List existing snapshots for a given prefix (`"tasks"` or `"brain"`),
|
|
232
|
+
* newest first. Returns an empty array if the backup directory does not
|
|
233
|
+
* exist.
|
|
104
234
|
*/
|
|
105
|
-
|
|
235
|
+
function listSqliteBackupsForPrefix(
|
|
236
|
+
prefix: string,
|
|
106
237
|
cwd?: string,
|
|
107
238
|
): Array<{ name: string; path: string; mtimeMs: number }> {
|
|
108
239
|
try {
|
|
@@ -110,8 +241,9 @@ export function listSqliteBackups(
|
|
|
110
241
|
const backupDir = join(cleoDir, 'backups', 'sqlite');
|
|
111
242
|
if (!existsSync(backupDir)) return [];
|
|
112
243
|
|
|
244
|
+
const pattern = snapshotPattern(prefix);
|
|
113
245
|
return readdirSync(backupDir)
|
|
114
|
-
.filter((f) =>
|
|
246
|
+
.filter((f) => pattern.test(f))
|
|
115
247
|
.map((f) => ({
|
|
116
248
|
name: f,
|
|
117
249
|
path: join(backupDir, f),
|
|
@@ -122,3 +254,202 @@ export function listSqliteBackups(
|
|
|
122
254
|
return [];
|
|
123
255
|
}
|
|
124
256
|
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* List existing tasks.db snapshots (newest first).
|
|
260
|
+
*
|
|
261
|
+
* Retained for backward compatibility. For new code prefer
|
|
262
|
+
* {@link listSqliteBackupsAll}.
|
|
263
|
+
*/
|
|
264
|
+
export function listSqliteBackups(
|
|
265
|
+
cwd?: string,
|
|
266
|
+
): Array<{ name: string; path: string; mtimeMs: number }> {
|
|
267
|
+
return listSqliteBackupsForPrefix('tasks', cwd);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* List existing brain.db snapshots (newest first).
|
|
272
|
+
*/
|
|
273
|
+
export function listBrainBackups(
|
|
274
|
+
cwd?: string,
|
|
275
|
+
): Array<{ name: string; path: string; mtimeMs: number }> {
|
|
276
|
+
return listSqliteBackupsForPrefix('brain', cwd);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Aggregated listing of all registered SQLite snapshots.
|
|
281
|
+
*
|
|
282
|
+
* Returns an object keyed by snapshot prefix (`tasks`, `brain`) where each
|
|
283
|
+
* value is the per-prefix list sorted newest-first. Missing prefixes are
|
|
284
|
+
* represented as empty arrays.
|
|
285
|
+
*/
|
|
286
|
+
export function listSqliteBackupsAll(
|
|
287
|
+
cwd?: string,
|
|
288
|
+
): Record<string, Array<{ name: string; path: string; mtimeMs: number }>> {
|
|
289
|
+
const out: Record<string, Array<{ name: string; path: string; mtimeMs: number }>> = {};
|
|
290
|
+
for (const target of SNAPSHOT_TARGETS) {
|
|
291
|
+
out[target.prefix] = listSqliteBackupsForPrefix(target.prefix, cwd);
|
|
292
|
+
}
|
|
293
|
+
return out;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// Global-tier backup (ADR-036 §Backup Mechanism)
|
|
298
|
+
// @task T306
|
|
299
|
+
// @epic T299
|
|
300
|
+
// ============================================================================
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Backup scope: project (per-project `.cleo/`) or global (`$XDG_DATA_HOME/cleo/`).
|
|
304
|
+
*
|
|
305
|
+
* @task T306
|
|
306
|
+
* @epic T299
|
|
307
|
+
*/
|
|
308
|
+
export type BackupScope = 'project' | 'global';
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Registered global-tier snapshot targets. `signaldock` is reserved for T310
|
|
312
|
+
* — only `nexus` is active in v2026.4.11.
|
|
313
|
+
*/
|
|
314
|
+
const GLOBAL_SNAPSHOT_TARGETS: SnapshotTarget[] = [{ prefix: 'nexus', getDb: getNexusNativeDb }];
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Resolve the global-tier backup directory, creating it on first use.
|
|
318
|
+
*
|
|
319
|
+
* Uses `cleoHomeOverride` when provided (test isolation) or falls back to
|
|
320
|
+
* `getCleoHome()` (XDG-compliant; never hardcodes `~/.cleo`).
|
|
321
|
+
*/
|
|
322
|
+
function resolveGlobalBackupDir(cleoHomeOverride?: string): string {
|
|
323
|
+
const base = cleoHomeOverride ?? getCleoHome();
|
|
324
|
+
return join(base, 'backups', 'sqlite');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Snapshot a global-tier SQLite database via VACUUM INTO.
|
|
329
|
+
*
|
|
330
|
+
* Writes to `$XDG_DATA_HOME/cleo/backups/sqlite/<dbName>-YYYYMMDD-HHmmss.db`
|
|
331
|
+
* and enforces a per-prefix rotation window (default 10 snapshots).
|
|
332
|
+
*
|
|
333
|
+
* Non-fatal: errors from any individual step are surfaced via the return value
|
|
334
|
+
* but never thrown — a failed snapshot MUST NOT interrupt normal operation.
|
|
335
|
+
*
|
|
336
|
+
* @param dbName - Which global-tier DB to snapshot (`'nexus'`; `'signaldock'` reserved for T310)
|
|
337
|
+
* @param opts.rotation - Maximum retained snapshots per prefix (default 10)
|
|
338
|
+
* @param opts.cleoHomeOverride - Override `getCleoHome()` path (use in tests to target a tmp dir)
|
|
339
|
+
* @returns Object containing the new snapshot path and any rotated (deleted) file paths
|
|
340
|
+
*
|
|
341
|
+
* @task T306
|
|
342
|
+
* @epic T299
|
|
343
|
+
* @why ADR-036 §Backup Mechanism requires VACUUM INTO rotation at the global tier;
|
|
344
|
+
* nexus.db has zero backup coverage prior to v2026.4.11.
|
|
345
|
+
*/
|
|
346
|
+
export async function vacuumIntoGlobalBackup(
|
|
347
|
+
dbName: 'nexus' | 'signaldock',
|
|
348
|
+
opts?: { rotation?: number; cleoHomeOverride?: string },
|
|
349
|
+
): Promise<{ snapshotPath: string; rotated: string[] }> {
|
|
350
|
+
const maxSnaps = opts?.rotation ?? MAX_SNAPSHOTS;
|
|
351
|
+
const backupDir = resolveGlobalBackupDir(opts?.cleoHomeOverride);
|
|
352
|
+
|
|
353
|
+
mkdirSync(backupDir, { recursive: true });
|
|
354
|
+
|
|
355
|
+
const target = GLOBAL_SNAPSHOT_TARGETS.find((t) => t.prefix === dbName);
|
|
356
|
+
if (!target) {
|
|
357
|
+
return { snapshotPath: '', rotated: [] };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const db = target.getDb();
|
|
361
|
+
if (!db) {
|
|
362
|
+
return { snapshotPath: '', rotated: [] };
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const now = new Date();
|
|
366
|
+
const snapshotName = `${dbName}-${formatTimestamp(now)}.db`;
|
|
367
|
+
const snapshotPath = join(backupDir, snapshotName);
|
|
368
|
+
|
|
369
|
+
// Collect files that will be rotated out before writing the new one.
|
|
370
|
+
const rotated: string[] = [];
|
|
371
|
+
try {
|
|
372
|
+
const pattern = snapshotPattern(dbName);
|
|
373
|
+
const existing = readdirSync(backupDir)
|
|
374
|
+
.filter((f) => pattern.test(f))
|
|
375
|
+
.map((f) => ({
|
|
376
|
+
name: f,
|
|
377
|
+
path: join(backupDir, f),
|
|
378
|
+
mtimeMs: statSync(join(backupDir, f)).mtimeMs,
|
|
379
|
+
}))
|
|
380
|
+
.sort((a, b) => a.mtimeMs - b.mtimeMs); // oldest first
|
|
381
|
+
|
|
382
|
+
// Remove oldest until we have room for the new snapshot.
|
|
383
|
+
while (existing.length >= maxSnaps) {
|
|
384
|
+
const oldest = existing.shift();
|
|
385
|
+
if (!oldest) break;
|
|
386
|
+
try {
|
|
387
|
+
unlinkSync(oldest.path);
|
|
388
|
+
rotated.push(oldest.path);
|
|
389
|
+
} catch {
|
|
390
|
+
// non-fatal rotation failure
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
} catch {
|
|
394
|
+
// non-fatal — continue even if rotation enumeration fails
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Checkpoint then VACUUM INTO for a WAL-free, atomic snapshot.
|
|
398
|
+
db.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
399
|
+
const safeDest = snapshotPath.replace(/'/g, "''");
|
|
400
|
+
db.exec(`VACUUM INTO '${safeDest}'`);
|
|
401
|
+
|
|
402
|
+
return { snapshotPath, rotated };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* A single entry returned by {@link listGlobalSqliteBackups}.
|
|
407
|
+
*
|
|
408
|
+
* @task T306
|
|
409
|
+
* @epic T299
|
|
410
|
+
*/
|
|
411
|
+
export interface GlobalBackupEntry {
|
|
412
|
+
/** Snapshot filename, e.g. `nexus-20260408-143022.db`. */
|
|
413
|
+
name: string;
|
|
414
|
+
/** Absolute path to the snapshot file. */
|
|
415
|
+
path: string;
|
|
416
|
+
/** File size in bytes. */
|
|
417
|
+
size: number;
|
|
418
|
+
/** Last-modified timestamp. */
|
|
419
|
+
mtime: Date;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* List global-tier SQLite backups from `$XDG_DATA_HOME/cleo/backups/sqlite/`,
|
|
424
|
+
* optionally filtered by prefix (e.g. `'nexus'`). Sorted newest-first by mtime.
|
|
425
|
+
*
|
|
426
|
+
* Returns an empty array when the backup directory does not exist.
|
|
427
|
+
*
|
|
428
|
+
* @param prefix - Optional prefix filter; when omitted all `.db` snapshot files are listed
|
|
429
|
+
* @param cleoHomeOverride - Override `getCleoHome()` path (use in tests to target a tmp dir)
|
|
430
|
+
*
|
|
431
|
+
* @task T306
|
|
432
|
+
* @epic T299
|
|
433
|
+
*/
|
|
434
|
+
export function listGlobalSqliteBackups(
|
|
435
|
+
prefix?: string,
|
|
436
|
+
cleoHomeOverride?: string,
|
|
437
|
+
): GlobalBackupEntry[] {
|
|
438
|
+
try {
|
|
439
|
+
const backupDir = resolveGlobalBackupDir(cleoHomeOverride);
|
|
440
|
+
if (!existsSync(backupDir)) return [];
|
|
441
|
+
|
|
442
|
+
const pattern = prefix ? snapshotPattern(prefix) : /^[a-zA-Z0-9_-]+-\d{8}-\d{6}\.db$/;
|
|
443
|
+
|
|
444
|
+
return readdirSync(backupDir)
|
|
445
|
+
.filter((f) => pattern.test(f))
|
|
446
|
+
.map((f) => {
|
|
447
|
+
const filePath = join(backupDir, f);
|
|
448
|
+
const s = statSync(filePath);
|
|
449
|
+
return { name: f, path: filePath, size: s.size, mtime: new Date(s.mtimeMs) };
|
|
450
|
+
})
|
|
451
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime()); // newest first
|
|
452
|
+
} catch {
|
|
453
|
+
return [];
|
|
454
|
+
}
|
|
455
|
+
}
|
package/src/store/sqlite.ts
CHANGED
|
@@ -328,7 +328,21 @@ export async function getDb(cwd?: string): Promise<NodeSQLiteDatabase<typeof sch
|
|
|
328
328
|
// causing data loss when the WAL contained uncommitted writes.
|
|
329
329
|
await autoRecoverFromBackup(nativeDb, dbPath, cwd);
|
|
330
330
|
|
|
331
|
-
// Check if tasks.db or its WAL/SHM are dangerously tracked by git (ADR-013, T5158, T5188)
|
|
331
|
+
// Check if tasks.db or its WAL/SHM are dangerously tracked by git (ADR-013, T5158, T5188).
|
|
332
|
+
//
|
|
333
|
+
// As of ADR-013 §9 (2026-04-07) the canonical resolution is:
|
|
334
|
+
// 1. `.cleo/tasks.db` + WAL/SHM and `.cleo/brain.db` + WAL/SHM are
|
|
335
|
+
// git-ignored at the project root and untracked via `git rm --cached`.
|
|
336
|
+
// 2. Recovery is provided by VACUUM INTO snapshots in
|
|
337
|
+
// `.cleo/backups/sqlite/` (auto-rotated, 10 per DB, refreshed on
|
|
338
|
+
// every `cleo session end` via the backup-session-end hook).
|
|
339
|
+
// 3. Full 4-file snapshots (including config.json + project-info.json)
|
|
340
|
+
// are created on demand via `cleo backup add` / listed via
|
|
341
|
+
// `cleo backup list` / restored via `cleo restore backup`.
|
|
342
|
+
//
|
|
343
|
+
// The warning below is retained as a regression guard: if someone
|
|
344
|
+
// accidentally re-stages the DB into project git, this warning fires at
|
|
345
|
+
// every process startup so they fix it before real data loss occurs.
|
|
332
346
|
if (!_gitTrackingChecked) {
|
|
333
347
|
_gitTrackingChecked = true;
|
|
334
348
|
try {
|
|
@@ -343,12 +357,14 @@ export async function getDb(cwd?: string): Promise<NodeSQLiteDatabase<typeof sch
|
|
|
343
357
|
cwd: gitCwd,
|
|
344
358
|
stdio: 'pipe',
|
|
345
359
|
});
|
|
346
|
-
// If we get here, the file IS tracked — that's dangerous
|
|
360
|
+
// If we get here, the file IS tracked — that's dangerous.
|
|
347
361
|
const basename = fileToCheck.split(/[\\/]/).pop();
|
|
362
|
+
const relPath = fileToCheck.replace(gitCwd + sep, '');
|
|
348
363
|
log.warn(
|
|
349
364
|
{ path: fileToCheck },
|
|
350
365
|
`${basename} is tracked by project git — this risks data loss on branch switch. ` +
|
|
351
|
-
`
|
|
366
|
+
`Resolution (ADR-013 §9): \`git rm --cached ${relPath}\` and rely on ` +
|
|
367
|
+
`\`.cleo/backups/sqlite/\` snapshots + \`cleo backup add\` for recovery.`,
|
|
352
368
|
);
|
|
353
369
|
} catch {
|
|
354
370
|
// Exit code 1 = not tracked = good
|