@cleocode/core 2026.9.21 → 2026.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/scaffold.d.ts.map +1 -1
- package/dist/agents/scaffold.js +0 -1
- package/dist/agents/scaffold.js.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +4 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/build-provenance.json +6 -0
- package/dist/decide/audit.d.ts +7 -1
- package/dist/decide/audit.d.ts.map +1 -1
- package/dist/decide/audit.js.map +1 -1
- package/dist/decide/client.d.ts +46 -4
- package/dist/decide/client.d.ts.map +1 -1
- package/dist/decide/client.js +328 -33
- package/dist/decide/client.js.map +1 -1
- package/dist/decide/credentials.d.ts +28 -4
- package/dist/decide/credentials.d.ts.map +1 -1
- package/dist/decide/credentials.js +50 -12
- package/dist/decide/credentials.js.map +1 -1
- package/dist/decide/index.d.ts +10 -4
- package/dist/decide/index.d.ts.map +1 -1
- package/dist/decide/index.js +10 -4
- package/dist/decide/index.js.map +1 -1
- package/dist/decide/jev-wire.d.ts +100 -8
- package/dist/decide/jev-wire.d.ts.map +1 -1
- package/dist/decide/jev-wire.js +402 -55
- package/dist/decide/jev-wire.js.map +1 -1
- package/dist/decide/operations.d.ts +97 -20
- package/dist/decide/operations.d.ts.map +1 -1
- package/dist/decide/operations.js +180 -28
- package/dist/decide/operations.js.map +1 -1
- package/dist/decide/provider-state.d.ts +89 -0
- package/dist/decide/provider-state.d.ts.map +1 -0
- package/dist/decide/provider-state.js +134 -0
- package/dist/decide/provider-state.js.map +1 -0
- package/dist/decide/provider.d.ts +26 -5
- package/dist/decide/provider.d.ts.map +1 -1
- package/dist/decide/provider.js.map +1 -1
- package/dist/decide/providers.d.ts +58 -0
- package/dist/decide/providers.d.ts.map +1 -0
- package/dist/decide/providers.js +69 -0
- package/dist/decide/providers.js.map +1 -0
- package/dist/decide/site.d.ts +2 -2
- package/dist/decide/site.d.ts.map +1 -1
- package/dist/decide/site.js +2 -0
- package/dist/decide/site.js.map +1 -1
- package/dist/decide/sites/list.d.ts +46 -0
- package/dist/decide/sites/list.d.ts.map +1 -0
- package/dist/decide/sites/list.js +206 -0
- package/dist/decide/sites/list.js.map +1 -0
- package/dist/decide/sites/registry.d.ts +130 -0
- package/dist/decide/sites/registry.d.ts.map +1 -0
- package/dist/decide/sites/registry.js +375 -0
- package/dist/decide/sites/registry.js.map +1 -0
- package/dist/decide/spend.d.ts +196 -0
- package/dist/decide/spend.d.ts.map +1 -0
- package/dist/decide/spend.js +387 -0
- package/dist/decide/spend.js.map +1 -0
- package/dist/decide/wizard.d.ts +53 -0
- package/dist/decide/wizard.d.ts.map +1 -0
- package/dist/decide/wizard.js +144 -0
- package/dist/decide/wizard.js.map +1 -0
- package/dist/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +5 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/docs/docs-audit.d.ts.map +1 -1
- package/dist/docs/docs-audit.js +1 -2
- package/dist/docs/docs-audit.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +25 -9
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/export-document.js +1073 -628
- package/dist/docs/export-document.js.map +3 -3
- package/dist/doctor/knowledge.d.ts +16 -1
- package/dist/doctor/knowledge.d.ts.map +1 -1
- package/dist/doctor/knowledge.js +53 -17
- package/dist/doctor/knowledge.js.map +1 -1
- package/dist/engine/engine-ops.d.ts +36 -6
- package/dist/engine/engine-ops.d.ts.map +1 -1
- package/dist/engine/engine-ops.js +115 -14
- package/dist/engine/engine-ops.js.map +1 -1
- package/dist/gateway-client/generated/types.gen.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init/scaffold-workflows.d.ts.map +1 -1
- package/dist/init/scaffold-workflows.js +6 -3
- package/dist/init/scaffold-workflows.js.map +1 -1
- package/dist/init/upgrade-workflows.d.ts.map +1 -1
- package/dist/init/upgrade-workflows.js +6 -3
- package/dist/init/upgrade-workflows.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +51 -11
- package/dist/init.js.map +1 -1
- package/dist/inject/index.d.ts.map +1 -1
- package/dist/inject/index.js +8 -3
- package/dist/inject/index.js.map +1 -1
- package/dist/internal.d.ts +3 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +1184 -739
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/memory/attention.d.ts.map +1 -1
- package/dist/memory/attention.js +2 -2
- package/dist/memory/attention.js.map +1 -1
- package/dist/memory/decision-contradiction.d.ts +3 -3
- package/dist/memory/decision-contradiction.d.ts.map +1 -1
- package/dist/memory/decision-contradiction.js +4 -3
- package/dist/memory/decision-contradiction.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +2 -0
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/observation-type-decision.d.ts +2 -2
- package/dist/memory/observation-type-decision.d.ts.map +1 -1
- package/dist/memory/observation-type-decision.js +3 -2
- package/dist/memory/observation-type-decision.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +111 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +230 -2
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/nexus/analyze-orchestrator.d.ts +38 -0
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +96 -21
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/knowledge.d.ts.map +1 -1
- package/dist/nexus/knowledge.js +15 -4
- package/dist/nexus/knowledge.js.map +1 -1
- package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
- package/dist/nexus/migrations/M-split-graph.js +4 -0
- package/dist/nexus/migrations/M-split-graph.js.map +1 -1
- package/dist/nexus/store.d.ts.map +1 -1
- package/dist/nexus/store.js +2 -0
- package/dist/nexus/store.js.map +1 -1
- package/dist/nexus/stored-roots.d.ts +65 -0
- package/dist/nexus/stored-roots.d.ts.map +1 -1
- package/dist/nexus/stored-roots.js +73 -0
- package/dist/nexus/stored-roots.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +4 -1
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +13 -8
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +8 -2
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts +7 -2
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +17 -6
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +5 -14
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +4 -2
- package/dist/orchestration/bootstrap.js.map +1 -1
- package/dist/orchestration/index.d.ts +1 -0
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +4 -3
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +8 -5
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +46 -17
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/owner-decision-readiness.d.ts +2 -2
- package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -1
- package/dist/orchestration/owner-decision-readiness.js +3 -2
- package/dist/orchestration/owner-decision-readiness.js.map +1 -1
- package/dist/orchestration/parallel.d.ts.map +1 -1
- package/dist/orchestration/parallel.js +10 -17
- package/dist/orchestration/parallel.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts +4 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +3 -2
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/status.d.ts +8 -3
- package/dist/orchestration/status.d.ts.map +1 -1
- package/dist/orchestration/status.js +9 -6
- package/dist/orchestration/status.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +2 -0
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/orchestration/wave-topic.d.ts +54 -0
- package/dist/orchestration/wave-topic.d.ts.map +1 -0
- package/dist/orchestration/wave-topic.js +68 -0
- package/dist/orchestration/wave-topic.js.map +1 -0
- package/dist/orchestration/waves.d.ts +47 -8
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +152 -43
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +6 -2
- package/dist/phases/index.js.map +1 -1
- package/dist/project-scope.d.ts +34 -0
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +73 -0
- package/dist/project-scope.js.map +1 -1
- package/dist/release/ci-evidence.d.ts +10 -0
- package/dist/release/ci-evidence.d.ts.map +1 -1
- package/dist/release/ci-evidence.js +23 -7
- package/dist/release/ci-evidence.js.map +1 -1
- package/dist/release/github-pr.d.ts +30 -0
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +42 -1
- package/dist/release/github-pr.js.map +1 -1
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +6 -3
- package/dist/release/plan.js.map +1 -1
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +12 -4
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/routing/capability-matrix.d.ts.map +1 -1
- package/dist/routing/capability-matrix.js +7 -0
- package/dist/routing/capability-matrix.js.map +1 -1
- package/dist/security/input-sanitization.d.ts.map +1 -1
- package/dist/security/input-sanitization.js +9 -2
- package/dist/security/input-sanitization.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +1193 -748
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/session/engine-ops.d.ts +6 -0
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +36 -4
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/briefing.d.ts +17 -0
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +68 -68
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/drift-watchdog.d.ts.map +1 -1
- package/dist/sessions/drift-watchdog.js +4 -3
- package/dist/sessions/drift-watchdog.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +94 -1
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +100 -1
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/index.d.ts +2 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +1 -1
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-drift.d.ts.map +1 -1
- package/dist/sessions/session-drift.js +4 -3
- package/dist/sessions/session-drift.js.map +1 -1
- package/dist/setup/config-json-merge.d.ts +28 -0
- package/dist/setup/config-json-merge.d.ts.map +1 -1
- package/dist/setup/config-json-merge.js +51 -0
- package/dist/setup/config-json-merge.js.map +1 -1
- package/dist/setup/index.d.ts +13 -10
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +15 -10
- package/dist/setup/index.js.map +1 -1
- package/dist/setup/sections/llm.js +1 -1
- package/dist/setup/sections/llm.js.map +1 -1
- package/dist/setup/sections/system-one.d.ts +28 -0
- package/dist/setup/sections/system-one.d.ts.map +1 -0
- package/dist/setup/sections/system-one.js +53 -0
- package/dist/setup/sections/system-one.js.map +1 -0
- package/dist/setup/wizard.d.ts +15 -1
- package/dist/setup/wizard.d.ts.map +1 -1
- package/dist/setup/wizard.js +15 -0
- package/dist/setup/wizard.js.map +1 -1
- package/dist/skills/discovery.d.ts +12 -1
- package/dist/skills/discovery.d.ts.map +1 -1
- package/dist/skills/discovery.js +27 -2
- package/dist/skills/discovery.js.map +1 -1
- package/dist/skills/orchestrator/startup.d.ts.map +1 -1
- package/dist/skills/orchestrator/startup.js +10 -5
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/skills/prune-bundled.d.ts +306 -0
- package/dist/skills/prune-bundled.d.ts.map +1 -0
- package/dist/skills/prune-bundled.js +652 -0
- package/dist/skills/prune-bundled.js.map +1 -0
- package/dist/skills/types.d.ts +9 -1
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/types.js +17 -34
- package/dist/skills/types.js.map +1 -1
- package/dist/spawn/branch-lock.d.ts.map +1 -1
- package/dist/spawn/branch-lock.js +26 -2
- package/dist/spawn/branch-lock.js.map +1 -1
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +4 -2
- package/dist/stats/index.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +2 -0
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/backup-pack.js +1 -1
- package/dist/store/backup-pack.js.map +1 -1
- package/dist/store/backup.d.ts +15 -1
- package/dist/store/backup.d.ts.map +1 -1
- package/dist/store/backup.js +18 -2
- package/dist/store/backup.js.map +1 -1
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +3 -0
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/credential-transfer.d.ts.map +1 -1
- package/dist/store/credential-transfer.js +2 -0
- package/dist/store/credential-transfer.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +2 -0
- package/dist/store/cross-db-cleanup.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +13 -2
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.js +3 -0
- package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +37 -3
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +2 -0
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +3 -0
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +3 -0
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +2 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +2 -0
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.js +1 -1
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/ports/domain-binding.d.ts.map +1 -1
- package/dist/store/ports/domain-binding.js +5 -0
- package/dist/store/ports/domain-binding.js.map +1 -1
- package/dist/store/skills-db.d.ts +17 -0
- package/dist/store/skills-db.d.ts.map +1 -1
- package/dist/store/skills-db.js +30 -0
- package/dist/store/skills-db.js.map +1 -1
- package/dist/store/snapshot-gate.d.ts.map +1 -1
- package/dist/store/snapshot-gate.js +3 -0
- package/dist/store/snapshot-gate.js.map +1 -1
- package/dist/store/split-brain-import.d.ts.map +1 -1
- package/dist/store/split-brain-import.js +2 -0
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +19 -2
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite-native.d.ts.map +1 -1
- package/dist/store/sqlite-native.js +1 -0
- package/dist/store/sqlite-native.js.map +1 -1
- package/dist/store/sqlite.d.ts +14 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +31 -4
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/twin-collapse.d.ts +46 -1
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +131 -5
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/worktree-build-guard.d.ts +191 -0
- package/dist/store/worktree-build-guard.d.ts.map +1 -0
- package/dist/store/worktree-build-guard.js +486 -0
- package/dist/store/worktree-build-guard.js.map +1 -0
- package/dist/store/worktree-isolation-guard.d.ts +27 -0
- package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
- package/dist/store/worktree-isolation-guard.js +71 -3
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +2 -0
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/backup.d.ts +6 -2
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +6 -3
- package/dist/system/backup.js.map +1 -1
- package/dist/system/inject-generate.d.ts.map +1 -1
- package/dist/system/inject-generate.js +4 -4
- package/dist/system/inject-generate.js.map +1 -1
- package/dist/task-tools/index.d.ts +4 -2
- package/dist/task-tools/index.d.ts.map +1 -1
- package/dist/task-tools/index.js +3 -2
- package/dist/task-tools/index.js.map +1 -1
- package/dist/task-tools/score-task-priority.d.ts +93 -18
- package/dist/task-tools/score-task-priority.d.ts.map +1 -1
- package/dist/task-tools/score-task-priority.js +193 -81
- package/dist/task-tools/score-task-priority.js.map +1 -1
- package/dist/task-work/index.d.ts +6 -0
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +6 -3
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +62 -13
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +158 -33
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/affected-scope.d.ts +59 -0
- package/dist/tasks/affected-scope.d.ts.map +1 -0
- package/dist/tasks/affected-scope.js +81 -0
- package/dist/tasks/affected-scope.js.map +1 -0
- package/dist/tasks/analyze.d.ts +29 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +52 -36
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
- package/dist/tasks/backfill-child-projections.js +4 -1
- package/dist/tasks/backfill-child-projections.js.map +1 -1
- package/dist/tasks/change-set.d.ts +24 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +143 -11
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/command-line.d.ts +54 -0
- package/dist/tasks/command-line.d.ts.map +1 -0
- package/dist/tasks/command-line.js +151 -0
- package/dist/tasks/command-line.js.map +1 -0
- package/dist/tasks/complete.d.ts +10 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +49 -0
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/component-pr.d.ts +106 -0
- package/dist/tasks/component-pr.d.ts.map +1 -0
- package/dist/tasks/component-pr.js +275 -0
- package/dist/tasks/component-pr.js.map +1 -0
- package/dist/tasks/delete.d.ts.map +1 -1
- package/dist/tasks/delete.js +20 -0
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/done-plan.d.ts +21 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +170 -15
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +9 -80
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/duplicate-detector.d.ts +3 -3
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +4 -3
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/engine-wrap-ops.d.ts +29 -0
- package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
- package/dist/tasks/engine-wrap-ops.js +40 -0
- package/dist/tasks/engine-wrap-ops.js.map +1 -1
- package/dist/tasks/engine-wrap.d.ts +1 -1
- package/dist/tasks/engine-wrap.d.ts.map +1 -1
- package/dist/tasks/engine-wrap.js +1 -1
- package/dist/tasks/engine-wrap.js.map +1 -1
- package/dist/tasks/evidence.d.ts +49 -2
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +85 -9
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +48 -12
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/ops.d.ts +1 -0
- package/dist/tasks/ops.d.ts.map +1 -1
- package/dist/tasks/ranking-audit.d.ts +122 -0
- package/dist/tasks/ranking-audit.d.ts.map +1 -0
- package/dist/tasks/ranking-audit.js +193 -0
- package/dist/tasks/ranking-audit.js.map +1 -0
- package/dist/tasks/task-analyze.d.ts.map +1 -1
- package/dist/tasks/task-analyze.js +19 -32
- package/dist/tasks/task-analyze.js.map +1 -1
- package/dist/tasks/task-next.d.ts +48 -2
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +84 -102
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/task-ops.d.ts +1 -1
- package/dist/tasks/task-ops.d.ts.map +1 -1
- package/dist/tasks/task-ops.js +1 -1
- package/dist/tasks/task-ops.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +7 -1
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +24 -10
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/update.d.ts +8 -2
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +28 -1
- package/dist/tasks/update.js.map +1 -1
- package/dist/telemetry/sqlite.d.ts.map +1 -1
- package/dist/telemetry/sqlite.js +2 -0
- package/dist/telemetry/sqlite.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +2 -2
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +9 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +24 -1
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/validation/validate-ops.d.ts.map +1 -1
- package/dist/validation/validate-ops.js +9 -3
- package/dist/validation/validate-ops.js.map +1 -1
- package/dist/worktree/worktree-adopt.d.ts.map +1 -1
- package/dist/worktree/worktree-adopt.js +5 -2
- package/dist/worktree/worktree-adopt.js.map +1 -1
- package/package.json +14 -14
- package/schemas/config.schema.json +13 -0
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +5 -1
|
@@ -102,9 +102,9 @@ function getLogDir() {
|
|
|
102
102
|
return currentLogDir;
|
|
103
103
|
}
|
|
104
104
|
function closeLogger() {
|
|
105
|
-
return new Promise((
|
|
105
|
+
return new Promise((resolve17) => {
|
|
106
106
|
if (!rootLogger) {
|
|
107
|
-
|
|
107
|
+
resolve17();
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
const logger8 = rootLogger;
|
|
@@ -116,7 +116,7 @@ function closeLogger() {
|
|
|
116
116
|
rootLogger = null;
|
|
117
117
|
currentLogDir = null;
|
|
118
118
|
currentTransport = null;
|
|
119
|
-
|
|
119
|
+
resolve17();
|
|
120
120
|
};
|
|
121
121
|
logger8.flush(() => {
|
|
122
122
|
if (transport && typeof transport.end === "function") {
|
|
@@ -479,7 +479,7 @@ var init_acceptance_gate_schema = __esm({
|
|
|
479
479
|
message: "Result cannot precede input capture"
|
|
480
480
|
});
|
|
481
481
|
const executable = ["test", "command", "lint"].includes(result.kind);
|
|
482
|
-
if (executable && !binding.invocation)
|
|
482
|
+
if (executable && !binding.invocation && result.result !== "error")
|
|
483
483
|
context.addIssue({
|
|
484
484
|
code: "custom",
|
|
485
485
|
path: ["binding", "invocation"],
|
|
@@ -3245,12 +3245,21 @@ var init_operations_registry = __esm({
|
|
|
3245
3245
|
gateway: "query",
|
|
3246
3246
|
domain: "tasks",
|
|
3247
3247
|
operation: "history",
|
|
3248
|
-
description: "Show task work history
|
|
3248
|
+
description: "Show task work history; with taskId, the task audit trail; with ranking, who changed its priority/severity/kind/depends and why (T12693)",
|
|
3249
3249
|
tier: 1,
|
|
3250
3250
|
idempotent: true,
|
|
3251
3251
|
sessionRequired: false,
|
|
3252
3252
|
requiredParams: [],
|
|
3253
|
-
params: [
|
|
3253
|
+
params: [
|
|
3254
|
+
{ name: "taskId", type: "string", required: false, description: "Task to show history for" },
|
|
3255
|
+
{ name: "limit", type: "number", required: false, description: "Maximum entries" },
|
|
3256
|
+
{
|
|
3257
|
+
name: "ranking",
|
|
3258
|
+
type: "boolean",
|
|
3259
|
+
required: false,
|
|
3260
|
+
description: "Only ranking-input changes (actor, session, reason, before/after)"
|
|
3261
|
+
}
|
|
3262
|
+
]
|
|
3254
3263
|
},
|
|
3255
3264
|
{
|
|
3256
3265
|
gateway: "query",
|
|
@@ -5745,6 +5754,32 @@ var init_operations_registry = __esm({
|
|
|
5745
5754
|
],
|
|
5746
5755
|
outputSchema: OUTPUT_CONTRACTS["tasks.assignee"]
|
|
5747
5756
|
},
|
|
5757
|
+
{
|
|
5758
|
+
gateway: "mutate",
|
|
5759
|
+
domain: "tasks",
|
|
5760
|
+
operation: "ranking.revert",
|
|
5761
|
+
description: "tasks.ranking.revert (mutate) \u2014 undo one recorded ranking change (priority/severity/kind/depends) as a new audited change (T12693, D11161)",
|
|
5762
|
+
tier: 1,
|
|
5763
|
+
idempotent: false,
|
|
5764
|
+
sessionRequired: false,
|
|
5765
|
+
requiredParams: ["entryId"],
|
|
5766
|
+
params: [
|
|
5767
|
+
{
|
|
5768
|
+
name: "entryId",
|
|
5769
|
+
type: "string",
|
|
5770
|
+
required: true,
|
|
5771
|
+
description: "ranking_changed audit row id (cleo history ranking <taskId>)",
|
|
5772
|
+
cli: { positional: true }
|
|
5773
|
+
},
|
|
5774
|
+
{ name: "reason", type: "string", required: false, description: "Why it is reverted" },
|
|
5775
|
+
{
|
|
5776
|
+
name: "force",
|
|
5777
|
+
type: "boolean",
|
|
5778
|
+
required: false,
|
|
5779
|
+
description: "Revert even though a field changed again since"
|
|
5780
|
+
}
|
|
5781
|
+
]
|
|
5782
|
+
},
|
|
5748
5783
|
{
|
|
5749
5784
|
gateway: "mutate",
|
|
5750
5785
|
domain: "tasks",
|
|
@@ -10668,7 +10703,7 @@ var init_operations_registry = __esm({
|
|
|
10668
10703
|
type: "string",
|
|
10669
10704
|
required: false,
|
|
10670
10705
|
enum: DOCS_LIFECYCLE_STATUSES,
|
|
10671
|
-
description: `Override the new lifecycle status. Defaults to "draft" on every update. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
|
|
10706
|
+
description: `Override the new lifecycle status. Defaults to "draft" on every update. Alone (no file or content) it changes only the lifecycle status. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
|
|
10672
10707
|
},
|
|
10673
10708
|
{
|
|
10674
10709
|
name: "dryRun",
|
|
@@ -13155,11 +13190,13 @@ var init_evidence_atom_schema = __esm({
|
|
|
13155
13190
|
});
|
|
13156
13191
|
prAtomSchema = z10.object({
|
|
13157
13192
|
kind: z10.literal("pr"),
|
|
13158
|
-
prNumber: z10.number().int().positive("pr atom requires a positive integer PR number")
|
|
13193
|
+
prNumber: z10.number().int().positive("pr atom requires a positive integer PR number"),
|
|
13194
|
+
componentPrNumber: z10.number().int().positive().optional()
|
|
13159
13195
|
});
|
|
13160
13196
|
ciAtomSchema = z10.object({
|
|
13161
13197
|
kind: z10.literal("ci"),
|
|
13162
|
-
prNumber: z10.number().int().positive("ci atom requires a positive integer PR number")
|
|
13198
|
+
prNumber: z10.number().int().positive("ci atom requires a positive integer PR number"),
|
|
13199
|
+
componentPrNumber: z10.number().int().positive().optional()
|
|
13163
13200
|
});
|
|
13164
13201
|
locDropAtomSchema = z10.object({
|
|
13165
13202
|
kind: z10.literal("loc-drop"),
|
|
@@ -13210,7 +13247,10 @@ var init_evidence_atom_schema = __esm({
|
|
|
13210
13247
|
["commit", "note"],
|
|
13211
13248
|
["decision", "files"],
|
|
13212
13249
|
["decision", "note"],
|
|
13213
|
-
["pr", "files"]
|
|
13250
|
+
["pr", "files"],
|
|
13251
|
+
// T12689: a deletion-only PR (no bytes to hash). Contextual validation
|
|
13252
|
+
// accepts this only when every change the PR made is a deletion.
|
|
13253
|
+
["pr", "note"]
|
|
13214
13254
|
]
|
|
13215
13255
|
},
|
|
13216
13256
|
testsPassed: { oneOf: [["test-run"], ["tool"], ["ci"]] },
|
|
@@ -17124,7 +17164,7 @@ var init_collection_keys = __esm({
|
|
|
17124
17164
|
|
|
17125
17165
|
// packages/contracts/src/decide.ts
|
|
17126
17166
|
import { z as z24 } from "zod";
|
|
17127
|
-
var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderConfigSchema;
|
|
17167
|
+
var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, DECISION_PROVIDER_KINDS, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderKindSchema, decisionProviderConfigSchema;
|
|
17128
17168
|
var init_decide = __esm({
|
|
17129
17169
|
"packages/contracts/src/decide.ts"() {
|
|
17130
17170
|
"use strict";
|
|
@@ -17148,6 +17188,7 @@ var init_decide = __esm({
|
|
|
17148
17188
|
/** Maximum number of levels on a `score` question's scale. */
|
|
17149
17189
|
maxScoreLevels: 10
|
|
17150
17190
|
};
|
|
17191
|
+
DECISION_PROVIDER_KINDS = ["layahost", "jev"];
|
|
17151
17192
|
decisionQuestionTypeSchema = z24.enum(DECISION_QUESTION_TYPES);
|
|
17152
17193
|
decisionOutcomeSourceSchema = z24.enum(DECISION_OUTCOME_SOURCES);
|
|
17153
17194
|
decisionInstructionsSchema = z24.union([z24.string(), z24.record(z24.string(), z24.json())]);
|
|
@@ -17185,6 +17226,8 @@ var init_decide = __esm({
|
|
|
17185
17226
|
]);
|
|
17186
17227
|
decisionRequestSchema = z24.object({
|
|
17187
17228
|
model: z24.string().min(1).optional(),
|
|
17229
|
+
lang: z24.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/).optional(),
|
|
17230
|
+
cache: z24.boolean().optional(),
|
|
17188
17231
|
state: decisionStateSchema,
|
|
17189
17232
|
questions: z24.record(z24.string().min(1), decisionQuestionSchema).refine(
|
|
17190
17233
|
(questions) => {
|
|
@@ -17225,14 +17268,26 @@ var init_decide = __esm({
|
|
|
17225
17268
|
requestId: z24.string().min(1).optional(),
|
|
17226
17269
|
latencyMs: z24.number().nonnegative(),
|
|
17227
17270
|
costUsd: z24.number().nonnegative().optional(),
|
|
17271
|
+
costMicros: z24.number().int().nonnegative().optional(),
|
|
17272
|
+
balanceMicros: z24.number().int().optional(),
|
|
17273
|
+
checkpoint: z24.string().min(1).optional(),
|
|
17228
17274
|
inputTokens: z24.number().int().nonnegative().optional()
|
|
17229
17275
|
});
|
|
17276
|
+
decisionProviderKindSchema = z24.enum(DECISION_PROVIDER_KINDS);
|
|
17230
17277
|
decisionProviderConfigSchema = z24.object({
|
|
17231
|
-
baseUrl: z24.url()
|
|
17278
|
+
baseUrl: z24.url(),
|
|
17279
|
+
provider: decisionProviderKindSchema.optional()
|
|
17232
17280
|
});
|
|
17233
17281
|
}
|
|
17234
17282
|
});
|
|
17235
17283
|
|
|
17284
|
+
// packages/contracts/src/decide-sites.ts
|
|
17285
|
+
var init_decide_sites = __esm({
|
|
17286
|
+
"packages/contracts/src/decide-sites.ts"() {
|
|
17287
|
+
"use strict";
|
|
17288
|
+
}
|
|
17289
|
+
});
|
|
17290
|
+
|
|
17236
17291
|
// packages/contracts/src/task-id.ts
|
|
17237
17292
|
var init_task_id = __esm({
|
|
17238
17293
|
"packages/contracts/src/task-id.ts"() {
|
|
@@ -17314,6 +17369,7 @@ var init_src = __esm({
|
|
|
17314
17369
|
init_caamp_markers();
|
|
17315
17370
|
init_collection_keys();
|
|
17316
17371
|
init_decide();
|
|
17372
|
+
init_decide_sites();
|
|
17317
17373
|
init_task_id();
|
|
17318
17374
|
}
|
|
17319
17375
|
});
|
|
@@ -18928,6 +18984,37 @@ function linkedWorktreeMainRoot(dir) {
|
|
|
18928
18984
|
if (basename2(commonDir) === ".git") return dirname3(commonDir);
|
|
18929
18985
|
return readCoreWorktree(commonDir);
|
|
18930
18986
|
}
|
|
18987
|
+
function describeWorktreeOwner(dir) {
|
|
18988
|
+
const mainRoot = linkedWorktreeMainRoot(dir);
|
|
18989
|
+
if (mainRoot === null) {
|
|
18990
|
+
const bare = bareRepositoryOfWorktree(dir);
|
|
18991
|
+
return bare === null ? "owning repository unknown (unreadable gitlink)" : `owning repository ${bare} is a bare git repository with no main checkout to hold a CLEO store; clone it to a regular checkout, run \`cleo init\` there, and create worktrees from that checkout`;
|
|
18992
|
+
}
|
|
18993
|
+
let projectId = null;
|
|
18994
|
+
try {
|
|
18995
|
+
const parsed = JSON.parse(
|
|
18996
|
+
readFileSync3(join5(mainRoot, ".cleo", "project-info.json"), "utf-8")
|
|
18997
|
+
);
|
|
18998
|
+
if (typeof parsed === "object" && parsed !== null && "projectId" in parsed) {
|
|
18999
|
+
const value = parsed.projectId;
|
|
19000
|
+
if (typeof value === "string" && value !== "") projectId = value;
|
|
19001
|
+
}
|
|
19002
|
+
} catch {
|
|
19003
|
+
}
|
|
19004
|
+
return projectId === null ? `owning repository ${mainRoot} (not an initialised CLEO project)` : `owning project ${mainRoot} (projectId ${projectId})`;
|
|
19005
|
+
}
|
|
19006
|
+
function bareRepositoryOfWorktree(dir) {
|
|
19007
|
+
const gitdir = readGitlinkTarget(dir);
|
|
19008
|
+
if (!gitdir || basename2(dirname3(gitdir)) !== "worktrees") return null;
|
|
19009
|
+
const commonDir = dirname3(dirname3(gitdir));
|
|
19010
|
+
try {
|
|
19011
|
+
const config2 = readFileSync3(join5(commonDir, "config"), "utf-8");
|
|
19012
|
+
const core = /^\[core\][^[]*/m.exec(config2)?.[0] ?? "";
|
|
19013
|
+
return /^\s*bare\s*=\s*true\s*$/im.test(core) ? commonDir : null;
|
|
19014
|
+
} catch {
|
|
19015
|
+
return null;
|
|
19016
|
+
}
|
|
19017
|
+
}
|
|
18931
19018
|
function readCoreWorktree(gitDir) {
|
|
18932
19019
|
try {
|
|
18933
19020
|
const config2 = readFileSync3(join5(gitDir, "config"), "utf-8");
|
|
@@ -19377,13 +19464,13 @@ function captureWriteFence(input) {
|
|
|
19377
19464
|
return writeFence;
|
|
19378
19465
|
}
|
|
19379
19466
|
function observeOperation(context, work) {
|
|
19380
|
-
return new Promise((
|
|
19467
|
+
return new Promise((resolve17) => {
|
|
19381
19468
|
let observed = false;
|
|
19382
19469
|
const finish = (result) => {
|
|
19383
19470
|
if (observed) return;
|
|
19384
19471
|
observed = true;
|
|
19385
19472
|
context.signal.removeEventListener("abort", abort);
|
|
19386
|
-
|
|
19473
|
+
resolve17(result);
|
|
19387
19474
|
};
|
|
19388
19475
|
const abort = () => {
|
|
19389
19476
|
const reason = context.signal.reason;
|
|
@@ -20017,7 +20104,7 @@ var init_sql = __esm({
|
|
|
20017
20104
|
return new SQL([new StringChunk(str)]);
|
|
20018
20105
|
}
|
|
20019
20106
|
_sql.raw = raw;
|
|
20020
|
-
function
|
|
20107
|
+
function join54(chunks, separator) {
|
|
20021
20108
|
const result = [];
|
|
20022
20109
|
for (const [i, chunk] of chunks.entries()) {
|
|
20023
20110
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -20025,7 +20112,7 @@ var init_sql = __esm({
|
|
|
20025
20112
|
}
|
|
20026
20113
|
return new SQL(result);
|
|
20027
20114
|
}
|
|
20028
|
-
_sql.join =
|
|
20115
|
+
_sql.join = join54;
|
|
20029
20116
|
function identifier2(value) {
|
|
20030
20117
|
return new Name(value);
|
|
20031
20118
|
}
|
|
@@ -22040,7 +22127,7 @@ var init_select = __esm({
|
|
|
22040
22127
|
const baseTableName = this.tableName;
|
|
22041
22128
|
const tableName = getTableLikeName(table);
|
|
22042
22129
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
22043
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
22130
|
+
if (typeof tableName === "string" && this.config.joins?.some((join54) => join54.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
22044
22131
|
if (!this.isPartialSelect) {
|
|
22045
22132
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
22046
22133
|
if (typeof tableName === "string" && !is(table, SQL)) {
|
|
@@ -23637,7 +23724,7 @@ var init_dialect = __esm({
|
|
|
23637
23724
|
if (!joins2) return;
|
|
23638
23725
|
const withEntries = Object.entries(joins2).filter(([_, v]) => v);
|
|
23639
23726
|
if (!withEntries.length) return;
|
|
23640
|
-
return sql.join(withEntries.map(([k,
|
|
23727
|
+
return sql.join(withEntries.map(([k, join54]) => {
|
|
23641
23728
|
const relation = tableConfig.relations[k];
|
|
23642
23729
|
const isSingle2 = is(relation, One);
|
|
23643
23730
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -23648,7 +23735,7 @@ var init_dialect = __esm({
|
|
|
23648
23735
|
table: targetTable,
|
|
23649
23736
|
mode: isSingle2 ? "first" : "many",
|
|
23650
23737
|
schema,
|
|
23651
|
-
queryConfig:
|
|
23738
|
+
queryConfig: join54,
|
|
23652
23739
|
tableConfig: schema[relation.targetTableName],
|
|
23653
23740
|
relationWhere: filter2,
|
|
23654
23741
|
isNested: true,
|
|
@@ -23662,7 +23749,7 @@ var init_dialect = __esm({
|
|
|
23662
23749
|
key: k,
|
|
23663
23750
|
selection: innerQuery.selection,
|
|
23664
23751
|
isArray: !isSingle2,
|
|
23665
|
-
isOptional: (relation.optional ?? false) ||
|
|
23752
|
+
isOptional: (relation.optional ?? false) || join54 !== true && !!join54.where
|
|
23666
23753
|
});
|
|
23667
23754
|
const jsonColumns = sql.join(innerQuery.selection.map((s) => {
|
|
23668
23755
|
return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
|
|
@@ -24084,7 +24171,7 @@ var init_update = __esm({
|
|
|
24084
24171
|
createJoin(joinType) {
|
|
24085
24172
|
return ((table, on) => {
|
|
24086
24173
|
const tableName = getTableLikeName(table);
|
|
24087
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
24174
|
+
if (typeof tableName === "string" && this.config.joins.some((join54) => join54.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
24088
24175
|
if (typeof on === "function") {
|
|
24089
24176
|
const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
|
|
24090
24177
|
on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -25209,7 +25296,7 @@ async function withWriteRetry(fn, opts = {}) {
|
|
|
25209
25296
|
throw contentionErr;
|
|
25210
25297
|
}
|
|
25211
25298
|
function sleep(ms) {
|
|
25212
|
-
return new Promise((
|
|
25299
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
25213
25300
|
}
|
|
25214
25301
|
var DEFAULT_MAX_ATTEMPTS, DEFAULT_BASE_DELAY_MS, DEFAULT_JITTER_MS;
|
|
25215
25302
|
var init_with_retry = __esm({
|
|
@@ -25221,9 +25308,250 @@ var init_with_retry = __esm({
|
|
|
25221
25308
|
}
|
|
25222
25309
|
});
|
|
25223
25310
|
|
|
25311
|
+
// packages/core/src/store/worktree-build-guard.ts
|
|
25312
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync3 } from "node:fs";
|
|
25313
|
+
import { createRequire } from "node:module";
|
|
25314
|
+
import { dirname as dirname4, isAbsolute as isAbsolute3, join as join7, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
|
|
25315
|
+
import { fileURLToPath } from "node:url";
|
|
25316
|
+
function realOrResolved(path) {
|
|
25317
|
+
try {
|
|
25318
|
+
return realpathSync3(path);
|
|
25319
|
+
} catch {
|
|
25320
|
+
return resolve2(path);
|
|
25321
|
+
}
|
|
25322
|
+
}
|
|
25323
|
+
function isWithin(root, path) {
|
|
25324
|
+
const local = relative2(root, path);
|
|
25325
|
+
return local === "" || !isAbsolute3(local) && local !== ".." && !local.startsWith(`..${sep2}`);
|
|
25326
|
+
}
|
|
25327
|
+
function insideGitCheckout(dir) {
|
|
25328
|
+
let current = dir;
|
|
25329
|
+
for (; ; ) {
|
|
25330
|
+
if (existsSync5(join7(current, ".git"))) return true;
|
|
25331
|
+
const parent = dirname4(current);
|
|
25332
|
+
if (parent === current) return false;
|
|
25333
|
+
current = parent;
|
|
25334
|
+
}
|
|
25335
|
+
}
|
|
25336
|
+
function insideTestSandbox(path) {
|
|
25337
|
+
let dir = dirname4(path);
|
|
25338
|
+
for (; ; ) {
|
|
25339
|
+
if (existsSync5(join7(dir, TEST_SANDBOX_MARKER))) return !insideGitCheckout(dir);
|
|
25340
|
+
const parent = dirname4(dir);
|
|
25341
|
+
if (parent === dir) return false;
|
|
25342
|
+
dir = parent;
|
|
25343
|
+
}
|
|
25344
|
+
}
|
|
25345
|
+
function linkedWorktreeRootOf(path) {
|
|
25346
|
+
let dir = realOrResolved(path);
|
|
25347
|
+
for (; ; ) {
|
|
25348
|
+
if (isGitLinkedCheckout(dir)) return dir;
|
|
25349
|
+
if (existsSync5(join7(dir, ".git"))) return null;
|
|
25350
|
+
const parent = dirname4(dir);
|
|
25351
|
+
if (parent === dir) return null;
|
|
25352
|
+
dir = parent;
|
|
25353
|
+
}
|
|
25354
|
+
}
|
|
25355
|
+
function readBuildProvenance(codePath) {
|
|
25356
|
+
let dir = dirname4(codePath);
|
|
25357
|
+
for (; ; ) {
|
|
25358
|
+
const stamp = join7(dir, "build-provenance.json");
|
|
25359
|
+
if (existsSync5(stamp)) {
|
|
25360
|
+
try {
|
|
25361
|
+
const parsed = JSON.parse(readFileSync4(stamp, "utf8"));
|
|
25362
|
+
if (typeof parsed === "object" && parsed !== null && "linkedWorktree" in parsed) {
|
|
25363
|
+
const value = parsed.linkedWorktree;
|
|
25364
|
+
if (value === null || typeof value === "string") return { linkedWorktree: value };
|
|
25365
|
+
}
|
|
25366
|
+
} catch {
|
|
25367
|
+
}
|
|
25368
|
+
return null;
|
|
25369
|
+
}
|
|
25370
|
+
if (existsSync5(join7(dir, "package.json"))) return null;
|
|
25371
|
+
const parent = dirname4(dir);
|
|
25372
|
+
if (parent === dir) return null;
|
|
25373
|
+
dir = parent;
|
|
25374
|
+
}
|
|
25375
|
+
}
|
|
25376
|
+
function devBuildWorktree(options = {}) {
|
|
25377
|
+
const codePath = options.codePath ?? overrides?.codePath ?? fileURLToPath(import.meta.url);
|
|
25378
|
+
const provenance = options.provenance !== void 0 ? options.provenance : overrides?.provenance !== void 0 ? overrides.provenance : readBuildProvenance(codePath);
|
|
25379
|
+
if (provenance) return provenance.linkedWorktree;
|
|
25380
|
+
if (codePath.split(/[\\/]/).includes("node_modules")) return null;
|
|
25381
|
+
return linkedWorktreeRootOf(codePath);
|
|
25382
|
+
}
|
|
25383
|
+
function schemaWriteRefusal(dbPath, options = {}) {
|
|
25384
|
+
const env = options.env ?? overrides?.env ?? process.env;
|
|
25385
|
+
const buildWorktree = devBuildWorktree(options);
|
|
25386
|
+
if (buildWorktree === null) return null;
|
|
25387
|
+
const store = realOrResolved(dbPath);
|
|
25388
|
+
if (isWithin(realOrResolved(buildWorktree), store)) return null;
|
|
25389
|
+
if (env["VITEST"]) return null;
|
|
25390
|
+
const honourTestSandbox = options.honourTestSandbox ?? overrides?.honourTestSandbox ?? true;
|
|
25391
|
+
if (honourTestSandbox && insideTestSandbox(store)) return null;
|
|
25392
|
+
if (env[ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV] === "1") return null;
|
|
25393
|
+
return `Refusing to change the schema of ${store}: this CLI was built inside the git worktree ${buildWorktree}, and its schema may be unreleased. Run the released \`cleo\` against this store, or opt in with ${ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV}=1 (T12687).`;
|
|
25394
|
+
}
|
|
25395
|
+
function decisionFor(dbPath) {
|
|
25396
|
+
const key = realOrResolved(dbPath);
|
|
25397
|
+
if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
|
|
25398
|
+
return decisions.get(key) ?? null;
|
|
25399
|
+
}
|
|
25400
|
+
function isWorktreeBuildSchemaError(error48) {
|
|
25401
|
+
return error48 instanceof Error && error48.message.includes(E_WORKTREE_BUILD_SCHEMA);
|
|
25402
|
+
}
|
|
25403
|
+
function codes() {
|
|
25404
|
+
if (authorizerCodes) return authorizerCodes;
|
|
25405
|
+
const sqlite = createRequire(import.meta.url)("node:sqlite").constants;
|
|
25406
|
+
authorizerCodes = {
|
|
25407
|
+
sqlite,
|
|
25408
|
+
creates: /* @__PURE__ */ new Map([
|
|
25409
|
+
[sqlite.SQLITE_CREATE_TABLE, "table"],
|
|
25410
|
+
[sqlite.SQLITE_CREATE_VTABLE, "table"],
|
|
25411
|
+
[sqlite.SQLITE_CREATE_INDEX, "index"],
|
|
25412
|
+
[sqlite.SQLITE_CREATE_TRIGGER, "trigger"],
|
|
25413
|
+
[sqlite.SQLITE_CREATE_VIEW, "view"]
|
|
25414
|
+
]),
|
|
25415
|
+
changes: /* @__PURE__ */ new Set([
|
|
25416
|
+
sqlite.SQLITE_ALTER_TABLE,
|
|
25417
|
+
sqlite.SQLITE_DROP_TABLE,
|
|
25418
|
+
sqlite.SQLITE_DROP_INDEX,
|
|
25419
|
+
sqlite.SQLITE_DROP_TRIGGER,
|
|
25420
|
+
sqlite.SQLITE_DROP_VIEW,
|
|
25421
|
+
sqlite.SQLITE_DROP_VTABLE
|
|
25422
|
+
])
|
|
25423
|
+
};
|
|
25424
|
+
return authorizerCodes;
|
|
25425
|
+
}
|
|
25426
|
+
function attachRefusal(name15) {
|
|
25427
|
+
if (name15 === "" || name15 === ":memory:") return null;
|
|
25428
|
+
if (typeof name15 !== "string" || /^file:/i.test(name15) || name15.includes("?")) {
|
|
25429
|
+
return UNKNOWN_ATTACH_REFUSAL;
|
|
25430
|
+
}
|
|
25431
|
+
return decisionFor(name15);
|
|
25432
|
+
}
|
|
25433
|
+
function readSchemas(nativeDb) {
|
|
25434
|
+
const schemas = /* @__PURE__ */ new Map();
|
|
25435
|
+
const list = nativeDb.prepare("PRAGMA database_list").all();
|
|
25436
|
+
for (const { name: name15, file: file2 } of list) {
|
|
25437
|
+
if (name15 === "temp") continue;
|
|
25438
|
+
const rows = nativeDb.prepare(`SELECT type, name FROM "${name15.replaceAll('"', '""')}".sqlite_master`).all();
|
|
25439
|
+
schemas.set(name15.toLowerCase(), {
|
|
25440
|
+
refusal: file2 ? decisionFor(file2) : null,
|
|
25441
|
+
// '' = in-memory
|
|
25442
|
+
objects: new Set(rows.map((r) => `${r.type}:${r.name}`))
|
|
25443
|
+
});
|
|
25444
|
+
}
|
|
25445
|
+
return schemas;
|
|
25446
|
+
}
|
|
25447
|
+
function guardActive() {
|
|
25448
|
+
const env = overrides?.env ?? process.env;
|
|
25449
|
+
if (env["VITEST"]) return false;
|
|
25450
|
+
if (overrides) return devBuildWorktree() !== null;
|
|
25451
|
+
if (processBuildWorktree === void 0) processBuildWorktree = devBuildWorktree();
|
|
25452
|
+
return processBuildWorktree !== null;
|
|
25453
|
+
}
|
|
25454
|
+
function installSchemaWriteGuard(nativeDb) {
|
|
25455
|
+
if (!guardActive()) return false;
|
|
25456
|
+
const location = nativeDb.location();
|
|
25457
|
+
const mainRefusal = location ? decisionFor(location) : null;
|
|
25458
|
+
if (typeof nativeDb.setAuthorizer !== "function") {
|
|
25459
|
+
if (mainRefusal) throw new WorktreeBuildSchemaError(mainRefusal);
|
|
25460
|
+
return false;
|
|
25461
|
+
}
|
|
25462
|
+
const state = {
|
|
25463
|
+
schemas: readSchemas(nativeDb),
|
|
25464
|
+
unmappedAttachRefusal: null,
|
|
25465
|
+
stale: false,
|
|
25466
|
+
lastDenied: null
|
|
25467
|
+
};
|
|
25468
|
+
guards.set(nativeDb, state);
|
|
25469
|
+
const { sqlite, creates, changes } = codes();
|
|
25470
|
+
nativeDb.setAuthorizer((action, arg1, arg2, dbName) => {
|
|
25471
|
+
if (action === sqlite.SQLITE_ATTACH) {
|
|
25472
|
+
const refusal2 = attachRefusal(arg1);
|
|
25473
|
+
if (refusal2 && !state.unmappedAttachRefusal) state.unmappedAttachRefusal = refusal2;
|
|
25474
|
+
return sqlite.SQLITE_OK;
|
|
25475
|
+
}
|
|
25476
|
+
if (action === sqlite.SQLITE_DETACH) {
|
|
25477
|
+
state.stale = true;
|
|
25478
|
+
return sqlite.SQLITE_OK;
|
|
25479
|
+
}
|
|
25480
|
+
const createType = creates.get(action);
|
|
25481
|
+
if (createType === void 0 && !changes.has(action)) return sqlite.SQLITE_OK;
|
|
25482
|
+
const schema = ((action === sqlite.SQLITE_ALTER_TABLE ? arg1 : dbName) ?? "main").toLowerCase();
|
|
25483
|
+
if (schema === "temp") return sqlite.SQLITE_OK;
|
|
25484
|
+
const mapped = state.schemas.get(schema);
|
|
25485
|
+
const policy = state.stale ? void 0 : mapped;
|
|
25486
|
+
const refusal = policy ? policy.refusal : (mapped?.refusal ?? null) || state.unmappedAttachRefusal;
|
|
25487
|
+
if (refusal === null) return sqlite.SQLITE_OK;
|
|
25488
|
+
if (createType !== void 0 && policy?.objects.has(`${createType}:${arg1}`)) {
|
|
25489
|
+
return sqlite.SQLITE_OK;
|
|
25490
|
+
}
|
|
25491
|
+
state.lastDenied = {
|
|
25492
|
+
what: createType !== void 0 ? `CREATE ${createType} ${schema}.${arg1}` : `schema change on ${schema}.${(action === sqlite.SQLITE_ALTER_TABLE ? arg2 : arg1) ?? ""}`,
|
|
25493
|
+
refusal
|
|
25494
|
+
};
|
|
25495
|
+
return sqlite.SQLITE_DENY;
|
|
25496
|
+
});
|
|
25497
|
+
return mainRefusal !== null;
|
|
25498
|
+
}
|
|
25499
|
+
function refreshSchemaWriteGuard(nativeDb) {
|
|
25500
|
+
const state = guards.get(nativeDb);
|
|
25501
|
+
if (!state) return;
|
|
25502
|
+
state.schemas = readSchemas(nativeDb);
|
|
25503
|
+
state.unmappedAttachRefusal = null;
|
|
25504
|
+
state.stale = false;
|
|
25505
|
+
}
|
|
25506
|
+
function explainSchemaWriteDenial(nativeDb, error48) {
|
|
25507
|
+
if (!(error48 instanceof Error) || !/not authorized/i.test(error48.message)) return error48;
|
|
25508
|
+
const denied = guards.get(nativeDb)?.lastDenied;
|
|
25509
|
+
if (!denied) return error48;
|
|
25510
|
+
return new WorktreeBuildSchemaError(`${denied.refusal} Denied: ${denied.what}.`);
|
|
25511
|
+
}
|
|
25512
|
+
function pendingMigrations(nativeDb, migrations) {
|
|
25513
|
+
const hasJournal = nativeDb.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '__drizzle_migrations'").get();
|
|
25514
|
+
const applied = hasJournal ? new Set(
|
|
25515
|
+
nativeDb.prepare('SELECT hash FROM main."__drizzle_migrations"').all().map((row) => row.hash)
|
|
25516
|
+
) : /* @__PURE__ */ new Set();
|
|
25517
|
+
return migrations.filter((m) => !applied.has(m.hash)).map((m) => m.name ?? m.hash);
|
|
25518
|
+
}
|
|
25519
|
+
function assertNoPendingMigrationsForWorktreeBuild(nativeDb, migrations) {
|
|
25520
|
+
const dbPath = nativeDb.location();
|
|
25521
|
+
if (!dbPath) return;
|
|
25522
|
+
const refusal = decisionFor(dbPath);
|
|
25523
|
+
if (refusal === null) return;
|
|
25524
|
+
const pending = pendingMigrations(nativeDb, migrations);
|
|
25525
|
+
if (pending.length === 0) return;
|
|
25526
|
+
throw new WorktreeBuildSchemaError(`${refusal} Pending migrations: ${pending.join(", ")}.`);
|
|
25527
|
+
}
|
|
25528
|
+
var ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV, TEST_SANDBOX_MARKER, E_WORKTREE_BUILD_SCHEMA, overrides, decisions, WorktreeBuildSchemaError, authorizerCodes, guards, UNKNOWN_ATTACH_REFUSAL, processBuildWorktree;
|
|
25529
|
+
var init_worktree_build_guard = __esm({
|
|
25530
|
+
"packages/core/src/store/worktree-build-guard.ts"() {
|
|
25531
|
+
"use strict";
|
|
25532
|
+
init_src();
|
|
25533
|
+
init_errors2();
|
|
25534
|
+
init_project_scope();
|
|
25535
|
+
ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV = "CLEO_ALLOW_WORKTREE_BUILD_MIGRATIONS";
|
|
25536
|
+
TEST_SANDBOX_MARKER = ".cleo-test-sandbox";
|
|
25537
|
+
E_WORKTREE_BUILD_SCHEMA = "E_WORKTREE_BUILD_SCHEMA";
|
|
25538
|
+
overrides = null;
|
|
25539
|
+
decisions = /* @__PURE__ */ new Map();
|
|
25540
|
+
WorktreeBuildSchemaError = class extends CleoError {
|
|
25541
|
+
constructor(message) {
|
|
25542
|
+
super(8 /* CONFIG_ERROR */, `${E_WORKTREE_BUILD_SCHEMA}: ${message}`, {
|
|
25543
|
+
fix: `Use the released \`cleo\` for this store, run the build against a store inside its own worktree, or set ${ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV}=1 to accept the schema change.`
|
|
25544
|
+
});
|
|
25545
|
+
}
|
|
25546
|
+
};
|
|
25547
|
+
guards = /* @__PURE__ */ new WeakMap();
|
|
25548
|
+
UNKNOWN_ATTACH_REFUSAL = "a store was ATTACHed by a bound, computed or URI filename, so this build cannot tell whose store it is; schema changes on unmapped schemas are refused until the guard is refreshed";
|
|
25549
|
+
}
|
|
25550
|
+
});
|
|
25551
|
+
|
|
25224
25552
|
// packages/core/src/store/migration-manager.ts
|
|
25225
|
-
import { copyFileSync, existsSync as
|
|
25226
|
-
import { dirname as
|
|
25553
|
+
import { copyFileSync, existsSync as existsSync6 } from "node:fs";
|
|
25554
|
+
import { dirname as dirname5, join as join8 } from "node:path";
|
|
25227
25555
|
function stripSqlComments(sql30) {
|
|
25228
25556
|
return sql30.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
25229
25557
|
}
|
|
@@ -25262,10 +25590,10 @@ function computeEliminatedTables(migrations) {
|
|
|
25262
25590
|
return eliminated;
|
|
25263
25591
|
}
|
|
25264
25592
|
function resolveConsolidationCutoverPrefix(migrationsFolder) {
|
|
25265
|
-
const parent =
|
|
25593
|
+
const parent = dirname5(migrationsFolder);
|
|
25266
25594
|
for (const setName of ["drizzle-cleo-project", "drizzle-cleo-global"]) {
|
|
25267
|
-
const folder =
|
|
25268
|
-
if (!
|
|
25595
|
+
const folder = join8(parent, setName);
|
|
25596
|
+
if (!existsSync6(folder)) continue;
|
|
25269
25597
|
try {
|
|
25270
25598
|
const consolidation = readMigrationFiles({ migrationsFolder: folder }).find(
|
|
25271
25599
|
(m) => /-consolidation-cleo-/.test(m.name ?? "")
|
|
@@ -25289,7 +25617,7 @@ function tableExists(nativeDb, tableName) {
|
|
|
25289
25617
|
}
|
|
25290
25618
|
function createSafetyBackup(dbPath) {
|
|
25291
25619
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
25292
|
-
if (!
|
|
25620
|
+
if (!existsSync6(backupPath)) {
|
|
25293
25621
|
try {
|
|
25294
25622
|
copyFileSync(dbPath, backupPath);
|
|
25295
25623
|
} catch {
|
|
@@ -25407,6 +25735,16 @@ function readSiblingMigrationHashes(siblingFolder) {
|
|
|
25407
25735
|
return /* @__PURE__ */ new Set();
|
|
25408
25736
|
}
|
|
25409
25737
|
}
|
|
25738
|
+
function readSiblingNewestMillis(siblingFolder) {
|
|
25739
|
+
try {
|
|
25740
|
+
return Math.max(
|
|
25741
|
+
0,
|
|
25742
|
+
...readMigrationFiles({ migrationsFolder: siblingFolder }).map((m) => m.folderMillis)
|
|
25743
|
+
);
|
|
25744
|
+
} catch {
|
|
25745
|
+
return 0;
|
|
25746
|
+
}
|
|
25747
|
+
}
|
|
25410
25748
|
function ensureJournalHashUnique(nativeDb) {
|
|
25411
25749
|
if (!tableExists(nativeDb, "__drizzle_migrations")) return;
|
|
25412
25750
|
try {
|
|
@@ -25455,6 +25793,7 @@ function upgradeSharedJournalFormat(nativeDb, lineageFolders) {
|
|
|
25455
25793
|
return { named, unnamed: rows.length - named };
|
|
25456
25794
|
}
|
|
25457
25795
|
function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsystem, siblingMigrationsFolders = []) {
|
|
25796
|
+
assertNoPendingMigrationsForWorktreeBuild(nativeDb, readMigrationFiles({ migrationsFolder }));
|
|
25458
25797
|
const eliminatedTables = computeEliminatedTables(readMigrationFiles({ migrationsFolder }));
|
|
25459
25798
|
const cutoverPrefix = resolveConsolidationCutoverPrefix(migrationsFolder);
|
|
25460
25799
|
if (siblingMigrationsFolders.length > 0)
|
|
@@ -25486,8 +25825,15 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
25486
25825
|
knownHashes.add(m);
|
|
25487
25826
|
}
|
|
25488
25827
|
}
|
|
25489
|
-
const
|
|
25490
|
-
|
|
25828
|
+
const newestKnownMillis = Math.max(
|
|
25829
|
+
0,
|
|
25830
|
+
...localMigrations.map((m) => m.folderMillis),
|
|
25831
|
+
...siblingMigrationsFolders.filter((folder) => folder !== migrationsFolder).map(readSiblingNewestMillis)
|
|
25832
|
+
);
|
|
25833
|
+
const dbEntries = nativeDb.prepare('SELECT id, hash, created_at FROM "__drizzle_migrations"').all();
|
|
25834
|
+
const orphanedEntries = dbEntries.filter(
|
|
25835
|
+
(e) => !knownHashes.has(e.hash) && !(Number(e.created_at) > newestKnownMillis)
|
|
25836
|
+
);
|
|
25491
25837
|
const hasOrphanedEntries = orphanedEntries.length > 0;
|
|
25492
25838
|
if (hasOrphanedEntries) {
|
|
25493
25839
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
@@ -25729,6 +26075,8 @@ function sanitizeMigrationStatements(migrations) {
|
|
|
25729
26075
|
}
|
|
25730
26076
|
function migrateSanitized(db, config2) {
|
|
25731
26077
|
const raw = readMigrationFiles(config2);
|
|
26078
|
+
const client = db.$client;
|
|
26079
|
+
if (client) assertNoPendingMigrationsForWorktreeBuild(client, raw);
|
|
25732
26080
|
const sanitized = sanitizeMigrationStatements(raw);
|
|
25733
26081
|
migrateSync(sanitized, db._.session, config2);
|
|
25734
26082
|
}
|
|
@@ -25792,6 +26140,7 @@ var init_migration_manager = __esm({
|
|
|
25792
26140
|
init_sqlite_core();
|
|
25793
26141
|
init_logger();
|
|
25794
26142
|
init_with_retry();
|
|
26143
|
+
init_worktree_build_guard();
|
|
25795
26144
|
MAX_MIGRATION_RETRIES = 5;
|
|
25796
26145
|
MIGRATION_RETRY_BASE_DELAY_MS = 100;
|
|
25797
26146
|
MIGRATION_RETRY_MAX_DELAY_MS = 2e3;
|
|
@@ -25801,13 +26150,13 @@ var init_migration_manager = __esm({
|
|
|
25801
26150
|
});
|
|
25802
26151
|
|
|
25803
26152
|
// packages/core/src/store/relocated-store-guard.ts
|
|
25804
|
-
import { existsSync as
|
|
25805
|
-
import { createRequire } from "node:module";
|
|
25806
|
-
import { basename as basename3, dirname as
|
|
26153
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
26154
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
26155
|
+
import { basename as basename3, dirname as dirname6 } from "node:path";
|
|
25807
26156
|
import { readDeclaredProjectIdentity as readDeclaredProjectIdentity2, readPortableProjectId } from "@cleocode/paths";
|
|
25808
26157
|
function real2(p) {
|
|
25809
26158
|
try {
|
|
25810
|
-
return
|
|
26159
|
+
return realpathSync4(p);
|
|
25811
26160
|
} catch {
|
|
25812
26161
|
return p;
|
|
25813
26162
|
}
|
|
@@ -25824,7 +26173,7 @@ function liveElsewhere(globalDbPath, projectId, root) {
|
|
|
25824
26173
|
"SELECT project_path AS projectPath FROM nexus_project_registry WHERE project_id = ?"
|
|
25825
26174
|
).get(projectId);
|
|
25826
26175
|
const live = row?.projectPath;
|
|
25827
|
-
if (!live || paths.has(live) || !
|
|
26176
|
+
if (!live || paths.has(live) || !existsSync7(live)) return null;
|
|
25828
26177
|
if (!isStrictlyInsideDir(root, live)) return null;
|
|
25829
26178
|
return readDeclaredProjectIdentity2(live)?.projectId === projectId ? live : null;
|
|
25830
26179
|
} catch {
|
|
@@ -25838,14 +26187,14 @@ function detectRelocatedRoot(root, globalDbPath) {
|
|
|
25838
26187
|
if (tombstone)
|
|
25839
26188
|
return { projectId: tombstone.projectId, movedTo: tombstone.movedTo, via: "tombstone" };
|
|
25840
26189
|
const declared = readPortableProjectId(root);
|
|
25841
|
-
if (declared.status !== "valid" || !
|
|
26190
|
+
if (declared.status !== "valid" || !existsSync7(globalDbPath)) return null;
|
|
25842
26191
|
const movedTo = liveElsewhere(globalDbPath, declared.projectId, root);
|
|
25843
26192
|
return movedTo ? { projectId: declared.projectId, movedTo, via: "registry" } : null;
|
|
25844
26193
|
}
|
|
25845
26194
|
function assertStoreNotRelocated(dbPath, globalDbPath) {
|
|
25846
|
-
if (basename3(dbPath) !== "cleo.db" || basename3(
|
|
25847
|
-
if (
|
|
25848
|
-
const root =
|
|
26195
|
+
if (basename3(dbPath) !== "cleo.db" || basename3(dirname6(dbPath)) !== ".cleo") return;
|
|
26196
|
+
if (existsSync7(dbPath) || globalDbPath === dbPath) return;
|
|
26197
|
+
const root = dirname6(dirname6(dbPath));
|
|
25849
26198
|
if (_adopted.has(root)) return;
|
|
25850
26199
|
const moved = detectRelocatedRoot(root, globalDbPath);
|
|
25851
26200
|
if (moved) throw projectMovedError(root, moved, void 0, moved.via);
|
|
@@ -25855,17 +26204,17 @@ var init_relocated_store_guard = __esm({
|
|
|
25855
26204
|
"packages/core/src/store/relocated-store-guard.ts"() {
|
|
25856
26205
|
"use strict";
|
|
25857
26206
|
init_project_tombstone();
|
|
25858
|
-
_require =
|
|
26207
|
+
_require = createRequire2(import.meta.url);
|
|
25859
26208
|
_adopted = /* @__PURE__ */ new Set();
|
|
25860
26209
|
}
|
|
25861
26210
|
});
|
|
25862
26211
|
|
|
25863
26212
|
// packages/core/src/store/resolve-migrations-folder.ts
|
|
25864
|
-
import { createRequire as
|
|
25865
|
-
import { dirname as
|
|
25866
|
-
import { fileURLToPath } from "node:url";
|
|
26213
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
26214
|
+
import { dirname as dirname7, join as join9 } from "node:path";
|
|
26215
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
25867
26216
|
function coreRootFromEntry(entryPath) {
|
|
25868
|
-
return
|
|
26217
|
+
return dirname7(dirname7(entryPath));
|
|
25869
26218
|
}
|
|
25870
26219
|
function resolveConsolidatedJournalSiblings(ownSetName) {
|
|
25871
26220
|
return CONSOLIDATED_JOURNAL_LINEAGES.filter((name15) => name15 !== ownSetName).map(
|
|
@@ -25875,14 +26224,14 @@ function resolveConsolidatedJournalSiblings(ownSetName) {
|
|
|
25875
26224
|
function resolveCorePackageMigrationsFolder(setName) {
|
|
25876
26225
|
try {
|
|
25877
26226
|
const resolved = import.meta.resolve("@cleocode/core", import.meta.url);
|
|
25878
|
-
const entryPath =
|
|
25879
|
-
return
|
|
26227
|
+
const entryPath = fileURLToPath2(resolved);
|
|
26228
|
+
return join9(coreRootFromEntry(entryPath), "migrations", setName);
|
|
25880
26229
|
} catch {
|
|
25881
26230
|
}
|
|
25882
|
-
const _require7 =
|
|
26231
|
+
const _require7 = createRequire3(import.meta.url);
|
|
25883
26232
|
try {
|
|
25884
26233
|
const entryPath = _require7.resolve("@cleocode/core");
|
|
25885
|
-
return
|
|
26234
|
+
return join9(coreRootFromEntry(entryPath), "migrations", setName);
|
|
25886
26235
|
} catch (err) {
|
|
25887
26236
|
throw new Error(
|
|
25888
26237
|
`resolveCorePackageMigrationsFolder("${setName}"): cannot locate @cleocode/core from "${import.meta.url}". Ensure @cleocode/core is installed (workspace or npm). Original error: ${err.message}`
|
|
@@ -25978,11 +26327,11 @@ var init_sqlite_pragmas = __esm({
|
|
|
25978
26327
|
});
|
|
25979
26328
|
|
|
25980
26329
|
// packages/core/src/store/worktree-isolation-guard.ts
|
|
25981
|
-
import { basename as basename4, dirname as
|
|
26330
|
+
import { basename as basename4, dirname as dirname8, join as join10, resolve as resolve3 } from "node:path";
|
|
25982
26331
|
function assertStorePathIsNotWorktreeResident(role, dbPath) {
|
|
25983
|
-
const cleoDir =
|
|
26332
|
+
const cleoDir = dirname8(dbPath);
|
|
25984
26333
|
if (basename4(cleoDir) !== ".cleo") return;
|
|
25985
|
-
const projectRoot =
|
|
26334
|
+
const projectRoot = dirname8(cleoDir);
|
|
25986
26335
|
if (!isGitLinkedCheckout(projectRoot)) return;
|
|
25987
26336
|
if (process.env["CLEO_ALLOW_WORKTREE_DB_CREATE"] === "1") {
|
|
25988
26337
|
process.stderr.write(
|
|
@@ -25991,9 +26340,10 @@ function assertStorePathIsNotWorktreeResident(role, dbPath) {
|
|
|
25991
26340
|
);
|
|
25992
26341
|
return;
|
|
25993
26342
|
}
|
|
26343
|
+
const owner = describeWorktreeOwner(projectRoot);
|
|
25994
26344
|
throw new CleoError(
|
|
25995
26345
|
8 /* CONFIG_ERROR */,
|
|
25996
|
-
`E_WT_DB_ISOLATION_VIOLATION: refusing to open '${role}' DB at ${dbPath} \u2014 parent ${projectRoot} is a git worktree (gitlink). DBs must open against the canonical project root.`,
|
|
26346
|
+
`E_WT_DB_ISOLATION_VIOLATION: refusing to open '${role}' DB at ${dbPath} \u2014 parent ${projectRoot} is a git worktree (gitlink); ${owner}. DBs must open against the canonical project root.`,
|
|
25997
26347
|
{
|
|
25998
26348
|
fix: `Run from the canonical project root, or make sure the worktree's main repository is an initialised CLEO project so it resolves there. Inspect stranded worktree stores with \`cleo doctor worktree-stores\`. Emergency override (audited): CLEO_ALLOW_WORKTREE_DB_CREATE=1.`
|
|
25999
26349
|
}
|
|
@@ -26006,7 +26356,7 @@ function assertDbPathIsNotWorktreeResident(role, cwd) {
|
|
|
26006
26356
|
} catch {
|
|
26007
26357
|
return;
|
|
26008
26358
|
}
|
|
26009
|
-
assertStorePathIsNotWorktreeResident(role,
|
|
26359
|
+
assertStorePathIsNotWorktreeResident(role, join10(cleoDir, PROJECT_STORE_FILENAME2));
|
|
26010
26360
|
}
|
|
26011
26361
|
var PROJECT_STORE_FILENAME2;
|
|
26012
26362
|
var init_worktree_isolation_guard = __esm({
|
|
@@ -26026,10 +26376,10 @@ __export(sqlite_native_exports, {
|
|
|
26026
26376
|
getDbSyncConstructor: () => getDbSyncConstructor,
|
|
26027
26377
|
openNativeDatabase: () => openNativeDatabase
|
|
26028
26378
|
});
|
|
26029
|
-
import { realpathSync as
|
|
26030
|
-
import { createRequire as
|
|
26379
|
+
import { realpathSync as realpathSync5 } from "node:fs";
|
|
26380
|
+
import { createRequire as createRequire4 } from "node:module";
|
|
26031
26381
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
26032
|
-
import { delimiter, dirname as
|
|
26382
|
+
import { delimiter, dirname as dirname9, isAbsolute as isAbsolute4, join as join11, resolve as resolve4, sep as sep3 } from "node:path";
|
|
26033
26383
|
function getDbSyncConstructor() {
|
|
26034
26384
|
if (_ctor === null) {
|
|
26035
26385
|
const mod = _require2("node:sqlite");
|
|
@@ -26038,19 +26388,19 @@ function getDbSyncConstructor() {
|
|
|
26038
26388
|
return _ctor;
|
|
26039
26389
|
}
|
|
26040
26390
|
function resolveAbsoluteSafe(p) {
|
|
26041
|
-
const abs =
|
|
26391
|
+
const abs = isAbsolute4(p) ? p : resolve4(p);
|
|
26042
26392
|
try {
|
|
26043
|
-
return
|
|
26393
|
+
return realpathSync5(abs);
|
|
26044
26394
|
} catch {
|
|
26045
26395
|
const missingParts = [];
|
|
26046
26396
|
let cursor = abs;
|
|
26047
26397
|
while (true) {
|
|
26048
|
-
const parent =
|
|
26398
|
+
const parent = dirname9(cursor);
|
|
26049
26399
|
if (parent === cursor) return abs;
|
|
26050
|
-
missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(
|
|
26400
|
+
missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep3) ? 0 : 1)));
|
|
26051
26401
|
cursor = parent;
|
|
26052
26402
|
try {
|
|
26053
|
-
return
|
|
26403
|
+
return join11(realpathSync5(cursor), ...missingParts);
|
|
26054
26404
|
} catch {
|
|
26055
26405
|
}
|
|
26056
26406
|
}
|
|
@@ -26058,7 +26408,7 @@ function resolveAbsoluteSafe(p) {
|
|
|
26058
26408
|
}
|
|
26059
26409
|
function isPathUnder(child, parent) {
|
|
26060
26410
|
if (child === parent) return true;
|
|
26061
|
-
const withSep = parent.endsWith(
|
|
26411
|
+
const withSep = parent.endsWith(sep3) ? parent : parent + sep3;
|
|
26062
26412
|
return child.startsWith(withSep);
|
|
26063
26413
|
}
|
|
26064
26414
|
function assertVitestSafePath(path) {
|
|
@@ -26081,6 +26431,7 @@ function openNativeDatabase(path, options) {
|
|
|
26081
26431
|
assertVitestSafePath(path);
|
|
26082
26432
|
const DatabaseSyncCtor = getDbSyncConstructor();
|
|
26083
26433
|
const db = new DatabaseSyncCtor(path, {
|
|
26434
|
+
// schema-guard-exempt: the native chokepoint; every writable caller installs the guard
|
|
26084
26435
|
enableForeignKeyConstraints: true,
|
|
26085
26436
|
readOnly: options?.readonly ?? false,
|
|
26086
26437
|
// Default handle-open lock timeout mirrors the SSoT busy_timeout
|
|
@@ -26132,7 +26483,7 @@ var init_sqlite_native = __esm({
|
|
|
26132
26483
|
"packages/core/src/store/sqlite-native.ts"() {
|
|
26133
26484
|
"use strict";
|
|
26134
26485
|
init_sqlite_pragmas();
|
|
26135
|
-
_require2 =
|
|
26486
|
+
_require2 = createRequire4(import.meta.url);
|
|
26136
26487
|
_ctor = null;
|
|
26137
26488
|
}
|
|
26138
26489
|
});
|
|
@@ -26206,7 +26557,7 @@ var init_writer_lease_schema = __esm({
|
|
|
26206
26557
|
// packages/core/src/store/writer-lease.ts
|
|
26207
26558
|
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
26208
26559
|
import { randomUUID } from "node:crypto";
|
|
26209
|
-
import { realpathSync as
|
|
26560
|
+
import { realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
|
|
26210
26561
|
import { resolve as resolvePath } from "node:path";
|
|
26211
26562
|
function log() {
|
|
26212
26563
|
if (_log === null) _log = getLogger("writer-lease");
|
|
@@ -26296,7 +26647,7 @@ function resolveDbIdentity(db) {
|
|
|
26296
26647
|
return identity;
|
|
26297
26648
|
}
|
|
26298
26649
|
function sleepAsync(ms) {
|
|
26299
|
-
return new Promise((
|
|
26650
|
+
return new Promise((resolve17) => setTimeout(resolve17, Math.max(0, Math.round(ms))));
|
|
26300
26651
|
}
|
|
26301
26652
|
function isPidAlive(pid) {
|
|
26302
26653
|
try {
|
|
@@ -26635,7 +26986,7 @@ function assertColdOpenFile(frame) {
|
|
|
26635
26986
|
async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
|
|
26636
26987
|
opts.execution?.assertActive();
|
|
26637
26988
|
const captured = opts.requiredIdentity;
|
|
26638
|
-
const path =
|
|
26989
|
+
const path = realpathSync6(captured.dbPath);
|
|
26639
26990
|
const identity = statSync2(path, { bigint: true });
|
|
26640
26991
|
if (captured.scope !== scope || captured.fileDevice !== String(identity.dev) || captured.fileInode !== String(identity.ino)) {
|
|
26641
26992
|
throw new LeaseUnavailableError(
|
|
@@ -26668,6 +27019,7 @@ async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
|
|
|
26668
27019
|
}
|
|
26669
27020
|
const remaining = opts.execution ? Math.max(1, opts.execution.deadlineAt - Date.now()) : ACQUIRE_DEADLINE_MS;
|
|
26670
27021
|
const owned = openNativeDatabase(path, { timeout: Math.min(ACQUIRE_DEADLINE_MS, remaining) });
|
|
27022
|
+
installSchemaWriteGuard(owned);
|
|
26671
27023
|
try {
|
|
26672
27024
|
opts.execution?.assertActive();
|
|
26673
27025
|
const afterOpen = statSync2(path, { bigint: true });
|
|
@@ -26861,6 +27213,7 @@ var init_writer_lease = __esm({
|
|
|
26861
27213
|
init_background_ops();
|
|
26862
27214
|
init_dual_scope_db();
|
|
26863
27215
|
init_sqlite_native();
|
|
27216
|
+
init_worktree_build_guard();
|
|
26864
27217
|
init_writer_lease_schema();
|
|
26865
27218
|
DEFAULT_TTL_MS = 3e4;
|
|
26866
27219
|
DEFAULT_PRIORITY = 100;
|
|
@@ -27403,10 +27756,10 @@ var init_monitor = __esm({
|
|
|
27403
27756
|
|
|
27404
27757
|
// packages/core/src/resources/supervisor-admit.ts
|
|
27405
27758
|
import { connect } from "node:net";
|
|
27406
|
-
import { join as
|
|
27759
|
+
import { join as join12 } from "node:path";
|
|
27407
27760
|
import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
|
|
27408
27761
|
function resolveSupervisorSocketPath() {
|
|
27409
|
-
return process.env.CLEO_SUPERVISOR_SOCKET ??
|
|
27762
|
+
return process.env.CLEO_SUPERVISOR_SOCKET ?? join12(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
|
|
27410
27763
|
}
|
|
27411
27764
|
async function sendResourceAdmit(socketPath, cls, holderId, budget) {
|
|
27412
27765
|
const result = await sendLeaseRequest(
|
|
@@ -27429,7 +27782,7 @@ async function sendResourceRelease(socketPath, cls, holderId) {
|
|
|
27429
27782
|
return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
|
|
27430
27783
|
}
|
|
27431
27784
|
function sendLeaseRequest(socketPath, request, expectedKind) {
|
|
27432
|
-
return new Promise((
|
|
27785
|
+
return new Promise((resolve17) => {
|
|
27433
27786
|
const id = `ra-${process.pid}-${request.kind}`;
|
|
27434
27787
|
const envelope = LeaseIpcRequestEnvelopeSchema.parse({
|
|
27435
27788
|
protocol_version: LEASE_IPC_PROTOCOL_VERSION,
|
|
@@ -27447,7 +27800,7 @@ function sendLeaseRequest(socketPath, request, expectedKind) {
|
|
|
27447
27800
|
settled = true;
|
|
27448
27801
|
socket.removeAllListeners();
|
|
27449
27802
|
socket.destroy();
|
|
27450
|
-
|
|
27803
|
+
resolve17(value);
|
|
27451
27804
|
};
|
|
27452
27805
|
const degrade = (reason) => done({ unavailable: true, reason });
|
|
27453
27806
|
socket.setTimeout(REQUEST_TIMEOUT_MS);
|
|
@@ -27518,9 +27871,9 @@ __export(governor_exports, {
|
|
|
27518
27871
|
resolveGovernorMode: () => resolveGovernorMode,
|
|
27519
27872
|
slotFileCount: () => slotFileCount
|
|
27520
27873
|
});
|
|
27521
|
-
import { existsSync as
|
|
27874
|
+
import { existsSync as existsSync8, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
27522
27875
|
import { availableParallelism, totalmem } from "node:os";
|
|
27523
|
-
import { join as
|
|
27876
|
+
import { join as join13 } from "node:path";
|
|
27524
27877
|
import lockfile from "proper-lockfile";
|
|
27525
27878
|
function log2() {
|
|
27526
27879
|
if (_log2 === null) _log2 = getLogger("resource-governor");
|
|
@@ -27589,14 +27942,14 @@ function clamp2(lo, v, hi) {
|
|
|
27589
27942
|
return Math.max(lo, Math.min(v, hi));
|
|
27590
27943
|
}
|
|
27591
27944
|
function governorSlotDir(cls) {
|
|
27592
|
-
return
|
|
27945
|
+
return join13(getCleoHome(), "locks", `resource-${cls}`);
|
|
27593
27946
|
}
|
|
27594
27947
|
function ensureSlotFiles(dir, count) {
|
|
27595
|
-
if (!
|
|
27948
|
+
if (!existsSync8(dir)) mkdirSync(dir, { recursive: true });
|
|
27596
27949
|
const paths = [];
|
|
27597
27950
|
for (let i = 0; i < count; i++) {
|
|
27598
|
-
const p =
|
|
27599
|
-
if (!
|
|
27951
|
+
const p = join13(dir, `slot-${i}.lock`);
|
|
27952
|
+
if (!existsSync8(p)) writeFileSync3(p, "", { flag: "a" });
|
|
27600
27953
|
paths.push(p);
|
|
27601
27954
|
}
|
|
27602
27955
|
return paths;
|
|
@@ -27636,7 +27989,7 @@ function shuffledIndices(n) {
|
|
|
27636
27989
|
}
|
|
27637
27990
|
async function countHeldSlots(cls, budget) {
|
|
27638
27991
|
const dir = governorSlotDir(cls);
|
|
27639
|
-
if (!
|
|
27992
|
+
if (!existsSync8(dir)) return 0;
|
|
27640
27993
|
const slots = ensureSlotFiles(dir, budget);
|
|
27641
27994
|
let held = 0;
|
|
27642
27995
|
for (const path of slots) {
|
|
@@ -27651,7 +28004,7 @@ async function countHeldSlots(cls, budget) {
|
|
|
27651
28004
|
}
|
|
27652
28005
|
function slotFileCount(cls) {
|
|
27653
28006
|
const dir = governorSlotDir(cls);
|
|
27654
|
-
if (!
|
|
28007
|
+
if (!existsSync8(dir)) return 0;
|
|
27655
28008
|
return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
|
|
27656
28009
|
}
|
|
27657
28010
|
var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
|
|
@@ -27851,11 +28204,11 @@ var init_lock = __esm({
|
|
|
27851
28204
|
|
|
27852
28205
|
// packages/core/src/store/atomic.ts
|
|
27853
28206
|
import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
|
|
27854
|
-
import { dirname as
|
|
28207
|
+
import { dirname as dirname10 } from "node:path";
|
|
27855
28208
|
import writeFileAtomic from "write-file-atomic";
|
|
27856
28209
|
async function atomicWrite(filePath, data, options) {
|
|
27857
28210
|
try {
|
|
27858
|
-
await mkdir(
|
|
28211
|
+
await mkdir(dirname10(filePath), { recursive: true });
|
|
27859
28212
|
await writeFileAtomic(filePath, data, {
|
|
27860
28213
|
encoding: options?.encoding ?? "utf8",
|
|
27861
28214
|
mode: options?.mode
|
|
@@ -27888,7 +28241,7 @@ var init_atomic = __esm({
|
|
|
27888
28241
|
|
|
27889
28242
|
// packages/core/src/store/backup.ts
|
|
27890
28243
|
import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
|
|
27891
|
-
import { basename as basename5, join as
|
|
28244
|
+
import { basename as basename5, dirname as dirname11, join as join14 } from "node:path";
|
|
27892
28245
|
async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
|
|
27893
28246
|
try {
|
|
27894
28247
|
await mkdir2(backupDir, { recursive: true });
|
|
@@ -27899,14 +28252,14 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
27899
28252
|
throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
|
|
27900
28253
|
}
|
|
27901
28254
|
for (let i = maxBackups; i >= 1; i--) {
|
|
27902
|
-
const current =
|
|
28255
|
+
const current = join14(backupDir, `${fileName}.${i}`);
|
|
27903
28256
|
if (i === maxBackups) {
|
|
27904
28257
|
try {
|
|
27905
28258
|
await unlink2(current);
|
|
27906
28259
|
} catch {
|
|
27907
28260
|
}
|
|
27908
28261
|
} else {
|
|
27909
|
-
const next =
|
|
28262
|
+
const next = join14(backupDir, `${fileName}.${i + 1}`);
|
|
27910
28263
|
try {
|
|
27911
28264
|
await stat2(current);
|
|
27912
28265
|
await fsRename(current, next);
|
|
@@ -27914,7 +28267,7 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
27914
28267
|
}
|
|
27915
28268
|
}
|
|
27916
28269
|
}
|
|
27917
|
-
const backupPath =
|
|
28270
|
+
const backupPath = join14(backupDir, `${fileName}.1`);
|
|
27918
28271
|
await copyFile(filePath, backupPath);
|
|
27919
28272
|
return backupPath;
|
|
27920
28273
|
} catch (err) {
|
|
@@ -27928,6 +28281,7 @@ var init_backup = __esm({
|
|
|
27928
28281
|
"use strict";
|
|
27929
28282
|
init_src();
|
|
27930
28283
|
init_errors2();
|
|
28284
|
+
init_worktree_isolation_guard();
|
|
27931
28285
|
DEFAULT_MAX_BACKUPS = 5;
|
|
27932
28286
|
}
|
|
27933
28287
|
});
|
|
@@ -28212,7 +28566,7 @@ __export(identity_exports, {
|
|
|
28212
28566
|
import { execFile } from "node:child_process";
|
|
28213
28567
|
import { createHash as createHash2 } from "node:crypto";
|
|
28214
28568
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
28215
|
-
import { join as
|
|
28569
|
+
import { join as join15, resolve as resolve5 } from "node:path";
|
|
28216
28570
|
import { promisify } from "node:util";
|
|
28217
28571
|
import { legacyProjectId } from "@cleocode/paths";
|
|
28218
28572
|
import { legacyProjectId as legacyProjectId2 } from "@cleocode/paths";
|
|
@@ -28220,14 +28574,14 @@ async function findGitRoot(fromPath, execution) {
|
|
|
28220
28574
|
execution?.assertActive();
|
|
28221
28575
|
try {
|
|
28222
28576
|
const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
28223
|
-
cwd:
|
|
28577
|
+
cwd: resolve5(fromPath),
|
|
28224
28578
|
signal: execution?.signal,
|
|
28225
28579
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28226
28580
|
killSignal: "SIGKILL",
|
|
28227
28581
|
maxBuffer: 64 * 1024
|
|
28228
28582
|
});
|
|
28229
28583
|
execution?.assertActive();
|
|
28230
|
-
return
|
|
28584
|
+
return resolve5(stdout.trim());
|
|
28231
28585
|
} catch {
|
|
28232
28586
|
execution?.assertActive();
|
|
28233
28587
|
return null;
|
|
@@ -28237,7 +28591,7 @@ async function findGitRemoteUrl(fromPath, execution) {
|
|
|
28237
28591
|
execution?.assertActive();
|
|
28238
28592
|
try {
|
|
28239
28593
|
const { stdout } = await execFileAsync("git", ["remote", "get-url", "origin"], {
|
|
28240
|
-
cwd:
|
|
28594
|
+
cwd: resolve5(fromPath),
|
|
28241
28595
|
signal: execution?.signal,
|
|
28242
28596
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28243
28597
|
killSignal: "SIGKILL",
|
|
@@ -28267,7 +28621,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
|
|
|
28267
28621
|
try {
|
|
28268
28622
|
const args = ["--no-replace-objects", "rev-list", "--max-parents=0", "HEAD"];
|
|
28269
28623
|
const { stdout } = await execFileAsync("git", args, {
|
|
28270
|
-
cwd:
|
|
28624
|
+
cwd: resolve5(fromPath),
|
|
28271
28625
|
signal: execution?.signal,
|
|
28272
28626
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28273
28627
|
killSignal: "SIGKILL",
|
|
@@ -28290,7 +28644,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
|
|
|
28290
28644
|
async function readProjectInfoName(repoRoot, execution) {
|
|
28291
28645
|
execution?.assertActive();
|
|
28292
28646
|
try {
|
|
28293
|
-
const raw = await readFile3(
|
|
28647
|
+
const raw = await readFile3(join15(repoRoot, ".cleo", "project-info.json"), {
|
|
28294
28648
|
encoding: "utf8",
|
|
28295
28649
|
signal: execution?.signal
|
|
28296
28650
|
});
|
|
@@ -28305,7 +28659,7 @@ async function readProjectInfoName(repoRoot, execution) {
|
|
|
28305
28659
|
}
|
|
28306
28660
|
async function projectPathFingerprint(repoPath, execution) {
|
|
28307
28661
|
execution?.assertActive();
|
|
28308
|
-
const realRepoPath =
|
|
28662
|
+
const realRepoPath = resolve5(repoPath);
|
|
28309
28663
|
const results = await Promise.allSettled([
|
|
28310
28664
|
findGitRoot(realRepoPath, execution),
|
|
28311
28665
|
findGitRemoteUrl(realRepoPath, execution)
|
|
@@ -28329,9 +28683,9 @@ async function projectPathFingerprint(repoPath, execution) {
|
|
|
28329
28683
|
}
|
|
28330
28684
|
function computeLegacyAliases(repoPath, additionalPaths) {
|
|
28331
28685
|
const aliases = /* @__PURE__ */ new Set();
|
|
28332
|
-
aliases.add(legacyProjectId(
|
|
28686
|
+
aliases.add(legacyProjectId(resolve5(repoPath)));
|
|
28333
28687
|
for (const p of additionalPaths ?? []) {
|
|
28334
|
-
aliases.add(legacyProjectId(
|
|
28688
|
+
aliases.add(legacyProjectId(resolve5(p)));
|
|
28335
28689
|
}
|
|
28336
28690
|
return [...aliases];
|
|
28337
28691
|
}
|
|
@@ -28365,17 +28719,17 @@ var init_project_identity = __esm({
|
|
|
28365
28719
|
});
|
|
28366
28720
|
|
|
28367
28721
|
// packages/core/src/scaffold/ensure-config.ts
|
|
28368
|
-
import { existsSync as
|
|
28369
|
-
import { basename as basename6, dirname as
|
|
28370
|
-
import { fileURLToPath as
|
|
28722
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
28723
|
+
import { basename as basename6, dirname as dirname12, join as join16, resolve as resolve6 } from "node:path";
|
|
28724
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
28371
28725
|
function getPackageRoot() {
|
|
28372
|
-
const thisFile =
|
|
28373
|
-
return
|
|
28726
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
28727
|
+
return resolve6(dirname12(thisFile), "..", "..");
|
|
28374
28728
|
}
|
|
28375
28729
|
function getCleoVersion() {
|
|
28376
28730
|
try {
|
|
28377
|
-
const pkgPath =
|
|
28378
|
-
const pkg = JSON.parse(
|
|
28731
|
+
const pkgPath = join16(getPackageRoot(), "package.json");
|
|
28732
|
+
const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
|
|
28379
28733
|
return pkg.version ?? "0.0.0";
|
|
28380
28734
|
} catch {
|
|
28381
28735
|
return "0.0.0";
|
|
@@ -28734,25 +29088,25 @@ var init_recovery = __esm({
|
|
|
28734
29088
|
// packages/core/src/store/exodus/archive.ts
|
|
28735
29089
|
import {
|
|
28736
29090
|
copyFileSync as copyFileSync2,
|
|
28737
|
-
existsSync as
|
|
29091
|
+
existsSync as existsSync10,
|
|
28738
29092
|
mkdirSync as mkdirSync2,
|
|
28739
|
-
readFileSync as
|
|
29093
|
+
readFileSync as readFileSync6,
|
|
28740
29094
|
renameSync as renameSync3,
|
|
28741
29095
|
unlinkSync,
|
|
28742
29096
|
writeFileSync as writeFileSync4
|
|
28743
29097
|
} from "node:fs";
|
|
28744
|
-
import { basename as basename7, dirname as
|
|
29098
|
+
import { basename as basename7, dirname as dirname13, join as join17, resolve as resolve7 } from "node:path";
|
|
28745
29099
|
import { z as z26 } from "zod";
|
|
28746
29100
|
function scopeBaseDir(scope, cwd, targetDbPath) {
|
|
28747
|
-
if (targetDbPath !== void 0) return
|
|
29101
|
+
if (targetDbPath !== void 0) return dirname13(targetDbPath);
|
|
28748
29102
|
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
28749
29103
|
}
|
|
28750
29104
|
function exodusArchiveDir(scope, cwd, targetDbPath) {
|
|
28751
|
-
return
|
|
29105
|
+
return join17(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
|
|
28752
29106
|
}
|
|
28753
29107
|
function exodusMarkerPath(scope, cwd, targetDbPath) {
|
|
28754
29108
|
const marker16 = targetDbPath !== void 0 && basename7(targetDbPath) !== "cleo.db" ? `${basename7(targetDbPath)}.${MARKER_FILENAME_BY_SCOPE[scope]}` : MARKER_FILENAME_BY_SCOPE[scope];
|
|
28755
|
-
return
|
|
29109
|
+
return join17(scopeBaseDir(scope, cwd, targetDbPath), marker16);
|
|
28756
29110
|
}
|
|
28757
29111
|
function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
28758
29112
|
let markerPath;
|
|
@@ -28762,13 +29116,13 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
|
28762
29116
|
if (targetDbPath) throw error48;
|
|
28763
29117
|
return false;
|
|
28764
29118
|
}
|
|
28765
|
-
if (!
|
|
28766
|
-
const marker16 = markerIdentity.parse(JSON.parse(
|
|
29119
|
+
if (!existsSync10(markerPath)) return false;
|
|
29120
|
+
const marker16 = markerIdentity.parse(JSON.parse(readFileSync6(markerPath, "utf8")));
|
|
28767
29121
|
if (nativeDb && (!marker16.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker16.databaseIdentity)))
|
|
28768
29122
|
throw new Error(
|
|
28769
29123
|
"Exodus completion marker does not certify this database generation; assessment required"
|
|
28770
29124
|
);
|
|
28771
|
-
return marker16.scope === scope && (!targetDbPath || !marker16.targetDbPath ||
|
|
29125
|
+
return marker16.scope === scope && (!targetDbPath || !marker16.targetDbPath || resolve7(marker16.targetDbPath) === resolve7(targetDbPath));
|
|
28772
29126
|
}
|
|
28773
29127
|
function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, databaseIdentity) {
|
|
28774
29128
|
const markerPath = exodusMarkerPath(scope, cwd, targetDbPath);
|
|
@@ -28780,7 +29134,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
28780
29134
|
cleoVersion: getCleoVersion(),
|
|
28781
29135
|
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28782
29136
|
archivedSources: [...archivedSources],
|
|
28783
|
-
targetDbPath:
|
|
29137
|
+
targetDbPath: resolve7(targetDbPath ?? join17(baseDir, "cleo.db")),
|
|
28784
29138
|
...databaseIdentity ? { databaseIdentity } : {}
|
|
28785
29139
|
};
|
|
28786
29140
|
const tmpPath = `${markerPath}.tmp`;
|
|
@@ -28791,10 +29145,10 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
28791
29145
|
}
|
|
28792
29146
|
function moveFileInto(srcPath, destDir) {
|
|
28793
29147
|
mkdirSync2(destDir, { recursive: true });
|
|
28794
|
-
let dest =
|
|
28795
|
-
if (
|
|
29148
|
+
let dest = join17(destDir, basename7(srcPath));
|
|
29149
|
+
if (existsSync10(dest)) {
|
|
28796
29150
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
28797
|
-
dest =
|
|
29151
|
+
dest = join17(destDir, `${basename7(srcPath)}.${stamp}`);
|
|
28798
29152
|
}
|
|
28799
29153
|
try {
|
|
28800
29154
|
renameSync3(srcPath, dest);
|
|
@@ -28805,14 +29159,14 @@ function moveFileInto(srcPath, destDir) {
|
|
|
28805
29159
|
return dest;
|
|
28806
29160
|
}
|
|
28807
29161
|
function archiveSourceDb(source, cwd, targetDbPath) {
|
|
28808
|
-
if (!
|
|
29162
|
+
if (!existsSync10(source.path)) {
|
|
28809
29163
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
28810
29164
|
}
|
|
28811
29165
|
const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
|
|
28812
29166
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
28813
29167
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
28814
29168
|
const sidecar = `${source.path}${suffix}`;
|
|
28815
|
-
if (
|
|
29169
|
+
if (existsSync10(sidecar)) {
|
|
28816
29170
|
try {
|
|
28817
29171
|
moveFileInto(sidecar, destDir);
|
|
28818
29172
|
} catch (err) {
|
|
@@ -28860,7 +29214,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
28860
29214
|
const stranded = [];
|
|
28861
29215
|
for (const source of sources) {
|
|
28862
29216
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
28863
|
-
if (
|
|
29217
|
+
if (existsSync10(source.path)) {
|
|
28864
29218
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
28865
29219
|
}
|
|
28866
29220
|
}
|
|
@@ -28925,7 +29279,7 @@ __export(open_cleo_db_exports, {
|
|
|
28925
29279
|
openCleoDbSnapshot: () => openCleoDbSnapshot,
|
|
28926
29280
|
validateProjectIdConsistency: () => validateProjectIdConsistency
|
|
28927
29281
|
});
|
|
28928
|
-
import { createRequire as
|
|
29282
|
+
import { createRequire as createRequire5 } from "node:module";
|
|
28929
29283
|
function unwrapNativeSqliteDb(db) {
|
|
28930
29284
|
if (db && typeof db === "object" && "$client" in db) {
|
|
28931
29285
|
return db.$client ?? db;
|
|
@@ -28989,9 +29343,10 @@ async function openCleoDb(role, cwd) {
|
|
|
28989
29343
|
}
|
|
28990
29344
|
function openCleoDbSnapshot(path, options = {}) {
|
|
28991
29345
|
const { readOnly = true, applyPragmas = true } = options;
|
|
28992
|
-
const _require7 =
|
|
29346
|
+
const _require7 = createRequire5(import.meta.url);
|
|
28993
29347
|
const { DatabaseSync: DatabaseSyncCtor } = _require7("node:sqlite");
|
|
28994
29348
|
const db = new DatabaseSyncCtor(path, { readOnly });
|
|
29349
|
+
if (!readOnly) installSchemaWriteGuard(db);
|
|
28995
29350
|
if (applyPragmas) {
|
|
28996
29351
|
applyPerfPragmas(db, { enableWal: !readOnly });
|
|
28997
29352
|
}
|
|
@@ -29019,6 +29374,7 @@ var init_open_cleo_db = __esm({
|
|
|
29019
29374
|
init_project_info();
|
|
29020
29375
|
init_dual_scope_db();
|
|
29021
29376
|
init_sqlite_pragmas();
|
|
29377
|
+
init_worktree_build_guard();
|
|
29022
29378
|
init_worktree_isolation_guard();
|
|
29023
29379
|
PROJECT_ID_TRACKING_ROLES = /* @__PURE__ */ new Set(["global"]);
|
|
29024
29380
|
}
|
|
@@ -29358,7 +29714,7 @@ var init_table_name_map = __esm({
|
|
|
29358
29714
|
});
|
|
29359
29715
|
|
|
29360
29716
|
// packages/core/src/store/exodus/count-parity.ts
|
|
29361
|
-
import { existsSync as
|
|
29717
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
29362
29718
|
function listTables(db) {
|
|
29363
29719
|
return db.prepare(
|
|
29364
29720
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
@@ -29379,14 +29735,14 @@ function rowCount(db, tableName) {
|
|
|
29379
29735
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
29380
29736
|
const entries = [];
|
|
29381
29737
|
let skipped = 0;
|
|
29382
|
-
if (!
|
|
29738
|
+
if (!existsSync11(projectDbPath) || !existsSync11(globalDbPath)) {
|
|
29383
29739
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
29384
29740
|
}
|
|
29385
29741
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
29386
29742
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
29387
29743
|
try {
|
|
29388
29744
|
for (const src of sources) {
|
|
29389
|
-
if (!
|
|
29745
|
+
if (!existsSync11(src.path)) continue;
|
|
29390
29746
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
29391
29747
|
try {
|
|
29392
29748
|
for (const legacyTable of listTables(srcSnap.db)) {
|
|
@@ -29444,8 +29800,8 @@ var init_count_parity = __esm({
|
|
|
29444
29800
|
});
|
|
29445
29801
|
|
|
29446
29802
|
// packages/core/src/store/exodus/plan.ts
|
|
29447
|
-
import { existsSync as
|
|
29448
|
-
import { join as
|
|
29803
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
|
|
29804
|
+
import { join as join18 } from "node:path";
|
|
29449
29805
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
29450
29806
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
29451
29807
|
}
|
|
@@ -29456,33 +29812,33 @@ function buildSourceDescriptors(cwd) {
|
|
|
29456
29812
|
// Project-tier — go into consolidated project-scope cleo.db
|
|
29457
29813
|
{
|
|
29458
29814
|
name: "tasks",
|
|
29459
|
-
path:
|
|
29815
|
+
path: join18(cleoDir, "tasks.db"),
|
|
29460
29816
|
targetScope: "project"
|
|
29461
29817
|
},
|
|
29462
29818
|
{
|
|
29463
29819
|
name: "brain (project)",
|
|
29464
|
-
path:
|
|
29820
|
+
path: join18(cleoDir, "brain.db"),
|
|
29465
29821
|
targetScope: "project"
|
|
29466
29822
|
},
|
|
29467
29823
|
{
|
|
29468
29824
|
name: "conduit",
|
|
29469
|
-
path:
|
|
29825
|
+
path: join18(cleoDir, "conduit.db"),
|
|
29470
29826
|
targetScope: "project"
|
|
29471
29827
|
},
|
|
29472
29828
|
// Global-tier — go into consolidated global-scope cleo.db
|
|
29473
29829
|
{
|
|
29474
29830
|
name: "nexus",
|
|
29475
|
-
path:
|
|
29831
|
+
path: join18(cleoHome, "nexus.db"),
|
|
29476
29832
|
targetScope: "global"
|
|
29477
29833
|
},
|
|
29478
29834
|
{
|
|
29479
29835
|
name: "signaldock",
|
|
29480
|
-
path:
|
|
29836
|
+
path: join18(cleoHome, "signaldock.db"),
|
|
29481
29837
|
targetScope: "global"
|
|
29482
29838
|
},
|
|
29483
29839
|
{
|
|
29484
29840
|
name: "skills",
|
|
29485
|
-
path:
|
|
29841
|
+
path: join18(cleoHome, "skills.db"),
|
|
29486
29842
|
targetScope: "global"
|
|
29487
29843
|
}
|
|
29488
29844
|
];
|
|
@@ -29511,7 +29867,7 @@ function findExistingStaging(cleoDir) {
|
|
|
29511
29867
|
const entries = readdirSync3(cleoDir, { withFileTypes: true });
|
|
29512
29868
|
const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
|
|
29513
29869
|
if (stagingDirs.length > 0) {
|
|
29514
|
-
return
|
|
29870
|
+
return join18(cleoDir, stagingDirs[0]);
|
|
29515
29871
|
}
|
|
29516
29872
|
} catch {
|
|
29517
29873
|
}
|
|
@@ -29527,7 +29883,7 @@ function buildExodusPlan(cwd) {
|
|
|
29527
29883
|
const availableBytes = getAvailableBytes(cleoDir);
|
|
29528
29884
|
const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
|
|
29529
29885
|
const existingStaging = findExistingStaging(cleoDir);
|
|
29530
|
-
const stagingDir = existingStaging ??
|
|
29886
|
+
const stagingDir = existingStaging ?? join18(cleoDir, deriveStagingDirName());
|
|
29531
29887
|
const resumeFromStaging = existingStaging !== null;
|
|
29532
29888
|
const projectDbPath = resolveDualScopeDbPath("project", cwd);
|
|
29533
29889
|
const globalDbPath = resolveDualScopeDbPath("global");
|
|
@@ -29546,7 +29902,7 @@ function buildExodusPlan(cwd) {
|
|
|
29546
29902
|
};
|
|
29547
29903
|
}
|
|
29548
29904
|
function sourcesPresent(sources) {
|
|
29549
|
-
return sources.some((s) =>
|
|
29905
|
+
return sources.some((s) => existsSync12(s.path));
|
|
29550
29906
|
}
|
|
29551
29907
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
29552
29908
|
var init_plan2 = __esm({
|
|
@@ -29560,18 +29916,18 @@ var init_plan2 = __esm({
|
|
|
29560
29916
|
});
|
|
29561
29917
|
|
|
29562
29918
|
// packages/core/src/store/exodus/health.ts
|
|
29563
|
-
import { existsSync as
|
|
29919
|
+
import { existsSync as existsSync13, statSync as statSync4 } from "node:fs";
|
|
29564
29920
|
function buildExodusHealth(cwd) {
|
|
29565
29921
|
const plan = buildExodusPlan(cwd);
|
|
29566
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
29922
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync13(s.path));
|
|
29567
29923
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
29568
29924
|
const consolidatedExistsByScope = {
|
|
29569
|
-
project:
|
|
29570
|
-
global:
|
|
29925
|
+
project: existsSync13(plan.projectDbPath),
|
|
29926
|
+
global: existsSync13(plan.globalDbPath)
|
|
29571
29927
|
};
|
|
29572
29928
|
const buildScope = (scope) => {
|
|
29573
29929
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
29574
|
-
const present =
|
|
29930
|
+
const present = existsSync13(s.path);
|
|
29575
29931
|
let bytes = 0;
|
|
29576
29932
|
if (present) {
|
|
29577
29933
|
try {
|
|
@@ -29923,8 +30279,8 @@ var init_types = __esm({
|
|
|
29923
30279
|
});
|
|
29924
30280
|
|
|
29925
30281
|
// packages/core/src/store/backup-sidecar.ts
|
|
29926
|
-
import { existsSync as
|
|
29927
|
-
import { join as
|
|
30282
|
+
import { existsSync as existsSync14, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
30283
|
+
import { join as join19 } from "node:path";
|
|
29928
30284
|
function formatBackupTimestamp(d) {
|
|
29929
30285
|
const pad = (n, len = 2) => String(n).padStart(len, "0");
|
|
29930
30286
|
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
|
|
@@ -29935,8 +30291,8 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29935
30291
|
const ownedPattern = new RegExp(`\\.${escapedType}-`);
|
|
29936
30292
|
const files = readdirSync4(backupDir).filter((f) => !f.endsWith(".meta.json") && !f.endsWith(".tmp") && ownedPattern.test(f)).map((f) => ({
|
|
29937
30293
|
name: f,
|
|
29938
|
-
path:
|
|
29939
|
-
mtimeMs: statSync5(
|
|
30294
|
+
path: join19(backupDir, f),
|
|
30295
|
+
mtimeMs: statSync5(join19(backupDir, f)).mtimeMs
|
|
29940
30296
|
})).sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
29941
30297
|
while (files.length > maxSnapshots) {
|
|
29942
30298
|
const oldest = files.shift();
|
|
@@ -29944,7 +30300,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29944
30300
|
try {
|
|
29945
30301
|
unlinkSync2(oldest.path);
|
|
29946
30302
|
const metaPath = `${oldest.path}.meta.json`;
|
|
29947
|
-
if (
|
|
30303
|
+
if (existsSync14(metaPath)) unlinkSync2(metaPath);
|
|
29948
30304
|
} catch {
|
|
29949
30305
|
}
|
|
29950
30306
|
}
|
|
@@ -29952,7 +30308,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29952
30308
|
}
|
|
29953
30309
|
}
|
|
29954
30310
|
function writeBackupSidecar(backupDir, sidecar) {
|
|
29955
|
-
const dest =
|
|
30311
|
+
const dest = join19(backupDir, `${sidecar.backupId}.meta.json`);
|
|
29956
30312
|
const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
|
|
29957
30313
|
writeFileSync5(tmp, JSON.stringify(sidecar, null, 2));
|
|
29958
30314
|
renameSync4(tmp, dest);
|
|
@@ -29964,23 +30320,23 @@ var init_backup_sidecar = __esm({
|
|
|
29964
30320
|
});
|
|
29965
30321
|
|
|
29966
30322
|
// packages/core/src/store/pre-repair-snapshot.ts
|
|
29967
|
-
import { existsSync as
|
|
29968
|
-
import { dirname as
|
|
30323
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
|
|
30324
|
+
import { dirname as dirname14, join as join20 } from "node:path";
|
|
29969
30325
|
function writePreRepairSnapshot(nativeDb, dbPath, label) {
|
|
29970
30326
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
29971
|
-
const backupDir =
|
|
30327
|
+
const backupDir = join20(dirname14(dbPath), "backups");
|
|
29972
30328
|
mkdirSync3(backupDir, { recursive: true });
|
|
29973
|
-
const snapshotPath =
|
|
30329
|
+
const snapshotPath = join20(backupDir, `cleo-pre-${label}-${stamp}.db`);
|
|
29974
30330
|
nativeDb.exec(`VACUUM INTO '${snapshotPath.replace(/'/g, "''")}'`);
|
|
29975
30331
|
return snapshotPath;
|
|
29976
30332
|
}
|
|
29977
30333
|
function existingAncestor(path) {
|
|
29978
30334
|
let p = path;
|
|
29979
|
-
while (!
|
|
30335
|
+
while (!existsSync15(p) && dirname14(p) !== p) p = dirname14(p);
|
|
29980
30336
|
return p;
|
|
29981
30337
|
}
|
|
29982
30338
|
function planMigrationSnapshot(nativeDb, dbPath) {
|
|
29983
|
-
const backupDir =
|
|
30339
|
+
const backupDir = join20(dirname14(dbPath), "backups", "sqlite");
|
|
29984
30340
|
const pragma = (name15) => Number(nativeDb.prepare(`PRAGMA main.${name15}`).get()[name15] ?? 0);
|
|
29985
30341
|
const liveBytes = (pragma("page_count") - pragma("freelist_count")) * pragma("page_size");
|
|
29986
30342
|
let availableBytes = null;
|
|
@@ -29992,13 +30348,13 @@ function planMigrationSnapshot(nativeDb, dbPath) {
|
|
|
29992
30348
|
}
|
|
29993
30349
|
const base = `migration-${formatBackupTimestamp(/* @__PURE__ */ new Date())}`;
|
|
29994
30350
|
let backupId = base;
|
|
29995
|
-
for (let n = 2;
|
|
30351
|
+
for (let n = 2; existsSync15(join20(backupDir, `${backupId}.meta.json`)); n++) {
|
|
29996
30352
|
backupId = `${base}-${n}`;
|
|
29997
30353
|
}
|
|
29998
30354
|
return {
|
|
29999
30355
|
backupDir,
|
|
30000
30356
|
backupId,
|
|
30001
|
-
snapshotPath:
|
|
30357
|
+
snapshotPath: join20(backupDir, `cleo.db.${backupId}`),
|
|
30002
30358
|
requiredBytes: liveBytes + SNAPSHOT_HEADROOM_BYTES,
|
|
30003
30359
|
availableBytes
|
|
30004
30360
|
};
|
|
@@ -30238,7 +30594,7 @@ var init_legacy_tasks_lineage = __esm({
|
|
|
30238
30594
|
|
|
30239
30595
|
// packages/core/src/store/ports/domain-binding.ts
|
|
30240
30596
|
import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
|
|
30241
|
-
import { resolve as
|
|
30597
|
+
import { resolve as resolve8 } from "node:path";
|
|
30242
30598
|
function getCleoRuntime() {
|
|
30243
30599
|
if (!_runtime) {
|
|
30244
30600
|
_runtime = createCleoRuntime();
|
|
@@ -30306,6 +30662,8 @@ async function bindAgainst(key, store, establish) {
|
|
|
30306
30662
|
() => establish(native, store)
|
|
30307
30663
|
);
|
|
30308
30664
|
return { store, native, db };
|
|
30665
|
+
} catch (error48) {
|
|
30666
|
+
throw explainSchemaWriteDenial(native, error48);
|
|
30309
30667
|
} finally {
|
|
30310
30668
|
membership.active = false;
|
|
30311
30669
|
}
|
|
@@ -30355,7 +30713,7 @@ async function bindLive(scope, key, dbPath, openStore, establish) {
|
|
|
30355
30713
|
);
|
|
30356
30714
|
}
|
|
30357
30715
|
async function bindProjectDomain(domain2, cwd, establish) {
|
|
30358
|
-
const dbPath =
|
|
30716
|
+
const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
|
|
30359
30717
|
const row = await bindLive(
|
|
30360
30718
|
"project",
|
|
30361
30719
|
bindingKey("project", dbPath, domain2),
|
|
@@ -30366,7 +30724,7 @@ async function bindProjectDomain(domain2, cwd, establish) {
|
|
|
30366
30724
|
return row;
|
|
30367
30725
|
}
|
|
30368
30726
|
async function bindGlobalDomain(domain2, establish, cwd) {
|
|
30369
|
-
const dbPath =
|
|
30727
|
+
const dbPath = resolve8(resolveDualScopeDbPath("global"));
|
|
30370
30728
|
const row = await bindLive(
|
|
30371
30729
|
"global",
|
|
30372
30730
|
bindingKey("global", dbPath, domain2),
|
|
@@ -30377,7 +30735,7 @@ async function bindGlobalDomain(domain2, establish, cwd) {
|
|
|
30377
30735
|
return row;
|
|
30378
30736
|
}
|
|
30379
30737
|
async function bindGlobalDomainAtPath(domain2, dbPath, establish) {
|
|
30380
|
-
const normalized =
|
|
30738
|
+
const normalized = resolve8(dbPath);
|
|
30381
30739
|
const row = await bindLive(
|
|
30382
30740
|
"global",
|
|
30383
30741
|
bindingKey("global", normalized, domain2),
|
|
@@ -30388,7 +30746,7 @@ async function bindGlobalDomainAtPath(domain2, dbPath, establish) {
|
|
|
30388
30746
|
return row;
|
|
30389
30747
|
}
|
|
30390
30748
|
function peekDomainAtPath(scope, dbPath, domain2) {
|
|
30391
|
-
const row = _bindings.get(bindingKey(scope,
|
|
30749
|
+
const row = _bindings.get(bindingKey(scope, resolve8(dbPath), domain2));
|
|
30392
30750
|
if (!row?.native.isOpen) return null;
|
|
30393
30751
|
return row;
|
|
30394
30752
|
}
|
|
@@ -30397,12 +30755,12 @@ function releaseDomainBindings(filter2) {
|
|
|
30397
30755
|
_bindings.clear();
|
|
30398
30756
|
return;
|
|
30399
30757
|
}
|
|
30400
|
-
const wantPath = filter2.dbPath === void 0 ? void 0 :
|
|
30758
|
+
const wantPath = filter2.dbPath === void 0 ? void 0 : resolve8(filter2.dbPath);
|
|
30401
30759
|
for (const key of [..._bindings.keys()]) {
|
|
30402
|
-
const
|
|
30760
|
+
const sep6 = key.indexOf("::");
|
|
30403
30761
|
const lastSep = key.lastIndexOf("::");
|
|
30404
|
-
const scope = key.slice(0,
|
|
30405
|
-
const dbPath = key.slice(
|
|
30762
|
+
const scope = key.slice(0, sep6);
|
|
30763
|
+
const dbPath = key.slice(sep6 + 2, lastSep);
|
|
30406
30764
|
const domain2 = key.slice(lastSep + 2);
|
|
30407
30765
|
if (filter2.scope !== void 0 && scope !== filter2.scope) continue;
|
|
30408
30766
|
if (wantPath !== void 0 && dbPath !== wantPath) continue;
|
|
@@ -30417,7 +30775,7 @@ function boundProjectNative(domain2, cwd) {
|
|
|
30417
30775
|
return peekProjectDomain(domain2, cwd)?.native ?? null;
|
|
30418
30776
|
}
|
|
30419
30777
|
function peekProjectDomain(domain2, cwd) {
|
|
30420
|
-
const dbPath =
|
|
30778
|
+
const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
|
|
30421
30779
|
const row = _bindings.get(bindingKey("project", dbPath, domain2));
|
|
30422
30780
|
if (row?.native.isOpen) return row;
|
|
30423
30781
|
if (cwd !== void 0) return null;
|
|
@@ -30432,7 +30790,7 @@ function peekProjectDomain(domain2, cwd) {
|
|
|
30432
30790
|
return sole ?? null;
|
|
30433
30791
|
}
|
|
30434
30792
|
function peekGlobalDomain(domain2) {
|
|
30435
|
-
const dbPath =
|
|
30793
|
+
const dbPath = resolve8(resolveDualScopeDbPath("global"));
|
|
30436
30794
|
const row = _bindings.get(bindingKey("global", dbPath, domain2));
|
|
30437
30795
|
if (!row || !row.native.isOpen) return null;
|
|
30438
30796
|
return row;
|
|
@@ -30443,6 +30801,7 @@ var init_domain_binding = __esm({
|
|
|
30443
30801
|
"use strict";
|
|
30444
30802
|
init_project_scope();
|
|
30445
30803
|
init_dual_scope_db();
|
|
30804
|
+
init_worktree_build_guard();
|
|
30446
30805
|
_runtime = null;
|
|
30447
30806
|
_bindings = /* @__PURE__ */ new Map();
|
|
30448
30807
|
_inflight = /* @__PURE__ */ new Map();
|
|
@@ -30453,9 +30812,9 @@ var init_domain_binding = __esm({
|
|
|
30453
30812
|
|
|
30454
30813
|
// packages/core/src/telemetry/sqlite.ts
|
|
30455
30814
|
import { mkdirSync as mkdirSync4 } from "node:fs";
|
|
30456
|
-
import { dirname as
|
|
30815
|
+
import { dirname as dirname15, join as join21 } from "node:path";
|
|
30457
30816
|
function getTelemetryDbPath() {
|
|
30458
|
-
return
|
|
30817
|
+
return join21(getCleoHome(), DB_FILENAME);
|
|
30459
30818
|
}
|
|
30460
30819
|
function resolveTelemetryMigrationsFolder() {
|
|
30461
30820
|
return resolveCorePackageMigrationsFolder("drizzle-telemetry");
|
|
@@ -30503,8 +30862,9 @@ async function getTelemetryDb() {
|
|
|
30503
30862
|
_initPromise = (async () => {
|
|
30504
30863
|
const dbPath = requestedPath;
|
|
30505
30864
|
_dbPath = dbPath;
|
|
30506
|
-
mkdirSync4(
|
|
30865
|
+
mkdirSync4(dirname15(dbPath), { recursive: true });
|
|
30507
30866
|
const nativeDb = openNativeDatabase(dbPath);
|
|
30867
|
+
installSchemaWriteGuard(nativeDb);
|
|
30508
30868
|
_nativeDb = nativeDb;
|
|
30509
30869
|
const db = drizzle({ client: nativeDb });
|
|
30510
30870
|
runTelemetryMigrations(nativeDb, db);
|
|
@@ -30525,6 +30885,7 @@ var init_sqlite2 = __esm({
|
|
|
30525
30885
|
init_migration_manager();
|
|
30526
30886
|
init_resolve_migrations_folder();
|
|
30527
30887
|
init_sqlite3();
|
|
30888
|
+
init_worktree_build_guard();
|
|
30528
30889
|
DB_FILENAME = "telemetry.db";
|
|
30529
30890
|
TELEMETRY_SCHEMA_VERSION = "1.0.0";
|
|
30530
30891
|
_db = null;
|
|
@@ -30535,11 +30896,11 @@ var init_sqlite2 = __esm({
|
|
|
30535
30896
|
});
|
|
30536
30897
|
|
|
30537
30898
|
// packages/core/src/store/agent-registry-store.ts
|
|
30538
|
-
import { existsSync as
|
|
30539
|
-
import { join as
|
|
30899
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
30900
|
+
import { join as join22 } from "node:path";
|
|
30540
30901
|
function getGlobalAgentRegistryDbPath() {
|
|
30541
30902
|
const cleoHome = getCleoHome();
|
|
30542
|
-
const dbPath =
|
|
30903
|
+
const dbPath = join22(cleoHome, "cleo.db");
|
|
30543
30904
|
if (!dbPath.startsWith(cleoHome)) {
|
|
30544
30905
|
throw new Error(
|
|
30545
30906
|
`BUG: getGlobalAgentRegistryDbPath() resolved to "${dbPath}" which is NOT under getCleoHome() ("${cleoHome}"). The Agent Registry is global-only per ADR-037. This indicates a code path that bypasses path resolution \u2014 fix the caller, do not suppress this error.`
|
|
@@ -30606,7 +30967,7 @@ function establishAgentRegistrySchema(native) {
|
|
|
30606
30967
|
}
|
|
30607
30968
|
async function ensureGlobalAgentRegistryDb() {
|
|
30608
30969
|
const dbPath = getGlobalAgentRegistryDbPath();
|
|
30609
|
-
const alreadyExists =
|
|
30970
|
+
const alreadyExists = existsSync16(dbPath);
|
|
30610
30971
|
let created = false;
|
|
30611
30972
|
const { native: nativeDb } = await bindGlobalDomainAtPath(
|
|
30612
30973
|
AGENT_REGISTRY_DOMAIN,
|
|
@@ -30651,8 +31012,8 @@ var init_agent_registry_store = __esm({
|
|
|
30651
31012
|
});
|
|
30652
31013
|
|
|
30653
31014
|
// packages/core/src/store/conduit-sqlite.ts
|
|
30654
|
-
import { existsSync as
|
|
30655
|
-
import { createRequire as
|
|
31015
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
31016
|
+
import { createRequire as createRequire6 } from "node:module";
|
|
30656
31017
|
function _getDrizzle() {
|
|
30657
31018
|
if (_drizzle === null) {
|
|
30658
31019
|
const mod = _require3("drizzle-orm/node-sqlite");
|
|
@@ -30680,7 +31041,7 @@ function runConduitMigrations(nativeDb) {
|
|
|
30680
31041
|
}
|
|
30681
31042
|
async function ensureConduitDb(projectRoot) {
|
|
30682
31043
|
const dbPath = getConduitDbPath(projectRoot);
|
|
30683
|
-
const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null ||
|
|
31044
|
+
const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync17(dbPath);
|
|
30684
31045
|
await bindConduitDomain(projectRoot);
|
|
30685
31046
|
return { action: alreadyExists ? "exists" : "created", path: dbPath };
|
|
30686
31047
|
}
|
|
@@ -30706,7 +31067,8 @@ var init_conduit_sqlite = __esm({
|
|
|
30706
31067
|
init_domain_binding();
|
|
30707
31068
|
init_resolve_migrations_folder();
|
|
30708
31069
|
init_sqlite_pragmas();
|
|
30709
|
-
|
|
31070
|
+
init_worktree_build_guard();
|
|
31071
|
+
_require3 = createRequire6(import.meta.url);
|
|
30710
31072
|
({ DatabaseSync: DatabaseSync2 } = _require3("node:sqlite"));
|
|
30711
31073
|
_drizzle = null;
|
|
30712
31074
|
CONDUIT_SCHEMA_VERSION = "2026.4.23";
|
|
@@ -32580,216 +32942,6 @@ var init_memory_schema = __esm({
|
|
|
32580
32942
|
}
|
|
32581
32943
|
});
|
|
32582
32944
|
|
|
32583
|
-
// packages/core/src/store/snapshot-gate.ts
|
|
32584
|
-
import { join as join22 } from "node:path";
|
|
32585
|
-
function readGateState(db) {
|
|
32586
|
-
const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
|
|
32587
|
-
const state = { generation: 0, prefixes: {} };
|
|
32588
|
-
if (!row) return state;
|
|
32589
|
-
try {
|
|
32590
|
-
const parsed = JSON.parse(row.value);
|
|
32591
|
-
if (parsed === null || typeof parsed !== "object") return state;
|
|
32592
|
-
if (typeof parsed.generation === "number" && Number.isSafeInteger(parsed.generation)) {
|
|
32593
|
-
state.generation = parsed.generation;
|
|
32594
|
-
}
|
|
32595
|
-
for (const [prefix, e] of Object.entries(parsed.prefixes ?? {})) {
|
|
32596
|
-
if (e && typeof e.generation === "number" && typeof e.startedAt === "number" && typeof e.completedAt === "number") {
|
|
32597
|
-
state.prefixes[prefix] = {
|
|
32598
|
-
generation: e.generation,
|
|
32599
|
-
startedAt: e.startedAt,
|
|
32600
|
-
completedAt: e.completedAt
|
|
32601
|
-
};
|
|
32602
|
-
}
|
|
32603
|
-
}
|
|
32604
|
-
} catch {
|
|
32605
|
-
}
|
|
32606
|
-
return state;
|
|
32607
|
-
}
|
|
32608
|
-
function writeGateState(db, state) {
|
|
32609
|
-
db.prepare(
|
|
32610
|
-
"INSERT INTO tasks_schema_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
32611
|
-
).run(SNAPSHOT_GATE_META_KEY, JSON.stringify(state));
|
|
32612
|
-
}
|
|
32613
|
-
function tryReadGateState(db) {
|
|
32614
|
-
if (!db) return null;
|
|
32615
|
-
try {
|
|
32616
|
-
return readGateState(db);
|
|
32617
|
-
} catch {
|
|
32618
|
-
return null;
|
|
32619
|
-
}
|
|
32620
|
-
}
|
|
32621
|
-
function needsSnapshot(entry, mode, nowMs, seenGeneration) {
|
|
32622
|
-
if (!entry) return true;
|
|
32623
|
-
if (mode === "required") return seenGeneration === null || entry.generation <= seenGeneration;
|
|
32624
|
-
const elapsed = nowMs - entry.startedAt;
|
|
32625
|
-
return elapsed < 0 || elapsed >= SNAPSHOT_DEBOUNCE_MS;
|
|
32626
|
-
}
|
|
32627
|
-
async function runGatedSnapshot(opts, snapshot) {
|
|
32628
|
-
const now = opts.now ?? Date.now;
|
|
32629
|
-
const mode = opts.mode ?? "routine";
|
|
32630
|
-
const db = opts.stateDb;
|
|
32631
|
-
const none = (skipped, error48) => ({
|
|
32632
|
-
snapshotted: [],
|
|
32633
|
-
linked: [],
|
|
32634
|
-
absent: [],
|
|
32635
|
-
failed: [],
|
|
32636
|
-
skipped,
|
|
32637
|
-
...error48 !== void 0 && { error: error48 }
|
|
32638
|
-
});
|
|
32639
|
-
const entryState = tryReadGateState(db);
|
|
32640
|
-
const seenGeneration = mode === "required" ? opts.seenGeneration ?? entryState?.generation ?? null : null;
|
|
32641
|
-
if (mode === "routine") {
|
|
32642
|
-
if (!entryState) return none("state-unavailable");
|
|
32643
|
-
const nowMs = now();
|
|
32644
|
-
if (!opts.prefixes.some((p) => needsSnapshot(entryState.prefixes[p], mode, nowMs, null))) {
|
|
32645
|
-
return none("debounced");
|
|
32646
|
-
}
|
|
32647
|
-
}
|
|
32648
|
-
const lockPath2 = join22(opts.backupDir, GATE_LOCK_BASENAME);
|
|
32649
|
-
let release;
|
|
32650
|
-
try {
|
|
32651
|
-
release = await acquireLock(lockPath2, {
|
|
32652
|
-
retries: mode === "required" ? opts.lockWaitRetries ?? SNAPSHOT_LOCK_WAIT_RETRIES : 0,
|
|
32653
|
-
stale: SNAPSHOT_LOCK_STALE_MS,
|
|
32654
|
-
// A compromised lock (e.g. the backup dir was removed) must not throw
|
|
32655
|
-
// from a timer and crash the host process.
|
|
32656
|
-
onCompromised: () => {
|
|
32657
|
-
}
|
|
32658
|
-
});
|
|
32659
|
-
} catch {
|
|
32660
|
-
if (mode === "routine") return none("in-flight");
|
|
32661
|
-
return none(
|
|
32662
|
-
"lock-timeout",
|
|
32663
|
-
`Snapshot lock ${lockPath2}.lock is still held after waiting. Another snapshot is running, or a crashed process left the lock (it expires after ${SNAPSHOT_LOCK_STALE_MS / 6e4} minutes). Remove it if no snapshot is running.`
|
|
32664
|
-
);
|
|
32665
|
-
}
|
|
32666
|
-
try {
|
|
32667
|
-
try {
|
|
32668
|
-
opts.onLockAcquired?.();
|
|
32669
|
-
} catch {
|
|
32670
|
-
}
|
|
32671
|
-
const state = tryReadGateState(db);
|
|
32672
|
-
if (!state && mode === "routine") return none("state-unavailable");
|
|
32673
|
-
const startMs = now();
|
|
32674
|
-
const admitted = mode === "required" && opts.alwaysSnapshot === true ? [...opts.prefixes] : opts.prefixes.filter(
|
|
32675
|
-
(p) => needsSnapshot(state?.prefixes[p], mode, startMs, seenGeneration)
|
|
32676
|
-
);
|
|
32677
|
-
if (admitted.length === 0) return none(mode === "routine" ? "debounced" : "covered");
|
|
32678
|
-
const generation = (state?.generation ?? 0) + 1;
|
|
32679
|
-
let claimed = false;
|
|
32680
|
-
if (db && state) {
|
|
32681
|
-
try {
|
|
32682
|
-
writeGateState(db, { ...state, generation });
|
|
32683
|
-
claimed = true;
|
|
32684
|
-
} catch {
|
|
32685
|
-
}
|
|
32686
|
-
}
|
|
32687
|
-
const snapshotted = [];
|
|
32688
|
-
const linked = [];
|
|
32689
|
-
const absent = [];
|
|
32690
|
-
const failed = [];
|
|
32691
|
-
for (const prefix of admitted) {
|
|
32692
|
-
try {
|
|
32693
|
-
const outcome = await snapshot(prefix);
|
|
32694
|
-
if (outcome === "absent") absent.push(prefix);
|
|
32695
|
-
else {
|
|
32696
|
-
snapshotted.push(prefix);
|
|
32697
|
-
if (outcome === "linked") linked.push(prefix);
|
|
32698
|
-
}
|
|
32699
|
-
} catch {
|
|
32700
|
-
failed.push(prefix);
|
|
32701
|
-
}
|
|
32702
|
-
}
|
|
32703
|
-
const satisfied = [...snapshotted, ...absent];
|
|
32704
|
-
if (db && claimed && satisfied.length > 0) {
|
|
32705
|
-
try {
|
|
32706
|
-
const latest = readGateState(db);
|
|
32707
|
-
const completedAt = now();
|
|
32708
|
-
latest.generation = Math.max(latest.generation, generation);
|
|
32709
|
-
for (const p of satisfied) {
|
|
32710
|
-
latest.prefixes[p] = { generation, startedAt: startMs, completedAt };
|
|
32711
|
-
}
|
|
32712
|
-
writeGateState(db, latest);
|
|
32713
|
-
} catch {
|
|
32714
|
-
}
|
|
32715
|
-
}
|
|
32716
|
-
return { snapshotted, linked, absent, failed, skipped: null };
|
|
32717
|
-
} finally {
|
|
32718
|
-
await release().catch(() => {
|
|
32719
|
-
});
|
|
32720
|
-
}
|
|
32721
|
-
}
|
|
32722
|
-
function isValidStamp(ymd, hms) {
|
|
32723
|
-
const y = Number(ymd.slice(0, 4));
|
|
32724
|
-
const mo = Number(ymd.slice(4, 6));
|
|
32725
|
-
const d = Number(ymd.slice(6, 8));
|
|
32726
|
-
const h = Number(hms.slice(0, 2));
|
|
32727
|
-
const mi = Number(hms.slice(2, 4));
|
|
32728
|
-
const se = Number(hms.slice(4, 6));
|
|
32729
|
-
if (mo < 1 || mo > 12 || d < 1 || h > 23 || mi > 59 || se > 59) return false;
|
|
32730
|
-
const probe = new Date(Date.UTC(y, mo - 1, d));
|
|
32731
|
-
return probe.getUTCFullYear() === y && probe.getUTCMonth() === mo - 1 && probe.getUTCDate() === d;
|
|
32732
|
-
}
|
|
32733
|
-
function selectSnapshotsToKeep(names, ctx = {}) {
|
|
32734
|
-
const policy = ctx.policy ?? DEFAULT_SNAPSHOT_RETENTION;
|
|
32735
|
-
const keep = /* @__PURE__ */ new Set();
|
|
32736
|
-
const stamped = [];
|
|
32737
|
-
for (const name15 of names) {
|
|
32738
|
-
const m = STAMP_PATTERN.exec(name15);
|
|
32739
|
-
const ymd = m?.[1];
|
|
32740
|
-
const hms = m?.[2];
|
|
32741
|
-
if (!ymd || !hms || !isValidStamp(ymd, hms)) {
|
|
32742
|
-
keep.add(name15);
|
|
32743
|
-
continue;
|
|
32744
|
-
}
|
|
32745
|
-
const stamp = `${ymd}-${hms}`;
|
|
32746
|
-
if (ctx.nowStamp !== void 0 && stamp > ctx.nowStamp) {
|
|
32747
|
-
keep.add(name15);
|
|
32748
|
-
continue;
|
|
32749
|
-
}
|
|
32750
|
-
stamped.push({ name: name15, stamp });
|
|
32751
|
-
}
|
|
32752
|
-
if (ctx.pinned !== void 0 && names.includes(ctx.pinned)) keep.add(ctx.pinned);
|
|
32753
|
-
stamped.sort((a, b) => a.stamp < b.stamp ? 1 : a.stamp > b.stamp ? -1 : 0);
|
|
32754
|
-
for (const s of stamped.slice(0, policy.latest)) keep.add(s.name);
|
|
32755
|
-
const keepNewestPerBucket = (bucketOf, slots) => {
|
|
32756
|
-
const seen = /* @__PURE__ */ new Set();
|
|
32757
|
-
for (const s of stamped) {
|
|
32758
|
-
const bucket = bucketOf(s.stamp);
|
|
32759
|
-
if (seen.has(bucket)) continue;
|
|
32760
|
-
if (seen.size >= slots) break;
|
|
32761
|
-
seen.add(bucket);
|
|
32762
|
-
keep.add(s.name);
|
|
32763
|
-
}
|
|
32764
|
-
};
|
|
32765
|
-
keepNewestPerBucket(
|
|
32766
|
-
(stamp) => `${stamp.slice(0, 11)}q${Math.floor(Number(stamp.slice(11, 13)) / 15)}`,
|
|
32767
|
-
policy.quarterHourly
|
|
32768
|
-
);
|
|
32769
|
-
keepNewestPerBucket((stamp) => stamp.slice(0, 11), policy.hourly);
|
|
32770
|
-
keepNewestPerBucket((stamp) => stamp.slice(0, 8), policy.daily);
|
|
32771
|
-
return keep;
|
|
32772
|
-
}
|
|
32773
|
-
var SNAPSHOT_DEBOUNCE_MS, SNAPSHOT_LOCK_STALE_MS, SNAPSHOT_LOCK_WAIT_RETRIES, SNAPSHOT_GATE_META_KEY, GATE_LOCK_BASENAME, DEFAULT_SNAPSHOT_RETENTION, STAMP_PATTERN;
|
|
32774
|
-
var init_snapshot_gate = __esm({
|
|
32775
|
-
"packages/core/src/store/snapshot-gate.ts"() {
|
|
32776
|
-
"use strict";
|
|
32777
|
-
init_lock();
|
|
32778
|
-
SNAPSHOT_DEBOUNCE_MS = 5 * 6e4;
|
|
32779
|
-
SNAPSHOT_LOCK_STALE_MS = 10 * 6e4;
|
|
32780
|
-
SNAPSHOT_LOCK_WAIT_RETRIES = 90;
|
|
32781
|
-
SNAPSHOT_GATE_META_KEY = "sqlite_snapshot_gate";
|
|
32782
|
-
GATE_LOCK_BASENAME = ".snapshot-gate";
|
|
32783
|
-
DEFAULT_SNAPSHOT_RETENTION = {
|
|
32784
|
-
latest: 1,
|
|
32785
|
-
quarterHourly: 3,
|
|
32786
|
-
hourly: 3,
|
|
32787
|
-
daily: 3
|
|
32788
|
-
};
|
|
32789
|
-
STAMP_PATTERN = /-(\d{8})-(\d{6})\.db$/;
|
|
32790
|
-
}
|
|
32791
|
-
});
|
|
32792
|
-
|
|
32793
32945
|
// packages/core/src/store/twin-collapse.ts
|
|
32794
32946
|
import { createHash as createHash3 } from "node:crypto";
|
|
32795
32947
|
function hasMainTable(db, name15) {
|
|
@@ -32866,6 +33018,22 @@ function mergeSchemaMetaValue(key, bare, twin) {
|
|
|
32866
33018
|
const field = SCHEMA_META_COUNTER_FIELDS[key];
|
|
32867
33019
|
return field === void 0 ? bare : withMaxCounter(bare, twin, field);
|
|
32868
33020
|
}
|
|
33021
|
+
function mirrorCounterToBare(db, key) {
|
|
33022
|
+
if (SCHEMA_META_COUNTER_FIELDS[key] === void 0) return;
|
|
33023
|
+
if (!hasMainTable(db, "schema_meta")) return;
|
|
33024
|
+
const twin = readKv(db, "tasks_schema_meta", key);
|
|
33025
|
+
if (twin === void 0) return;
|
|
33026
|
+
const bare = readKv(db, "schema_meta", key);
|
|
33027
|
+
const next = bare === void 0 ? twin : mergeSchemaMetaValue(key, bare, twin);
|
|
33028
|
+
if (next === null || next === bare) return;
|
|
33029
|
+
writeKv(db, "schema_meta", key, next);
|
|
33030
|
+
}
|
|
33031
|
+
function bareCounterOf(db, key) {
|
|
33032
|
+
const name15 = SCHEMA_META_COUNTER_FIELDS[key];
|
|
33033
|
+
if (name15 === void 0 || !hasMainTable(db, "schema_meta")) return 0;
|
|
33034
|
+
const bare = readKv(db, "schema_meta", key);
|
|
33035
|
+
return (bare === void 0 ? void 0 : counterOf(bare, name15)) ?? 0;
|
|
33036
|
+
}
|
|
32869
33037
|
function kvRows(db, table, schema = "main") {
|
|
32870
33038
|
const rows = db.prepare(`SELECT key, value FROM ${schema}.${table}`).all();
|
|
32871
33039
|
return new Map(rows.map((r) => [r.key, r.value]));
|
|
@@ -32998,6 +33166,39 @@ function applyStickyRows(db, schema, plan) {
|
|
|
32998
33166
|
}
|
|
32999
33167
|
return { inserted, replaced: 0, deleted };
|
|
33000
33168
|
}
|
|
33169
|
+
function tagsOf(tagsJson) {
|
|
33170
|
+
if (!tagsJson) return [];
|
|
33171
|
+
try {
|
|
33172
|
+
const parsed = JSON.parse(tagsJson);
|
|
33173
|
+
if (!Array.isArray(parsed)) return [];
|
|
33174
|
+
return [...new Set(parsed.filter((t) => typeof t === "string" && t.length > 0))];
|
|
33175
|
+
} catch {
|
|
33176
|
+
return [];
|
|
33177
|
+
}
|
|
33178
|
+
}
|
|
33179
|
+
function syncStickyJunction(db, schema) {
|
|
33180
|
+
const notes = db.prepare("SELECT id, tags_json FROM main.brain_sticky_notes").all();
|
|
33181
|
+
const have = /* @__PURE__ */ new Map();
|
|
33182
|
+
for (const r of db.prepare(`SELECT sticky_id, tag FROM ${schema}.brain_sticky_tags`).all()) {
|
|
33183
|
+
const set2 = have.get(r.sticky_id) ?? /* @__PURE__ */ new Set();
|
|
33184
|
+
set2.add(r.tag);
|
|
33185
|
+
have.set(r.sticky_id, set2);
|
|
33186
|
+
}
|
|
33187
|
+
const insert = db.prepare(
|
|
33188
|
+
`INSERT OR IGNORE INTO ${schema}.brain_sticky_tags (sticky_id, tag) VALUES (?, ?)`
|
|
33189
|
+
);
|
|
33190
|
+
const del = db.prepare(`DELETE FROM ${schema}.brain_sticky_tags WHERE sticky_id = ? AND tag = ?`);
|
|
33191
|
+
let inserted = 0;
|
|
33192
|
+
let deleted = 0;
|
|
33193
|
+
for (const note of notes) {
|
|
33194
|
+
const want = new Set(tagsOf(note.tags_json));
|
|
33195
|
+
const current = have.get(note.id) ?? /* @__PURE__ */ new Set();
|
|
33196
|
+
for (const tag of want)
|
|
33197
|
+
if (!current.has(tag)) inserted += Number(insert.run(note.id, tag).changes);
|
|
33198
|
+
for (const tag of current) if (!want.has(tag)) deleted += Number(del.run(note.id, tag).changes);
|
|
33199
|
+
}
|
|
33200
|
+
return { inserted, deleted };
|
|
33201
|
+
}
|
|
33001
33202
|
function twinCollapseFailureOf(db) {
|
|
33002
33203
|
return degraded.get(db);
|
|
33003
33204
|
}
|
|
@@ -33207,7 +33408,7 @@ function collapseTwinTables(nativeDb, dbPath, options = {}) {
|
|
|
33207
33408
|
}
|
|
33208
33409
|
return inOrder();
|
|
33209
33410
|
}
|
|
33210
|
-
var log6, TWIN_COLLAPSE_MARKER_PREFIX, TWIN_COLLAPSE_FAILURE_PREFIX, SCHEMA_META_COUNTER_FIELDS, SCHEMA_META_NEVER_DELETED, MAX_CONFLICTS, sha, ABSENT, hashMap, emptyPlan, SCHEMA_META, hashSets, EMPTY_SET, STICKY_TAGS, PAIRS, degraded, SHADOW_WRITE_REFUSED, SHADOW_WRITE_OPS;
|
|
33411
|
+
var log6, TWIN_COLLAPSE_MARKER_PREFIX, TWIN_COLLAPSE_FAILURE_PREFIX, SNAPSHOT_GATE_KEY, SCHEMA_META_COUNTER_FIELDS, SCHEMA_META_NEVER_DELETED, MAX_CONFLICTS, sha, ABSENT, hashMap, emptyPlan, SCHEMA_META, hashSets, EMPTY_SET, STICKY_TAGS, PAIRS, degraded, SHADOW_WRITE_REFUSED, SHADOW_WRITE_OPS;
|
|
33211
33412
|
var init_twin_collapse = __esm({
|
|
33212
33413
|
"packages/core/src/store/twin-collapse.ts"() {
|
|
33213
33414
|
"use strict";
|
|
@@ -33215,18 +33416,18 @@ var init_twin_collapse = __esm({
|
|
|
33215
33416
|
init_errors2();
|
|
33216
33417
|
init_logger();
|
|
33217
33418
|
init_pre_repair_snapshot();
|
|
33218
|
-
init_snapshot_gate();
|
|
33219
33419
|
log6 = getLogger("twin-collapse");
|
|
33220
33420
|
TWIN_COLLAPSE_MARKER_PREFIX = "twin_collapse:";
|
|
33221
33421
|
TWIN_COLLAPSE_FAILURE_PREFIX = "twin_collapse_failed:";
|
|
33422
|
+
SNAPSHOT_GATE_KEY = "sqlite_snapshot_gate";
|
|
33222
33423
|
SCHEMA_META_COUNTER_FIELDS = {
|
|
33223
33424
|
task_id_sequence: "counter",
|
|
33224
|
-
[
|
|
33425
|
+
[SNAPSHOT_GATE_KEY]: "generation",
|
|
33225
33426
|
file_meta: "generation"
|
|
33226
33427
|
};
|
|
33227
33428
|
SCHEMA_META_NEVER_DELETED = /* @__PURE__ */ new Set([
|
|
33228
33429
|
"task_id_sequence",
|
|
33229
|
-
|
|
33430
|
+
SNAPSHOT_GATE_KEY
|
|
33230
33431
|
]);
|
|
33231
33432
|
MAX_CONFLICTS = 50;
|
|
33232
33433
|
sha = (value) => createHash3("sha256").update(value).digest("hex");
|
|
@@ -33291,7 +33492,12 @@ var init_twin_collapse = __esm({
|
|
|
33291
33492
|
throw new Error(
|
|
33292
33493
|
`sticky_tags collapse did not verify: ${missing} missing, ${lingering} not removed`
|
|
33293
33494
|
);
|
|
33294
|
-
|
|
33495
|
+
const synced = syncStickyJunction(db, "main");
|
|
33496
|
+
return {
|
|
33497
|
+
inserted: counts.inserted + synced.inserted,
|
|
33498
|
+
replaced: 0,
|
|
33499
|
+
deleted: counts.deleted + synced.deleted
|
|
33500
|
+
};
|
|
33295
33501
|
},
|
|
33296
33502
|
shadow(db, plan) {
|
|
33297
33503
|
db.exec(
|
|
@@ -33302,6 +33508,7 @@ var init_twin_collapse = __esm({
|
|
|
33302
33508
|
"INSERT INTO temp.brain_sticky_tags (sticky_id, tag) SELECT sticky_id, tag FROM main.brain_sticky_tags"
|
|
33303
33509
|
);
|
|
33304
33510
|
applyStickyRows(db, "temp", plan);
|
|
33511
|
+
syncStickyJunction(db, "temp");
|
|
33305
33512
|
}
|
|
33306
33513
|
};
|
|
33307
33514
|
PAIRS = [SCHEMA_META, STICKY_TAGS];
|
|
@@ -33333,7 +33540,7 @@ __export(config_exports, {
|
|
|
33333
33540
|
parseConfigValue: () => parseConfigValue,
|
|
33334
33541
|
setConfigValue: () => setConfigValue
|
|
33335
33542
|
});
|
|
33336
|
-
import { existsSync as
|
|
33543
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
33337
33544
|
function getNestedValue(obj, path) {
|
|
33338
33545
|
const parts = path.split(".");
|
|
33339
33546
|
let current = obj;
|
|
@@ -33455,7 +33662,7 @@ function parseConfigValue(value) {
|
|
|
33455
33662
|
}
|
|
33456
33663
|
async function setConfigValue(key, value, cwd, opts) {
|
|
33457
33664
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
33458
|
-
if (!
|
|
33665
|
+
if (!existsSync18(configPath)) {
|
|
33459
33666
|
await atomicWriteJson(configPath, {});
|
|
33460
33667
|
}
|
|
33461
33668
|
const config2 = await readJson(configPath) ?? {};
|
|
@@ -33467,7 +33674,7 @@ async function setConfigValue(key, value, cwd, opts) {
|
|
|
33467
33674
|
async function applyStrictnessPreset(preset, cwd, opts) {
|
|
33468
33675
|
const definition = STRICTNESS_PRESETS[preset];
|
|
33469
33676
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
33470
|
-
if (!
|
|
33677
|
+
if (!existsSync18(configPath)) {
|
|
33471
33678
|
await atomicWriteJson(configPath, {});
|
|
33472
33679
|
}
|
|
33473
33680
|
const config2 = await readJson(configPath) ?? {};
|
|
@@ -34044,6 +34251,7 @@ var init_cross_db_cleanup = __esm({
|
|
|
34044
34251
|
"use strict";
|
|
34045
34252
|
init_memory_sqlite();
|
|
34046
34253
|
init_memory_schema();
|
|
34254
|
+
init_worktree_build_guard();
|
|
34047
34255
|
}
|
|
34048
34256
|
});
|
|
34049
34257
|
|
|
@@ -38736,7 +38944,7 @@ __export(sqlite_data_accessor_exports, {
|
|
|
38736
38944
|
setMetaValue: () => setMetaValue
|
|
38737
38945
|
});
|
|
38738
38946
|
import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
|
|
38739
|
-
import { resolve as
|
|
38947
|
+
import { resolve as resolve9 } from "node:path";
|
|
38740
38948
|
import {
|
|
38741
38949
|
and as and5,
|
|
38742
38950
|
eq as eq6,
|
|
@@ -38776,9 +38984,12 @@ async function writeMetaValue(cwd, key, value) {
|
|
|
38776
38984
|
target: tasksSchemaMeta.key,
|
|
38777
38985
|
set: { value: json2 }
|
|
38778
38986
|
}).run();
|
|
38987
|
+
const native = getNativeTasksDb(cwd);
|
|
38988
|
+
if (native) mirrorCounterToBare(native, key);
|
|
38779
38989
|
}
|
|
38780
38990
|
function advanceTaskIdSequence(nativeDb, floor) {
|
|
38781
38991
|
assertTwinCollapseWritable(nativeDb);
|
|
38992
|
+
const lowest = Math.max(floor, bareCounterOf(nativeDb, "task_id_sequence"));
|
|
38782
38993
|
nativeDb.prepare(`
|
|
38783
38994
|
UPDATE tasks_schema_meta
|
|
38784
38995
|
SET value = json_set(value,
|
|
@@ -38787,7 +38998,8 @@ function advanceTaskIdSequence(nativeDb, floor) {
|
|
|
38787
38998
|
'$.checksum', 'alloc-' || strftime('%s','now')
|
|
38788
38999
|
)
|
|
38789
39000
|
WHERE key = 'task_id_sequence'
|
|
38790
|
-
`).run(
|
|
39001
|
+
`).run(lowest, lowest);
|
|
39002
|
+
mirrorCounterToBare(nativeDb, "task_id_sequence");
|
|
38791
39003
|
const row = nativeDb.prepare(`
|
|
38792
39004
|
SELECT json_extract(value, '$.counter') AS counter
|
|
38793
39005
|
FROM tasks_schema_meta WHERE key = 'task_id_sequence'
|
|
@@ -38841,7 +39053,7 @@ function bindTaskAccessorScope(accessor, scope) {
|
|
|
38841
39053
|
}
|
|
38842
39054
|
async function createSqliteDataAccessor(cwd) {
|
|
38843
39055
|
const scope = captureProjectScope(
|
|
38844
|
-
|
|
39056
|
+
resolve9(cwd ?? getProjectRoot()),
|
|
38845
39057
|
worktreeScope.getStore()
|
|
38846
39058
|
);
|
|
38847
39059
|
return worktreeScope.run(
|
|
@@ -38956,7 +39168,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38956
39168
|
actor: entry.actor ?? "system",
|
|
38957
39169
|
detailsJson: entry.details ? JSON.stringify(entry.details) : "{}",
|
|
38958
39170
|
beforeJson: entry.before ? JSON.stringify(entry.before) : null,
|
|
38959
|
-
afterJson: entry.after ? JSON.stringify(entry.after) : null
|
|
39171
|
+
afterJson: entry.after ? JSON.stringify(entry.after) : null,
|
|
39172
|
+
// T12693: the session a ranking change ran in.
|
|
39173
|
+
sessionId: typeof entry.sessionId === "string" ? entry.sessionId : null
|
|
38960
39174
|
}).run()
|
|
38961
39175
|
);
|
|
38962
39176
|
});
|
|
@@ -38964,6 +39178,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38964
39178
|
async queryAuditLog(query) {
|
|
38965
39179
|
const db = await getDb(cwd);
|
|
38966
39180
|
const conditions = [];
|
|
39181
|
+
if (query.ids && query.ids.length > 0) {
|
|
39182
|
+
conditions.push(inArray4(tasksAuditLog.id, [...query.ids]));
|
|
39183
|
+
}
|
|
38967
39184
|
if (query.taskIds && query.taskIds.length > 0) {
|
|
38968
39185
|
conditions.push(inArray4(tasksAuditLog.taskId, [...query.taskIds]));
|
|
38969
39186
|
}
|
|
@@ -38982,7 +39199,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38982
39199
|
actor: tasksAuditLog.actor,
|
|
38983
39200
|
detailsJson: tasksAuditLog.detailsJson,
|
|
38984
39201
|
beforeJson: tasksAuditLog.beforeJson,
|
|
38985
|
-
afterJson: tasksAuditLog.afterJson
|
|
39202
|
+
afterJson: tasksAuditLog.afterJson,
|
|
39203
|
+
sessionId: tasksAuditLog.sessionId
|
|
38986
39204
|
}).from(tasksAuditLog).where(conditions.length > 0 ? and5(...conditions) : void 0).orderBy(sql26`${tasksAuditLog.timestamp} DESC`).limit(limit).all();
|
|
38987
39205
|
return rows.map((row) => ({
|
|
38988
39206
|
id: row.id,
|
|
@@ -38992,7 +39210,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38992
39210
|
actor: row.actor,
|
|
38993
39211
|
detailsJson: row.detailsJson ?? null,
|
|
38994
39212
|
beforeJson: row.beforeJson ?? null,
|
|
38995
|
-
afterJson: row.afterJson ?? null
|
|
39213
|
+
afterJson: row.afterJson ?? null,
|
|
39214
|
+
sessionId: row.sessionId ?? null
|
|
38996
39215
|
}));
|
|
38997
39216
|
},
|
|
38998
39217
|
// ---- Fine-grained task operations (T5034) ----
|
|
@@ -39830,7 +40049,7 @@ var init_sqlite_data_accessor = __esm({
|
|
|
39830
40049
|
});
|
|
39831
40050
|
|
|
39832
40051
|
// packages/core/src/sequence/index.ts
|
|
39833
|
-
import { existsSync as
|
|
40052
|
+
import { existsSync as existsSync19, readFileSync as readFileSync7, renameSync as renameSync5 } from "node:fs";
|
|
39834
40053
|
import { join as join23 } from "node:path";
|
|
39835
40054
|
function getLegacySequenceJsonPath(cwd) {
|
|
39836
40055
|
return join23(resolveOrCwd(cwd), ".cleo", ".sequence.json");
|
|
@@ -39847,19 +40066,19 @@ function isSeedSequence(value) {
|
|
|
39847
40066
|
return value.counter === 0 && value.lastId === "T000" && value.checksum === "seed";
|
|
39848
40067
|
}
|
|
39849
40068
|
function readLegacySequenceFile(path) {
|
|
39850
|
-
if (!
|
|
40069
|
+
if (!existsSync19(path)) return null;
|
|
39851
40070
|
try {
|
|
39852
|
-
const parsed = JSON.parse(
|
|
40071
|
+
const parsed = JSON.parse(readFileSync7(path, "utf-8"));
|
|
39853
40072
|
return isValidSequenceState(parsed) ? parsed : null;
|
|
39854
40073
|
} catch {
|
|
39855
40074
|
return null;
|
|
39856
40075
|
}
|
|
39857
40076
|
}
|
|
39858
40077
|
function renameLegacyFile(path) {
|
|
39859
|
-
if (!
|
|
40078
|
+
if (!existsSync19(path)) return;
|
|
39860
40079
|
const migratedPath = `${path}.migrated`;
|
|
39861
40080
|
try {
|
|
39862
|
-
if (!
|
|
40081
|
+
if (!existsSync19(migratedPath)) {
|
|
39863
40082
|
renameSync5(path, migratedPath);
|
|
39864
40083
|
return;
|
|
39865
40084
|
}
|
|
@@ -40025,12 +40244,12 @@ var init_checkpoint_git_dir = __esm({
|
|
|
40025
40244
|
|
|
40026
40245
|
// packages/core/src/store/git-checkpoint.ts
|
|
40027
40246
|
import { execFile as execFile2 } from "node:child_process";
|
|
40028
|
-
import { existsSync as
|
|
40247
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
40029
40248
|
import { readFile as readFile4, writeFile } from "node:fs/promises";
|
|
40030
|
-
import { join as join25, resolve as
|
|
40249
|
+
import { join as join25, resolve as resolve10 } from "node:path";
|
|
40031
40250
|
import { promisify as promisify2 } from "node:util";
|
|
40032
40251
|
function makeCleoGitEnv(cleoDir) {
|
|
40033
|
-
const abs =
|
|
40252
|
+
const abs = resolve10(cleoDir);
|
|
40034
40253
|
return {
|
|
40035
40254
|
...process.env,
|
|
40036
40255
|
GIT_DIR: checkpointGitDir(abs),
|
|
@@ -40040,7 +40259,7 @@ function makeCleoGitEnv(cleoDir) {
|
|
|
40040
40259
|
async function cleoGitCommand(args, cleoDir) {
|
|
40041
40260
|
try {
|
|
40042
40261
|
const result = await execFileAsync2("git", args, {
|
|
40043
|
-
cwd:
|
|
40262
|
+
cwd: resolve10(cleoDir),
|
|
40044
40263
|
// absolute cwd so relative paths in args resolve correctly
|
|
40045
40264
|
env: makeCleoGitEnv(cleoDir),
|
|
40046
40265
|
timeout: 1e4
|
|
@@ -40051,7 +40270,7 @@ async function cleoGitCommand(args, cleoDir) {
|
|
|
40051
40270
|
}
|
|
40052
40271
|
}
|
|
40053
40272
|
function isCleoGitInitialized(cleoDir) {
|
|
40054
|
-
return
|
|
40273
|
+
return existsSync20(join25(checkpointGitDir(cleoDir), "HEAD"));
|
|
40055
40274
|
}
|
|
40056
40275
|
async function loadStateFileAllowlist(cwd) {
|
|
40057
40276
|
try {
|
|
@@ -40095,14 +40314,14 @@ async function isCleoGitRepo(cleoDir) {
|
|
|
40095
40314
|
return result.success && (result.stdout === "true" || isCleoGitInitialized(cleoDir));
|
|
40096
40315
|
}
|
|
40097
40316
|
function isMergeInProgress(cleoDir) {
|
|
40098
|
-
return
|
|
40317
|
+
return existsSync20(join25(checkpointGitDir(cleoDir), "MERGE_HEAD"));
|
|
40099
40318
|
}
|
|
40100
40319
|
async function isDetachedHead(cleoDir) {
|
|
40101
40320
|
const result = await cleoGitCommand(["symbolic-ref", "HEAD"], cleoDir);
|
|
40102
40321
|
return !result.success;
|
|
40103
40322
|
}
|
|
40104
40323
|
function isRebaseInProgress(cleoDir) {
|
|
40105
|
-
return
|
|
40324
|
+
return existsSync20(join25(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync20(join25(checkpointGitDir(cleoDir), "rebase-apply"));
|
|
40106
40325
|
}
|
|
40107
40326
|
async function recordCheckpointTime(cleoDir) {
|
|
40108
40327
|
try {
|
|
@@ -40126,7 +40345,7 @@ async function getChangedStateFiles(cleoDir, cwd) {
|
|
|
40126
40345
|
const allStateFiles = await getAllStateFiles(cwd);
|
|
40127
40346
|
for (const stateFile of allStateFiles) {
|
|
40128
40347
|
const fullPath = join25(cleoDir, stateFile);
|
|
40129
|
-
if (!
|
|
40348
|
+
if (!existsSync20(fullPath)) continue;
|
|
40130
40349
|
const diffResult = await cleoGitCommand(["diff", "--quiet", "--", stateFile], cleoDir);
|
|
40131
40350
|
const cachedResult = await cleoGitCommand(
|
|
40132
40351
|
["diff", "--cached", "--quiet", "--", stateFile],
|
|
@@ -40153,7 +40372,7 @@ async function shouldCheckpoint(options) {
|
|
|
40153
40372
|
const config2 = await loadCheckpointConfig(cwd);
|
|
40154
40373
|
if (!config2.enabled) return false;
|
|
40155
40374
|
const cleoDir = getCleoDir(cwd);
|
|
40156
|
-
if (!
|
|
40375
|
+
if (!existsSync20(cleoDir)) return false;
|
|
40157
40376
|
if (!isCleoGitInitialized(cleoDir)) return false;
|
|
40158
40377
|
if (!await isCleoGitRepo(cleoDir)) return false;
|
|
40159
40378
|
if (isMergeInProgress(cleoDir)) return false;
|
|
@@ -40226,6 +40445,218 @@ var init_git_checkpoint = __esm({
|
|
|
40226
40445
|
}
|
|
40227
40446
|
});
|
|
40228
40447
|
|
|
40448
|
+
// packages/core/src/store/snapshot-gate.ts
|
|
40449
|
+
import { join as join26 } from "node:path";
|
|
40450
|
+
function readGateState(db) {
|
|
40451
|
+
const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
|
|
40452
|
+
const state = { generation: 0, prefixes: {} };
|
|
40453
|
+
if (!row) return state;
|
|
40454
|
+
try {
|
|
40455
|
+
const parsed = JSON.parse(row.value);
|
|
40456
|
+
if (parsed === null || typeof parsed !== "object") return state;
|
|
40457
|
+
if (typeof parsed.generation === "number" && Number.isSafeInteger(parsed.generation)) {
|
|
40458
|
+
state.generation = parsed.generation;
|
|
40459
|
+
}
|
|
40460
|
+
for (const [prefix, e] of Object.entries(parsed.prefixes ?? {})) {
|
|
40461
|
+
if (e && typeof e.generation === "number" && typeof e.startedAt === "number" && typeof e.completedAt === "number") {
|
|
40462
|
+
state.prefixes[prefix] = {
|
|
40463
|
+
generation: e.generation,
|
|
40464
|
+
startedAt: e.startedAt,
|
|
40465
|
+
completedAt: e.completedAt
|
|
40466
|
+
};
|
|
40467
|
+
}
|
|
40468
|
+
}
|
|
40469
|
+
} catch {
|
|
40470
|
+
}
|
|
40471
|
+
return state;
|
|
40472
|
+
}
|
|
40473
|
+
function writeGateState(db, state) {
|
|
40474
|
+
db.prepare(
|
|
40475
|
+
"INSERT INTO tasks_schema_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
40476
|
+
).run(SNAPSHOT_GATE_META_KEY, JSON.stringify(state));
|
|
40477
|
+
mirrorCounterToBare(db, SNAPSHOT_GATE_META_KEY);
|
|
40478
|
+
}
|
|
40479
|
+
function tryReadGateState(db) {
|
|
40480
|
+
if (!db) return null;
|
|
40481
|
+
try {
|
|
40482
|
+
return readGateState(db);
|
|
40483
|
+
} catch {
|
|
40484
|
+
return null;
|
|
40485
|
+
}
|
|
40486
|
+
}
|
|
40487
|
+
function needsSnapshot(entry, mode, nowMs, seenGeneration) {
|
|
40488
|
+
if (!entry) return true;
|
|
40489
|
+
if (mode === "required") return seenGeneration === null || entry.generation <= seenGeneration;
|
|
40490
|
+
const elapsed = nowMs - entry.startedAt;
|
|
40491
|
+
return elapsed < 0 || elapsed >= SNAPSHOT_DEBOUNCE_MS;
|
|
40492
|
+
}
|
|
40493
|
+
async function runGatedSnapshot(opts, snapshot) {
|
|
40494
|
+
const now = opts.now ?? Date.now;
|
|
40495
|
+
const mode = opts.mode ?? "routine";
|
|
40496
|
+
const db = opts.stateDb;
|
|
40497
|
+
const none = (skipped, error48) => ({
|
|
40498
|
+
snapshotted: [],
|
|
40499
|
+
linked: [],
|
|
40500
|
+
absent: [],
|
|
40501
|
+
failed: [],
|
|
40502
|
+
skipped,
|
|
40503
|
+
...error48 !== void 0 && { error: error48 }
|
|
40504
|
+
});
|
|
40505
|
+
const entryState = tryReadGateState(db);
|
|
40506
|
+
const seenGeneration = mode === "required" ? opts.seenGeneration ?? entryState?.generation ?? null : null;
|
|
40507
|
+
if (mode === "routine") {
|
|
40508
|
+
if (!entryState) return none("state-unavailable");
|
|
40509
|
+
const nowMs = now();
|
|
40510
|
+
if (!opts.prefixes.some((p) => needsSnapshot(entryState.prefixes[p], mode, nowMs, null))) {
|
|
40511
|
+
return none("debounced");
|
|
40512
|
+
}
|
|
40513
|
+
}
|
|
40514
|
+
const lockPath2 = join26(opts.backupDir, GATE_LOCK_BASENAME);
|
|
40515
|
+
let release;
|
|
40516
|
+
try {
|
|
40517
|
+
release = await acquireLock(lockPath2, {
|
|
40518
|
+
retries: mode === "required" ? opts.lockWaitRetries ?? SNAPSHOT_LOCK_WAIT_RETRIES : 0,
|
|
40519
|
+
stale: SNAPSHOT_LOCK_STALE_MS,
|
|
40520
|
+
// A compromised lock (e.g. the backup dir was removed) must not throw
|
|
40521
|
+
// from a timer and crash the host process.
|
|
40522
|
+
onCompromised: () => {
|
|
40523
|
+
}
|
|
40524
|
+
});
|
|
40525
|
+
} catch {
|
|
40526
|
+
if (mode === "routine") return none("in-flight");
|
|
40527
|
+
return none(
|
|
40528
|
+
"lock-timeout",
|
|
40529
|
+
`Snapshot lock ${lockPath2}.lock is still held after waiting. Another snapshot is running, or a crashed process left the lock (it expires after ${SNAPSHOT_LOCK_STALE_MS / 6e4} minutes). Remove it if no snapshot is running.`
|
|
40530
|
+
);
|
|
40531
|
+
}
|
|
40532
|
+
try {
|
|
40533
|
+
try {
|
|
40534
|
+
opts.onLockAcquired?.();
|
|
40535
|
+
} catch {
|
|
40536
|
+
}
|
|
40537
|
+
const state = tryReadGateState(db);
|
|
40538
|
+
if (!state && mode === "routine") return none("state-unavailable");
|
|
40539
|
+
const startMs = now();
|
|
40540
|
+
const admitted = mode === "required" && opts.alwaysSnapshot === true ? [...opts.prefixes] : opts.prefixes.filter(
|
|
40541
|
+
(p) => needsSnapshot(state?.prefixes[p], mode, startMs, seenGeneration)
|
|
40542
|
+
);
|
|
40543
|
+
if (admitted.length === 0) return none(mode === "routine" ? "debounced" : "covered");
|
|
40544
|
+
const generation = (state?.generation ?? 0) + 1;
|
|
40545
|
+
let claimed = false;
|
|
40546
|
+
if (db && state) {
|
|
40547
|
+
try {
|
|
40548
|
+
writeGateState(db, { ...state, generation });
|
|
40549
|
+
claimed = true;
|
|
40550
|
+
} catch {
|
|
40551
|
+
}
|
|
40552
|
+
}
|
|
40553
|
+
const snapshotted = [];
|
|
40554
|
+
const linked = [];
|
|
40555
|
+
const absent = [];
|
|
40556
|
+
const failed = [];
|
|
40557
|
+
for (const prefix of admitted) {
|
|
40558
|
+
try {
|
|
40559
|
+
const outcome = await snapshot(prefix);
|
|
40560
|
+
if (outcome === "absent") absent.push(prefix);
|
|
40561
|
+
else {
|
|
40562
|
+
snapshotted.push(prefix);
|
|
40563
|
+
if (outcome === "linked") linked.push(prefix);
|
|
40564
|
+
}
|
|
40565
|
+
} catch {
|
|
40566
|
+
failed.push(prefix);
|
|
40567
|
+
}
|
|
40568
|
+
}
|
|
40569
|
+
const satisfied = [...snapshotted, ...absent];
|
|
40570
|
+
if (db && claimed && satisfied.length > 0) {
|
|
40571
|
+
try {
|
|
40572
|
+
const latest = readGateState(db);
|
|
40573
|
+
const completedAt = now();
|
|
40574
|
+
latest.generation = Math.max(latest.generation, generation);
|
|
40575
|
+
for (const p of satisfied) {
|
|
40576
|
+
latest.prefixes[p] = { generation, startedAt: startMs, completedAt };
|
|
40577
|
+
}
|
|
40578
|
+
writeGateState(db, latest);
|
|
40579
|
+
} catch {
|
|
40580
|
+
}
|
|
40581
|
+
}
|
|
40582
|
+
return { snapshotted, linked, absent, failed, skipped: null };
|
|
40583
|
+
} finally {
|
|
40584
|
+
await release().catch(() => {
|
|
40585
|
+
});
|
|
40586
|
+
}
|
|
40587
|
+
}
|
|
40588
|
+
function isValidStamp(ymd, hms) {
|
|
40589
|
+
const y = Number(ymd.slice(0, 4));
|
|
40590
|
+
const mo = Number(ymd.slice(4, 6));
|
|
40591
|
+
const d = Number(ymd.slice(6, 8));
|
|
40592
|
+
const h = Number(hms.slice(0, 2));
|
|
40593
|
+
const mi = Number(hms.slice(2, 4));
|
|
40594
|
+
const se = Number(hms.slice(4, 6));
|
|
40595
|
+
if (mo < 1 || mo > 12 || d < 1 || h > 23 || mi > 59 || se > 59) return false;
|
|
40596
|
+
const probe = new Date(Date.UTC(y, mo - 1, d));
|
|
40597
|
+
return probe.getUTCFullYear() === y && probe.getUTCMonth() === mo - 1 && probe.getUTCDate() === d;
|
|
40598
|
+
}
|
|
40599
|
+
function selectSnapshotsToKeep(names, ctx = {}) {
|
|
40600
|
+
const policy = ctx.policy ?? DEFAULT_SNAPSHOT_RETENTION;
|
|
40601
|
+
const keep = /* @__PURE__ */ new Set();
|
|
40602
|
+
const stamped = [];
|
|
40603
|
+
for (const name15 of names) {
|
|
40604
|
+
const m = STAMP_PATTERN.exec(name15);
|
|
40605
|
+
const ymd = m?.[1];
|
|
40606
|
+
const hms = m?.[2];
|
|
40607
|
+
if (!ymd || !hms || !isValidStamp(ymd, hms)) {
|
|
40608
|
+
keep.add(name15);
|
|
40609
|
+
continue;
|
|
40610
|
+
}
|
|
40611
|
+
const stamp = `${ymd}-${hms}`;
|
|
40612
|
+
if (ctx.nowStamp !== void 0 && stamp > ctx.nowStamp) {
|
|
40613
|
+
keep.add(name15);
|
|
40614
|
+
continue;
|
|
40615
|
+
}
|
|
40616
|
+
stamped.push({ name: name15, stamp });
|
|
40617
|
+
}
|
|
40618
|
+
if (ctx.pinned !== void 0 && names.includes(ctx.pinned)) keep.add(ctx.pinned);
|
|
40619
|
+
stamped.sort((a, b) => a.stamp < b.stamp ? 1 : a.stamp > b.stamp ? -1 : 0);
|
|
40620
|
+
for (const s of stamped.slice(0, policy.latest)) keep.add(s.name);
|
|
40621
|
+
const keepNewestPerBucket = (bucketOf, slots) => {
|
|
40622
|
+
const seen = /* @__PURE__ */ new Set();
|
|
40623
|
+
for (const s of stamped) {
|
|
40624
|
+
const bucket = bucketOf(s.stamp);
|
|
40625
|
+
if (seen.has(bucket)) continue;
|
|
40626
|
+
if (seen.size >= slots) break;
|
|
40627
|
+
seen.add(bucket);
|
|
40628
|
+
keep.add(s.name);
|
|
40629
|
+
}
|
|
40630
|
+
};
|
|
40631
|
+
keepNewestPerBucket(
|
|
40632
|
+
(stamp) => `${stamp.slice(0, 11)}q${Math.floor(Number(stamp.slice(11, 13)) / 15)}`,
|
|
40633
|
+
policy.quarterHourly
|
|
40634
|
+
);
|
|
40635
|
+
keepNewestPerBucket((stamp) => stamp.slice(0, 11), policy.hourly);
|
|
40636
|
+
keepNewestPerBucket((stamp) => stamp.slice(0, 8), policy.daily);
|
|
40637
|
+
return keep;
|
|
40638
|
+
}
|
|
40639
|
+
var SNAPSHOT_DEBOUNCE_MS, SNAPSHOT_LOCK_STALE_MS, SNAPSHOT_LOCK_WAIT_RETRIES, SNAPSHOT_GATE_META_KEY, GATE_LOCK_BASENAME, DEFAULT_SNAPSHOT_RETENTION, STAMP_PATTERN;
|
|
40640
|
+
var init_snapshot_gate = __esm({
|
|
40641
|
+
"packages/core/src/store/snapshot-gate.ts"() {
|
|
40642
|
+
"use strict";
|
|
40643
|
+
init_lock();
|
|
40644
|
+
init_twin_collapse();
|
|
40645
|
+
SNAPSHOT_DEBOUNCE_MS = 5 * 6e4;
|
|
40646
|
+
SNAPSHOT_LOCK_STALE_MS = 10 * 6e4;
|
|
40647
|
+
SNAPSHOT_LOCK_WAIT_RETRIES = 90;
|
|
40648
|
+
SNAPSHOT_GATE_META_KEY = "sqlite_snapshot_gate";
|
|
40649
|
+
GATE_LOCK_BASENAME = ".snapshot-gate";
|
|
40650
|
+
DEFAULT_SNAPSHOT_RETENTION = {
|
|
40651
|
+
latest: 1,
|
|
40652
|
+
quarterHourly: 3,
|
|
40653
|
+
hourly: 3,
|
|
40654
|
+
daily: 3
|
|
40655
|
+
};
|
|
40656
|
+
STAMP_PATTERN = /-(\d{8})-(\d{6})\.db$/;
|
|
40657
|
+
}
|
|
40658
|
+
});
|
|
40659
|
+
|
|
40229
40660
|
// packages/core/src/store/data-safety-central.ts
|
|
40230
40661
|
import { eq as eq7 } from "drizzle-orm";
|
|
40231
40662
|
function inSafetyScope(cwd, operation) {
|
|
@@ -40636,7 +41067,7 @@ __export(data_accessor_exports, {
|
|
|
40636
41067
|
getAccessorDb: () => getAccessorDb,
|
|
40637
41068
|
getTaskAccessor: () => getTaskAccessor
|
|
40638
41069
|
});
|
|
40639
|
-
import { resolve as
|
|
41070
|
+
import { resolve as resolve11 } from "node:path";
|
|
40640
41071
|
function assertTestEnv(dbPath) {
|
|
40641
41072
|
const testMode = process.env["CLEO_TEST_MODE"];
|
|
40642
41073
|
if (testMode !== "1") return;
|
|
@@ -40657,7 +41088,7 @@ function assertTestEnv(dbPath) {
|
|
|
40657
41088
|
}
|
|
40658
41089
|
}
|
|
40659
41090
|
async function createDataAccessor(cwd) {
|
|
40660
|
-
const root =
|
|
41091
|
+
const root = resolve11(cwd ?? getProjectRoot());
|
|
40661
41092
|
const inherited = worktreeScope.getStore();
|
|
40662
41093
|
const captured = inherited ? { ...inherited } : void 0;
|
|
40663
41094
|
captured?.execution?.assertActive();
|
|
@@ -40701,7 +41132,7 @@ __export(memory_sqlite_exports, {
|
|
|
40701
41132
|
resetBrainDbState: () => resetBrainDbState,
|
|
40702
41133
|
resolveBrainMigrationsFolder: () => resolveBrainMigrationsFolder
|
|
40703
41134
|
});
|
|
40704
|
-
import { createRequire as
|
|
41135
|
+
import { createRequire as createRequire7 } from "node:module";
|
|
40705
41136
|
function _getDrizzle2() {
|
|
40706
41137
|
if (_drizzle2 === null) {
|
|
40707
41138
|
const mod = _require4("drizzle-orm/node-sqlite");
|
|
@@ -40838,7 +41269,7 @@ var init_memory_sqlite = __esm({
|
|
|
40838
41269
|
init_resolve_migrations_folder();
|
|
40839
41270
|
init_memory_schema();
|
|
40840
41271
|
init_twin_collapse();
|
|
40841
|
-
_require4 =
|
|
41272
|
+
_require4 = createRequire7(import.meta.url);
|
|
40842
41273
|
_drizzle2 = null;
|
|
40843
41274
|
BRAIN_SCHEMA_VERSION = "1.0.0";
|
|
40844
41275
|
CONSOLIDATED_BRAIN_TABLES = [
|
|
@@ -41026,11 +41457,11 @@ var init_skills_schema = __esm({
|
|
|
41026
41457
|
});
|
|
41027
41458
|
|
|
41028
41459
|
// packages/core/src/store/skills-db.ts
|
|
41029
|
-
import { join as
|
|
41460
|
+
import { join as join27 } from "node:path";
|
|
41030
41461
|
import { and as and6, eq as eq8 } from "drizzle-orm";
|
|
41031
41462
|
function getDefaultSkillsDbPath() {
|
|
41032
41463
|
const cleoHome = getCleoHome();
|
|
41033
|
-
const dbPath =
|
|
41464
|
+
const dbPath = join27(cleoHome, "cleo.db");
|
|
41034
41465
|
if (!dbPath.startsWith(cleoHome)) {
|
|
41035
41466
|
throw new Error(
|
|
41036
41467
|
`BUG: getDefaultSkillsDbPath() resolved to "${dbPath}" which is NOT under getCleoHome() ("${cleoHome}"). The skills registry is global-only per SG-CLEO-SKILLS-architecture-v3.md \xA74. Fix the caller, do not suppress.`
|
|
@@ -41078,19 +41509,19 @@ import {
|
|
|
41078
41509
|
chmodSync,
|
|
41079
41510
|
closeSync,
|
|
41080
41511
|
copyFileSync as copyFileSync3,
|
|
41081
|
-
existsSync as
|
|
41512
|
+
existsSync as existsSync21,
|
|
41082
41513
|
fsyncSync,
|
|
41083
41514
|
linkSync,
|
|
41084
41515
|
mkdirSync as mkdirSync5,
|
|
41085
41516
|
openSync,
|
|
41086
41517
|
readdirSync as readdirSync5,
|
|
41087
|
-
realpathSync as
|
|
41518
|
+
realpathSync as realpathSync7,
|
|
41088
41519
|
renameSync as renameSync6,
|
|
41089
41520
|
rmSync,
|
|
41090
41521
|
statSync as statSync6,
|
|
41091
41522
|
unlinkSync as unlinkSync3
|
|
41092
41523
|
} from "node:fs";
|
|
41093
|
-
import { dirname as
|
|
41524
|
+
import { dirname as dirname16, join as join28, sep as sep4 } from "node:path";
|
|
41094
41525
|
function resolveInventoryPath(entry, cwd) {
|
|
41095
41526
|
try {
|
|
41096
41527
|
if (entry.tier === "global") {
|
|
@@ -41126,8 +41557,8 @@ async function openAgentRegistryDbForSnapshot() {
|
|
|
41126
41557
|
}
|
|
41127
41558
|
async function openTelemetryDbForSnapshot() {
|
|
41128
41559
|
try {
|
|
41129
|
-
const path =
|
|
41130
|
-
if (!
|
|
41560
|
+
const path = join28(getCleoHome(), "telemetry.db");
|
|
41561
|
+
if (!existsSync21(path)) return null;
|
|
41131
41562
|
} catch {
|
|
41132
41563
|
return null;
|
|
41133
41564
|
}
|
|
@@ -41239,7 +41670,7 @@ function rotateSnapshots(backupDir, prefix, justWritten) {
|
|
|
41239
41670
|
for (const name15 of names) {
|
|
41240
41671
|
if (keep.has(name15)) continue;
|
|
41241
41672
|
try {
|
|
41242
|
-
unlinkSync3(
|
|
41673
|
+
unlinkSync3(join28(backupDir, name15));
|
|
41243
41674
|
} catch {
|
|
41244
41675
|
}
|
|
41245
41676
|
}
|
|
@@ -41261,7 +41692,7 @@ async function snapshotProjectTargetsGated(targets, opts) {
|
|
|
41261
41692
|
let backupDir;
|
|
41262
41693
|
try {
|
|
41263
41694
|
const cleoDir = getCleoDir(cwd);
|
|
41264
|
-
backupDir =
|
|
41695
|
+
backupDir = join28(cleoDir, "backups", "sqlite");
|
|
41265
41696
|
mkdirSync5(backupDir, { recursive: true });
|
|
41266
41697
|
} catch {
|
|
41267
41698
|
return null;
|
|
@@ -41293,7 +41724,7 @@ function sourceFileOf(db) {
|
|
|
41293
41724
|
const location = db.location();
|
|
41294
41725
|
if (!location) return null;
|
|
41295
41726
|
try {
|
|
41296
|
-
return
|
|
41727
|
+
return realpathSync7(location);
|
|
41297
41728
|
} catch {
|
|
41298
41729
|
return location;
|
|
41299
41730
|
}
|
|
@@ -41304,10 +41735,10 @@ function hasLocation(db) {
|
|
|
41304
41735
|
function assertOwnedByProject(source, prefix, cwd) {
|
|
41305
41736
|
let cleoDir = getCleoDir(cwd);
|
|
41306
41737
|
try {
|
|
41307
|
-
cleoDir =
|
|
41738
|
+
cleoDir = realpathSync7(cleoDir);
|
|
41308
41739
|
} catch {
|
|
41309
41740
|
}
|
|
41310
|
-
if (!source.startsWith(cleoDir +
|
|
41741
|
+
if (!source.startsWith(cleoDir + sep4)) {
|
|
41311
41742
|
throw new Error(
|
|
41312
41743
|
`refusing to snapshot ${prefix}: its database ${source} is not inside ${cleoDir}`
|
|
41313
41744
|
);
|
|
@@ -41336,7 +41767,7 @@ function commitSnapshotFile(tmp, dest) {
|
|
|
41336
41767
|
}
|
|
41337
41768
|
renameSync6(tmp, dest);
|
|
41338
41769
|
try {
|
|
41339
|
-
const dirFd = openSync(
|
|
41770
|
+
const dirFd = openSync(dirname16(dest), "r");
|
|
41340
41771
|
try {
|
|
41341
41772
|
fsyncSync(dirFd);
|
|
41342
41773
|
} finally {
|
|
@@ -41359,7 +41790,7 @@ function removeDeadTempSnapshots(backupDir) {
|
|
|
41359
41790
|
const m = TEMP_SNAPSHOT_RE.exec(name15);
|
|
41360
41791
|
if (!m) continue;
|
|
41361
41792
|
const pid = Number(m[1]);
|
|
41362
|
-
const path =
|
|
41793
|
+
const path = join28(backupDir, name15);
|
|
41363
41794
|
const stale = pid !== process.pid && (!isPidAlive2(pid) || Date.now() - statSync6(path).mtimeMs > TEMP_SNAPSHOT_MAX_AGE_MS);
|
|
41364
41795
|
if (stale) rmSync(path, { force: true });
|
|
41365
41796
|
}
|
|
@@ -41369,7 +41800,7 @@ function removeDeadTempSnapshots(backupDir) {
|
|
|
41369
41800
|
async function freeSnapshotName(backupDir, prefix) {
|
|
41370
41801
|
for (let attempt = 0; attempt < SNAPSHOT_NAME_ATTEMPTS; attempt++) {
|
|
41371
41802
|
const name15 = `${prefix}-${formatTimestamp(/* @__PURE__ */ new Date())}.db`;
|
|
41372
|
-
if (!
|
|
41803
|
+
if (!existsSync21(join28(backupDir, name15))) return name15;
|
|
41373
41804
|
await new Promise((r) => setTimeout(r, 1e3 - Date.now() % 1e3 + 5));
|
|
41374
41805
|
}
|
|
41375
41806
|
throw new Error(`no free snapshot filename for ${prefix} in ${backupDir}`);
|
|
@@ -41397,7 +41828,7 @@ async function snapshotOne(target, backupDir, writtenBySource, cwd) {
|
|
|
41397
41828
|
if (opened && target.closeDb) target.closeDb(opened);
|
|
41398
41829
|
throw err;
|
|
41399
41830
|
}
|
|
41400
|
-
const dest =
|
|
41831
|
+
const dest = join28(backupDir, destName);
|
|
41401
41832
|
removeDeadTempSnapshots(backupDir);
|
|
41402
41833
|
const existing = source !== null ? writtenBySource.get(source) : void 0;
|
|
41403
41834
|
if (existing !== void 0) {
|
|
@@ -41451,13 +41882,13 @@ async function vacuumIntoBackup(opts = {}) {
|
|
|
41451
41882
|
function listSqliteBackupsForPrefix(prefix, cwd) {
|
|
41452
41883
|
try {
|
|
41453
41884
|
const cleoDir = getCleoDir(cwd);
|
|
41454
|
-
const backupDir =
|
|
41455
|
-
if (!
|
|
41885
|
+
const backupDir = join28(cleoDir, "backups", "sqlite");
|
|
41886
|
+
if (!existsSync21(backupDir)) return [];
|
|
41456
41887
|
const pattern = snapshotPattern(prefix);
|
|
41457
41888
|
return readdirSync5(backupDir).filter((f) => pattern.test(f)).map((f) => ({
|
|
41458
41889
|
name: f,
|
|
41459
|
-
path:
|
|
41460
|
-
mtimeMs: statSync6(
|
|
41890
|
+
path: join28(backupDir, f),
|
|
41891
|
+
mtimeMs: statSync6(join28(backupDir, f)).mtimeMs
|
|
41461
41892
|
})).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
41462
41893
|
} catch {
|
|
41463
41894
|
return [];
|
|
@@ -41527,15 +41958,16 @@ __export(sqlite_exports, {
|
|
|
41527
41958
|
resetDbState: () => resetDbState,
|
|
41528
41959
|
resolveMigrationsFolder: () => resolveMigrationsFolder,
|
|
41529
41960
|
schema: () => tasks_schema_exports,
|
|
41530
|
-
seedTasksMeta: () => seedTasksMeta
|
|
41961
|
+
seedTasksMeta: () => seedTasksMeta,
|
|
41962
|
+
worktreeRecoveryRefusal: () => worktreeRecoveryRefusal
|
|
41531
41963
|
});
|
|
41532
|
-
import { copyFileSync as copyFileSync4, existsSync as
|
|
41533
|
-
import { createRequire as
|
|
41534
|
-
import { basename as basename8, dirname as
|
|
41964
|
+
import { copyFileSync as copyFileSync4, existsSync as existsSync22, realpathSync as realpathSync8, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
41965
|
+
import { createRequire as createRequire8 } from "node:module";
|
|
41966
|
+
import { basename as basename8, dirname as dirname17, resolve as resolve12 } from "node:path";
|
|
41535
41967
|
import { eq as eq9 } from "drizzle-orm";
|
|
41536
41968
|
function _getDrizzle3() {
|
|
41537
41969
|
if (_drizzle3 === null) {
|
|
41538
|
-
const _require7 =
|
|
41970
|
+
const _require7 = createRequire8(import.meta.url);
|
|
41539
41971
|
const mod = _require7("drizzle-orm/node-sqlite");
|
|
41540
41972
|
_drizzle3 = mod.drizzle;
|
|
41541
41973
|
}
|
|
@@ -41571,13 +42003,19 @@ function countBackupTasks(backupDb) {
|
|
|
41571
42003
|
return 0;
|
|
41572
42004
|
}
|
|
41573
42005
|
function isSameDirectory(a, b) {
|
|
41574
|
-
if (
|
|
42006
|
+
if (resolve12(a) === resolve12(b)) return true;
|
|
41575
42007
|
try {
|
|
41576
|
-
return
|
|
42008
|
+
return realpathSync8(a) === realpathSync8(b);
|
|
41577
42009
|
} catch {
|
|
41578
42010
|
return false;
|
|
41579
42011
|
}
|
|
41580
42012
|
}
|
|
42013
|
+
function worktreeRecoveryRefusal(dbPath) {
|
|
42014
|
+
const storeCleoDir = dirname17(dbPath);
|
|
42015
|
+
const root = dirname17(storeCleoDir);
|
|
42016
|
+
if (basename8(storeCleoDir) !== ".cleo" || !isGitLinkedCheckout(root)) return null;
|
|
42017
|
+
return `Auto-recovery refused: ${dbPath} lives inside the git worktree ${root}; ${describeWorktreeOwner(root)}. A worktree uses its owning project's store and never receives a restored copy (T12460, T12677).`;
|
|
42018
|
+
}
|
|
41581
42019
|
async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
41582
42020
|
const { openNativeDatabase: openNativeDatabase2 } = await Promise.resolve().then(() => (init_sqlite_native(), sqlite_native_exports));
|
|
41583
42021
|
const log15 = getLogger("sqlite");
|
|
@@ -41586,12 +42024,10 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
41586
42024
|
const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks_tasks").get();
|
|
41587
42025
|
const taskCount = countResult?.cnt ?? 0;
|
|
41588
42026
|
if (taskCount > 0) return false;
|
|
41589
|
-
const storeCleoDir =
|
|
41590
|
-
|
|
41591
|
-
|
|
41592
|
-
|
|
41593
|
-
"Auto-recovery refused: the empty store lives inside a git worktree (T12460). Worktrees must resolve the parent project store."
|
|
41594
|
-
);
|
|
42027
|
+
const storeCleoDir = dirname17(dbPath);
|
|
42028
|
+
const worktreeRefusal = worktreeRecoveryRefusal(dbPath);
|
|
42029
|
+
if (worktreeRefusal !== null) {
|
|
42030
|
+
log15.warn({ dbPath }, worktreeRefusal);
|
|
41595
42031
|
return false;
|
|
41596
42032
|
}
|
|
41597
42033
|
const backups = listSqliteBackups(cwd);
|
|
@@ -41599,7 +42035,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
41599
42035
|
return false;
|
|
41600
42036
|
}
|
|
41601
42037
|
const newestBackup = backups[0];
|
|
41602
|
-
const backupCleoDir =
|
|
42038
|
+
const backupCleoDir = dirname17(dirname17(dirname17(newestBackup.path)));
|
|
41603
42039
|
if (!isSameDirectory(backupCleoDir, storeCleoDir)) {
|
|
41604
42040
|
log15.warn(
|
|
41605
42041
|
{ dbPath, backupPath: newestBackup.path },
|
|
@@ -41721,6 +42157,7 @@ function runMigrations(nativeDb, db, dbPath) {
|
|
|
41721
42157
|
try {
|
|
41722
42158
|
migrateWithRetry(db, migrationsFolder, nativeDb, "tasks", "sqlite");
|
|
41723
42159
|
} catch (error48) {
|
|
42160
|
+
if (isWorktreeBuildSchemaError(error48)) throw error48;
|
|
41724
42161
|
if (isSqliteBusy(error48) || !tableExists(nativeDb, "tasks_tasks")) throw error48;
|
|
41725
42162
|
try {
|
|
41726
42163
|
rebuildLegacyTasksLineage(
|
|
@@ -41762,7 +42199,7 @@ async function getSchemaVersion(cwd) {
|
|
|
41762
42199
|
return result[0]?.value ?? null;
|
|
41763
42200
|
}
|
|
41764
42201
|
function dbExists(cwd) {
|
|
41765
|
-
return
|
|
42202
|
+
return existsSync22(resolveDualScopeDbPath("project", cwd));
|
|
41766
42203
|
}
|
|
41767
42204
|
function getNativeDb(cwd) {
|
|
41768
42205
|
return boundProjectNative("tasks", cwd);
|
|
@@ -41798,6 +42235,7 @@ var init_sqlite3 = __esm({
|
|
|
41798
42235
|
init_resolve_migrations_folder();
|
|
41799
42236
|
init_sqlite_backup();
|
|
41800
42237
|
init_twin_collapse();
|
|
42238
|
+
init_worktree_build_guard();
|
|
41801
42239
|
init_worktree_isolation_guard();
|
|
41802
42240
|
init_sqlite_native();
|
|
41803
42241
|
init_tasks_schema();
|
|
@@ -41826,15 +42264,15 @@ var init_sqlite3 = __esm({
|
|
|
41826
42264
|
// packages/core/src/store/exodus/migrate.ts
|
|
41827
42265
|
import {
|
|
41828
42266
|
copyFileSync as copyFileSync5,
|
|
41829
|
-
existsSync as
|
|
42267
|
+
existsSync as existsSync23,
|
|
41830
42268
|
mkdirSync as mkdirSync6,
|
|
41831
|
-
readFileSync as
|
|
42269
|
+
readFileSync as readFileSync8,
|
|
41832
42270
|
renameSync as renameSync8,
|
|
41833
42271
|
statSync as statSync7,
|
|
41834
42272
|
unlinkSync as unlinkSync5,
|
|
41835
42273
|
writeFileSync as writeFileSync6
|
|
41836
42274
|
} from "node:fs";
|
|
41837
|
-
import { join as
|
|
42275
|
+
import { join as join29 } from "node:path";
|
|
41838
42276
|
function getSqliteVersion(db) {
|
|
41839
42277
|
try {
|
|
41840
42278
|
const row = db.prepare("SELECT sqlite_version() AS v").get();
|
|
@@ -41865,24 +42303,24 @@ function restoreGrandfatheredGuards(db, suspended) {
|
|
|
41865
42303
|
}
|
|
41866
42304
|
}
|
|
41867
42305
|
function writeJournal(stagingDir, journal) {
|
|
41868
|
-
const journalPath =
|
|
42306
|
+
const journalPath = join29(stagingDir, JOURNAL_FILENAME);
|
|
41869
42307
|
const tmpPath = `${journalPath}.tmp`;
|
|
41870
42308
|
writeFileSync6(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
|
|
41871
42309
|
renameSync8(tmpPath, journalPath);
|
|
41872
42310
|
}
|
|
41873
42311
|
function readJournal(stagingDir) {
|
|
41874
|
-
const journalPath =
|
|
41875
|
-
if (!
|
|
42312
|
+
const journalPath = join29(stagingDir, JOURNAL_FILENAME);
|
|
42313
|
+
if (!existsSync23(journalPath)) return null;
|
|
41876
42314
|
try {
|
|
41877
|
-
return JSON.parse(
|
|
42315
|
+
return JSON.parse(readFileSync8(journalPath, "utf8"));
|
|
41878
42316
|
} catch {
|
|
41879
42317
|
return null;
|
|
41880
42318
|
}
|
|
41881
42319
|
}
|
|
41882
42320
|
function clearExodusJournal(stagingDir) {
|
|
41883
|
-
const journalPath =
|
|
42321
|
+
const journalPath = join29(stagingDir, JOURNAL_FILENAME);
|
|
41884
42322
|
try {
|
|
41885
|
-
if (!
|
|
42323
|
+
if (!existsSync23(journalPath)) return false;
|
|
41886
42324
|
unlinkSync5(journalPath);
|
|
41887
42325
|
log10.info(
|
|
41888
42326
|
{ stagingDir },
|
|
@@ -42178,7 +42616,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42178
42616
|
mkdirSync6(stagingDir, { recursive: true });
|
|
42179
42617
|
let sqliteVersion = "unknown";
|
|
42180
42618
|
for (const src of sources) {
|
|
42181
|
-
if (
|
|
42619
|
+
if (existsSync23(src.path)) {
|
|
42182
42620
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
42183
42621
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
42184
42622
|
snap.close();
|
|
@@ -42208,15 +42646,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42208
42646
|
let reseedProject = null;
|
|
42209
42647
|
try {
|
|
42210
42648
|
for (const src of sources) {
|
|
42211
|
-
if (!
|
|
42212
|
-
const backupDest =
|
|
42649
|
+
if (!existsSync23(src.path)) continue;
|
|
42650
|
+
const backupDest = join29(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
42213
42651
|
const srcBytes = safeStatBytes(src.path);
|
|
42214
42652
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
42215
42653
|
if (skipStagingCopy) {
|
|
42216
42654
|
onProgress?.(
|
|
42217
42655
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
42218
42656
|
);
|
|
42219
|
-
} else if (!
|
|
42657
|
+
} else if (!existsSync23(backupDest)) {
|
|
42220
42658
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
42221
42659
|
copyFileSync5(src.path, backupDest);
|
|
42222
42660
|
backupPaths.push(backupDest);
|
|
@@ -42249,8 +42687,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42249
42687
|
}
|
|
42250
42688
|
prepareExodusRecovery(projectNative, stagingDir);
|
|
42251
42689
|
if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
|
|
42252
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
42253
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
42690
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync23(s.path));
|
|
42691
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync23(s.path));
|
|
42254
42692
|
if (globalNative === null && globalSources.length > 0)
|
|
42255
42693
|
throw new Error("A projectOnly exodus run was given global-scope sources");
|
|
42256
42694
|
await migrateScope(
|
|
@@ -42558,9 +42996,9 @@ __export(reconcile_exports, {
|
|
|
42558
42996
|
reconcileSupersededStores: () => reconcileSupersededStores,
|
|
42559
42997
|
unmigratedBareSources: () => unmigratedBareSources
|
|
42560
42998
|
});
|
|
42561
|
-
import { copyFileSync as copyFileSync6, existsSync as
|
|
42999
|
+
import { copyFileSync as copyFileSync6, existsSync as existsSync24, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
42562
43000
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
42563
|
-
import { basename as basename9, join as
|
|
43001
|
+
import { basename as basename9, join as join30 } from "node:path";
|
|
42564
43002
|
function ident2(name15) {
|
|
42565
43003
|
return `"${name15.replace(/"/g, '""')}"`;
|
|
42566
43004
|
}
|
|
@@ -42629,7 +43067,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
|
|
|
42629
43067
|
}
|
|
42630
43068
|
function legacySourcesHoldRows(sources) {
|
|
42631
43069
|
for (const src of sources) {
|
|
42632
|
-
if (!
|
|
43070
|
+
if (!existsSync24(src.path)) continue;
|
|
42633
43071
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
42634
43072
|
try {
|
|
42635
43073
|
for (const table of orderTablesForCopy(snap.db)) {
|
|
@@ -42660,8 +43098,8 @@ async function bareTaskCoreSource(liveStorePath, resolveTarget, outDir) {
|
|
|
42660
43098
|
live.close();
|
|
42661
43099
|
}
|
|
42662
43100
|
if (tables.length === 0) return null;
|
|
42663
|
-
const seedPath = await buildFreshProjectStore(
|
|
42664
|
-
const path =
|
|
43101
|
+
const seedPath = await buildFreshProjectStore(join30(outDir, "fresh-project-seed.db"));
|
|
43102
|
+
const path = join30(outDir, "cleo-bare-task-core.db");
|
|
42665
43103
|
const snap = openCleoDbSnapshot(path, { readOnly: false });
|
|
42666
43104
|
let kept = 0;
|
|
42667
43105
|
try {
|
|
@@ -42709,7 +43147,7 @@ async function buildFreshProjectStore(path) {
|
|
|
42709
43147
|
}
|
|
42710
43148
|
function snapshotFresherBareRows(barePath, legacyTasksPath, stagingDir) {
|
|
42711
43149
|
if (legacyTasksPath === void 0) return null;
|
|
42712
|
-
const path =
|
|
43150
|
+
const path = join30(stagingDir, "cleo-bare-task-core-fresher.db");
|
|
42713
43151
|
const snap = openCleoDbSnapshot(barePath, { readOnly: true });
|
|
42714
43152
|
try {
|
|
42715
43153
|
snap.db.exec(`VACUUM INTO '${path.replace(/'/g, "''")}'`);
|
|
@@ -42860,7 +43298,7 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
42860
43298
|
const additive = options.additive === true;
|
|
42861
43299
|
const plan = buildExodusPlan(projectRoot);
|
|
42862
43300
|
const resolveTarget = await buildRuntimeTargetResolver();
|
|
42863
|
-
const scratch = mkdtempSync(
|
|
43301
|
+
const scratch = mkdtempSync(join30(tmpdir3(), "cleo-reconcile-"));
|
|
42864
43302
|
try {
|
|
42865
43303
|
return await reconcileWithScratch(
|
|
42866
43304
|
projectRoot,
|
|
@@ -42876,8 +43314,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
42876
43314
|
}
|
|
42877
43315
|
}
|
|
42878
43316
|
async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
|
|
42879
|
-
const fileSources = plan.sources.filter((s) => s.targetScope === "project" &&
|
|
42880
|
-
const bare = !additive &&
|
|
43317
|
+
const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync24(s.path));
|
|
43318
|
+
const bare = !additive && existsSync24(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
|
|
42881
43319
|
const copyResolver = additive ? (sourceName, legacyTable) => {
|
|
42882
43320
|
const r = resolveTarget(sourceName, legacyTable);
|
|
42883
43321
|
return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
|
|
@@ -42896,7 +43334,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42896
43334
|
stagingDir: null,
|
|
42897
43335
|
receiptPath: null
|
|
42898
43336
|
};
|
|
42899
|
-
if (sources.length === 0 || !
|
|
43337
|
+
if (sources.length === 0 || !existsSync24(liveStorePath)) {
|
|
42900
43338
|
return {
|
|
42901
43339
|
...base,
|
|
42902
43340
|
outcome: "nothing-to-reconcile",
|
|
@@ -42936,11 +43374,11 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42936
43374
|
};
|
|
42937
43375
|
}
|
|
42938
43376
|
const iso = (/* @__PURE__ */ new Date()).toISOString().replace(/[:]/g, "").replace(/\..+Z$/, "Z");
|
|
42939
|
-
const stagingDir =
|
|
43377
|
+
const stagingDir = join30(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
|
|
42940
43378
|
mkdirSync7(stagingDir, { recursive: true });
|
|
42941
43379
|
const copySources = sources.map((s) => {
|
|
42942
43380
|
if (s !== bare) return s;
|
|
42943
|
-
const kept =
|
|
43381
|
+
const kept = join30(stagingDir, basename9(s.path));
|
|
42944
43382
|
copyFileSync6(s.path, kept);
|
|
42945
43383
|
return { ...s, path: kept };
|
|
42946
43384
|
});
|
|
@@ -42960,7 +43398,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42960
43398
|
const result = await withLock(
|
|
42961
43399
|
`${liveStorePath}.exodus-on-open.lock`,
|
|
42962
43400
|
async () => {
|
|
42963
|
-
const liveBefore =
|
|
43401
|
+
const liveBefore = join30(scratch, "live-before.db");
|
|
42964
43402
|
snapshotLive(liveStorePath, liveBefore);
|
|
42965
43403
|
const migrated = await runExodusMigrate(reconcilePlan, false, (msg) => log11.debug(msg), {
|
|
42966
43404
|
projectOnly: true,
|
|
@@ -43010,7 +43448,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
43010
43448
|
},
|
|
43011
43449
|
{ stale: 6e5, retries: 30 }
|
|
43012
43450
|
);
|
|
43013
|
-
const receiptPath =
|
|
43451
|
+
const receiptPath = join30(stagingDir, RECEIPT_FILENAME);
|
|
43014
43452
|
const receipt2 = { ...result, receiptPath };
|
|
43015
43453
|
writeFileSync7(receiptPath, `${JSON.stringify(receipt2, null, 2)}
|
|
43016
43454
|
`, "utf8");
|
|
@@ -43087,20 +43525,20 @@ var init_seal = __esm({
|
|
|
43087
43525
|
});
|
|
43088
43526
|
|
|
43089
43527
|
// packages/core/src/store/exodus/status.ts
|
|
43090
|
-
import { existsSync as
|
|
43091
|
-
import { join as
|
|
43528
|
+
import { existsSync as existsSync25, readdirSync as readdirSync6, readFileSync as readFileSync9, statSync as statSync8 } from "node:fs";
|
|
43529
|
+
import { join as join31 } from "node:path";
|
|
43092
43530
|
function readJournal2(stagingDir) {
|
|
43093
|
-
const p =
|
|
43094
|
-
if (!
|
|
43531
|
+
const p = join31(stagingDir, JOURNAL_FILENAME2);
|
|
43532
|
+
if (!existsSync25(p)) return null;
|
|
43095
43533
|
try {
|
|
43096
|
-
return JSON.parse(
|
|
43534
|
+
return JSON.parse(readFileSync9(p, "utf8"));
|
|
43097
43535
|
} catch {
|
|
43098
43536
|
return null;
|
|
43099
43537
|
}
|
|
43100
43538
|
}
|
|
43101
43539
|
function findStagingDirs(cleoDir) {
|
|
43102
43540
|
try {
|
|
43103
|
-
return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) =>
|
|
43541
|
+
return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join31(cleoDir, e.name)).sort().reverse();
|
|
43104
43542
|
} catch {
|
|
43105
43543
|
return [];
|
|
43106
43544
|
}
|
|
@@ -43123,15 +43561,15 @@ function runExodusStatus(cwd) {
|
|
|
43123
43561
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
43124
43562
|
name: s.name,
|
|
43125
43563
|
path: s.path,
|
|
43126
|
-
exists:
|
|
43564
|
+
exists: existsSync25(s.path),
|
|
43127
43565
|
bytes: safeBytes(s.path)
|
|
43128
43566
|
}));
|
|
43129
43567
|
return {
|
|
43130
43568
|
hasStaging: latestStaging !== null,
|
|
43131
43569
|
stagingDir: latestStaging,
|
|
43132
43570
|
journal,
|
|
43133
|
-
projectDbExists:
|
|
43134
|
-
globalDbExists:
|
|
43571
|
+
projectDbExists: existsSync25(projectDbPath),
|
|
43572
|
+
globalDbExists: existsSync25(globalDbPath),
|
|
43135
43573
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
43136
43574
|
sources: sourcesInfo
|
|
43137
43575
|
};
|
|
@@ -43148,8 +43586,8 @@ var init_status = __esm({
|
|
|
43148
43586
|
});
|
|
43149
43587
|
|
|
43150
43588
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
43151
|
-
import { existsSync as
|
|
43152
|
-
import { createRequire as
|
|
43589
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
43590
|
+
import { createRequire as createRequire9 } from "node:module";
|
|
43153
43591
|
function orderByClause(db, tableName) {
|
|
43154
43592
|
try {
|
|
43155
43593
|
const pragma = db.prepare(`PRAGMA table_info("${tableName}")`).all();
|
|
@@ -43413,7 +43851,7 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
|
|
|
43413
43851
|
const anyFeeder = (targetTable, probe) => {
|
|
43414
43852
|
for (const feeder of feedersOf(targetTable)) {
|
|
43415
43853
|
const src = sources.find((s) => s.name === feeder.sourceName);
|
|
43416
|
-
if (src === void 0 || !
|
|
43854
|
+
if (src === void 0 || !existsSync26(src.path)) continue;
|
|
43417
43855
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
43418
43856
|
try {
|
|
43419
43857
|
if (!tableExists3(snap.db, feeder.legacyTable)) continue;
|
|
@@ -43468,7 +43906,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43468
43906
|
const preExistingForeignKeyViolations = [];
|
|
43469
43907
|
const failureLines = [];
|
|
43470
43908
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
43471
|
-
if (!
|
|
43909
|
+
if (!existsSync26(projectDbPath)) {
|
|
43472
43910
|
return {
|
|
43473
43911
|
ok: false,
|
|
43474
43912
|
tables: [],
|
|
@@ -43479,7 +43917,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43479
43917
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
43480
43918
|
};
|
|
43481
43919
|
}
|
|
43482
|
-
if (!
|
|
43920
|
+
if (!existsSync26(globalDbPath)) {
|
|
43483
43921
|
return {
|
|
43484
43922
|
ok: false,
|
|
43485
43923
|
tables: [],
|
|
@@ -43494,7 +43932,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43494
43932
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
43495
43933
|
try {
|
|
43496
43934
|
for (const src of sources) {
|
|
43497
|
-
if (!
|
|
43935
|
+
if (!existsSync26(src.path)) {
|
|
43498
43936
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
43499
43937
|
continue;
|
|
43500
43938
|
}
|
|
@@ -43689,7 +44127,7 @@ var init_verify_migration = __esm({
|
|
|
43689
44127
|
init_column_transforms();
|
|
43690
44128
|
init_table_name_map();
|
|
43691
44129
|
log13 = getLogger("verify-migration");
|
|
43692
|
-
_require5 =
|
|
44130
|
+
_require5 = createRequire9(import.meta.url);
|
|
43693
44131
|
CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
|
|
43694
44132
|
}
|
|
43695
44133
|
});
|
|
@@ -43785,11 +44223,11 @@ __export(on_open_exports, {
|
|
|
43785
44223
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
|
|
43786
44224
|
withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
|
|
43787
44225
|
});
|
|
43788
|
-
import { existsSync as
|
|
44226
|
+
import { existsSync as existsSync27, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
43789
44227
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
43790
|
-
import { join as
|
|
44228
|
+
import { join as join32, resolve as resolve13 } from "node:path";
|
|
43791
44229
|
async function withExodusOnOpenSuppressed(dbPath, fn) {
|
|
43792
|
-
const key =
|
|
44230
|
+
const key = resolve13(dbPath);
|
|
43793
44231
|
_reconcileInProgress.set(key, (_reconcileInProgress.get(key) ?? 0) + 1);
|
|
43794
44232
|
try {
|
|
43795
44233
|
return await fn();
|
|
@@ -43827,7 +44265,7 @@ function remedyFor(scope) {
|
|
|
43827
44265
|
}
|
|
43828
44266
|
async function strandedLegacySources(scope, cwd) {
|
|
43829
44267
|
const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
43830
|
-
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope &&
|
|
44268
|
+
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync27(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
|
|
43831
44269
|
}
|
|
43832
44270
|
async function rollbackBothScopes(plan) {
|
|
43833
44271
|
const { getDualScopeNativeDb: getDualScopeNativeDb2, openDualScopeDbAtPath: openDualScopeDbAtPath2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
|
|
@@ -43905,7 +44343,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43905
44343
|
if (_exodusInProgress) {
|
|
43906
44344
|
return { outcome: "skipped", reason: "re-entrant open during active migration" };
|
|
43907
44345
|
}
|
|
43908
|
-
if (_reconcileInProgress.has(
|
|
44346
|
+
if (_reconcileInProgress.has(resolve13(dbPath))) {
|
|
43909
44347
|
return {
|
|
43910
44348
|
outcome: "skipped",
|
|
43911
44349
|
reason: "an explicit superseded-store reconcile of this store is in progress"
|
|
@@ -43938,14 +44376,14 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43938
44376
|
const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
43939
44377
|
const plan = buildExodusPlan2(cwd);
|
|
43940
44378
|
const plannedTarget = scope === "project" ? plan.projectDbPath : plan.globalDbPath;
|
|
43941
|
-
if (
|
|
44379
|
+
if (resolve13(plannedTarget) !== resolve13(dbPath)) {
|
|
43942
44380
|
return {
|
|
43943
44381
|
outcome: "aborted",
|
|
43944
44382
|
reason: `migration plan target ${plannedTarget} does not match opened database ${dbPath}; no migration applied`
|
|
43945
44383
|
};
|
|
43946
44384
|
}
|
|
43947
44385
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
43948
|
-
if (!scopeSources.some((s) =>
|
|
44386
|
+
if (!scopeSources.some((s) => existsSync27(s.path))) {
|
|
43949
44387
|
return {
|
|
43950
44388
|
outcome: "skipped",
|
|
43951
44389
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -43962,12 +44400,12 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43962
44400
|
{
|
|
43963
44401
|
scope,
|
|
43964
44402
|
dbPath,
|
|
43965
|
-
sources: plan.sources.filter((s) =>
|
|
44403
|
+
sources: plan.sources.filter((s) => existsSync27(s.path)).map((s) => s.name)
|
|
43966
44404
|
},
|
|
43967
44405
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
43968
44406
|
);
|
|
43969
44407
|
_exodusInProgress = true;
|
|
43970
|
-
const bareScratch = mkdtempSync2(
|
|
44408
|
+
const bareScratch = mkdtempSync2(join32(tmpdir4(), "cleo-exodus-bare-"));
|
|
43971
44409
|
try {
|
|
43972
44410
|
const { buildRuntimeTargetResolver: buildRuntimeTargetResolver2 } = await Promise.resolve().then(() => (init_runtime_targets(), runtime_targets_exports));
|
|
43973
44411
|
const resolveTarget = await buildRuntimeTargetResolver2();
|
|
@@ -43975,7 +44413,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43975
44413
|
const bare = scope === "project" ? await unmigratedBareSources2(
|
|
43976
44414
|
dbPath,
|
|
43977
44415
|
resolveTarget,
|
|
43978
|
-
plan.sources.find((s) => s.name === "tasks" &&
|
|
44416
|
+
plan.sources.find((s) => s.name === "tasks" && existsSync27(s.path))?.path,
|
|
43979
44417
|
bareScratch
|
|
43980
44418
|
) : { first: [], last: [] };
|
|
43981
44419
|
const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
|
|
@@ -44039,7 +44477,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
44039
44477
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
44040
44478
|
);
|
|
44041
44479
|
try {
|
|
44042
|
-
const consumed = plan.sources.filter((s) =>
|
|
44480
|
+
const consumed = plan.sources.filter((s) => existsSync27(s.path));
|
|
44043
44481
|
const identities = await sealTargets(plan, consumed);
|
|
44044
44482
|
const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
|
|
44045
44483
|
log14.info(
|
|
@@ -44114,9 +44552,9 @@ __export(dual_scope_db_exports, {
|
|
|
44114
44552
|
upsertIdempotent: () => upsertIdempotent,
|
|
44115
44553
|
withStoreSchemaOwnership: () => withStoreSchemaOwnership
|
|
44116
44554
|
});
|
|
44117
|
-
import { existsSync as
|
|
44118
|
-
import { createRequire as
|
|
44119
|
-
import { dirname as
|
|
44555
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync8 } from "node:fs";
|
|
44556
|
+
import { createRequire as createRequire10 } from "node:module";
|
|
44557
|
+
import { dirname as dirname18, join as join33, resolve as resolve14 } from "node:path";
|
|
44120
44558
|
function getDualScopeNativeDb(handle) {
|
|
44121
44559
|
const db = handle.db;
|
|
44122
44560
|
if ("$client" in db && db.$client instanceof getDatabaseSyncCtor()) return db.$client;
|
|
@@ -44138,9 +44576,9 @@ function cacheKey(scope, dbPath) {
|
|
|
44138
44576
|
}
|
|
44139
44577
|
function resolveDualScopeDbPath(scope, cwd, capturedGlobalHome) {
|
|
44140
44578
|
if (scope === "project") {
|
|
44141
|
-
return
|
|
44579
|
+
return join33(resolveCleoDir(cwd), "cleo.db");
|
|
44142
44580
|
}
|
|
44143
|
-
return
|
|
44581
|
+
return join33(capturedGlobalHome ?? getCleoHome(), "cleo.db");
|
|
44144
44582
|
}
|
|
44145
44583
|
function migrationsSetName(scope) {
|
|
44146
44584
|
return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
|
|
@@ -44190,8 +44628,8 @@ async function openDualScopeDb(scope, cwd, options) {
|
|
|
44190
44628
|
async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
44191
44629
|
execution?.assertActive();
|
|
44192
44630
|
log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
44193
|
-
const dir =
|
|
44194
|
-
if (!
|
|
44631
|
+
const dir = dirname18(dbPath);
|
|
44632
|
+
if (!existsSync28(dir)) {
|
|
44195
44633
|
mkdirSync8(dir, { recursive: true });
|
|
44196
44634
|
}
|
|
44197
44635
|
execution?.assertActive();
|
|
@@ -44199,6 +44637,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
44199
44637
|
const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
|
|
44200
44638
|
try {
|
|
44201
44639
|
applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
|
|
44640
|
+
installSchemaWriteGuard(nativeDb);
|
|
44202
44641
|
const drizzle2 = getDrizzle();
|
|
44203
44642
|
const db = drizzle2({ client: nativeDb });
|
|
44204
44643
|
const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
|
|
@@ -44247,11 +44686,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
44247
44686
|
execution?.assertActive();
|
|
44248
44687
|
return handle;
|
|
44249
44688
|
} catch (err) {
|
|
44689
|
+
const explained = explainSchemaWriteDenial(nativeDb, err);
|
|
44250
44690
|
try {
|
|
44251
44691
|
nativeDb.close();
|
|
44252
44692
|
} catch {
|
|
44253
44693
|
}
|
|
44254
|
-
throw
|
|
44694
|
+
throw explained;
|
|
44255
44695
|
}
|
|
44256
44696
|
}
|
|
44257
44697
|
async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
@@ -44272,7 +44712,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44272
44712
|
);
|
|
44273
44713
|
}
|
|
44274
44714
|
const dedicated = options?.dedicated === true;
|
|
44275
|
-
const normalizedPath =
|
|
44715
|
+
const normalizedPath = resolve14(dbPath);
|
|
44276
44716
|
const key = cacheKey(scope, normalizedPath);
|
|
44277
44717
|
if (!dedicated) {
|
|
44278
44718
|
const existing = _cache.get(key);
|
|
@@ -44309,8 +44749,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44309
44749
|
}
|
|
44310
44750
|
let initResolve = null;
|
|
44311
44751
|
let initReject = null;
|
|
44312
|
-
const initPromise = new Promise((
|
|
44313
|
-
initResolve =
|
|
44752
|
+
const initPromise = new Promise((resolve17, reject) => {
|
|
44753
|
+
initResolve = resolve17;
|
|
44314
44754
|
initReject = reject;
|
|
44315
44755
|
});
|
|
44316
44756
|
_cache.set(key, {
|
|
@@ -44331,8 +44771,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44331
44771
|
try {
|
|
44332
44772
|
execution?.assertActive();
|
|
44333
44773
|
log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
|
|
44334
|
-
const dir =
|
|
44335
|
-
if (!
|
|
44774
|
+
const dir = dirname18(normalizedPath);
|
|
44775
|
+
if (!existsSync28(dir)) {
|
|
44336
44776
|
mkdirSync8(dir, { recursive: true });
|
|
44337
44777
|
}
|
|
44338
44778
|
execution?.assertActive();
|
|
@@ -44340,6 +44780,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44340
44780
|
const nativeDb = new DatabaseSyncCtor(normalizedPath, { allowExtension: true });
|
|
44341
44781
|
openingNative = nativeDb;
|
|
44342
44782
|
applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
|
|
44783
|
+
installSchemaWriteGuard(nativeDb);
|
|
44343
44784
|
const drizzle2 = getDrizzle();
|
|
44344
44785
|
const db = drizzle2({ client: nativeDb });
|
|
44345
44786
|
const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
|
|
@@ -44470,12 +44911,13 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44470
44911
|
execution?.assertActive();
|
|
44471
44912
|
initResolve(finalHandle);
|
|
44472
44913
|
} catch (err) {
|
|
44914
|
+
const explained = openingNative ? explainSchemaWriteDenial(openingNative, err) : err;
|
|
44473
44915
|
try {
|
|
44474
44916
|
if (!published && openingNative?.isOpen) openingNative.close();
|
|
44475
44917
|
} catch (closeError) {
|
|
44476
44918
|
log15.warn({ closeError }, "failed to close unpublished database initializer");
|
|
44477
44919
|
}
|
|
44478
|
-
initReject(
|
|
44920
|
+
initReject(explained);
|
|
44479
44921
|
}
|
|
44480
44922
|
})();
|
|
44481
44923
|
return initPromise;
|
|
@@ -44548,6 +44990,7 @@ var init_dual_scope_db = __esm({
|
|
|
44548
44990
|
init_relocated_store_guard();
|
|
44549
44991
|
init_resolve_migrations_folder();
|
|
44550
44992
|
init_sqlite_pragmas();
|
|
44993
|
+
init_worktree_build_guard();
|
|
44551
44994
|
init_worktree_isolation_guard();
|
|
44552
44995
|
init_writer_lease();
|
|
44553
44996
|
ExodusAbortWriteUnsafeError = class extends Error {
|
|
@@ -44570,7 +45013,7 @@ var init_dual_scope_db = __esm({
|
|
|
44570
45013
|
}
|
|
44571
45014
|
};
|
|
44572
45015
|
_cache = /* @__PURE__ */ new Map();
|
|
44573
|
-
_require6 =
|
|
45016
|
+
_require6 = createRequire10(import.meta.url);
|
|
44574
45017
|
_drizzle4 = null;
|
|
44575
45018
|
_DatabaseSyncCtor = null;
|
|
44576
45019
|
EntryCancelledError = class extends Error {
|
|
@@ -44601,7 +45044,7 @@ var init_dual_scope_db = __esm({
|
|
|
44601
45044
|
}
|
|
44602
45045
|
/** @inheritdoc */
|
|
44603
45046
|
async openProject(dbPath, options) {
|
|
44604
|
-
const normalized =
|
|
45047
|
+
const normalized = resolve14(dbPath);
|
|
44605
45048
|
if (options?.dedicated) {
|
|
44606
45049
|
const handle = await openDualScopeDbAtPath("project", normalized, options?.exodusCwd, {
|
|
44607
45050
|
dedicated: true
|
|
@@ -44613,7 +45056,7 @@ var init_dual_scope_db = __esm({
|
|
|
44613
45056
|
/** @inheritdoc */
|
|
44614
45057
|
async openGlobal(options) {
|
|
44615
45058
|
const dbPath = resolveDualScopeDbPath("global");
|
|
44616
|
-
const normalized =
|
|
45059
|
+
const normalized = resolve14(dbPath);
|
|
44617
45060
|
if (options?.dedicated) {
|
|
44618
45061
|
const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
|
|
44619
45062
|
dedicated: true
|
|
@@ -44624,7 +45067,7 @@ var init_dual_scope_db = __esm({
|
|
|
44624
45067
|
}
|
|
44625
45068
|
/** @inheritdoc */
|
|
44626
45069
|
async openGlobalAt(dbPath, options) {
|
|
44627
|
-
const normalized =
|
|
45070
|
+
const normalized = resolve14(dbPath);
|
|
44628
45071
|
if (options?.dedicated) {
|
|
44629
45072
|
const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
|
|
44630
45073
|
dedicated: true
|
|
@@ -44635,7 +45078,7 @@ var init_dual_scope_db = __esm({
|
|
|
44635
45078
|
}
|
|
44636
45079
|
/** @inheritdoc */
|
|
44637
45080
|
closeProject(dbPath) {
|
|
44638
|
-
const normalized =
|
|
45081
|
+
const normalized = resolve14(dbPath);
|
|
44639
45082
|
this.closeEntry("project", normalized);
|
|
44640
45083
|
}
|
|
44641
45084
|
/** @inheritdoc */
|
|
@@ -44672,8 +45115,8 @@ var init_dual_scope_db = __esm({
|
|
|
44672
45115
|
const entryId = ++this._nextId;
|
|
44673
45116
|
let initResolve;
|
|
44674
45117
|
let initReject;
|
|
44675
|
-
const initPromise = new Promise((
|
|
44676
|
-
initResolve =
|
|
45118
|
+
const initPromise = new Promise((resolve17, reject) => {
|
|
45119
|
+
initResolve = resolve17;
|
|
44677
45120
|
initReject = reject;
|
|
44678
45121
|
});
|
|
44679
45122
|
this._registry.set(key, { id: entryId, store: null, initPromise });
|
|
@@ -45466,8 +45909,8 @@ __export(nexus_sqlite_exports, {
|
|
|
45466
45909
|
resetNexusDbState: () => resetNexusDbState,
|
|
45467
45910
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
45468
45911
|
});
|
|
45469
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
45470
|
-
import { join as
|
|
45912
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync29 } from "node:fs";
|
|
45913
|
+
import { join as join34 } from "node:path";
|
|
45471
45914
|
function getNexusDbPath(cwd) {
|
|
45472
45915
|
return resolveDualScopeDbPath("project", cwd);
|
|
45473
45916
|
}
|
|
@@ -45503,12 +45946,13 @@ function ensureGlobalRegistryAttached(nativeDb) {
|
|
|
45503
45946
|
}
|
|
45504
45947
|
}
|
|
45505
45948
|
nativeDb.exec(`ATTACH DATABASE '${escaped}' AS ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
|
|
45949
|
+
refreshSchemaWriteGuard(nativeDb);
|
|
45506
45950
|
}
|
|
45507
45951
|
function resolveNexusMigrationsFolder() {
|
|
45508
45952
|
return resolveCorePackageMigrationsFolder("drizzle-nexus");
|
|
45509
45953
|
}
|
|
45510
45954
|
function getNestedNexusSentinelPath() {
|
|
45511
|
-
return
|
|
45955
|
+
return join34(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
|
|
45512
45956
|
}
|
|
45513
45957
|
function detectAndWarnOnNestedNexus() {
|
|
45514
45958
|
let nestedPath;
|
|
@@ -45517,7 +45961,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
45517
45961
|
} catch {
|
|
45518
45962
|
return false;
|
|
45519
45963
|
}
|
|
45520
|
-
if (!
|
|
45964
|
+
if (!existsSync29(nestedPath)) return false;
|
|
45521
45965
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
45522
45966
|
_warnedNestedPaths.add(nestedPath);
|
|
45523
45967
|
const canonicalPath = getNexusDbPath();
|
|
@@ -45676,7 +46120,7 @@ function runNexusMigrations(nativeDb, db, dbPath) {
|
|
|
45676
46120
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
45677
46121
|
if (tableExists4(nativeDb, "nexus_nodes")) {
|
|
45678
46122
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
45679
|
-
if (!
|
|
46123
|
+
if (!existsSync29(backupPath)) {
|
|
45680
46124
|
try {
|
|
45681
46125
|
copyFileSync7(dbPath, backupPath);
|
|
45682
46126
|
} catch {
|
|
@@ -45771,6 +46215,7 @@ var init_nexus_sqlite = __esm({
|
|
|
45771
46215
|
init_resolve_migrations_folder();
|
|
45772
46216
|
init_nexus_schema();
|
|
45773
46217
|
init_with_retry();
|
|
46218
|
+
init_worktree_build_guard();
|
|
45774
46219
|
NEXUS_SCHEMA_VERSION = "1.0.0";
|
|
45775
46220
|
NEXUS_GLOBAL_ATTACH_ALIAS = "nexus_global";
|
|
45776
46221
|
NESTED_NEXUS_SENTINEL = "nexus.db";
|
|
@@ -45805,15 +46250,15 @@ var init_legacy_alias = __esm({
|
|
|
45805
46250
|
|
|
45806
46251
|
// packages/core/src/llm/stable-device-id.ts
|
|
45807
46252
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
45808
|
-
import { existsSync as
|
|
45809
|
-
import { dirname as
|
|
46253
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync9, readFileSync as readFileSync10, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
|
|
46254
|
+
import { dirname as dirname19 } from "node:path";
|
|
45810
46255
|
import { resolveStableDeviceIdPath } from "@cleocode/paths";
|
|
45811
46256
|
function getStableDeviceId() {
|
|
45812
46257
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
45813
46258
|
const path = resolveStableDeviceIdPath();
|
|
45814
|
-
if (
|
|
46259
|
+
if (existsSync30(path)) {
|
|
45815
46260
|
try {
|
|
45816
|
-
const raw =
|
|
46261
|
+
const raw = readFileSync10(path, "utf-8").trim();
|
|
45817
46262
|
if (raw.length > 0) {
|
|
45818
46263
|
_cachedDeviceId = raw;
|
|
45819
46264
|
return raw;
|
|
@@ -45823,8 +46268,8 @@ function getStableDeviceId() {
|
|
|
45823
46268
|
}
|
|
45824
46269
|
const fresh = randomUUID3();
|
|
45825
46270
|
try {
|
|
45826
|
-
const dir =
|
|
45827
|
-
if (!
|
|
46271
|
+
const dir = dirname19(path);
|
|
46272
|
+
if (!existsSync30(dir)) {
|
|
45828
46273
|
mkdirSync9(dir, { recursive: true });
|
|
45829
46274
|
}
|
|
45830
46275
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
@@ -45861,8 +46306,8 @@ var init_registry_roots = __esm({
|
|
|
45861
46306
|
// packages/core/src/nexus/projects-scan.ts
|
|
45862
46307
|
async function withinBudget(promise2, ms) {
|
|
45863
46308
|
let timer;
|
|
45864
|
-
const expiry = new Promise((
|
|
45865
|
-
timer = setTimeout(() =>
|
|
46309
|
+
const expiry = new Promise((resolve17) => {
|
|
46310
|
+
timer = setTimeout(() => resolve17("timeout"), ms);
|
|
45866
46311
|
timer.unref();
|
|
45867
46312
|
});
|
|
45868
46313
|
try {
|
|
@@ -45900,9 +46345,9 @@ __export(path_map_exports, {
|
|
|
45900
46345
|
supersededRegistryPath: () => supersededRegistryPath,
|
|
45901
46346
|
touchProjectLocation: () => touchProjectLocation
|
|
45902
46347
|
});
|
|
45903
|
-
import { existsSync as
|
|
46348
|
+
import { existsSync as existsSync31, lstatSync, readdirSync as readdirSync7 } from "node:fs";
|
|
45904
46349
|
import { lstat, readdir as readdir2 } from "node:fs/promises";
|
|
45905
|
-
import { isAbsolute as
|
|
46350
|
+
import { isAbsolute as isAbsolute5, join as join35, relative as relative3, sep as sep5 } from "node:path";
|
|
45906
46351
|
import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity3 } from "@cleocode/paths";
|
|
45907
46352
|
import { and as and7, desc as desc3, eq as eq11, inArray as inArray5, ne as ne3 } from "drizzle-orm";
|
|
45908
46353
|
function holdingKey(projectId, path) {
|
|
@@ -45918,7 +46363,7 @@ function isSupersededRegistryPath(projectPath) {
|
|
|
45918
46363
|
return projectPath.startsWith(SUPERSEDED_PATH_PREFIX);
|
|
45919
46364
|
}
|
|
45920
46365
|
function projectHolding(path, projectId) {
|
|
45921
|
-
const cleoDir =
|
|
46366
|
+
const cleoDir = join35(path, ".cleo");
|
|
45922
46367
|
try {
|
|
45923
46368
|
lstatSync(cleoDir);
|
|
45924
46369
|
readdirSync7(cleoDir);
|
|
@@ -45930,7 +46375,7 @@ function projectHolding(path, projectId) {
|
|
|
45930
46375
|
return declared === null || declared.projectId === projectId ? "yes" : "no";
|
|
45931
46376
|
}
|
|
45932
46377
|
async function probeProjectHolding(path, projectId, timeoutMs) {
|
|
45933
|
-
const cleoDir =
|
|
46378
|
+
const cleoDir = join35(path, ".cleo");
|
|
45934
46379
|
const probe = async () => {
|
|
45935
46380
|
try {
|
|
45936
46381
|
await lstat(cleoDir);
|
|
@@ -45948,8 +46393,8 @@ async function probeProjectHolding(path, projectId, timeoutMs) {
|
|
|
45948
46393
|
return declared === null || declared.projectId === projectId ? "yes" : "no";
|
|
45949
46394
|
}
|
|
45950
46395
|
function isStrictlyInside(outer, inner) {
|
|
45951
|
-
const rel =
|
|
45952
|
-
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${
|
|
46396
|
+
const rel = relative3(canonicalizePath3(outer), canonicalizePath3(inner));
|
|
46397
|
+
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep5}`) && !isAbsolute5(rel);
|
|
45953
46398
|
}
|
|
45954
46399
|
function locationKey(projectId, deviceId, path) {
|
|
45955
46400
|
return and7(
|
|
@@ -46111,7 +46556,7 @@ function hasOtherLiveLocation(db, record2, deviceId) {
|
|
|
46111
46556
|
ne3(projectLocations.path, record2.projectPath)
|
|
46112
46557
|
)
|
|
46113
46558
|
).all().some(
|
|
46114
|
-
(location) => isStrictlyInside(record2.projectPath, location.path) &&
|
|
46559
|
+
(location) => isStrictlyInside(record2.projectPath, location.path) && existsSync31(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record2.projectId
|
|
46115
46560
|
);
|
|
46116
46561
|
}
|
|
46117
46562
|
function demoteProjectLocation(db, record2, state) {
|
|
@@ -46162,7 +46607,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
|
|
|
46162
46607
|
).orderBy(desc3(projectLocations.lastSeen)).all();
|
|
46163
46608
|
const present = (path) => {
|
|
46164
46609
|
const holding = probed?.get(holdingKey(row.projectId, path));
|
|
46165
|
-
return holding === void 0 ?
|
|
46610
|
+
return holding === void 0 ? existsSync31(path) : holding === "yes";
|
|
46166
46611
|
};
|
|
46167
46612
|
const home = candidates.find(
|
|
46168
46613
|
(c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq11(projectRegistry.projectPath, c.path)).all().length === 0
|
|
@@ -46191,7 +46636,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
|
|
|
46191
46636
|
projectHash: generateProjectHash(row.path),
|
|
46192
46637
|
firstSeen: row.firstSeen,
|
|
46193
46638
|
lastSeen: row.lastSeen,
|
|
46194
|
-
exists: local &&
|
|
46639
|
+
exists: local && existsSync31(row.path),
|
|
46195
46640
|
deviceId: local ? deviceId : row.deviceId,
|
|
46196
46641
|
state: row.state
|
|
46197
46642
|
});
|
|
@@ -46220,13 +46665,13 @@ __export(checkout_nonce_exports, {
|
|
|
46220
46665
|
readCheckoutNonce: () => readCheckoutNonce
|
|
46221
46666
|
});
|
|
46222
46667
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
46223
|
-
import { existsSync as
|
|
46224
|
-
import { join as
|
|
46668
|
+
import { existsSync as existsSync32, readFileSync as readFileSync11, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
|
|
46669
|
+
import { join as join36 } from "node:path";
|
|
46225
46670
|
function readInfo(projectRoot) {
|
|
46226
|
-
const path =
|
|
46227
|
-
if (!
|
|
46671
|
+
const path = join36(projectRoot, ".cleo", "project-info.json");
|
|
46672
|
+
if (!existsSync32(path)) return null;
|
|
46228
46673
|
try {
|
|
46229
|
-
const parsed = JSON.parse(
|
|
46674
|
+
const parsed = JSON.parse(readFileSync11(path, "utf-8"));
|
|
46230
46675
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
46231
46676
|
} catch {
|
|
46232
46677
|
return null;
|
|
@@ -46242,7 +46687,7 @@ function ensureCheckoutNonce(projectRoot) {
|
|
|
46242
46687
|
const info = readInfo(projectRoot);
|
|
46243
46688
|
if (!info) return null;
|
|
46244
46689
|
const nonce = randomBytes2(16).toString("hex");
|
|
46245
|
-
const path =
|
|
46690
|
+
const path = join36(projectRoot, ".cleo", "project-info.json");
|
|
46246
46691
|
const temp = `${path}.${randomBytes2(6).toString("hex")}.tmp`;
|
|
46247
46692
|
writeFileSync9(temp, `${JSON.stringify({ ...info, [CHECKOUT_NONCE_FIELD]: nonce }, null, 2)}
|
|
46248
46693
|
`);
|
|
@@ -46317,10 +46762,10 @@ __export(paths_exports, {
|
|
|
46317
46762
|
validateProjectRoot: () => validateProjectRoot,
|
|
46318
46763
|
worktreeScope: () => worktreeScope
|
|
46319
46764
|
});
|
|
46320
|
-
import { existsSync as
|
|
46321
|
-
import { createRequire as
|
|
46765
|
+
import { existsSync as existsSync33, readFileSync as readFileSync12, statSync as statSync9 } from "node:fs";
|
|
46766
|
+
import { createRequire as createRequire11 } from "node:module";
|
|
46322
46767
|
import { homedir as homedir2 } from "node:os";
|
|
46323
|
-
import { basename as basename10, dirname as
|
|
46768
|
+
import { basename as basename10, dirname as dirname20, join as join37, resolve as resolve15 } from "node:path";
|
|
46324
46769
|
import {
|
|
46325
46770
|
getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
|
|
46326
46771
|
getCleoTemplatesTildePath as _getCleoTemplatesTildePath,
|
|
@@ -46330,7 +46775,7 @@ import {
|
|
|
46330
46775
|
resolveCanonicalCleoDir as _resolveCanonicalCleoDir
|
|
46331
46776
|
} from "@cleocode/paths";
|
|
46332
46777
|
function _getDatabaseSyncCtor() {
|
|
46333
|
-
const _require7 =
|
|
46778
|
+
const _require7 = createRequire11(import.meta.url);
|
|
46334
46779
|
const mod = _require7("node:sqlite");
|
|
46335
46780
|
return mod.DatabaseSync;
|
|
46336
46781
|
}
|
|
@@ -46342,20 +46787,20 @@ function runWithWorktreeScopeFromEnv(fn) {
|
|
|
46342
46787
|
}
|
|
46343
46788
|
function isProjectInitialized(projectRoot) {
|
|
46344
46789
|
const root = projectRoot ?? getProjectRoot();
|
|
46345
|
-
const cleoDir =
|
|
46346
|
-
return
|
|
46790
|
+
const cleoDir = join37(root, ".cleo");
|
|
46791
|
+
return existsSync33(cleoDir) && existsSync33(join37(cleoDir, "tasks.db"));
|
|
46347
46792
|
}
|
|
46348
46793
|
function getCleoHome() {
|
|
46349
46794
|
return getPlatformPaths().data;
|
|
46350
46795
|
}
|
|
46351
46796
|
function getCleoTemplatesDir() {
|
|
46352
|
-
return
|
|
46797
|
+
return join37(getCleoHome(), "templates");
|
|
46353
46798
|
}
|
|
46354
46799
|
function getCleoSchemasDir() {
|
|
46355
|
-
return
|
|
46800
|
+
return join37(getCleoHome(), "schemas");
|
|
46356
46801
|
}
|
|
46357
46802
|
function getCleoDocsDir() {
|
|
46358
|
-
return
|
|
46803
|
+
return join37(getCleoHome(), "docs");
|
|
46359
46804
|
}
|
|
46360
46805
|
function getCleoDir(cwd) {
|
|
46361
46806
|
if (cwd) {
|
|
@@ -46404,24 +46849,24 @@ function getCleoDirAbsolute(cwd, opts) {
|
|
|
46404
46849
|
try {
|
|
46405
46850
|
const projectRoot = getProjectRoot(cwd);
|
|
46406
46851
|
const canonical = _resolveCanonicalCleoDir(project.projectId);
|
|
46407
|
-
if (canonical !== null && canonical ===
|
|
46852
|
+
if (canonical !== null && canonical === resolve15(projectRoot, cleoDir)) {
|
|
46408
46853
|
return canonical;
|
|
46409
46854
|
}
|
|
46410
|
-
return
|
|
46855
|
+
return resolve15(projectRoot, cleoDir);
|
|
46411
46856
|
} catch {
|
|
46412
|
-
return
|
|
46857
|
+
return resolve15(project.projectRoot, cleoDir);
|
|
46413
46858
|
}
|
|
46414
46859
|
}
|
|
46415
46860
|
try {
|
|
46416
|
-
return
|
|
46861
|
+
return resolve15(getProjectRoot(cwd), cleoDir);
|
|
46417
46862
|
} catch (err) {
|
|
46418
46863
|
if (opts?.bootstrap) {
|
|
46419
|
-
return
|
|
46864
|
+
return resolve15(cwd ?? process.cwd(), cleoDir);
|
|
46420
46865
|
}
|
|
46421
46866
|
if (_cwdHasGitAncestor(cwd)) {
|
|
46422
46867
|
throw err;
|
|
46423
46868
|
}
|
|
46424
|
-
return
|
|
46869
|
+
return resolve15(cwd ?? process.cwd(), cleoDir);
|
|
46425
46870
|
}
|
|
46426
46871
|
}
|
|
46427
46872
|
function resolveCanonicalCleoDir(projectId) {
|
|
@@ -46448,9 +46893,9 @@ function resolveCanonicalCleoDir(projectId) {
|
|
|
46448
46893
|
function _resolveProjectByCwdFromNexus(cwd) {
|
|
46449
46894
|
try {
|
|
46450
46895
|
const cleoHome = getCleoHome();
|
|
46451
|
-
const globalDbPath =
|
|
46452
|
-
if (!
|
|
46453
|
-
const start =
|
|
46896
|
+
const globalDbPath = join37(cleoHome, "cleo.db");
|
|
46897
|
+
if (!existsSync33(globalDbPath)) return null;
|
|
46898
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46454
46899
|
let current = start;
|
|
46455
46900
|
const DatabaseSync3 = _getDatabaseSyncCtor();
|
|
46456
46901
|
const db = new DatabaseSync3(globalDbPath, { readOnly: true });
|
|
@@ -46463,7 +46908,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
46463
46908
|
if (row && typeof row.project_id === "string" && row.project_id.length > 0) {
|
|
46464
46909
|
return row.project_id;
|
|
46465
46910
|
}
|
|
46466
|
-
const parent =
|
|
46911
|
+
const parent = dirname20(current);
|
|
46467
46912
|
if (parent === current) break;
|
|
46468
46913
|
current = parent;
|
|
46469
46914
|
}
|
|
@@ -46483,18 +46928,18 @@ function _cleoDirEnvOverride() {
|
|
|
46483
46928
|
}
|
|
46484
46929
|
function _findCleoDirRoot(cwd) {
|
|
46485
46930
|
const homeRoot = homedir2();
|
|
46486
|
-
let current =
|
|
46931
|
+
let current = resolve15(cwd ?? process.cwd());
|
|
46487
46932
|
while (true) {
|
|
46488
46933
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
46489
46934
|
if (!isDangerousRoot) {
|
|
46490
46935
|
try {
|
|
46491
|
-
if (statSync9(
|
|
46936
|
+
if (statSync9(join37(current, ".cleo")).isDirectory()) {
|
|
46492
46937
|
return current;
|
|
46493
46938
|
}
|
|
46494
46939
|
} catch {
|
|
46495
46940
|
}
|
|
46496
46941
|
}
|
|
46497
|
-
const parent =
|
|
46942
|
+
const parent = dirname20(current);
|
|
46498
46943
|
if (parent === current) break;
|
|
46499
46944
|
current = parent;
|
|
46500
46945
|
}
|
|
@@ -46513,7 +46958,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46513
46958
|
if (pathsResult !== null) {
|
|
46514
46959
|
return pathsResult.projectId;
|
|
46515
46960
|
}
|
|
46516
|
-
const start =
|
|
46961
|
+
const start = resolve15(from ?? process.cwd());
|
|
46517
46962
|
let current = start;
|
|
46518
46963
|
while (true) {
|
|
46519
46964
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
@@ -46524,7 +46969,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46524
46969
|
}
|
|
46525
46970
|
break;
|
|
46526
46971
|
}
|
|
46527
|
-
const parent =
|
|
46972
|
+
const parent = dirname20(current);
|
|
46528
46973
|
if (parent === current) break;
|
|
46529
46974
|
current = parent;
|
|
46530
46975
|
}
|
|
@@ -46543,7 +46988,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46543
46988
|
function resolveCleoDir(cwd) {
|
|
46544
46989
|
const scope = worktreeScope.getStore();
|
|
46545
46990
|
if (scope !== void 0) {
|
|
46546
|
-
return
|
|
46991
|
+
return join37(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
|
|
46547
46992
|
}
|
|
46548
46993
|
const override = _cleoDirEnvOverride();
|
|
46549
46994
|
if (override !== null) {
|
|
@@ -46551,16 +46996,16 @@ function resolveCleoDir(cwd) {
|
|
|
46551
46996
|
}
|
|
46552
46997
|
const root = _findCleoDirRoot(cwd);
|
|
46553
46998
|
if (root !== null) {
|
|
46554
|
-
return
|
|
46999
|
+
return join37(resolveStoreOwnerRoot(root), ".cleo");
|
|
46555
47000
|
}
|
|
46556
|
-
const start =
|
|
47001
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46557
47002
|
let current = start;
|
|
46558
47003
|
while (true) {
|
|
46559
47004
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
46560
47005
|
if (mainRepo !== null) {
|
|
46561
|
-
return
|
|
47006
|
+
return join37(mainRepo, ".cleo");
|
|
46562
47007
|
}
|
|
46563
|
-
const parent =
|
|
47008
|
+
const parent = dirname20(current);
|
|
46564
47009
|
if (parent === current) {
|
|
46565
47010
|
break;
|
|
46566
47011
|
}
|
|
@@ -46599,25 +47044,25 @@ function _resolveCleoDir(cwd) {
|
|
|
46599
47044
|
const project = _pathsResolveProjectByCwd(cwd);
|
|
46600
47045
|
if (project !== null) {
|
|
46601
47046
|
try {
|
|
46602
|
-
return
|
|
47047
|
+
return resolve15(getProjectRoot(cwd), cleoDir);
|
|
46603
47048
|
} catch {
|
|
46604
|
-
return
|
|
47049
|
+
return resolve15(project.projectRoot, cleoDir);
|
|
46605
47050
|
}
|
|
46606
47051
|
}
|
|
46607
47052
|
return getCleoDirAbsolute(cwd);
|
|
46608
47053
|
}
|
|
46609
47054
|
function _cwdHasGitAncestor(cwd) {
|
|
46610
|
-
const start =
|
|
47055
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46611
47056
|
let current = start;
|
|
46612
47057
|
while (true) {
|
|
46613
|
-
const gitMarker =
|
|
47058
|
+
const gitMarker = join37(current, ".git");
|
|
46614
47059
|
try {
|
|
46615
|
-
if (
|
|
47060
|
+
if (existsSync33(gitMarker)) {
|
|
46616
47061
|
return true;
|
|
46617
47062
|
}
|
|
46618
47063
|
} catch {
|
|
46619
47064
|
}
|
|
46620
|
-
const parent =
|
|
47065
|
+
const parent = dirname20(current);
|
|
46621
47066
|
if (parent === current) return false;
|
|
46622
47067
|
current = parent;
|
|
46623
47068
|
}
|
|
@@ -46644,55 +47089,55 @@ function resolveProjectPath(relativePath, cwd) {
|
|
|
46644
47089
|
return relativePath;
|
|
46645
47090
|
}
|
|
46646
47091
|
if (relativePath.startsWith("~/") || relativePath.startsWith("~\\") || relativePath === "~") {
|
|
46647
|
-
return
|
|
47092
|
+
return resolve15(homedir2(), relativePath.slice(2));
|
|
46648
47093
|
}
|
|
46649
|
-
return
|
|
47094
|
+
return resolve15(getProjectRoot(cwd), relativePath);
|
|
46650
47095
|
}
|
|
46651
47096
|
function getTaskPath(cwd) {
|
|
46652
|
-
return
|
|
47097
|
+
return join37(_resolveCleoDir(cwd), "tasks.db");
|
|
46653
47098
|
}
|
|
46654
47099
|
function getConfigPath(cwd) {
|
|
46655
|
-
return
|
|
47100
|
+
return join37(_resolveCleoDir(cwd), "config.json");
|
|
46656
47101
|
}
|
|
46657
47102
|
function getSessionsPath(cwd) {
|
|
46658
|
-
return
|
|
47103
|
+
return join37(_resolveCleoDir(cwd), "sessions.json");
|
|
46659
47104
|
}
|
|
46660
47105
|
function getArchivePath(cwd) {
|
|
46661
|
-
return
|
|
47106
|
+
return join37(_resolveCleoDir(cwd), "tasks-archive.json");
|
|
46662
47107
|
}
|
|
46663
47108
|
function getLogPath(cwd) {
|
|
46664
|
-
return
|
|
47109
|
+
return join37(_resolveCleoDir(cwd), "logs", "cleo.log");
|
|
46665
47110
|
}
|
|
46666
47111
|
function getBackupDir(cwd) {
|
|
46667
|
-
return
|
|
47112
|
+
return join37(_resolveCleoDir(cwd), "backups", "operational");
|
|
46668
47113
|
}
|
|
46669
47114
|
function getGlobalConfigPath() {
|
|
46670
|
-
return
|
|
47115
|
+
return join37(getCleoHome(), "config.json");
|
|
46671
47116
|
}
|
|
46672
47117
|
function getCleoGlobalRecipesDir() {
|
|
46673
|
-
return
|
|
47118
|
+
return join37(getCleoHome(), "global-recipes");
|
|
46674
47119
|
}
|
|
46675
47120
|
function getCleoGlobalJustfilePath() {
|
|
46676
|
-
return
|
|
47121
|
+
return join37(getCleoGlobalRecipesDir(), "justfile");
|
|
46677
47122
|
}
|
|
46678
47123
|
function getCleoPiExtensionsDir() {
|
|
46679
|
-
return
|
|
47124
|
+
return join37(getCleoHome(), "pi-extensions");
|
|
46680
47125
|
}
|
|
46681
47126
|
function getCleoCantWorkflowsDir() {
|
|
46682
|
-
return
|
|
47127
|
+
return join37(getCleoHome(), "cant-workflows");
|
|
46683
47128
|
}
|
|
46684
47129
|
function getCleoGlobalAgentsDir() {
|
|
46685
|
-
return
|
|
47130
|
+
return join37(getCleoHome(), "agents");
|
|
46686
47131
|
}
|
|
46687
47132
|
function getCleoGlobalCantAgentsDir() {
|
|
46688
|
-
return
|
|
47133
|
+
return join37(getCleoHome(), "cant", "agents");
|
|
46689
47134
|
}
|
|
46690
47135
|
function getAgentOutputsDir(cwd) {
|
|
46691
47136
|
const projectRoot = getProjectRoot(cwd);
|
|
46692
|
-
const configPath =
|
|
46693
|
-
if (
|
|
47137
|
+
const configPath = join37(projectRoot, ".cleo", "config.json");
|
|
47138
|
+
if (existsSync33(configPath)) {
|
|
46694
47139
|
try {
|
|
46695
|
-
const config2 = JSON.parse(
|
|
47140
|
+
const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
46696
47141
|
if (typeof config2.agentOutputs === "object" && config2.agentOutputs?.directory) {
|
|
46697
47142
|
return config2.agentOutputs.directory;
|
|
46698
47143
|
}
|
|
@@ -46715,17 +47160,17 @@ function getAgentOutputsAbsolute(cwd) {
|
|
|
46715
47160
|
if (isAbsolutePath2(dir)) {
|
|
46716
47161
|
return dir;
|
|
46717
47162
|
}
|
|
46718
|
-
return
|
|
47163
|
+
return resolve15(getProjectRoot(cwd), dir);
|
|
46719
47164
|
}
|
|
46720
47165
|
function getManifestPath(cwd) {
|
|
46721
47166
|
const outputDir = getAgentOutputsDir(cwd);
|
|
46722
47167
|
const projectRoot = getProjectRoot(cwd);
|
|
46723
|
-
const configPath =
|
|
47168
|
+
const configPath = join37(projectRoot, ".cleo", "config.json");
|
|
46724
47169
|
const legacyFileName = ["MANIFEST", "jsonl"].join(".");
|
|
46725
47170
|
let manifestFile = legacyFileName;
|
|
46726
|
-
if (
|
|
47171
|
+
if (existsSync33(configPath)) {
|
|
46727
47172
|
try {
|
|
46728
|
-
const config2 = JSON.parse(
|
|
47173
|
+
const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
46729
47174
|
const customFile = config2.agentOutputs?.manifestFile ?? config2.research?.manifestFile;
|
|
46730
47175
|
if (customFile) {
|
|
46731
47176
|
manifestFile = customFile;
|
|
@@ -46733,12 +47178,12 @@ function getManifestPath(cwd) {
|
|
|
46733
47178
|
} catch {
|
|
46734
47179
|
}
|
|
46735
47180
|
}
|
|
46736
|
-
return
|
|
47181
|
+
return resolve15(projectRoot, outputDir, manifestFile);
|
|
46737
47182
|
}
|
|
46738
47183
|
function getManifestArchivePath(cwd) {
|
|
46739
47184
|
const outputDir = getAgentOutputsDir(cwd);
|
|
46740
47185
|
const projectRoot = getProjectRoot(cwd);
|
|
46741
|
-
return
|
|
47186
|
+
return resolve15(projectRoot, outputDir, "MANIFEST.archive.jsonl");
|
|
46742
47187
|
}
|
|
46743
47188
|
function isAbsolutePath2(path) {
|
|
46744
47189
|
return _isAbsolutePath(path);
|
|
@@ -46762,24 +47207,24 @@ function getCanonicalTemplatesTildePath() {
|
|
|
46762
47207
|
return _getCanonicalTemplatesTildePath();
|
|
46763
47208
|
}
|
|
46764
47209
|
function getAgentsHome() {
|
|
46765
|
-
return process.env["AGENTS_HOME"] ??
|
|
47210
|
+
return process.env["AGENTS_HOME"] ?? join37(homedir2(), ".agents");
|
|
46766
47211
|
}
|
|
46767
47212
|
function getClaudeAgentsDir() {
|
|
46768
|
-
const claudeDir = process.env["CLAUDE_HOME"] ??
|
|
46769
|
-
return
|
|
47213
|
+
const claudeDir = process.env["CLAUDE_HOME"] ?? join37(homedir2(), ".claude");
|
|
47214
|
+
return join37(claudeDir, "agents");
|
|
46770
47215
|
}
|
|
46771
47216
|
function getClaudeMemDbPath() {
|
|
46772
|
-
return process.env["CLAUDE_MEM_DB"] ??
|
|
47217
|
+
return process.env["CLAUDE_MEM_DB"] ?? join37(homedir2(), ".claude-mem", "claude-mem.db");
|
|
46773
47218
|
}
|
|
46774
47219
|
function resolveWorktreeRouting(cwdOverride) {
|
|
46775
|
-
const cwd =
|
|
47220
|
+
const cwd = resolve15(cwdOverride ?? process.cwd());
|
|
46776
47221
|
const home = homedir2();
|
|
46777
47222
|
let worktreePath;
|
|
46778
47223
|
let current = cwd;
|
|
46779
47224
|
while (current !== home && current !== "/" && current !== "") {
|
|
46780
|
-
const gitPath =
|
|
47225
|
+
const gitPath = join37(current, ".git");
|
|
46781
47226
|
try {
|
|
46782
|
-
if (
|
|
47227
|
+
if (existsSync33(gitPath)) {
|
|
46783
47228
|
const stat3 = statSync9(gitPath);
|
|
46784
47229
|
if (stat3.isFile()) {
|
|
46785
47230
|
worktreePath = current;
|
|
@@ -46791,7 +47236,7 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
46791
47236
|
}
|
|
46792
47237
|
} catch {
|
|
46793
47238
|
}
|
|
46794
|
-
const parent =
|
|
47239
|
+
const parent = dirname20(current);
|
|
46795
47240
|
if (parent === current) break;
|
|
46796
47241
|
current = parent;
|
|
46797
47242
|
}
|
|
@@ -46808,17 +47253,17 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
46808
47253
|
}
|
|
46809
47254
|
function resolveWorktreeFilePath(filePath, routing) {
|
|
46810
47255
|
if (!routing.isWorktree || routing.worktreePath === void 0) {
|
|
46811
|
-
return
|
|
47256
|
+
return resolve15(filePath);
|
|
46812
47257
|
}
|
|
46813
|
-
return
|
|
47258
|
+
return resolve15(routing.cwd, filePath);
|
|
46814
47259
|
}
|
|
46815
47260
|
function detectStrayCleoDb(routing) {
|
|
46816
47261
|
if (!routing.isWorktree || routing.worktreePath === void 0) {
|
|
46817
47262
|
return void 0;
|
|
46818
47263
|
}
|
|
46819
|
-
const tasksDbPath =
|
|
47264
|
+
const tasksDbPath = join37(routing.worktreePath, ".cleo", "tasks.db");
|
|
46820
47265
|
try {
|
|
46821
|
-
if (
|
|
47266
|
+
if (existsSync33(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
|
|
46822
47267
|
return tasksDbPath;
|
|
46823
47268
|
}
|
|
46824
47269
|
} catch {
|
|
@@ -46828,7 +47273,7 @@ function detectStrayCleoDb(routing) {
|
|
|
46828
47273
|
async function resolveProjectById(projectId) {
|
|
46829
47274
|
try {
|
|
46830
47275
|
const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
46831
|
-
if (!
|
|
47276
|
+
if (!existsSync33(getNexusRegistryDbPath2())) return null;
|
|
46832
47277
|
const { eq: eq12 } = await import("drizzle-orm");
|
|
46833
47278
|
const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
46834
47279
|
const db = await getNexusDb2();
|
|
@@ -46863,9 +47308,9 @@ function _rowToRegistryEntry(row) {
|
|
|
46863
47308
|
};
|
|
46864
47309
|
}
|
|
46865
47310
|
function _readProjectNameFromInfo(projectRoot) {
|
|
46866
|
-
const infoPath =
|
|
46867
|
-
if (!
|
|
46868
|
-
const raw =
|
|
47311
|
+
const infoPath = join37(projectRoot, ".cleo", "project-info.json");
|
|
47312
|
+
if (!existsSync33(infoPath)) return void 0;
|
|
47313
|
+
const raw = readFileSync12(infoPath, "utf-8");
|
|
46869
47314
|
const data = JSON.parse(raw);
|
|
46870
47315
|
return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
|
|
46871
47316
|
}
|
|
@@ -46916,7 +47361,7 @@ async function recordProjectEncounter(cwd) {
|
|
|
46916
47361
|
if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
|
|
46917
47362
|
const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
|
|
46918
47363
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
46919
|
-
if (
|
|
47364
|
+
if (existsSync33(getNexusRegistryDbPath2(cleoHome))) {
|
|
46920
47365
|
const { and: and8, eq: eq12 } = await import("drizzle-orm");
|
|
46921
47366
|
const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
46922
47367
|
const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
|
|
@@ -47174,42 +47619,42 @@ var init_api_mode = __esm({
|
|
|
47174
47619
|
// packages/core/src/store/file-utils.ts
|
|
47175
47620
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
47176
47621
|
import {
|
|
47177
|
-
existsSync as
|
|
47622
|
+
existsSync as existsSync34,
|
|
47178
47623
|
mkdirSync as mkdirSync10,
|
|
47179
47624
|
readdirSync as readdirSync8,
|
|
47180
|
-
readFileSync as
|
|
47625
|
+
readFileSync as readFileSync13,
|
|
47181
47626
|
renameSync as renameSync11,
|
|
47182
47627
|
unlinkSync as unlinkSync6,
|
|
47183
47628
|
writeFileSync as writeFileSync10
|
|
47184
47629
|
} from "node:fs";
|
|
47185
|
-
import { basename as basename11, dirname as
|
|
47630
|
+
import { basename as basename11, dirname as dirname21, join as join38 } from "node:path";
|
|
47186
47631
|
import * as lockfile3 from "proper-lockfile";
|
|
47187
47632
|
function rotateBackup(filePath, mode) {
|
|
47188
|
-
const dir =
|
|
47633
|
+
const dir = dirname21(filePath);
|
|
47189
47634
|
const name15 = basename11(filePath);
|
|
47190
|
-
const backupDir =
|
|
47635
|
+
const backupDir = join38(dir, ".backups");
|
|
47191
47636
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
47192
|
-
if (!
|
|
47637
|
+
if (!existsSync34(backupDir)) {
|
|
47193
47638
|
mkdirSync10(backupDir, { recursive: true, mode: dirMode });
|
|
47194
47639
|
}
|
|
47195
47640
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
47196
|
-
const current =
|
|
47641
|
+
const current = join38(backupDir, `${name15}.${i}`);
|
|
47197
47642
|
if (i === MAX_BACKUPS) {
|
|
47198
47643
|
try {
|
|
47199
47644
|
unlinkSync6(current);
|
|
47200
47645
|
} catch {
|
|
47201
47646
|
}
|
|
47202
47647
|
} else {
|
|
47203
|
-
const next =
|
|
47648
|
+
const next = join38(backupDir, `${name15}.${i + 1}`);
|
|
47204
47649
|
try {
|
|
47205
|
-
if (
|
|
47650
|
+
if (existsSync34(current)) renameSync11(current, next);
|
|
47206
47651
|
} catch {
|
|
47207
47652
|
}
|
|
47208
47653
|
}
|
|
47209
47654
|
}
|
|
47210
47655
|
try {
|
|
47211
|
-
const content =
|
|
47212
|
-
const backupPath =
|
|
47656
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
47657
|
+
const backupPath = join38(backupDir, `${name15}.1`);
|
|
47213
47658
|
if (typeof mode === "number") {
|
|
47214
47659
|
writeFileSync10(backupPath, content, { encoding: "utf-8", mode });
|
|
47215
47660
|
} else {
|
|
@@ -47229,8 +47674,8 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
47229
47674
|
const opts = typeof optsOrIndent === "number" ? { indent: optsOrIndent } : optsOrIndent;
|
|
47230
47675
|
const indent = opts.indent ?? 2;
|
|
47231
47676
|
const mode = opts.mode;
|
|
47232
|
-
const dir =
|
|
47233
|
-
const tempPath =
|
|
47677
|
+
const dir = dirname21(filePath);
|
|
47678
|
+
const tempPath = join38(dir, `.${basename11(filePath)}.${randomBytes3(6).toString("hex")}.tmp`);
|
|
47234
47679
|
const content = JSON.stringify(data, null, indent) + "\n";
|
|
47235
47680
|
if (typeof mode === "number") {
|
|
47236
47681
|
writeFileSync10(tempPath, content, { encoding: "utf-8", mode });
|
|
@@ -47238,7 +47683,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
47238
47683
|
writeFileSync10(tempPath, content, "utf-8");
|
|
47239
47684
|
}
|
|
47240
47685
|
try {
|
|
47241
|
-
if (
|
|
47686
|
+
if (existsSync34(filePath)) {
|
|
47242
47687
|
rotateBackup(filePath, mode);
|
|
47243
47688
|
}
|
|
47244
47689
|
renameSync11(tempPath, filePath);
|
|
@@ -47252,7 +47697,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
47252
47697
|
}
|
|
47253
47698
|
function readJsonFile(filePath) {
|
|
47254
47699
|
try {
|
|
47255
|
-
const content =
|
|
47700
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
47256
47701
|
return JSON.parse(content);
|
|
47257
47702
|
} catch (error48) {
|
|
47258
47703
|
if (error48.code === "ENOENT") {
|
|
@@ -47262,12 +47707,12 @@ function readJsonFile(filePath) {
|
|
|
47262
47707
|
}
|
|
47263
47708
|
}
|
|
47264
47709
|
async function withLock2(filePath, transform2, opts = {}) {
|
|
47265
|
-
const dir =
|
|
47710
|
+
const dir = dirname21(filePath);
|
|
47266
47711
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
47267
|
-
if (!
|
|
47712
|
+
if (!existsSync34(dir)) {
|
|
47268
47713
|
mkdirSync10(dir, { recursive: true, mode: dirMode });
|
|
47269
47714
|
}
|
|
47270
|
-
if (!
|
|
47715
|
+
if (!existsSync34(filePath)) {
|
|
47271
47716
|
if (typeof opts.mode === "number") {
|
|
47272
47717
|
writeFileSync10(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
47273
47718
|
} else {
|
|
@@ -47288,11 +47733,11 @@ async function withLock2(filePath, transform2, opts = {}) {
|
|
|
47288
47733
|
}
|
|
47289
47734
|
}
|
|
47290
47735
|
async function withFileLock(filePath, operation) {
|
|
47291
|
-
const dir =
|
|
47292
|
-
if (!
|
|
47736
|
+
const dir = dirname21(filePath);
|
|
47737
|
+
if (!existsSync34(dir)) {
|
|
47293
47738
|
mkdirSync10(dir, { recursive: true });
|
|
47294
47739
|
}
|
|
47295
|
-
if (!
|
|
47740
|
+
if (!existsSync34(filePath)) {
|
|
47296
47741
|
writeFileSync10(filePath, "", "utf-8");
|
|
47297
47742
|
}
|
|
47298
47743
|
let release;
|
|
@@ -47326,7 +47771,7 @@ var init_file_utils = __esm({
|
|
|
47326
47771
|
|
|
47327
47772
|
// packages/core/src/llm/credential-removal.ts
|
|
47328
47773
|
import { unlinkSync as unlinkSync7 } from "node:fs";
|
|
47329
|
-
import { join as
|
|
47774
|
+
import { join as join39 } from "node:path";
|
|
47330
47775
|
import { getCleoHome as getCleoHome4 } from "@cleocode/paths";
|
|
47331
47776
|
function buildBuiltinRemovalRegistry() {
|
|
47332
47777
|
const registry2 = new RemovalRegistry();
|
|
@@ -47418,7 +47863,7 @@ var init_credential_removal = __esm({
|
|
|
47418
47863
|
sourceId: "cleo-pkce",
|
|
47419
47864
|
description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
|
|
47420
47865
|
async remove() {
|
|
47421
|
-
const path =
|
|
47866
|
+
const path = join39(getCleoHome4(), "anthropic-oauth.json");
|
|
47422
47867
|
const cleaned = [];
|
|
47423
47868
|
try {
|
|
47424
47869
|
unlinkSync7(path);
|
|
@@ -47476,12 +47921,12 @@ var init_credential_removal = __esm({
|
|
|
47476
47921
|
});
|
|
47477
47922
|
|
|
47478
47923
|
// packages/core/src/llm/credential-seeders/claude-code-seeder.ts
|
|
47479
|
-
import { readFileSync as
|
|
47924
|
+
import { readFileSync as readFileSync14 } from "node:fs";
|
|
47480
47925
|
import { homedir as homedir3 } from "node:os";
|
|
47481
|
-
import { join as
|
|
47926
|
+
import { join as join40 } from "node:path";
|
|
47482
47927
|
function defaultReadCredentialFile() {
|
|
47483
47928
|
try {
|
|
47484
|
-
return
|
|
47929
|
+
return readFileSync14(join40(homedir3(), ".claude", ".credentials.json"), "utf-8");
|
|
47485
47930
|
} catch {
|
|
47486
47931
|
return null;
|
|
47487
47932
|
}
|
|
@@ -47575,14 +48020,14 @@ var init_claude_code_seeder = __esm({
|
|
|
47575
48020
|
});
|
|
47576
48021
|
|
|
47577
48022
|
// packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
|
|
47578
|
-
import { readFileSync as
|
|
47579
|
-
import { join as
|
|
48023
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
48024
|
+
import { join as join41 } from "node:path";
|
|
47580
48025
|
function defaultCleoPkcePath() {
|
|
47581
|
-
return
|
|
48026
|
+
return join41(getCleoHome(), "anthropic-oauth.json");
|
|
47582
48027
|
}
|
|
47583
48028
|
function defaultReadCredentialFile2() {
|
|
47584
48029
|
try {
|
|
47585
|
-
return
|
|
48030
|
+
return readFileSync15(defaultCleoPkcePath(), "utf-8");
|
|
47586
48031
|
} catch {
|
|
47587
48032
|
return null;
|
|
47588
48033
|
}
|
|
@@ -47649,13 +48094,13 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
47649
48094
|
});
|
|
47650
48095
|
|
|
47651
48096
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
47652
|
-
import { existsSync as
|
|
48097
|
+
import { existsSync as existsSync35, readFileSync as readFileSync16 } from "node:fs";
|
|
47653
48098
|
import { homedir as homedir4 } from "node:os";
|
|
47654
|
-
import { join as
|
|
48099
|
+
import { join as join42 } from "node:path";
|
|
47655
48100
|
function getCodexAuthPath() {
|
|
47656
48101
|
const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
|
|
47657
|
-
const root = codexHome ||
|
|
47658
|
-
return
|
|
48102
|
+
const root = codexHome || join42(homedir4(), ".codex");
|
|
48103
|
+
return join42(root, "auth.json");
|
|
47659
48104
|
}
|
|
47660
48105
|
var CodexCliSeeder, codexCliSeeder;
|
|
47661
48106
|
var init_codex_cli_seeder = __esm({
|
|
@@ -47674,12 +48119,12 @@ var init_codex_cli_seeder = __esm({
|
|
|
47674
48119
|
*/
|
|
47675
48120
|
async seed() {
|
|
47676
48121
|
const authPath = getCodexAuthPath();
|
|
47677
|
-
if (!
|
|
48122
|
+
if (!existsSync35(authPath)) {
|
|
47678
48123
|
return { entries: [] };
|
|
47679
48124
|
}
|
|
47680
48125
|
let raw;
|
|
47681
48126
|
try {
|
|
47682
|
-
raw =
|
|
48127
|
+
raw = readFileSync16(authPath, "utf-8");
|
|
47683
48128
|
} catch (err) {
|
|
47684
48129
|
return {
|
|
47685
48130
|
entries: [],
|
|
@@ -47869,11 +48314,11 @@ var init_google_pkce = __esm({
|
|
|
47869
48314
|
});
|
|
47870
48315
|
|
|
47871
48316
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
47872
|
-
import { existsSync as
|
|
47873
|
-
import { join as
|
|
48317
|
+
import { existsSync as existsSync36, readFileSync as readFileSync17 } from "node:fs";
|
|
48318
|
+
import { join as join43 } from "node:path";
|
|
47874
48319
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
47875
48320
|
function getGoogleOauthPath() {
|
|
47876
|
-
return
|
|
48321
|
+
return join43(getCleoHome5(), "google_oauth.json");
|
|
47877
48322
|
}
|
|
47878
48323
|
function parseGoogleOauthFile(raw) {
|
|
47879
48324
|
let json2;
|
|
@@ -47918,12 +48363,12 @@ var init_gemini_cli_seeder = __esm({
|
|
|
47918
48363
|
*/
|
|
47919
48364
|
async seed() {
|
|
47920
48365
|
const path = getGoogleOauthPath();
|
|
47921
|
-
if (!
|
|
48366
|
+
if (!existsSync36(path)) {
|
|
47922
48367
|
return { entries: [] };
|
|
47923
48368
|
}
|
|
47924
48369
|
let raw;
|
|
47925
48370
|
try {
|
|
47926
|
-
raw =
|
|
48371
|
+
raw = readFileSync17(path, "utf-8");
|
|
47927
48372
|
} catch (err) {
|
|
47928
48373
|
return {
|
|
47929
48374
|
entries: [],
|
|
@@ -48143,23 +48588,23 @@ var init_credential_seeders = __esm({
|
|
|
48143
48588
|
|
|
48144
48589
|
// packages/core/src/llm/global-config-migration.ts
|
|
48145
48590
|
import {
|
|
48146
|
-
existsSync as
|
|
48591
|
+
existsSync as existsSync37,
|
|
48147
48592
|
mkdirSync as mkdirSync11,
|
|
48148
|
-
readFileSync as
|
|
48593
|
+
readFileSync as readFileSync18,
|
|
48149
48594
|
renameSync as renameSync12,
|
|
48150
48595
|
unlinkSync as unlinkSync8,
|
|
48151
48596
|
writeFileSync as writeFileSync11
|
|
48152
48597
|
} from "node:fs";
|
|
48153
|
-
import { join as
|
|
48598
|
+
import { join as join44 } from "node:path";
|
|
48154
48599
|
import { getCleoHome as getCleoHome6, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
|
|
48155
48600
|
function configDirGlobalConfigPath() {
|
|
48156
|
-
return
|
|
48601
|
+
return join44(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
|
|
48157
48602
|
}
|
|
48158
48603
|
function legacyGlobalConfigPath() {
|
|
48159
|
-
return
|
|
48604
|
+
return join44(getCleoHome6(), GLOBAL_CONFIG_FILENAME);
|
|
48160
48605
|
}
|
|
48161
48606
|
function migrationMarkerPath() {
|
|
48162
|
-
return
|
|
48607
|
+
return join44(getCleoHome6(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
|
|
48163
48608
|
}
|
|
48164
48609
|
function tempTargetPath() {
|
|
48165
48610
|
return `${configDirGlobalConfigPath()}.tmp`;
|
|
@@ -48169,17 +48614,17 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
48169
48614
|
const source = legacyGlobalConfigPath();
|
|
48170
48615
|
const target = configDirGlobalConfigPath();
|
|
48171
48616
|
const marker16 = migrationMarkerPath();
|
|
48172
|
-
if (
|
|
48173
|
-
if (!
|
|
48617
|
+
if (existsSync37(marker16)) return false;
|
|
48618
|
+
if (!existsSync37(source)) {
|
|
48174
48619
|
stampMarker(marker16);
|
|
48175
48620
|
return false;
|
|
48176
48621
|
}
|
|
48177
|
-
if (
|
|
48622
|
+
if (existsSync37(target)) {
|
|
48178
48623
|
backupSourceQuiet(source);
|
|
48179
48624
|
stampMarker(marker16);
|
|
48180
48625
|
return false;
|
|
48181
48626
|
}
|
|
48182
|
-
const raw =
|
|
48627
|
+
const raw = readFileSync18(source, "utf-8");
|
|
48183
48628
|
try {
|
|
48184
48629
|
JSON.parse(raw);
|
|
48185
48630
|
} catch (err) {
|
|
@@ -48207,7 +48652,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
48207
48652
|
} catch (err) {
|
|
48208
48653
|
try {
|
|
48209
48654
|
const temp = tempTargetPath();
|
|
48210
|
-
if (
|
|
48655
|
+
if (existsSync37(temp)) unlinkSync8(temp);
|
|
48211
48656
|
} catch {
|
|
48212
48657
|
}
|
|
48213
48658
|
console.error(
|
|
@@ -48218,7 +48663,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
48218
48663
|
}
|
|
48219
48664
|
function stampMarker(markerPath) {
|
|
48220
48665
|
try {
|
|
48221
|
-
mkdirSync11(
|
|
48666
|
+
mkdirSync11(join44(getCleoHome6(), MIGRATIONS_SUBDIR), { recursive: true });
|
|
48222
48667
|
writeFileSync11(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
48223
48668
|
`, { mode: 420 });
|
|
48224
48669
|
} catch {
|
|
@@ -48227,7 +48672,7 @@ function stampMarker(markerPath) {
|
|
|
48227
48672
|
function backupSourceQuiet(source) {
|
|
48228
48673
|
try {
|
|
48229
48674
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
48230
|
-
if (
|
|
48675
|
+
if (existsSync37(backup)) return;
|
|
48231
48676
|
renameSync12(source, backup);
|
|
48232
48677
|
} catch {
|
|
48233
48678
|
}
|
|
@@ -48250,15 +48695,15 @@ var init_global_config_migration = __esm({
|
|
|
48250
48695
|
});
|
|
48251
48696
|
|
|
48252
48697
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
48253
|
-
import { existsSync as
|
|
48254
|
-
import { join as
|
|
48698
|
+
import { existsSync as existsSync38, readFileSync as readFileSync19, renameSync as renameSync13, writeFileSync as writeFileSync12 } from "node:fs";
|
|
48699
|
+
import { join as join45 } from "node:path";
|
|
48255
48700
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
48256
48701
|
function migrationPaths() {
|
|
48257
48702
|
const home = getCleoHome7();
|
|
48258
48703
|
return {
|
|
48259
|
-
flatPath:
|
|
48260
|
-
bakPath:
|
|
48261
|
-
markerPath:
|
|
48704
|
+
flatPath: join45(home, "anthropic-key"),
|
|
48705
|
+
bakPath: join45(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
|
|
48706
|
+
markerPath: join45(home, LEGACY_FLAT_KEY_MARKER)
|
|
48262
48707
|
};
|
|
48263
48708
|
}
|
|
48264
48709
|
function writeMarker(markerPath) {
|
|
@@ -48279,8 +48724,8 @@ function writeMarker(markerPath) {
|
|
|
48279
48724
|
}
|
|
48280
48725
|
function readFlatKey(flatPath) {
|
|
48281
48726
|
try {
|
|
48282
|
-
if (!
|
|
48283
|
-
const raw =
|
|
48727
|
+
if (!existsSync38(flatPath)) return null;
|
|
48728
|
+
const raw = readFileSync19(flatPath, "utf-8").trim();
|
|
48284
48729
|
return raw || null;
|
|
48285
48730
|
} catch (err) {
|
|
48286
48731
|
logger.warn(
|
|
@@ -48292,7 +48737,7 @@ function readFlatKey(flatPath) {
|
|
|
48292
48737
|
}
|
|
48293
48738
|
async function importLegacyFlatAnthropicKey() {
|
|
48294
48739
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
48295
|
-
if (
|
|
48740
|
+
if (existsSync38(markerPath)) {
|
|
48296
48741
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
48297
48742
|
}
|
|
48298
48743
|
let existing = null;
|
|
@@ -48309,7 +48754,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
48309
48754
|
writeMarker(markerPath);
|
|
48310
48755
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
48311
48756
|
}
|
|
48312
|
-
if (!
|
|
48757
|
+
if (!existsSync38(flatPath)) {
|
|
48313
48758
|
writeMarker(markerPath);
|
|
48314
48759
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
48315
48760
|
}
|
|
@@ -48371,15 +48816,15 @@ var init_legacy_flat_key_import = __esm({
|
|
|
48371
48816
|
});
|
|
48372
48817
|
|
|
48373
48818
|
// packages/core/src/llm/credentials.ts
|
|
48374
|
-
import { existsSync as
|
|
48375
|
-
import { join as
|
|
48819
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "node:fs";
|
|
48820
|
+
import { join as join46 } from "node:path";
|
|
48376
48821
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
48377
48822
|
function globalConfigPath() {
|
|
48378
48823
|
return configDirGlobalConfigPath();
|
|
48379
48824
|
}
|
|
48380
48825
|
function projectConfigPath(projectRoot) {
|
|
48381
48826
|
const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
|
|
48382
|
-
return
|
|
48827
|
+
return join46(projectRoot, cleoDir, "config.json");
|
|
48383
48828
|
}
|
|
48384
48829
|
function readGlobalProviderKey(provider) {
|
|
48385
48830
|
ensureGlobalConfigMigrated();
|
|
@@ -48389,9 +48834,9 @@ function readGlobalProviderKey(provider) {
|
|
|
48389
48834
|
}
|
|
48390
48835
|
function readFlatAnthropicKey() {
|
|
48391
48836
|
try {
|
|
48392
|
-
const keyFile =
|
|
48393
|
-
if (!
|
|
48394
|
-
const stored =
|
|
48837
|
+
const keyFile = join46(getCleoHome8(), "anthropic-key");
|
|
48838
|
+
if (!existsSync39(keyFile)) return null;
|
|
48839
|
+
const stored = readFileSync20(keyFile, "utf-8").trim();
|
|
48395
48840
|
return stored || null;
|
|
48396
48841
|
} catch {
|
|
48397
48842
|
return null;
|
|
@@ -48399,8 +48844,8 @@ function readFlatAnthropicKey() {
|
|
|
48399
48844
|
}
|
|
48400
48845
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
48401
48846
|
try {
|
|
48402
|
-
if (!
|
|
48403
|
-
const raw =
|
|
48847
|
+
if (!existsSync39(configFile)) return null;
|
|
48848
|
+
const raw = readFileSync20(configFile, "utf-8");
|
|
48404
48849
|
const config2 = JSON.parse(raw);
|
|
48405
48850
|
const llm = config2["llm"];
|
|
48406
48851
|
if (!llm || typeof llm !== "object") return null;
|
|
@@ -48539,16 +48984,16 @@ __export(credentials_store_exports, {
|
|
|
48539
48984
|
pickCredentialForProviderSync: () => pickCredentialForProviderSync,
|
|
48540
48985
|
removeCredential: () => removeCredential
|
|
48541
48986
|
});
|
|
48542
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
48543
|
-
import { dirname as
|
|
48987
|
+
import { chmodSync as chmodSync2, existsSync as existsSync40, mkdirSync as mkdirSync13, readFileSync as readFileSync21, statSync as statSync10, writeFileSync as writeFileSync14 } from "node:fs";
|
|
48988
|
+
import { dirname as dirname22, join as join47 } from "node:path";
|
|
48544
48989
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
48545
48990
|
function credentialsStorePath() {
|
|
48546
|
-
return
|
|
48991
|
+
return join47(getCleoHome9(), "llm-credentials.json");
|
|
48547
48992
|
}
|
|
48548
48993
|
function ensureFileInitialized(path) {
|
|
48549
|
-
if (
|
|
48550
|
-
const dir =
|
|
48551
|
-
if (!
|
|
48994
|
+
if (existsSync40(path)) return;
|
|
48995
|
+
const dir = dirname22(path);
|
|
48996
|
+
if (!existsSync40(dir)) {
|
|
48552
48997
|
mkdirSync13(dir, { recursive: true, mode: 448 });
|
|
48553
48998
|
} else {
|
|
48554
48999
|
try {
|
|
@@ -48592,7 +49037,7 @@ function readStoreSync() {
|
|
|
48592
49037
|
const path = credentialsStorePath();
|
|
48593
49038
|
let raw;
|
|
48594
49039
|
try {
|
|
48595
|
-
raw =
|
|
49040
|
+
raw = readFileSync21(path, "utf-8");
|
|
48596
49041
|
} catch {
|
|
48597
49042
|
return emptyStore();
|
|
48598
49043
|
}
|
|
@@ -49181,13 +49626,13 @@ var init_xai = __esm({
|
|
|
49181
49626
|
|
|
49182
49627
|
// packages/core/src/llm/provider-registry/loader.ts
|
|
49183
49628
|
import { readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
|
|
49184
|
-
import { join as
|
|
49629
|
+
import { join as join48 } from "node:path";
|
|
49185
49630
|
import { pathToFileURL } from "node:url";
|
|
49186
49631
|
function isPluginFile(filename) {
|
|
49187
49632
|
return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
|
|
49188
49633
|
}
|
|
49189
49634
|
function getPluginDir() {
|
|
49190
|
-
return
|
|
49635
|
+
return join48(getCleoHome(), "plugins", "model-providers");
|
|
49191
49636
|
}
|
|
49192
49637
|
async function loadOnePlugin(absPath, api) {
|
|
49193
49638
|
let mod;
|
|
@@ -49235,13 +49680,13 @@ async function scanAndLoadPlugins(pluginDir, api) {
|
|
|
49235
49680
|
}
|
|
49236
49681
|
const pluginFiles = entries.filter((name15) => !name15.startsWith(".") && isPluginFile(name15)).filter((name15) => {
|
|
49237
49682
|
try {
|
|
49238
|
-
return statSync11(
|
|
49683
|
+
return statSync11(join48(pluginDir, name15)).isFile();
|
|
49239
49684
|
} catch {
|
|
49240
49685
|
return false;
|
|
49241
49686
|
}
|
|
49242
49687
|
}).sort();
|
|
49243
49688
|
for (const filename of pluginFiles) {
|
|
49244
|
-
await loadOnePlugin(
|
|
49689
|
+
await loadOnePlugin(join48(pluginDir, filename), api);
|
|
49245
49690
|
}
|
|
49246
49691
|
}
|
|
49247
49692
|
async function runDiscovery(registerProvider2, builtins) {
|
|
@@ -49344,15 +49789,15 @@ var init_provider_registry = __esm({
|
|
|
49344
49789
|
});
|
|
49345
49790
|
|
|
49346
49791
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
49347
|
-
import { existsSync as
|
|
49348
|
-
import { join as
|
|
49792
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync9 } from "node:fs";
|
|
49793
|
+
import { join as join49 } from "node:path";
|
|
49349
49794
|
import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
|
|
49350
49795
|
function sanitize(value) {
|
|
49351
49796
|
return value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
49352
49797
|
}
|
|
49353
49798
|
function rateLimitStatePath(provider, label) {
|
|
49354
|
-
const dir =
|
|
49355
|
-
return
|
|
49799
|
+
const dir = join49(getCleoHome10(), "rate-limit-state");
|
|
49800
|
+
return join49(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
|
|
49356
49801
|
}
|
|
49357
49802
|
function parseResetFromHeaders(headers) {
|
|
49358
49803
|
const get = (k) => {
|
|
@@ -49399,8 +49844,8 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
49399
49844
|
source = "default";
|
|
49400
49845
|
}
|
|
49401
49846
|
const filePath = rateLimitStatePath(provider, label);
|
|
49402
|
-
const dir =
|
|
49403
|
-
if (!
|
|
49847
|
+
const dir = join49(getCleoHome10(), "rate-limit-state");
|
|
49848
|
+
if (!existsSync41(dir)) {
|
|
49404
49849
|
mkdirSync14(dir, { recursive: true });
|
|
49405
49850
|
}
|
|
49406
49851
|
const state = { resetAt, recordedAt: now, source };
|
|
@@ -49985,31 +50430,31 @@ var init_local_inference_probe = __esm({
|
|
|
49985
50430
|
|
|
49986
50431
|
// packages/core/src/llm/catalog-cache.ts
|
|
49987
50432
|
import {
|
|
49988
|
-
existsSync as
|
|
50433
|
+
existsSync as existsSync42,
|
|
49989
50434
|
mkdirSync as mkdirSync15,
|
|
49990
50435
|
readdirSync as readdirSync10,
|
|
49991
|
-
readFileSync as
|
|
50436
|
+
readFileSync as readFileSync22,
|
|
49992
50437
|
statSync as statSync12,
|
|
49993
50438
|
symlinkSync,
|
|
49994
50439
|
unlinkSync as unlinkSync10,
|
|
49995
50440
|
writeFileSync as writeFileSync15
|
|
49996
50441
|
} from "node:fs";
|
|
49997
|
-
import { join as
|
|
50442
|
+
import { join as join50 } from "node:path";
|
|
49998
50443
|
import { getCleoHome as getCleoHome11 } from "@cleocode/paths";
|
|
49999
50444
|
function getCatalogDir() {
|
|
50000
50445
|
if (process.env["CLEO_DATA_DIR"]) {
|
|
50001
|
-
return
|
|
50446
|
+
return join50(process.env["CLEO_DATA_DIR"], "llm-catalog");
|
|
50002
50447
|
}
|
|
50003
|
-
return
|
|
50448
|
+
return join50(getCleoHome11(), "llm-catalog");
|
|
50004
50449
|
}
|
|
50005
50450
|
function findLatestCacheFile(dir) {
|
|
50006
|
-
if (!
|
|
50007
|
-
const files = readdirSync10(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync12(
|
|
50008
|
-
return files.length > 0 ?
|
|
50451
|
+
if (!existsSync42(dir)) return null;
|
|
50452
|
+
const files = readdirSync10(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync12(join50(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
50453
|
+
return files.length > 0 ? join50(dir, files[0].name) : null;
|
|
50009
50454
|
}
|
|
50010
50455
|
function readCacheFile(filePath) {
|
|
50011
50456
|
try {
|
|
50012
|
-
const raw =
|
|
50457
|
+
const raw = readFileSync22(filePath, "utf-8");
|
|
50013
50458
|
return JSON.parse(raw);
|
|
50014
50459
|
} catch {
|
|
50015
50460
|
return null;
|
|
@@ -50788,9 +51233,9 @@ __export(catalog_resolver_exports, {
|
|
|
50788
51233
|
openCatalogAtPath: () => openCatalogAtPath,
|
|
50789
51234
|
resolveCatalogEntry: () => resolveCatalogEntry
|
|
50790
51235
|
});
|
|
50791
|
-
import { readFileSync as
|
|
50792
|
-
import { dirname as
|
|
50793
|
-
import { fileURLToPath as
|
|
51236
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
51237
|
+
import { dirname as dirname23, join as join51 } from "node:path";
|
|
51238
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
50794
51239
|
async function openCatalogAtPath(dbPath) {
|
|
50795
51240
|
const handle = await openDualScopeDbAtPath("global", dbPath);
|
|
50796
51241
|
return handle.db;
|
|
@@ -50798,9 +51243,9 @@ async function openCatalogAtPath(dbPath) {
|
|
|
50798
51243
|
function loadShippedSeed() {
|
|
50799
51244
|
if (_seed !== void 0) return _seed;
|
|
50800
51245
|
try {
|
|
50801
|
-
const thisDir =
|
|
50802
|
-
const jsonPath =
|
|
50803
|
-
_seed = JSON.parse(
|
|
51246
|
+
const thisDir = dirname23(fileURLToPath4(import.meta.url));
|
|
51247
|
+
const jsonPath = join51(thisDir, "curated-catalog.json");
|
|
51248
|
+
_seed = JSON.parse(readFileSync23(jsonPath, "utf-8"));
|
|
50804
51249
|
} catch (err) {
|
|
50805
51250
|
logger5.warn(
|
|
50806
51251
|
{ err: err instanceof Error ? err.message : String(err) },
|
|
@@ -51223,16 +51668,16 @@ var init_message_utils = __esm({
|
|
|
51223
51668
|
});
|
|
51224
51669
|
|
|
51225
51670
|
// packages/core/src/llm/model-metadata.ts
|
|
51226
|
-
import { readFileSync as
|
|
51227
|
-
import { dirname as
|
|
51228
|
-
import { fileURLToPath as
|
|
51671
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
51672
|
+
import { dirname as dirname24, join as join52 } from "node:path";
|
|
51673
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
51229
51674
|
function getCuratedTable() {
|
|
51230
51675
|
if (_curated !== void 0) {
|
|
51231
51676
|
return _curated;
|
|
51232
51677
|
}
|
|
51233
|
-
const thisDir =
|
|
51234
|
-
const jsonPath =
|
|
51235
|
-
const raw = JSON.parse(
|
|
51678
|
+
const thisDir = dirname24(fileURLToPath5(import.meta.url));
|
|
51679
|
+
const jsonPath = join52(thisDir, "curated-models.json");
|
|
51680
|
+
const raw = JSON.parse(readFileSync24(jsonPath, "utf-8"));
|
|
51236
51681
|
_curated = raw.models;
|
|
51237
51682
|
return _curated;
|
|
51238
51683
|
}
|
|
@@ -51311,7 +51756,7 @@ function storedToResolved(stored) {
|
|
|
51311
51756
|
};
|
|
51312
51757
|
}
|
|
51313
51758
|
function sleep3(ms) {
|
|
51314
|
-
return new Promise((
|
|
51759
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
51315
51760
|
}
|
|
51316
51761
|
function backoffMs(policy, attempt) {
|
|
51317
51762
|
const base = policy.baseDelayMs * 2 ** attempt;
|
|
@@ -55133,7 +55578,7 @@ function normalizeOllamaToolCall(tc) {
|
|
|
55133
55578
|
};
|
|
55134
55579
|
}
|
|
55135
55580
|
function sleep4(ms) {
|
|
55136
|
-
return new Promise((
|
|
55581
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
55137
55582
|
}
|
|
55138
55583
|
var OLLAMA_DEFAULT_BASE_URL, MAX_RETRIES, INITIAL_BACKOFF_MS, RETRYABLE_STATUS_CODES, OllamaTransport;
|
|
55139
55584
|
var init_ollama2 = __esm({
|
|
@@ -75647,7 +76092,7 @@ function createProviderToolFactoryWithOutputSchema({
|
|
|
75647
76092
|
supportsDeferredResults
|
|
75648
76093
|
});
|
|
75649
76094
|
}
|
|
75650
|
-
async function
|
|
76095
|
+
async function resolve16(value) {
|
|
75651
76096
|
if (typeof value === "function") {
|
|
75652
76097
|
value = value();
|
|
75653
76098
|
}
|
|
@@ -79681,14 +80126,14 @@ var init_dist4 = __esm({
|
|
|
79681
80126
|
headers
|
|
79682
80127
|
}) {
|
|
79683
80128
|
return combineHeaders(
|
|
79684
|
-
await
|
|
80129
|
+
await resolve16(this.config.headers),
|
|
79685
80130
|
headers,
|
|
79686
80131
|
betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {}
|
|
79687
80132
|
);
|
|
79688
80133
|
}
|
|
79689
80134
|
async getBetasFromHeaders(requestHeaders) {
|
|
79690
80135
|
var _a17, _b16;
|
|
79691
|
-
const configHeaders = await
|
|
80136
|
+
const configHeaders = await resolve16(this.config.headers);
|
|
79692
80137
|
const configBetaHeader = (_a17 = configHeaders["anthropic-beta"]) != null ? _a17 : "";
|
|
79693
80138
|
const requestBetaHeader = (_b16 = requestHeaders == null ? void 0 : requestHeaders["anthropic-beta"]) != null ? _b16 : "";
|
|
79694
80139
|
return new Set(
|
|
@@ -83276,7 +83721,7 @@ var init_model_runner = __esm({
|
|
|
83276
83721
|
|
|
83277
83722
|
// packages/core/src/selfimprove/fix-gen.ts
|
|
83278
83723
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16 } from "node:fs";
|
|
83279
|
-
import { dirname as
|
|
83724
|
+
import { dirname as dirname25, join as join53, resolve as resolvePath2 } from "node:path";
|
|
83280
83725
|
import { cwd as processCwd } from "node:process";
|
|
83281
83726
|
|
|
83282
83727
|
// packages/utils/src/redact.ts
|
|
@@ -83540,7 +83985,7 @@ var FIXGEN_SYSTEM = "task-executor";
|
|
|
83540
83985
|
var UNIFIED_DIFF_MARKERS = ["diff --git ", "--- ", "+++ ", "@@ "];
|
|
83541
83986
|
function fixPatchPath(scenario, cwd) {
|
|
83542
83987
|
const safeScenario = scenario.replace(/[^a-z0-9-]/gi, "-");
|
|
83543
|
-
return resolvePath2(cwd ?? processCwd(),
|
|
83988
|
+
return resolvePath2(cwd ?? processCwd(), join53(".cleo", "selfimprove", `${safeScenario}.patch`));
|
|
83544
83989
|
}
|
|
83545
83990
|
function looksLikeUnifiedDiff(text2) {
|
|
83546
83991
|
if (text2.trim().length === 0) return false;
|
|
@@ -83625,7 +84070,7 @@ async function generateFixPatch(opts) {
|
|
|
83625
84070
|
}
|
|
83626
84071
|
const diff = output.diff.endsWith("\n") ? output.diff : `${output.diff}
|
|
83627
84072
|
`;
|
|
83628
|
-
mkdirSync16(
|
|
84073
|
+
mkdirSync16(dirname25(patchPath), { recursive: true });
|
|
83629
84074
|
writeFileSync16(patchPath, diff, "utf8");
|
|
83630
84075
|
const bytes = Buffer.byteLength(diff, "utf8");
|
|
83631
84076
|
logger8.info(
|