@cleocode/core 2026.9.8 → 2026.9.10
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/audit/reconstruct.d.ts +13 -43
- package/dist/audit/reconstruct.d.ts.map +1 -1
- package/dist/audit/reconstruct.js +295 -290
- package/dist/audit/reconstruct.js.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +8 -2
- package/dist/bootstrap.js.map +1 -1
- package/dist/compliance/protocol-rules.d.ts.map +1 -1
- package/dist/compliance/protocol-rules.js +3 -1
- package/dist/compliance/protocol-rules.js.map +1 -1
- package/dist/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +12 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/dispatch/mvi-projection.d.ts +29 -6
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +109 -139
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/docs-read-model.d.ts +3 -2
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +4 -3
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/export-document.js +5129 -2297
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/projection.d.ts +67 -0
- package/dist/docs/projection.d.ts.map +1 -0
- package/dist/docs/projection.js +370 -0
- package/dist/docs/projection.js.map +1 -0
- package/dist/doctor/acceptance-drift.d.ts +6 -2
- package/dist/doctor/acceptance-drift.d.ts.map +1 -1
- package/dist/doctor/acceptance-drift.js +43 -5
- package/dist/doctor/acceptance-drift.js.map +1 -1
- package/dist/doctor/knowledge-summary.d.ts +41 -0
- package/dist/doctor/knowledge-summary.d.ts.map +1 -0
- package/dist/doctor/knowledge-summary.js +81 -0
- package/dist/doctor/knowledge-summary.js.map +1 -0
- package/dist/doctor/knowledge.d.ts +192 -0
- package/dist/doctor/knowledge.d.ts.map +1 -0
- package/dist/doctor/knowledge.js +1864 -0
- package/dist/doctor/knowledge.js.map +1 -0
- package/dist/git/work-tree.d.ts +169 -0
- package/dist/git/work-tree.d.ts.map +1 -0
- package/dist/git/work-tree.js +341 -0
- package/dist/git/work-tree.js.map +1 -0
- package/dist/hooks/handlers/task-hooks.d.ts +8 -5
- package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/task-hooks.js +15 -60
- package/dist/hooks/handlers/task-hooks.js.map +1 -1
- package/dist/identity/cleo-identity.d.ts +13 -0
- package/dist/identity/cleo-identity.d.ts.map +1 -1
- package/dist/identity/cleo-identity.js +20 -6
- package/dist/identity/cleo-identity.js.map +1 -1
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +29 -13
- package/dist/injection.js.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -1
- package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
- package/dist/lifecycle/verification/satisfies-validator.js +124 -120
- package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
- package/dist/llm/plugin-facade.js +4047 -1726
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/memory/brain-backfill.d.ts +27 -12
- package/dist/memory/brain-backfill.d.ts.map +1 -1
- package/dist/memory/brain-backfill.js +325 -134
- package/dist/memory/brain-backfill.js.map +1 -1
- package/dist/memory/brain-doctor.d.ts +21 -0
- package/dist/memory/brain-doctor.d.ts.map +1 -1
- package/dist/memory/brain-doctor.js +111 -53
- package/dist/memory/brain-doctor.js.map +1 -1
- package/dist/memory/brain-links.d.ts.map +1 -1
- package/dist/memory/brain-links.js +31 -4
- package/dist/memory/brain-links.js.map +1 -1
- package/dist/memory/brain-reasoning.d.ts.map +1 -1
- package/dist/memory/brain-reasoning.js +28 -2
- package/dist/memory/brain-reasoning.js.map +1 -1
- package/dist/memory/brain-reconciler.d.ts +14 -19
- package/dist/memory/brain-reconciler.d.ts.map +1 -1
- package/dist/memory/brain-reconciler.js +70 -97
- package/dist/memory/brain-reconciler.js.map +1 -1
- package/dist/memory/brain-search.d.ts +2 -0
- package/dist/memory/brain-search.d.ts.map +1 -1
- package/dist/memory/brain-search.js +59 -29
- package/dist/memory/brain-search.js.map +1 -1
- package/dist/memory/brain-similarity.d.ts.map +1 -1
- package/dist/memory/brain-similarity.js +5 -4
- package/dist/memory/brain-similarity.js.map +1 -1
- package/dist/memory/brain-stub-prune.d.ts +31 -9
- package/dist/memory/brain-stub-prune.d.ts.map +1 -1
- package/dist/memory/brain-stub-prune.js +65 -18
- package/dist/memory/brain-stub-prune.js.map +1 -1
- package/dist/memory/brain-writer-handlers.d.ts +10 -1
- package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
- package/dist/memory/brain-writer-handlers.js +23 -3
- package/dist/memory/brain-writer-handlers.js.map +1 -1
- package/dist/memory/brain-writer-thread.d.ts +11 -1
- package/dist/memory/brain-writer-thread.d.ts.map +1 -1
- package/dist/memory/brain-writer-thread.js +87 -20
- package/dist/memory/brain-writer-thread.js.map +1 -1
- package/dist/memory/brain-writer-worker.js +8 -1
- package/dist/memory/brain-writer-worker.js.map +1 -1
- package/dist/memory/decision-cross-link.d.ts +39 -0
- package/dist/memory/decision-cross-link.d.ts.map +1 -1
- package/dist/memory/decision-cross-link.js +316 -0
- package/dist/memory/decision-cross-link.js.map +1 -1
- package/dist/memory/decisions.d.ts +4 -1
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +7 -24
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/dispatch-trace.d.ts +12 -5
- package/dist/memory/dispatch-trace.d.ts.map +1 -1
- package/dist/memory/dispatch-trace.js +17 -7
- package/dist/memory/dispatch-trace.js.map +1 -1
- package/dist/memory/eligibility.d.ts +51 -0
- package/dist/memory/eligibility.d.ts.map +1 -0
- package/dist/memory/eligibility.js +77 -0
- package/dist/memory/eligibility.js.map +1 -0
- package/dist/memory/engine-compat.d.ts +2 -0
- package/dist/memory/engine-compat.d.ts.map +1 -1
- package/dist/memory/engine-compat.js +10 -0
- package/dist/memory/engine-compat.js.map +1 -1
- package/dist/memory/extraction-gate.d.ts +21 -7
- package/dist/memory/extraction-gate.d.ts.map +1 -1
- package/dist/memory/extraction-gate.js +178 -216
- package/dist/memory/extraction-gate.js.map +1 -1
- package/dist/memory/graph-auto-populate.d.ts +38 -5
- package/dist/memory/graph-auto-populate.d.ts.map +1 -1
- package/dist/memory/graph-auto-populate.js +182 -60
- package/dist/memory/graph-auto-populate.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts +14 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +66 -28
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/index.d.ts +1 -19
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -50
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/learnings.d.ts.map +1 -1
- package/dist/memory/learnings.js +2 -23
- package/dist/memory/learnings.js.map +1 -1
- package/dist/memory/manifest-filter.d.ts +21 -0
- package/dist/memory/manifest-filter.d.ts.map +1 -0
- package/dist/memory/manifest-filter.js +51 -0
- package/dist/memory/manifest-filter.js.map +1 -0
- package/dist/memory/manifest-ingestion.d.ts +28 -30
- package/dist/memory/manifest-ingestion.d.ts.map +1 -1
- package/dist/memory/manifest-ingestion.js +104 -235
- package/dist/memory/manifest-ingestion.js.map +1 -1
- package/dist/memory/observer-reflector.d.ts +2 -0
- package/dist/memory/observer-reflector.d.ts.map +1 -1
- package/dist/memory/observer-reflector.js +6 -49
- package/dist/memory/observer-reflector.js.map +1 -1
- package/dist/memory/patterns.d.ts +10 -0
- package/dist/memory/patterns.d.ts.map +1 -1
- package/dist/memory/patterns.js +25 -33
- package/dist/memory/patterns.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +72 -9
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +508 -412
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.js +16 -15
- package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
- package/dist/memory/retrieval/fetch.d.ts +7 -0
- package/dist/memory/retrieval/fetch.d.ts.map +1 -1
- package/dist/memory/retrieval/fetch.js +14 -11
- package/dist/memory/retrieval/fetch.js.map +1 -1
- package/dist/memory/retrieval/observe.d.ts +7 -1
- package/dist/memory/retrieval/observe.d.ts.map +1 -1
- package/dist/memory/retrieval/observe.js +58 -4
- package/dist/memory/retrieval/observe.js.map +1 -1
- package/dist/memory/retrieval/search.d.ts +14 -1
- package/dist/memory/retrieval/search.d.ts.map +1 -1
- package/dist/memory/retrieval/search.js +133 -69
- package/dist/memory/retrieval/search.js.map +1 -1
- package/dist/memory/retrieval/telemetry.d.ts +31 -0
- package/dist/memory/retrieval/telemetry.d.ts.map +1 -0
- package/dist/memory/retrieval/telemetry.js +53 -0
- package/dist/memory/retrieval/telemetry.js.map +1 -0
- package/dist/nexus/analyze-orchestrator.d.ts +41 -9
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +257 -58
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/api-contracts.d.ts +2 -6
- package/dist/nexus/api-contracts.d.ts.map +1 -1
- package/dist/nexus/api-contracts.js +11 -2
- package/dist/nexus/api-contracts.js.map +1 -1
- package/dist/nexus/context.d.ts.map +1 -1
- package/dist/nexus/context.js +14 -37
- package/dist/nexus/context.js.map +1 -1
- package/dist/nexus/diff.d.ts.map +1 -1
- package/dist/nexus/diff.js +2 -1
- package/dist/nexus/diff.js.map +1 -1
- package/dist/nexus/identity.d.ts +29 -3
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +63 -12
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/impact.d.ts +21 -19
- package/dist/nexus/impact.d.ts.map +1 -1
- package/dist/nexus/impact.js +96 -192
- package/dist/nexus/impact.js.map +1 -1
- package/dist/nexus/knowledge.d.ts +80 -0
- package/dist/nexus/knowledge.d.ts.map +1 -0
- package/dist/nexus/knowledge.js +786 -0
- package/dist/nexus/knowledge.js.map +1 -0
- package/dist/nexus/living-brain.d.ts +8 -5
- package/dist/nexus/living-brain.d.ts.map +1 -1
- package/dist/nexus/living-brain.js +252 -188
- package/dist/nexus/living-brain.js.map +1 -1
- package/dist/nexus/registry.d.ts +11 -2
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +144 -128
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/source-roots.d.ts +16 -0
- package/dist/nexus/source-roots.d.ts.map +1 -0
- package/dist/nexus/source-roots.js +174 -0
- package/dist/nexus/source-roots.js.map +1 -0
- package/dist/nexus/task-evidence.d.ts +22 -0
- package/dist/nexus/task-evidence.d.ts.map +1 -0
- package/dist/nexus/task-evidence.js +210 -0
- package/dist/nexus/task-evidence.js.map +1 -0
- package/dist/nexus/tasks-bridge.d.ts +14 -7
- package/dist/nexus/tasks-bridge.d.ts.map +1 -1
- package/dist/nexus/tasks-bridge.js +81 -40
- package/dist/nexus/tasks-bridge.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +170 -120
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts +6 -7
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +509 -532
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts +15 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +21 -10
- package/dist/orchestration/bootstrap.js.map +1 -1
- package/dist/orchestration/index.d.ts +35 -3
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +64 -35
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +24 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +31 -11
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +25 -45
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/unblock.d.ts +15 -1
- package/dist/orchestration/unblock.d.ts.map +1 -1
- package/dist/orchestration/unblock.js +23 -12
- package/dist/orchestration/unblock.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +3 -3
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/orchestration/waves.d.ts +29 -13
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +43 -55
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/paths.d.ts +17 -163
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +145 -496
- package/dist/paths.js.map +1 -1
- package/dist/project-info.d.ts +2 -11
- package/dist/project-info.d.ts.map +1 -1
- package/dist/project-info.js +3 -31
- package/dist/project-info.js.map +1 -1
- package/dist/project-scope.d.ts +239 -0
- package/dist/project-scope.d.ts.map +1 -0
- package/dist/project-scope.js +473 -0
- package/dist/project-scope.js.map +1 -0
- package/dist/release/pr-evidence.d.ts +23 -4
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +65 -9
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/render/nexus/graph/index.d.ts.map +1 -1
- package/dist/render/nexus/graph/index.js +4 -2
- package/dist/render/nexus/graph/index.js.map +1 -1
- package/dist/render/orchestration/audit-reconstruct.d.ts +11 -0
- package/dist/render/orchestration/audit-reconstruct.d.ts.map +1 -1
- package/dist/render/orchestration/audit-reconstruct.js +21 -6
- package/dist/render/orchestration/audit-reconstruct.js.map +1 -1
- package/dist/render/tasks/show.js +2 -1
- package/dist/render/tasks/show.js.map +1 -1
- package/dist/resources/spawn-wrapper.d.ts +82 -14
- package/dist/resources/spawn-wrapper.d.ts.map +1 -1
- package/dist/resources/spawn-wrapper.js +585 -27
- package/dist/resources/spawn-wrapper.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +4055 -1734
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sequence/index.d.ts.map +1 -1
- package/dist/sequence/index.js +76 -68
- package/dist/sequence/index.js.map +1 -1
- package/dist/session/canon-lint.d.ts +24 -3
- package/dist/session/canon-lint.d.ts.map +1 -1
- package/dist/session/canon-lint.js +72 -31
- package/dist/session/canon-lint.js.map +1 -1
- package/dist/session/engine-ops.d.ts +1 -4
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +42 -6
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/briefing.d.ts +11 -1
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +76 -8
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/handoff.d.ts +3 -1
- package/dist/sessions/handoff.d.ts.map +1 -1
- package/dist/sessions/handoff.js +2 -0
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/shutdown-deadline.d.ts +24 -33
- package/dist/shutdown-deadline.d.ts.map +1 -1
- package/dist/shutdown-deadline.js +71 -14
- package/dist/shutdown-deadline.js.map +1 -1
- package/dist/shutdown.d.ts +21 -10
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +89 -42
- package/dist/shutdown.js.map +1 -1
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/orchestrator/validator.d.ts +87 -20
- package/dist/skills/orchestrator/validator.d.ts.map +1 -1
- package/dist/skills/orchestrator/validator.js +330 -241
- package/dist/skills/orchestrator/validator.js.map +1 -1
- package/dist/store/agent-resolver.d.ts.map +1 -1
- package/dist/store/agent-resolver.js +16 -9
- package/dist/store/agent-resolver.js.map +1 -1
- package/dist/store/attachment-store.d.ts +4 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +20 -3
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/background-jobs.d.ts +426 -105
- package/dist/store/background-jobs.d.ts.map +1 -1
- package/dist/store/background-jobs.js +1208 -252
- package/dist/store/background-jobs.js.map +1 -1
- package/dist/store/background-ops.d.ts +145 -8
- package/dist/store/background-ops.d.ts.map +1 -1
- package/dist/store/background-ops.js +459 -15
- package/dist/store/background-ops.js.map +1 -1
- package/dist/store/backup-inspect.d.ts +48 -4
- package/dist/store/backup-inspect.d.ts.map +1 -1
- package/dist/store/backup-inspect.js +384 -4
- package/dist/store/backup-inspect.js.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +19 -2
- package/dist/store/converters.js.map +1 -1
- package/dist/store/data-accessor.d.ts +9 -1
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js +22 -5
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/data-safety-central.d.ts.map +1 -1
- package/dist/store/data-safety-central.js +272 -232
- package/dist/store/data-safety-central.js.map +1 -1
- package/dist/store/db-helpers.d.ts +19 -3
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +42 -58
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +63 -4
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +166 -19
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/archive.d.ts +21 -7
- package/dist/store/exodus/archive.d.ts.map +1 -1
- package/dist/store/exodus/archive.js +60 -18
- package/dist/store/exodus/archive.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +27 -23
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +16 -27
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +121 -169
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts +90 -0
- package/dist/store/exodus/recovery.d.ts.map +1 -0
- package/dist/store/exodus/recovery.js +434 -0
- package/dist/store/exodus/recovery.js.map +1 -0
- package/dist/store/exodus/types.d.ts +15 -0
- package/dist/store/exodus/types.d.ts.map +1 -1
- package/dist/store/memory-accessor.d.ts +52 -3
- package/dist/store/memory-accessor.d.ts.map +1 -1
- package/dist/store/memory-accessor.js +122 -7
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts +24 -6
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +39 -20
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/ports/domain-binding.d.ts.map +1 -1
- package/dist/store/ports/domain-binding.js +27 -5
- package/dist/store/ports/domain-binding.js.map +1 -1
- package/dist/store/schema/background-jobs.d.ts +181 -2
- package/dist/store/schema/background-jobs.d.ts.map +1 -1
- package/dist/store/schema/background-jobs.js +27 -3
- package/dist/store/schema/background-jobs.js.map +1 -1
- package/dist/store/schema/cleo-global/skills.d.ts +2 -2
- package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
- package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +1 -1
- package/dist/store/schema/lifecycle.d.ts +2 -2
- package/dist/store/schema/skills-schema.d.ts +2 -2
- package/dist/store/schema/tasks.d.ts +1 -1
- package/dist/store/session-store.d.ts +3 -1
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +252 -207
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +39 -4
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +689 -527
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +3 -1
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +309 -279
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +8 -8
- package/dist/store/writer-lease.d.ts +80 -8
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +503 -134
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/audit.d.ts +2 -1
- package/dist/system/audit.d.ts.map +1 -1
- package/dist/system/audit.js +118 -71
- package/dist/system/audit.js.map +1 -1
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +5 -5
- package/dist/system/backup.js.map +1 -1
- package/dist/system/inject-generate.js +1 -1
- package/dist/task-work/index.d.ts +3 -0
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +34 -37
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
- package/dist/tasks/ac-coverage-gate.js +4 -0
- package/dist/tasks/ac-coverage-gate.js.map +1 -1
- package/dist/tasks/ac-immutability.d.ts +7 -4
- package/dist/tasks/ac-immutability.d.ts.map +1 -1
- package/dist/tasks/ac-immutability.js +19 -17
- package/dist/tasks/ac-immutability.js.map +1 -1
- package/dist/tasks/ac-table.d.ts +5 -5
- package/dist/tasks/ac-table.d.ts.map +1 -1
- package/dist/tasks/ac-table.js +26 -12
- package/dist/tasks/ac-table.js.map +1 -1
- package/dist/tasks/acceptance-input.d.ts +52 -0
- package/dist/tasks/acceptance-input.d.ts.map +1 -0
- package/dist/tasks/acceptance-input.js +259 -0
- package/dist/tasks/acceptance-input.js.map +1 -0
- package/dist/tasks/add.d.ts +67 -29
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +255 -97
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/complete.d.ts +16 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +152 -55
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/decompose.d.ts +103 -0
- package/dist/tasks/decompose.d.ts.map +1 -0
- package/dist/tasks/decompose.js +224 -0
- package/dist/tasks/decompose.js.map +1 -0
- package/dist/tasks/delete.d.ts +5 -8
- package/dist/tasks/delete.d.ts.map +1 -1
- package/dist/tasks/delete.js +4 -3
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/dependency-check.d.ts +59 -0
- package/dist/tasks/dependency-check.d.ts.map +1 -1
- package/dist/tasks/dependency-check.js +73 -0
- package/dist/tasks/dependency-check.js.map +1 -1
- package/dist/tasks/deps-ready.d.ts +13 -1
- package/dist/tasks/deps-ready.d.ts.map +1 -1
- package/dist/tasks/deps-ready.js +16 -5
- package/dist/tasks/deps-ready.js.map +1 -1
- package/dist/tasks/engine-converters.d.ts +7 -0
- package/dist/tasks/engine-converters.d.ts.map +1 -1
- package/dist/tasks/engine-converters.js +8 -1
- package/dist/tasks/engine-converters.js.map +1 -1
- package/dist/tasks/evidence.d.ts +88 -27
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +344 -43
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/find.d.ts +16 -12
- package/dist/tasks/find.d.ts.map +1 -1
- package/dist/tasks/find.js +107 -93
- package/dist/tasks/find.js.map +1 -1
- package/dist/tasks/gate-preview.d.ts +73 -0
- package/dist/tasks/gate-preview.d.ts.map +1 -0
- package/dist/tasks/gate-preview.js +119 -0
- package/dist/tasks/gate-preview.js.map +1 -0
- package/dist/tasks/gate-runner.d.ts +88 -14
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +719 -250
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/hierarchy-policy.d.ts +8 -0
- package/dist/tasks/hierarchy-policy.d.ts.map +1 -1
- package/dist/tasks/hierarchy-policy.js +9 -2
- package/dist/tasks/hierarchy-policy.js.map +1 -1
- package/dist/tasks/hierarchy.d.ts +67 -1
- package/dist/tasks/hierarchy.d.ts.map +1 -1
- package/dist/tasks/hierarchy.js +81 -1
- package/dist/tasks/hierarchy.js.map +1 -1
- package/dist/tasks/index.d.ts +3 -0
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +3 -0
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/infer-add-params.d.ts +1 -20
- package/dist/tasks/infer-add-params.d.ts.map +1 -1
- package/dist/tasks/infer-add-params.js +2 -203
- package/dist/tasks/infer-add-params.js.map +1 -1
- package/dist/tasks/list.d.ts +7 -2
- package/dist/tasks/list.d.ts.map +1 -1
- package/dist/tasks/list.js +24 -36
- package/dist/tasks/list.js.map +1 -1
- package/dist/tasks/ops.d.ts +6 -61
- package/dist/tasks/ops.d.ts.map +1 -1
- package/dist/tasks/ops.js +5 -53
- package/dist/tasks/ops.js.map +1 -1
- package/dist/tasks/plan.d.ts +15 -1
- package/dist/tasks/plan.d.ts.map +1 -1
- package/dist/tasks/plan.js +23 -25
- package/dist/tasks/plan.js.map +1 -1
- package/dist/tasks/population.d.ts +46 -0
- package/dist/tasks/population.d.ts.map +1 -0
- package/dist/tasks/population.js +88 -0
- package/dist/tasks/population.js.map +1 -0
- package/dist/tasks/reconcile-scope.d.ts +157 -0
- package/dist/tasks/reconcile-scope.d.ts.map +1 -0
- package/dist/tasks/reconcile-scope.js +242 -0
- package/dist/tasks/reconcile-scope.js.map +1 -0
- package/dist/tasks/req.d.ts +51 -12
- package/dist/tasks/req.d.ts.map +1 -1
- package/dist/tasks/req.js +125 -69
- package/dist/tasks/req.js.map +1 -1
- package/dist/tasks/session-scope.d.ts +6 -31
- package/dist/tasks/session-scope.d.ts.map +1 -1
- package/dist/tasks/session-scope.js +3 -17
- package/dist/tasks/session-scope.js.map +1 -1
- package/dist/tasks/severity-attestation.d.ts +39 -10
- package/dist/tasks/severity-attestation.d.ts.map +1 -1
- package/dist/tasks/severity-attestation.js +75 -36
- package/dist/tasks/severity-attestation.js.map +1 -1
- package/dist/tasks/task-next.d.ts +5 -0
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +10 -9
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/task-reparent.d.ts.map +1 -1
- package/dist/tasks/task-reparent.js +3 -13
- package/dist/tasks/task-reparent.js.map +1 -1
- package/dist/tasks/update.d.ts +20 -43
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +64 -49
- package/dist/tasks/update.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +17 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +149 -11
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/workgraph/reparent-preflight.d.ts +1 -1
- package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
- package/dist/workgraph/reparent-preflight.js +6 -1
- package/dist/workgraph/reparent-preflight.js.map +1 -1
- package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
- package/dist/workgraph/scaffold-apply.js +81 -76
- package/dist/workgraph/scaffold-apply.js.map +1 -1
- package/dist/workgraph/structure-validation.d.ts +1 -1
- package/dist/workgraph/structure-validation.d.ts.map +1 -1
- package/dist/workgraph/structure-validation.js +6 -1
- package/dist/workgraph/structure-validation.js.map +1 -1
- package/migrations/drizzle-tasks/20260919180000_t12263-job-ownership-fences/migration.sql +34 -0
- package/migrations/drizzle-tasks/20260919184500_t12265-durable-pending-proposals/migration.sql +4 -0
- package/package.json +18 -13
- package/schemas/config.schema.json +2 -2
- package/schemas/project-context.schema.json +12 -0
- package/templates/CLEO-INJECTION.md +114 -101
package/dist/paths.js
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
* @epic T4454
|
|
15
15
|
* @task T4458
|
|
16
16
|
*/
|
|
17
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
18
17
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
19
18
|
import { createRequire } from 'node:module';
|
|
20
19
|
import { homedir } from 'node:os';
|
|
@@ -22,6 +21,9 @@ import { basename, dirname, join, resolve } from 'node:path';
|
|
|
22
21
|
import { E_CWD_WALKUP_FORBIDDEN, ExitCode } from '@cleocode/contracts';
|
|
23
22
|
import { computeCanonicalProjectId as _computeCanonicalProjectId, getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath, getCleoTemplatesTildePath as _getCleoTemplatesTildePath, isAbsolutePath as _isAbsolutePath, resolveProjectByCwd as _pathsResolveProjectByCwd, resolveCanonicalCleoDir as _resolveCanonicalCleoDir, } from '@cleocode/paths';
|
|
24
23
|
import { CleoError } from './errors.js';
|
|
24
|
+
import { _resolveMainRepoFromGitlink, captureProjectScope, getProjectRoot, validateProjectRoot, worktreeScope, } from './project-scope.js';
|
|
25
|
+
export { getProjectRoot, validateProjectRoot, worktreeScope } from './project-scope.js';
|
|
26
|
+
import { createOperationExecutionContext, trackBackgroundOp } from './store/background-ops.js';
|
|
25
27
|
import { getPlatformPaths } from './system/platform-paths.js';
|
|
26
28
|
/**
|
|
27
29
|
* Lazily-resolved `node:sqlite` `DatabaseSync` constructor.
|
|
@@ -39,36 +41,9 @@ function _getDatabaseSyncCtor() {
|
|
|
39
41
|
const mod = _require('node:sqlite');
|
|
40
42
|
return mod.DatabaseSync;
|
|
41
43
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
*
|
|
46
|
-
* @remarks
|
|
47
|
-
* Set by the spawn adapter (or any caller that wants to redirect CLEO path
|
|
48
|
-
* resolution to a worktree directory) before invoking subagent logic.
|
|
49
|
-
* `getProjectRoot()` checks this store BEFORE the `CLEO_ROOT` env-var and
|
|
50
|
-
* ancestor-walk, so scoped callers transparently receive the worktree root.
|
|
51
|
-
*
|
|
52
|
-
* Callers outside a worktree context receive `undefined` from
|
|
53
|
-
* `worktreeScope.getStore()` and fall through to the existing resolution
|
|
54
|
-
* order unchanged.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* import { worktreeScope } from '@cleocode/core/paths';
|
|
59
|
-
*
|
|
60
|
-
* worktreeScope.run(
|
|
61
|
-
* { worktreeRoot: '/path/to/worktree', projectHash: 'abc123' },
|
|
62
|
-
* async () => {
|
|
63
|
-
* const root = getProjectRoot(); // returns '/path/to/worktree'
|
|
64
|
-
* }
|
|
65
|
-
* );
|
|
66
|
-
* ```
|
|
67
|
-
*
|
|
68
|
-
* @task T380
|
|
69
|
-
* @public
|
|
70
|
-
*/
|
|
71
|
-
export const worktreeScope = new AsyncLocalStorage();
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Worktree Scope (T380/ADR-041 §D3)
|
|
46
|
+
// ============================================================================
|
|
72
47
|
/**
|
|
73
48
|
* Run `fn` inside a `worktreeScope.run()` AsyncLocalStorage frame derived
|
|
74
49
|
* from the `CLEO_WORKTREE_ROOT` and `CLEO_PROJECT_HASH` environment variables.
|
|
@@ -297,10 +272,16 @@ export function getCleoDir(cwd) {
|
|
|
297
272
|
* getCleoDirAbsolute('/tmp/new-project', { bootstrap: true }); // "/tmp/new-project/.cleo"
|
|
298
273
|
* ```
|
|
299
274
|
*
|
|
275
|
+
* @remarks Active worktree scope takes precedence over ambient CLEO_DIR, matching
|
|
276
|
+
* resolveCleoDir. Outside a scope, absolute CLEO_DIR retains its override behavior.
|
|
300
277
|
* @deprecated Migrate to {@link resolveProjectByCwd} + {@link resolveCanonicalCleoDir}
|
|
301
278
|
* @task T11009
|
|
302
279
|
*/
|
|
303
280
|
export function getCleoDirAbsolute(cwd, opts) {
|
|
281
|
+
// Captured ownership has the same precedence as the canonical resolver.
|
|
282
|
+
// Ambient overrides retain their historical behavior only outside a scope.
|
|
283
|
+
if (worktreeScope.getStore() !== undefined)
|
|
284
|
+
return resolveCleoDir(cwd);
|
|
304
285
|
const cleoDir = getCleoDir();
|
|
305
286
|
if (isAbsolutePath(cleoDir)) {
|
|
306
287
|
return cleoDir;
|
|
@@ -350,7 +331,7 @@ export function getCleoDirAbsolute(cwd, opts) {
|
|
|
350
331
|
// as the path authority.
|
|
351
332
|
const project = _pathsResolveProjectByCwd(cwd);
|
|
352
333
|
if (project !== null) {
|
|
353
|
-
// T11021:
|
|
334
|
+
// T11021: Schedule lifecycle-tracked registration against captured global ownership.
|
|
354
335
|
// T11023: pass legacyUUID so it gets registered as an alias alongside
|
|
355
336
|
// the canonical ID.
|
|
356
337
|
// T11281: unit tests that exercise the nexus registration/reconcile contract
|
|
@@ -359,7 +340,9 @@ export function getCleoDirAbsolute(cwd, opts) {
|
|
|
359
340
|
// test's explicit registration state. Off by default — production always
|
|
360
341
|
// auto-registers on encounter.
|
|
361
342
|
if (process.env['CLEO_DISABLE_PROJECT_AUTOREGISTER'] !== '1') {
|
|
362
|
-
registerProjectOnEncounter(project.projectRoot, project.legacyUUID ?? project.projectId).catch(() => {
|
|
343
|
+
registerProjectOnEncounter(project.projectRoot, project.legacyUUID ?? project.projectId).catch((error) => {
|
|
344
|
+
process.stderr.write(`[cleo] Project encounter registration failed: ${error.message}\n`);
|
|
345
|
+
});
|
|
363
346
|
}
|
|
364
347
|
try {
|
|
365
348
|
const projectRoot = getProjectRoot(cwd);
|
|
@@ -808,43 +791,6 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
808
791
|
current = parent;
|
|
809
792
|
}
|
|
810
793
|
}
|
|
811
|
-
/**
|
|
812
|
-
* Attempt to resolve the main git repo root from a gitlink (.git as FILE).
|
|
813
|
-
* Returns the main repo path if the gitlink is valid and the main repo is a
|
|
814
|
-
* CLEO project; otherwise returns `null`.
|
|
815
|
-
*
|
|
816
|
-
* @internal
|
|
817
|
-
* @task T11034
|
|
818
|
-
*/
|
|
819
|
-
function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
820
|
-
try {
|
|
821
|
-
const gitLinkPath = join(gitlinkDir, '.git');
|
|
822
|
-
if (!existsSync(gitLinkPath))
|
|
823
|
-
return null;
|
|
824
|
-
const stat = statSync(gitLinkPath);
|
|
825
|
-
if (!stat.isFile())
|
|
826
|
-
return null;
|
|
827
|
-
const gitLinkContent = readFileSync(gitLinkPath, 'utf-8').trim();
|
|
828
|
-
const match = gitLinkContent.match(/^gitdir:\s*(.+)$/m);
|
|
829
|
-
if (!match)
|
|
830
|
-
return null;
|
|
831
|
-
const gitdir = match[1].trim();
|
|
832
|
-
// gitdir is `<main>/.git/worktrees/<name>` → strip last 3 segments.
|
|
833
|
-
const mainRepo = dirname(dirname(dirname(gitdir)));
|
|
834
|
-
if (existsSync(join(mainRepo, '.cleo')) && validateProjectRoot(mainRepo)) {
|
|
835
|
-
return mainRepo;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
catch {
|
|
839
|
-
// Parse error — not a valid gitlink.
|
|
840
|
-
}
|
|
841
|
-
return null;
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* Module-level flag: emit the legacy-fallback warning at most once per process.
|
|
845
|
-
* Prevents log spam when `validateProjectRoot` is called repeatedly in a session.
|
|
846
|
-
*/
|
|
847
|
-
let _legacyFallbackWarned = false;
|
|
848
794
|
/**
|
|
849
795
|
* Module-level flag: emit the T10297 deprecation warning for
|
|
850
796
|
* `getCleoDirAbsolute` at most once per process (AC4).
|
|
@@ -854,133 +800,6 @@ let _legacyFallbackWarned = false;
|
|
|
854
800
|
* @saga T10295
|
|
855
801
|
*/
|
|
856
802
|
let _getCleoDirAbsoluteDeprecatedWarned = false;
|
|
857
|
-
/**
|
|
858
|
-
* Validate that a candidate project root directory is a legitimate CLEO
|
|
859
|
-
* project root and not a stray parent `.cleo/` directory that happened to
|
|
860
|
-
* be found by the walk-up algorithm.
|
|
861
|
-
*
|
|
862
|
-
* ## Primary path (T1864 — project-info.json contract)
|
|
863
|
-
*
|
|
864
|
-
* A candidate is **accepted** when `.cleo/project-info.json` exists and
|
|
865
|
-
* parses as JSON with a non-empty `projectId` string field. This is the
|
|
866
|
-
* canonical form written by `cleo init` and is the only form that guarantees
|
|
867
|
-
* the directory is a proper CLEO project rather than a stray `.cleo/` left by
|
|
868
|
-
* an old installation or a git worktree that auto-created its own `.cleo/`.
|
|
869
|
-
*
|
|
870
|
-
* ## Legacy fallback (backwards-compatibility)
|
|
871
|
-
*
|
|
872
|
-
* Projects initialized before `project-info.json` was introduced are still
|
|
873
|
-
* accepted when **both** of the following are true:
|
|
874
|
-
* 1. `.cleo/` exists in `candidate`
|
|
875
|
-
* 2. `.git/` exists as a sibling of `.cleo/` in `candidate`
|
|
876
|
-
*
|
|
877
|
-
* A one-time stderr warning is emitted (guarded by `_legacyFallbackWarned`)
|
|
878
|
-
* so operators know to re-run `cleo init` to upgrade the project metadata.
|
|
879
|
-
*
|
|
880
|
-
* **Breaking change vs. prior implementation**: bare `package.json` alone is
|
|
881
|
-
* no longer sufficient. The old check `existsSync(gitDir) || existsSync(pkgJson)`
|
|
882
|
-
* accepted any Node.js package directory as a valid project root, which caused
|
|
883
|
-
* the monorepo-package bug where sub-packages inside `packages/` created their
|
|
884
|
-
* own empty `.cleo/` databases.
|
|
885
|
-
*
|
|
886
|
-
* @param candidate - Absolute path to the directory being considered as the
|
|
887
|
-
* project root (parent of the `.cleo/` directory).
|
|
888
|
-
* @returns `true` when the candidate is a recognised CLEO project root.
|
|
889
|
-
*
|
|
890
|
-
* @example
|
|
891
|
-
* ```typescript
|
|
892
|
-
* // Project root with project-info.json — valid (primary path)
|
|
893
|
-
* validateProjectRoot('/home/user/myproject'); // true
|
|
894
|
-
*
|
|
895
|
-
* // Legacy project root with .git/ but no project-info.json — valid + warning
|
|
896
|
-
* validateProjectRoot('/home/user/legacy-project'); // true (+ stderr warning)
|
|
897
|
-
*
|
|
898
|
-
* // Stray .cleo in home dir with no markers — invalid
|
|
899
|
-
* validateProjectRoot('/home/user'); // false
|
|
900
|
-
* ```
|
|
901
|
-
*
|
|
902
|
-
* @task T1463
|
|
903
|
-
* @task T1864
|
|
904
|
-
*/
|
|
905
|
-
export function validateProjectRoot(candidate) {
|
|
906
|
-
const cleoDir = join(candidate, '.cleo');
|
|
907
|
-
if (!existsSync(cleoDir)) {
|
|
908
|
-
return false;
|
|
909
|
-
}
|
|
910
|
-
// Primary: .cleo/project-info.json with a valid projectId string.
|
|
911
|
-
// T11034 — Worktree guard: a worktree has .git as a gitlink FILE, not a
|
|
912
|
-
// directory. project-info.json is copied into worktrees for identity
|
|
913
|
-
// inheritance (T11033), but worktrees must NOT be treated as standalone
|
|
914
|
-
// project roots — path resolution must walk past them to the parent project.
|
|
915
|
-
const projectInfoPath = join(cleoDir, 'project-info.json');
|
|
916
|
-
if (existsSync(projectInfoPath)) {
|
|
917
|
-
try {
|
|
918
|
-
const raw = readFileSync(projectInfoPath, 'utf-8');
|
|
919
|
-
const parsed = JSON.parse(raw);
|
|
920
|
-
if (typeof parsed === 'object' &&
|
|
921
|
-
parsed !== null &&
|
|
922
|
-
'projectId' in parsed &&
|
|
923
|
-
typeof parsed['projectId'] === 'string' &&
|
|
924
|
-
parsed['projectId'] !== '') {
|
|
925
|
-
// T11034: Reject worktrees — .git is a gitlink FILE, not a directory.
|
|
926
|
-
// Workers should resolve through to the parent project root.
|
|
927
|
-
const gitMarker = join(candidate, '.git');
|
|
928
|
-
if (existsSync(gitMarker)) {
|
|
929
|
-
try {
|
|
930
|
-
if (!statSync(gitMarker).isDirectory()) {
|
|
931
|
-
// Gitlink file (worktree) — NOT a project root.
|
|
932
|
-
return false;
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
catch {
|
|
936
|
-
// Stat failed — treat as non-directory (reject).
|
|
937
|
-
return false;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return true;
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
catch {
|
|
944
|
-
// JSON parse error or read error — fall through to legacy check.
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
// Legacy fallback: .cleo/ + .git/ sibling (no project-info.json required).
|
|
948
|
-
// Emits a one-time warning to prompt the operator to run `cleo init`.
|
|
949
|
-
//
|
|
950
|
-
// CRITICAL (T9092): a git worktree has `.git` as a *file* (a "gitlink" pointing
|
|
951
|
-
// back to the main repo's .git/worktrees/<name> directory), NOT a directory.
|
|
952
|
-
// Accepting such candidates as project roots recreates the 2026-05-04 dead-end-DB
|
|
953
|
-
// disaster pattern: workers spawned in a worktree create rogue `.cleo/tasks.db`
|
|
954
|
-
// files isolated from the real project database. The legacy fallback MUST only
|
|
955
|
-
// accept candidates where `.git` is a true directory (a real repo root).
|
|
956
|
-
const gitDir = join(candidate, '.git');
|
|
957
|
-
if (existsSync(gitDir)) {
|
|
958
|
-
let isRealGitDir = false;
|
|
959
|
-
try {
|
|
960
|
-
const stat = statSync(gitDir);
|
|
961
|
-
isRealGitDir = stat.isDirectory();
|
|
962
|
-
}
|
|
963
|
-
catch {
|
|
964
|
-
isRealGitDir = false;
|
|
965
|
-
}
|
|
966
|
-
if (!isRealGitDir) {
|
|
967
|
-
// .git is a gitlink file (worktree marker) — NOT a project root.
|
|
968
|
-
return false;
|
|
969
|
-
}
|
|
970
|
-
if (!_legacyFallbackWarned) {
|
|
971
|
-
_legacyFallbackWarned = true;
|
|
972
|
-
// T9774: debug-only — surfaced via CLEO_DEBUG to keep stderr clean by default.
|
|
973
|
-
// Cannot use pushWarning here because paths.ts is in the import chain of
|
|
974
|
-
// output.ts (output → sessions/context-alert → paths) — circular dep.
|
|
975
|
-
if (process.env['CLEO_DEBUG']) {
|
|
976
|
-
process.stderr.write(`[cleo][debug] W_PATH_RESOLUTION: ${candidate}/.cleo/ lacks project-info.json. ` +
|
|
977
|
-
`Run \`cleo init\` to upgrade project metadata (T1864 legacy-fallback).\n`);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
return true;
|
|
981
|
-
}
|
|
982
|
-
return false;
|
|
983
|
-
}
|
|
984
803
|
/**
|
|
985
804
|
* Assert that the given directory is an initialized CLEO project root,
|
|
986
805
|
* throwing a `CleoError` if it is not.
|
|
@@ -1010,184 +829,6 @@ export function assertProjectInitialized(projectRoot) {
|
|
|
1010
829
|
});
|
|
1011
830
|
}
|
|
1012
831
|
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Get the project root by walking ancestor directories for `.cleo/` or `.git/`.
|
|
1015
|
-
*
|
|
1016
|
-
* Stops at the **first** ancestor directory that contains either sentinel
|
|
1017
|
-
* directory and never drifts past it — even when multiple nested projects
|
|
1018
|
-
* exist above the starting directory.
|
|
1019
|
-
*
|
|
1020
|
-
* Resolution order:
|
|
1021
|
-
* 1. `CLEO_ROOT` env var — bypasses walk entirely (CI / test override)
|
|
1022
|
-
* 2. `CLEO_DIR` env var (absolute path only) — derives project root from dirname
|
|
1023
|
-
* 3. Walk ancestors from `cwd` (or `process.cwd()`) toward filesystem root:
|
|
1024
|
-
* - `.cleo/` found with a sibling `.git/` or `package.json` → accept as root
|
|
1025
|
-
* - `.cleo/` found but **no** sibling marker → skip (stray/parent `.cleo/`)
|
|
1026
|
-
* - `.git/` found (without `.cleo/` sibling) → throw `E_NOT_INITIALIZED`
|
|
1027
|
-
* 4. Filesystem root reached without a valid root → throw `E_INVALID_PROJECT_ROOT`
|
|
1028
|
-
* (if at least one `.cleo/` was skipped) or `E_NO_PROJECT` (none found)
|
|
1029
|
-
*
|
|
1030
|
-
* @param cwd - Optional starting directory; defaults to `process.cwd()`
|
|
1031
|
-
* @returns Absolute path to the project root directory (parent of `.cleo/`)
|
|
1032
|
-
* @throws {CleoError} `ExitCode.CONFIG_ERROR` (`E_NOT_INITIALIZED`) when a
|
|
1033
|
-
* `.git/` is found but no `.cleo/` is present at that level.
|
|
1034
|
-
* @throws {CleoError} `ExitCode.CONFIG_ERROR` (`E_INVALID_PROJECT_ROOT`) when
|
|
1035
|
-
* one or more `.cleo/` directories are found but none have the required sibling
|
|
1036
|
-
* markers (`.git/` or `package.json`). This prevents accidental operations on
|
|
1037
|
-
* the wrong project when a stray parent `.cleo/` exists higher in the filesystem.
|
|
1038
|
-
* @throws {CleoError} `ExitCode.NOT_FOUND` (`E_NO_PROJECT`) when neither
|
|
1039
|
-
* sentinel is found in any ancestor.
|
|
1040
|
-
*
|
|
1041
|
-
* @remarks
|
|
1042
|
-
* `CLEO_ROOT` is an absolute-path escape hatch for environments where the
|
|
1043
|
-
* working directory is unrelated to the project (CI tmpdirs, monorepo scripts,
|
|
1044
|
-
* test harnesses). When set it is returned as-is without scanning ancestors.
|
|
1045
|
-
*
|
|
1046
|
-
* `CLEO_DIR` set to an absolute path (e.g. `/project/.cleo`) also bypasses
|
|
1047
|
-
* the walk: the project root is derived as its `dirname`. This preserves
|
|
1048
|
-
* backward compatibility for test harnesses that use `CLEO_DIR` to pin the
|
|
1049
|
-
* project root.
|
|
1050
|
-
*
|
|
1051
|
-
* NEVER auto-creates `.cleo/`. Project initialisation is an explicit opt-in
|
|
1052
|
-
* via `cleo init`.
|
|
1053
|
-
*
|
|
1054
|
-
* @example
|
|
1055
|
-
* ```typescript
|
|
1056
|
-
* // Running from packages/core inside the monorepo:
|
|
1057
|
-
* const root = getProjectRoot(); // "/mnt/projects/cleocode"
|
|
1058
|
-
* ```
|
|
1059
|
-
*/
|
|
1060
|
-
export function getProjectRoot(cwd) {
|
|
1061
|
-
// 0. AsyncLocalStorage worktree scope (T380/ADR-041 §D3) — checked FIRST.
|
|
1062
|
-
// When a spawn adapter wraps execution in worktreeScope.run(...), the
|
|
1063
|
-
// scoped root wins over all env-var and walk-based resolution.
|
|
1064
|
-
const scope = worktreeScope.getStore();
|
|
1065
|
-
if (scope !== undefined) {
|
|
1066
|
-
return scope.worktreeRoot;
|
|
1067
|
-
}
|
|
1068
|
-
// 1. Honour CLEO_ROOT / CLEO_PROJECT_ROOT env var — bypass walk entirely.
|
|
1069
|
-
// CLEO_PROJECT_ROOT is the agent-friendly alias (T090).
|
|
1070
|
-
const envRoot = process.env['CLEO_ROOT'] ?? process.env['CLEO_PROJECT_ROOT'];
|
|
1071
|
-
if (envRoot) {
|
|
1072
|
-
return envRoot;
|
|
1073
|
-
}
|
|
1074
|
-
// 2. If CLEO_DIR is an absolute path, derive the project root from it.
|
|
1075
|
-
// This preserves backward compatibility for test harnesses that set
|
|
1076
|
-
// CLEO_DIR=/some/absolute/path/.cleo to pin the project root.
|
|
1077
|
-
const cleoDirEnv = process.env['CLEO_DIR'];
|
|
1078
|
-
if (cleoDirEnv && isAbsolutePath(cleoDirEnv)) {
|
|
1079
|
-
if (cleoDirEnv.endsWith('/.cleo') || cleoDirEnv.endsWith('\\.cleo')) {
|
|
1080
|
-
return dirname(cleoDirEnv);
|
|
1081
|
-
}
|
|
1082
|
-
return cleoDirEnv;
|
|
1083
|
-
}
|
|
1084
|
-
const start = resolve(cwd ?? process.cwd());
|
|
1085
|
-
let current = start;
|
|
1086
|
-
// 2.5. T9092 + T11034: if `start` is inside a git worktree (i.e. has `.git` as a
|
|
1087
|
-
// gitlink FILE pointing to `<mainrepo>/.git/worktrees/<name>`), the
|
|
1088
|
-
// canonical project root is the MAIN repo, not the worktree dir.
|
|
1089
|
-
// Delegates to the shared _resolveMainRepoFromGitlink helper which
|
|
1090
|
-
// provides deterministic resolution from any worktree path.
|
|
1091
|
-
const mainRepoFromStart = _resolveMainRepoFromGitlink(start);
|
|
1092
|
-
if (mainRepoFromStart !== null)
|
|
1093
|
-
return mainRepoFromStart;
|
|
1094
|
-
// T889/T909 guard: snapshot $HOME and filesystem root sentinels.
|
|
1095
|
-
//
|
|
1096
|
-
// Historical bug: when `cleo` ran with `cwd=$HOME` and a stray
|
|
1097
|
-
// `~/.cleo/` existed (from a prior buggy run or user mistake), the
|
|
1098
|
-
// walk-up returned `$HOME` as the project root. This silently created
|
|
1099
|
-
// `~/.cleo/conduit.db`, `~/.cleo/tasks.db`, etc. — diverging from the
|
|
1100
|
-
// real project DBs and losing data on branch switch. See ADR-037
|
|
1101
|
-
// (conduit.db is project-tier-only) and the orphan-conduit remediation.
|
|
1102
|
-
//
|
|
1103
|
-
// Contract: `getProjectRoot` MUST NEVER resolve to `$HOME` or `/`.
|
|
1104
|
-
// If the walk would land there, treat it as "no project" rather than
|
|
1105
|
-
// silently accepting a pathological root. Users who legitimately want
|
|
1106
|
-
// `$HOME` as a project root must set `CLEO_ROOT=$HOME` explicitly — the
|
|
1107
|
-
// env-var path above bypasses this guard, making the opt-in explicit.
|
|
1108
|
-
const homeRoot = homedir();
|
|
1109
|
-
// T1463/P1-7: track if we skipped any .cleo/ dirs that failed validation.
|
|
1110
|
-
// Used to produce a more informative error message when every candidate
|
|
1111
|
-
// was rejected by validateProjectRoot.
|
|
1112
|
-
const skippedCleoDirs = [];
|
|
1113
|
-
// 3. Walk ancestors toward filesystem root
|
|
1114
|
-
while (true) {
|
|
1115
|
-
const cleoDir = join(current, '.cleo');
|
|
1116
|
-
const gitDir = join(current, '.git');
|
|
1117
|
-
// T889/T909: refuse to accept $HOME or / as a project root, even if a
|
|
1118
|
-
// `.cleo/` sentinel exists there. This blocks the orphan-DB vector.
|
|
1119
|
-
const isDangerousRoot = current === homeRoot || current === '/' || current === '';
|
|
1120
|
-
if (existsSync(cleoDir) && !isDangerousRoot) {
|
|
1121
|
-
// T1463/P1-7: validate that the .cleo/ dir has the required sibling
|
|
1122
|
-
// markers (.git/ or package.json) before accepting this candidate.
|
|
1123
|
-
//
|
|
1124
|
-
// T9092: previously the start-directory short-circuit was unconditional —
|
|
1125
|
-
// `current === start` returned the candidate without running
|
|
1126
|
-
// validateProjectRoot. That allowed a worktree (whose `.git` is a gitlink
|
|
1127
|
-
// FILE not a directory) to be accepted as a project root if any process
|
|
1128
|
-
// had previously created a stray `.cleo/` inside it. validateProjectRoot
|
|
1129
|
-
// now rejects gitlink-only candidates, so we must run it on the start dir
|
|
1130
|
-
// too — but only as a *gate* to walk up further, not to reject outright.
|
|
1131
|
-
// If start dir validation fails, we continue walking to find the real
|
|
1132
|
-
// project root (the main repo).
|
|
1133
|
-
if (validateProjectRoot(current)) {
|
|
1134
|
-
// Valid project root.
|
|
1135
|
-
return current;
|
|
1136
|
-
}
|
|
1137
|
-
// Stray/rogue .cleo/ found (e.g. worktree with gitlink, or .cleo without
|
|
1138
|
-
// project-info.json AND without a real .git/ sibling) — skip it and
|
|
1139
|
-
// continue walking up for the canonical project root.
|
|
1140
|
-
skippedCleoDirs.push(current);
|
|
1141
|
-
}
|
|
1142
|
-
if (existsSync(gitDir) && !isDangerousRoot) {
|
|
1143
|
-
// T9092: only treat .git as a "real repo root" boundary when it is a
|
|
1144
|
-
// DIRECTORY. A gitlink FILE (worktree marker) does not anchor a project
|
|
1145
|
-
// root — keep walking up to find the canonical main repo.
|
|
1146
|
-
let isRealGitDir = false;
|
|
1147
|
-
try {
|
|
1148
|
-
isRealGitDir = statSync(gitDir).isDirectory();
|
|
1149
|
-
}
|
|
1150
|
-
catch {
|
|
1151
|
-
isRealGitDir = false;
|
|
1152
|
-
}
|
|
1153
|
-
if (isRealGitDir) {
|
|
1154
|
-
// Real .git/ found but no .cleo/ sibling — not initialised
|
|
1155
|
-
throw new CleoError(ExitCode.CONFIG_ERROR, `Run cleo init at ${current}`, {
|
|
1156
|
-
fix: `cd ${current} && cleo init`,
|
|
1157
|
-
});
|
|
1158
|
-
}
|
|
1159
|
-
// gitlink file — attempt to resolve the main repo from it (T11034).
|
|
1160
|
-
// When a worktree lives under ~/.local/share/cleo/worktrees/... and the
|
|
1161
|
-
// caller is in a subdirectory (not the worktree root), the start-level
|
|
1162
|
-
// gitlink check misses it. During the walk we must resolve gitlinks
|
|
1163
|
-
// to ensure deterministic resolution from any worktree path.
|
|
1164
|
-
const mainRepoFromWalk = _resolveMainRepoFromGitlink(current);
|
|
1165
|
-
if (mainRepoFromWalk !== null)
|
|
1166
|
-
return mainRepoFromWalk;
|
|
1167
|
-
// gitlink we couldn't resolve — keep walking up.
|
|
1168
|
-
}
|
|
1169
|
-
// Move up one level
|
|
1170
|
-
const parent = dirname(current);
|
|
1171
|
-
if (parent === current) {
|
|
1172
|
-
// Reached filesystem root without finding either sentinel
|
|
1173
|
-
break;
|
|
1174
|
-
}
|
|
1175
|
-
current = parent;
|
|
1176
|
-
}
|
|
1177
|
-
// 4a. At least one .cleo/ was found but all were rejected by validateProjectRoot.
|
|
1178
|
-
// This is the "parent .cleo/ trap" scenario: a stray .cleo/ dir higher in
|
|
1179
|
-
// the filesystem lacks a .git/ or package.json sibling, so it cannot be
|
|
1180
|
-
// trusted as a project root.
|
|
1181
|
-
if (skippedCleoDirs.length > 0) {
|
|
1182
|
-
throw new CleoError(ExitCode.CONFIG_ERROR, `E_INVALID_PROJECT_ROOT: no .cleo with sibling .git found from ${start} (skipped: ${skippedCleoDirs.join(', ')})`, {
|
|
1183
|
-
fix: `cleo init or add a .git directory alongside the .cleo dir`,
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
// 4b. No sentinel found in any ancestor
|
|
1187
|
-
throw new CleoError(ExitCode.NOT_FOUND, 'Not inside a CLEO project. Run cleo init or cd to an existing project', {
|
|
1188
|
-
fix: 'cleo init',
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
832
|
/**
|
|
1192
833
|
* Resolve an optional caller-provided root, falling back to canonical project root.
|
|
1193
834
|
*
|
|
@@ -2069,133 +1710,141 @@ function _rowToRegistryEntry(row) {
|
|
|
2069
1710
|
taskCount: Number(row['taskCount'] ?? 0),
|
|
2070
1711
|
};
|
|
2071
1712
|
}
|
|
2072
|
-
/** Read project name
|
|
1713
|
+
/** Read optional project name; malformed or unreadable existing metadata is a diagnostic. */
|
|
2073
1714
|
function _readProjectNameFromInfo(projectRoot) {
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
if (!existsSync(infoPath))
|
|
2077
|
-
return undefined;
|
|
2078
|
-
const raw = readFileSync(infoPath, 'utf-8');
|
|
2079
|
-
const data = JSON.parse(raw);
|
|
2080
|
-
return typeof data.name === 'string' && data.name.length > 0 ? data.name : undefined;
|
|
2081
|
-
}
|
|
2082
|
-
catch {
|
|
1715
|
+
const infoPath = join(projectRoot, '.cleo', 'project-info.json');
|
|
1716
|
+
if (!existsSync(infoPath))
|
|
2083
1717
|
return undefined;
|
|
2084
|
-
|
|
1718
|
+
const raw = readFileSync(infoPath, 'utf-8');
|
|
1719
|
+
const data = JSON.parse(raw);
|
|
1720
|
+
return typeof data.name === 'string' && data.name.length > 0 ? data.name : undefined;
|
|
2085
1721
|
}
|
|
2086
|
-
/**
|
|
1722
|
+
/**
|
|
1723
|
+
* Register an encountered project's immutable identity in its captured global registry.
|
|
1724
|
+
* @param projectRoot - Explicit project ownership captured before asynchronous work.
|
|
1725
|
+
* @param infoProjectId - Existing immutable project identity, never inferred from similarity.
|
|
1726
|
+
* @returns Completion of the fully tracked operation, including any failure.
|
|
1727
|
+
* @remarks Lazy work obeys the existing transaction/queue boundary and shares the
|
|
1728
|
+
* original execution deadline. Registry writes never initialize the project graph.
|
|
1729
|
+
* Cancellation is checked before the actual synchronous registry transaction commits.
|
|
1730
|
+
* @example
|
|
1731
|
+
* ```ts
|
|
1732
|
+
* await registerProjectOnEncounter(projectRoot, projectId);
|
|
1733
|
+
* ```
|
|
1734
|
+
*/
|
|
2087
1735
|
export async function registerProjectOnEncounter(projectRoot, infoProjectId) {
|
|
1736
|
+
const scope = captureProjectScope(projectRoot, worktreeScope.getStore());
|
|
1737
|
+
const capturedHome = getCleoHome();
|
|
1738
|
+
const resolvedPath = scope.worktreeRoot;
|
|
1739
|
+
const projectName = _readProjectNameFromInfo(resolvedPath) || basename(resolvedPath) || 'unnamed';
|
|
1740
|
+
if (!infoProjectId.trim())
|
|
1741
|
+
throw new Error('Project encounter requires an existing immutable identity');
|
|
1742
|
+
const ownedExecution = !scope.execution;
|
|
1743
|
+
const execution = scope.execution ??
|
|
1744
|
+
createOperationExecutionContext({
|
|
1745
|
+
projectId: infoProjectId,
|
|
1746
|
+
projectRoot: resolvedPath,
|
|
1747
|
+
actor: 'project-encounter',
|
|
1748
|
+
operation: 'nexus.register-encounter',
|
|
1749
|
+
idempotencyKey: `${capturedHome}:${infoProjectId}:${resolvedPath}`,
|
|
1750
|
+
});
|
|
2088
1751
|
try {
|
|
2089
|
-
const {
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
const { legacyProjectId } = await import('./nexus/identity.js');
|
|
2182
|
-
const directLegacy = legacyProjectId(resolvedPath);
|
|
2183
|
-
const allAliases = new Set([directLegacy, canonicalId, infoProjectId, ...aliases]);
|
|
2184
|
-
allAliases.delete(immutableId);
|
|
2185
|
-
for (const legacyId of allAliases) {
|
|
2186
|
-
try {
|
|
2187
|
-
await db
|
|
2188
|
-
.insert(projectIdAliases)
|
|
2189
|
-
.values({ legacyId, canonicalId: immutableId, createdAt: now })
|
|
2190
|
-
.onConflictDoNothing();
|
|
2191
|
-
}
|
|
2192
|
-
catch {
|
|
2193
|
-
/* best-effort */
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
1752
|
+
const outcome = await trackBackgroundOp(() => worktreeScope.run({ ...scope, execution }, async () => {
|
|
1753
|
+
const { canonicalProjectId, legacyProjectId } = await import('./nexus/identity.js');
|
|
1754
|
+
const { generateProjectHash } = await import('./nexus/hash.js');
|
|
1755
|
+
const canonical = await canonicalProjectId(resolvedPath, execution);
|
|
1756
|
+
execution.assertActive();
|
|
1757
|
+
const { getNexusRegistryDb } = await import('./store/nexus-sqlite.js');
|
|
1758
|
+
const { eq, or } = await import('drizzle-orm');
|
|
1759
|
+
const { projectRegistry, projectIdAliases } = await import('./store/schema/nexus-schema.js');
|
|
1760
|
+
const db = await getNexusRegistryDb(capturedHome);
|
|
1761
|
+
execution.assertActive();
|
|
1762
|
+
const projectHash = generateProjectHash(resolvedPath);
|
|
1763
|
+
const legacyAlias = legacyProjectId(resolvedPath);
|
|
1764
|
+
const skippedAliases = [];
|
|
1765
|
+
const aliases = new Set([legacyAlias, canonical.id, ...(canonical.legacyAliases ?? [])]);
|
|
1766
|
+
aliases.delete(infoProjectId);
|
|
1767
|
+
db.transaction((tx) => {
|
|
1768
|
+
execution.assertActive();
|
|
1769
|
+
const owners = tx
|
|
1770
|
+
.select()
|
|
1771
|
+
.from(projectRegistry)
|
|
1772
|
+
.where(or(eq(projectRegistry.projectId, infoProjectId), eq(projectRegistry.projectPath, resolvedPath), eq(projectRegistry.projectHash, projectHash)))
|
|
1773
|
+
.all();
|
|
1774
|
+
if (owners.some((owner) => owner.projectId !== infoProjectId))
|
|
1775
|
+
throw new Error('Project encounter path or hash belongs to another immutable identity');
|
|
1776
|
+
const now = new Date().toISOString();
|
|
1777
|
+
const existing = owners.find((owner) => owner.projectId === infoProjectId);
|
|
1778
|
+
if (existing) {
|
|
1779
|
+
tx.update(projectRegistry)
|
|
1780
|
+
.set({
|
|
1781
|
+
projectPath: resolvedPath,
|
|
1782
|
+
projectHash,
|
|
1783
|
+
lastSeen: now,
|
|
1784
|
+
brainDbPath: join(resolvedPath, '.cleo', 'brain.db'),
|
|
1785
|
+
tasksDbPath: join(resolvedPath, '.cleo', 'tasks.db'),
|
|
1786
|
+
})
|
|
1787
|
+
.where(eq(projectRegistry.projectId, infoProjectId))
|
|
1788
|
+
.run();
|
|
1789
|
+
}
|
|
1790
|
+
else {
|
|
1791
|
+
tx.insert(projectRegistry)
|
|
1792
|
+
.values({
|
|
1793
|
+
projectId: infoProjectId,
|
|
1794
|
+
projectHash,
|
|
1795
|
+
projectPath: resolvedPath,
|
|
1796
|
+
name: projectName,
|
|
1797
|
+
registeredAt: now,
|
|
1798
|
+
lastSeen: now,
|
|
1799
|
+
healthStatus: 'unknown',
|
|
1800
|
+
healthLastCheck: null,
|
|
1801
|
+
permissions: 'read',
|
|
1802
|
+
lastSync: now,
|
|
1803
|
+
taskCount: 0,
|
|
1804
|
+
labelsJson: '[]',
|
|
1805
|
+
brainDbPath: join(resolvedPath, '.cleo', 'brain.db'),
|
|
1806
|
+
tasksDbPath: join(resolvedPath, '.cleo', 'tasks.db'),
|
|
1807
|
+
statsJson: '{}',
|
|
1808
|
+
})
|
|
1809
|
+
.run();
|
|
1810
|
+
}
|
|
1811
|
+
for (const alias of aliases) {
|
|
1812
|
+
const owner = tx
|
|
1813
|
+
.select()
|
|
1814
|
+
.from(projectIdAliases)
|
|
1815
|
+
.where(eq(projectIdAliases.legacyId, alias))
|
|
1816
|
+
.get();
|
|
1817
|
+
const directOwner = tx
|
|
1818
|
+
.select()
|
|
1819
|
+
.from(projectRegistry)
|
|
1820
|
+
.where(eq(projectRegistry.projectId, alias))
|
|
1821
|
+
.get();
|
|
1822
|
+
if ((owner && owner.canonicalId !== infoProjectId) ||
|
|
1823
|
+
(directOwner && directOwner.projectId !== infoProjectId)) {
|
|
1824
|
+
// Match explicit registration: this old truncated token is lossy.
|
|
1825
|
+
// Preserve its existing owner; the immutable identity still registers.
|
|
1826
|
+
if (alias === legacyAlias) {
|
|
1827
|
+
skippedAliases.push(alias);
|
|
1828
|
+
continue;
|
|
1829
|
+
}
|
|
1830
|
+
throw new Error('Project encounter alias belongs to another immutable identity');
|
|
1831
|
+
}
|
|
1832
|
+
if (!owner)
|
|
1833
|
+
tx.insert(projectIdAliases)
|
|
1834
|
+
.values({ legacyId: alias, canonicalId: infoProjectId, createdAt: now })
|
|
1835
|
+
.run();
|
|
1836
|
+
}
|
|
1837
|
+
execution.assertActive();
|
|
1838
|
+
}, { behavior: 'immediate' });
|
|
1839
|
+
if (skippedAliases.length > 0)
|
|
1840
|
+
process.stderr.write(`[cleo] Project encounter omitted colliding legacy alias: ${skippedAliases.join(', ')}\n`);
|
|
1841
|
+
}), execution);
|
|
1842
|
+
if (outcome.status === 'rejected')
|
|
1843
|
+
throw outcome.reason;
|
|
2196
1844
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
1845
|
+
finally {
|
|
1846
|
+
if (ownedExecution)
|
|
1847
|
+
execution.close();
|
|
2199
1848
|
}
|
|
2200
1849
|
}
|
|
2201
1850
|
//# sourceMappingURL=paths.js.map
|