@cleocode/core 2026.9.22 → 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/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/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/export-document.js +775 -415
- package/dist/docs/export-document.js.map +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- 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/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +886 -526
- package/dist/llm/plugin-facade.js.map +3 -3
- 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/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/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 +3 -0
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestration/lead-rollup.js +14 -2
- 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/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/project-scope.d.ts +16 -0
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +38 -2
- package/dist/project-scope.js.map +1 -1
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +2 -1
- package/dist/release/github-pr.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/selfimprove/fix-gen.js +895 -535
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +23 -62
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +6 -1
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +5 -2
- package/dist/sessions/focus-state-store.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/prune-bundled.d.ts +40 -1
- package/dist/skills/prune-bundled.d.ts.map +1 -1
- package/dist/skills/prune-bundled.js +117 -1
- package/dist/skills/prune-bundled.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/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.js +7 -0
- 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.map +1 -1
- package/dist/store/sqlite.js +5 -0
- package/dist/store/sqlite.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 +67 -1
- 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/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/tasks/affected-packages.d.ts +5 -1
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +21 -3
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/analyze.d.ts +29 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +45 -34
- 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.map +1 -1
- package/dist/tasks/change-set.js +16 -3
- 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/component-pr.d.ts.map +1 -1
- package/dist/tasks/component-pr.js +97 -12
- package/dist/tasks/component-pr.js.map +1 -1
- 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/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 +2 -0
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +30 -4
- 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 +44 -2
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +80 -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/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
|
@@ -344,7 +344,7 @@ var init_acceptance_gate_schema = __esm({
|
|
|
344
344
|
message: "Result cannot precede input capture"
|
|
345
345
|
});
|
|
346
346
|
const executable = ["test", "command", "lint"].includes(result.kind);
|
|
347
|
-
if (executable && !binding.invocation)
|
|
347
|
+
if (executable && !binding.invocation && result.result !== "error")
|
|
348
348
|
context.addIssue({
|
|
349
349
|
code: "custom",
|
|
350
350
|
path: ["binding", "invocation"],
|
|
@@ -3086,12 +3086,21 @@ var init_operations_registry = __esm({
|
|
|
3086
3086
|
gateway: "query",
|
|
3087
3087
|
domain: "tasks",
|
|
3088
3088
|
operation: "history",
|
|
3089
|
-
description: "Show task work history
|
|
3089
|
+
description: "Show task work history; with taskId, the task audit trail; with ranking, who changed its priority/severity/kind/depends and why (T12693)",
|
|
3090
3090
|
tier: 1,
|
|
3091
3091
|
idempotent: true,
|
|
3092
3092
|
sessionRequired: false,
|
|
3093
3093
|
requiredParams: [],
|
|
3094
|
-
params: [
|
|
3094
|
+
params: [
|
|
3095
|
+
{ name: "taskId", type: "string", required: false, description: "Task to show history for" },
|
|
3096
|
+
{ name: "limit", type: "number", required: false, description: "Maximum entries" },
|
|
3097
|
+
{
|
|
3098
|
+
name: "ranking",
|
|
3099
|
+
type: "boolean",
|
|
3100
|
+
required: false,
|
|
3101
|
+
description: "Only ranking-input changes (actor, session, reason, before/after)"
|
|
3102
|
+
}
|
|
3103
|
+
]
|
|
3095
3104
|
},
|
|
3096
3105
|
{
|
|
3097
3106
|
gateway: "query",
|
|
@@ -5586,6 +5595,32 @@ var init_operations_registry = __esm({
|
|
|
5586
5595
|
],
|
|
5587
5596
|
outputSchema: OUTPUT_CONTRACTS["tasks.assignee"]
|
|
5588
5597
|
},
|
|
5598
|
+
{
|
|
5599
|
+
gateway: "mutate",
|
|
5600
|
+
domain: "tasks",
|
|
5601
|
+
operation: "ranking.revert",
|
|
5602
|
+
description: "tasks.ranking.revert (mutate) \u2014 undo one recorded ranking change (priority/severity/kind/depends) as a new audited change (T12693, D11161)",
|
|
5603
|
+
tier: 1,
|
|
5604
|
+
idempotent: false,
|
|
5605
|
+
sessionRequired: false,
|
|
5606
|
+
requiredParams: ["entryId"],
|
|
5607
|
+
params: [
|
|
5608
|
+
{
|
|
5609
|
+
name: "entryId",
|
|
5610
|
+
type: "string",
|
|
5611
|
+
required: true,
|
|
5612
|
+
description: "ranking_changed audit row id (cleo history ranking <taskId>)",
|
|
5613
|
+
cli: { positional: true }
|
|
5614
|
+
},
|
|
5615
|
+
{ name: "reason", type: "string", required: false, description: "Why it is reverted" },
|
|
5616
|
+
{
|
|
5617
|
+
name: "force",
|
|
5618
|
+
type: "boolean",
|
|
5619
|
+
required: false,
|
|
5620
|
+
description: "Revert even though a field changed again since"
|
|
5621
|
+
}
|
|
5622
|
+
]
|
|
5623
|
+
},
|
|
5589
5624
|
{
|
|
5590
5625
|
gateway: "mutate",
|
|
5591
5626
|
domain: "tasks",
|
|
@@ -13053,7 +13088,10 @@ var init_evidence_atom_schema = __esm({
|
|
|
13053
13088
|
["commit", "note"],
|
|
13054
13089
|
["decision", "files"],
|
|
13055
13090
|
["decision", "note"],
|
|
13056
|
-
["pr", "files"]
|
|
13091
|
+
["pr", "files"],
|
|
13092
|
+
// T12689: a deletion-only PR (no bytes to hash). Contextual validation
|
|
13093
|
+
// accepts this only when every change the PR made is a deletion.
|
|
13094
|
+
["pr", "note"]
|
|
13057
13095
|
]
|
|
13058
13096
|
},
|
|
13059
13097
|
testsPassed: { oneOf: [["test-run"], ["tool"], ["ci"]] },
|
|
@@ -16955,7 +16993,7 @@ var init_collection_keys = __esm({
|
|
|
16955
16993
|
|
|
16956
16994
|
// packages/contracts/src/decide.ts
|
|
16957
16995
|
import { z as z24 } from "zod";
|
|
16958
|
-
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;
|
|
16996
|
+
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;
|
|
16959
16997
|
var init_decide = __esm({
|
|
16960
16998
|
"packages/contracts/src/decide.ts"() {
|
|
16961
16999
|
"use strict";
|
|
@@ -16979,6 +17017,7 @@ var init_decide = __esm({
|
|
|
16979
17017
|
/** Maximum number of levels on a `score` question's scale. */
|
|
16980
17018
|
maxScoreLevels: 10
|
|
16981
17019
|
};
|
|
17020
|
+
DECISION_PROVIDER_KINDS = ["layahost", "jev"];
|
|
16982
17021
|
decisionQuestionTypeSchema = z24.enum(DECISION_QUESTION_TYPES);
|
|
16983
17022
|
decisionOutcomeSourceSchema = z24.enum(DECISION_OUTCOME_SOURCES);
|
|
16984
17023
|
decisionInstructionsSchema = z24.union([z24.string(), z24.record(z24.string(), z24.json())]);
|
|
@@ -17016,6 +17055,8 @@ var init_decide = __esm({
|
|
|
17016
17055
|
]);
|
|
17017
17056
|
decisionRequestSchema = z24.object({
|
|
17018
17057
|
model: z24.string().min(1).optional(),
|
|
17058
|
+
lang: z24.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/).optional(),
|
|
17059
|
+
cache: z24.boolean().optional(),
|
|
17019
17060
|
state: decisionStateSchema,
|
|
17020
17061
|
questions: z24.record(z24.string().min(1), decisionQuestionSchema).refine(
|
|
17021
17062
|
(questions) => {
|
|
@@ -17056,14 +17097,26 @@ var init_decide = __esm({
|
|
|
17056
17097
|
requestId: z24.string().min(1).optional(),
|
|
17057
17098
|
latencyMs: z24.number().nonnegative(),
|
|
17058
17099
|
costUsd: z24.number().nonnegative().optional(),
|
|
17100
|
+
costMicros: z24.number().int().nonnegative().optional(),
|
|
17101
|
+
balanceMicros: z24.number().int().optional(),
|
|
17102
|
+
checkpoint: z24.string().min(1).optional(),
|
|
17059
17103
|
inputTokens: z24.number().int().nonnegative().optional()
|
|
17060
17104
|
});
|
|
17105
|
+
decisionProviderKindSchema = z24.enum(DECISION_PROVIDER_KINDS);
|
|
17061
17106
|
decisionProviderConfigSchema = z24.object({
|
|
17062
|
-
baseUrl: z24.url()
|
|
17107
|
+
baseUrl: z24.url(),
|
|
17108
|
+
provider: decisionProviderKindSchema.optional()
|
|
17063
17109
|
});
|
|
17064
17110
|
}
|
|
17065
17111
|
});
|
|
17066
17112
|
|
|
17113
|
+
// packages/contracts/src/decide-sites.ts
|
|
17114
|
+
var init_decide_sites = __esm({
|
|
17115
|
+
"packages/contracts/src/decide-sites.ts"() {
|
|
17116
|
+
"use strict";
|
|
17117
|
+
}
|
|
17118
|
+
});
|
|
17119
|
+
|
|
17067
17120
|
// packages/contracts/src/task-id.ts
|
|
17068
17121
|
var init_task_id = __esm({
|
|
17069
17122
|
"packages/contracts/src/task-id.ts"() {
|
|
@@ -17145,6 +17198,7 @@ var init_src = __esm({
|
|
|
17145
17198
|
init_caamp_markers();
|
|
17146
17199
|
init_collection_keys();
|
|
17147
17200
|
init_decide();
|
|
17201
|
+
init_decide_sites();
|
|
17148
17202
|
init_task_id();
|
|
17149
17203
|
}
|
|
17150
17204
|
});
|
|
@@ -18644,7 +18698,10 @@ function linkedWorktreeMainRoot(dir) {
|
|
|
18644
18698
|
}
|
|
18645
18699
|
function describeWorktreeOwner(dir) {
|
|
18646
18700
|
const mainRoot = linkedWorktreeMainRoot(dir);
|
|
18647
|
-
if (mainRoot === null)
|
|
18701
|
+
if (mainRoot === null) {
|
|
18702
|
+
const bare = bareRepositoryOfWorktree(dir);
|
|
18703
|
+
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`;
|
|
18704
|
+
}
|
|
18648
18705
|
let projectId = null;
|
|
18649
18706
|
try {
|
|
18650
18707
|
const parsed = JSON.parse(
|
|
@@ -18658,6 +18715,18 @@ function describeWorktreeOwner(dir) {
|
|
|
18658
18715
|
}
|
|
18659
18716
|
return projectId === null ? `owning repository ${mainRoot} (not an initialised CLEO project)` : `owning project ${mainRoot} (projectId ${projectId})`;
|
|
18660
18717
|
}
|
|
18718
|
+
function bareRepositoryOfWorktree(dir) {
|
|
18719
|
+
const gitdir = readGitlinkTarget(dir);
|
|
18720
|
+
if (!gitdir || basename2(dirname2(gitdir)) !== "worktrees") return null;
|
|
18721
|
+
const commonDir = dirname2(dirname2(gitdir));
|
|
18722
|
+
try {
|
|
18723
|
+
const config = readFileSync2(join3(commonDir, "config"), "utf-8");
|
|
18724
|
+
const core = /^\[core\][^[]*/m.exec(config)?.[0] ?? "";
|
|
18725
|
+
return /^\s*bare\s*=\s*true\s*$/im.test(core) ? commonDir : null;
|
|
18726
|
+
} catch {
|
|
18727
|
+
return null;
|
|
18728
|
+
}
|
|
18729
|
+
}
|
|
18661
18730
|
function readCoreWorktree(gitDir) {
|
|
18662
18731
|
try {
|
|
18663
18732
|
const config = readFileSync2(join3(gitDir, "config"), "utf-8");
|
|
@@ -19107,13 +19176,13 @@ function captureWriteFence(input) {
|
|
|
19107
19176
|
return writeFence;
|
|
19108
19177
|
}
|
|
19109
19178
|
function observeOperation(context, work) {
|
|
19110
|
-
return new Promise((
|
|
19179
|
+
return new Promise((resolve16) => {
|
|
19111
19180
|
let observed = false;
|
|
19112
19181
|
const finish = (result) => {
|
|
19113
19182
|
if (observed) return;
|
|
19114
19183
|
observed = true;
|
|
19115
19184
|
context.signal.removeEventListener("abort", abort);
|
|
19116
|
-
|
|
19185
|
+
resolve16(result);
|
|
19117
19186
|
};
|
|
19118
19187
|
const abort = () => {
|
|
19119
19188
|
const reason = context.signal.reason;
|
|
@@ -19747,7 +19816,7 @@ var init_sql = __esm({
|
|
|
19747
19816
|
return new SQL([new StringChunk(str)]);
|
|
19748
19817
|
}
|
|
19749
19818
|
_sql.raw = raw;
|
|
19750
|
-
function
|
|
19819
|
+
function join36(chunks, separator) {
|
|
19751
19820
|
const result = [];
|
|
19752
19821
|
for (const [i, chunk] of chunks.entries()) {
|
|
19753
19822
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -19755,7 +19824,7 @@ var init_sql = __esm({
|
|
|
19755
19824
|
}
|
|
19756
19825
|
return new SQL(result);
|
|
19757
19826
|
}
|
|
19758
|
-
_sql.join =
|
|
19827
|
+
_sql.join = join36;
|
|
19759
19828
|
function identifier2(value) {
|
|
19760
19829
|
return new Name(value);
|
|
19761
19830
|
}
|
|
@@ -21770,7 +21839,7 @@ var init_select = __esm({
|
|
|
21770
21839
|
const baseTableName = this.tableName;
|
|
21771
21840
|
const tableName = getTableLikeName(table);
|
|
21772
21841
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
21773
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
21842
|
+
if (typeof tableName === "string" && this.config.joins?.some((join36) => join36.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
21774
21843
|
if (!this.isPartialSelect) {
|
|
21775
21844
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
21776
21845
|
if (typeof tableName === "string" && !is(table, SQL)) {
|
|
@@ -23367,7 +23436,7 @@ var init_dialect = __esm({
|
|
|
23367
23436
|
if (!joins2) return;
|
|
23368
23437
|
const withEntries = Object.entries(joins2).filter(([_, v]) => v);
|
|
23369
23438
|
if (!withEntries.length) return;
|
|
23370
|
-
return sql.join(withEntries.map(([k,
|
|
23439
|
+
return sql.join(withEntries.map(([k, join36]) => {
|
|
23371
23440
|
const relation = tableConfig.relations[k];
|
|
23372
23441
|
const isSingle2 = is(relation, One);
|
|
23373
23442
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -23378,7 +23447,7 @@ var init_dialect = __esm({
|
|
|
23378
23447
|
table: targetTable,
|
|
23379
23448
|
mode: isSingle2 ? "first" : "many",
|
|
23380
23449
|
schema,
|
|
23381
|
-
queryConfig:
|
|
23450
|
+
queryConfig: join36,
|
|
23382
23451
|
tableConfig: schema[relation.targetTableName],
|
|
23383
23452
|
relationWhere: filter,
|
|
23384
23453
|
isNested: true,
|
|
@@ -23392,7 +23461,7 @@ var init_dialect = __esm({
|
|
|
23392
23461
|
key: k,
|
|
23393
23462
|
selection: innerQuery.selection,
|
|
23394
23463
|
isArray: !isSingle2,
|
|
23395
|
-
isOptional: (relation.optional ?? false) ||
|
|
23464
|
+
isOptional: (relation.optional ?? false) || join36 !== true && !!join36.where
|
|
23396
23465
|
});
|
|
23397
23466
|
const jsonColumns = sql.join(innerQuery.selection.map((s) => {
|
|
23398
23467
|
return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
|
|
@@ -23814,7 +23883,7 @@ var init_update = __esm({
|
|
|
23814
23883
|
createJoin(joinType) {
|
|
23815
23884
|
return ((table, on) => {
|
|
23816
23885
|
const tableName = getTableLikeName(table);
|
|
23817
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
23886
|
+
if (typeof tableName === "string" && this.config.joins.some((join36) => join36.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
23818
23887
|
if (typeof on === "function") {
|
|
23819
23888
|
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;
|
|
23820
23889
|
on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -24970,7 +25039,7 @@ async function withWriteRetry(fn, opts = {}) {
|
|
|
24970
25039
|
throw contentionErr;
|
|
24971
25040
|
}
|
|
24972
25041
|
function sleep(ms) {
|
|
24973
|
-
return new Promise((
|
|
25042
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
24974
25043
|
}
|
|
24975
25044
|
var DEFAULT_MAX_ATTEMPTS, DEFAULT_BASE_DELAY_MS, DEFAULT_JITTER_MS;
|
|
24976
25045
|
var init_with_retry = __esm({
|
|
@@ -24982,9 +25051,250 @@ var init_with_retry = __esm({
|
|
|
24982
25051
|
}
|
|
24983
25052
|
});
|
|
24984
25053
|
|
|
25054
|
+
// packages/core/src/store/worktree-build-guard.ts
|
|
25055
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, realpathSync as realpathSync3 } from "node:fs";
|
|
25056
|
+
import { createRequire } from "node:module";
|
|
25057
|
+
import { dirname as dirname3, isAbsolute as isAbsolute3, join as join5, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
|
|
25058
|
+
import { fileURLToPath } from "node:url";
|
|
25059
|
+
function realOrResolved(path2) {
|
|
25060
|
+
try {
|
|
25061
|
+
return realpathSync3(path2);
|
|
25062
|
+
} catch {
|
|
25063
|
+
return resolve2(path2);
|
|
25064
|
+
}
|
|
25065
|
+
}
|
|
25066
|
+
function isWithin(root, path2) {
|
|
25067
|
+
const local = relative2(root, path2);
|
|
25068
|
+
return local === "" || !isAbsolute3(local) && local !== ".." && !local.startsWith(`..${sep2}`);
|
|
25069
|
+
}
|
|
25070
|
+
function insideGitCheckout(dir) {
|
|
25071
|
+
let current = dir;
|
|
25072
|
+
for (; ; ) {
|
|
25073
|
+
if (existsSync4(join5(current, ".git"))) return true;
|
|
25074
|
+
const parent = dirname3(current);
|
|
25075
|
+
if (parent === current) return false;
|
|
25076
|
+
current = parent;
|
|
25077
|
+
}
|
|
25078
|
+
}
|
|
25079
|
+
function insideTestSandbox(path2) {
|
|
25080
|
+
let dir = dirname3(path2);
|
|
25081
|
+
for (; ; ) {
|
|
25082
|
+
if (existsSync4(join5(dir, TEST_SANDBOX_MARKER))) return !insideGitCheckout(dir);
|
|
25083
|
+
const parent = dirname3(dir);
|
|
25084
|
+
if (parent === dir) return false;
|
|
25085
|
+
dir = parent;
|
|
25086
|
+
}
|
|
25087
|
+
}
|
|
25088
|
+
function linkedWorktreeRootOf(path2) {
|
|
25089
|
+
let dir = realOrResolved(path2);
|
|
25090
|
+
for (; ; ) {
|
|
25091
|
+
if (isGitLinkedCheckout(dir)) return dir;
|
|
25092
|
+
if (existsSync4(join5(dir, ".git"))) return null;
|
|
25093
|
+
const parent = dirname3(dir);
|
|
25094
|
+
if (parent === dir) return null;
|
|
25095
|
+
dir = parent;
|
|
25096
|
+
}
|
|
25097
|
+
}
|
|
25098
|
+
function readBuildProvenance(codePath) {
|
|
25099
|
+
let dir = dirname3(codePath);
|
|
25100
|
+
for (; ; ) {
|
|
25101
|
+
const stamp = join5(dir, "build-provenance.json");
|
|
25102
|
+
if (existsSync4(stamp)) {
|
|
25103
|
+
try {
|
|
25104
|
+
const parsed = JSON.parse(readFileSync3(stamp, "utf8"));
|
|
25105
|
+
if (typeof parsed === "object" && parsed !== null && "linkedWorktree" in parsed) {
|
|
25106
|
+
const value = parsed.linkedWorktree;
|
|
25107
|
+
if (value === null || typeof value === "string") return { linkedWorktree: value };
|
|
25108
|
+
}
|
|
25109
|
+
} catch {
|
|
25110
|
+
}
|
|
25111
|
+
return null;
|
|
25112
|
+
}
|
|
25113
|
+
if (existsSync4(join5(dir, "package.json"))) return null;
|
|
25114
|
+
const parent = dirname3(dir);
|
|
25115
|
+
if (parent === dir) return null;
|
|
25116
|
+
dir = parent;
|
|
25117
|
+
}
|
|
25118
|
+
}
|
|
25119
|
+
function devBuildWorktree(options = {}) {
|
|
25120
|
+
const codePath = options.codePath ?? overrides?.codePath ?? fileURLToPath(import.meta.url);
|
|
25121
|
+
const provenance = options.provenance !== void 0 ? options.provenance : overrides?.provenance !== void 0 ? overrides.provenance : readBuildProvenance(codePath);
|
|
25122
|
+
if (provenance) return provenance.linkedWorktree;
|
|
25123
|
+
if (codePath.split(/[\\/]/).includes("node_modules")) return null;
|
|
25124
|
+
return linkedWorktreeRootOf(codePath);
|
|
25125
|
+
}
|
|
25126
|
+
function schemaWriteRefusal(dbPath, options = {}) {
|
|
25127
|
+
const env = options.env ?? overrides?.env ?? process.env;
|
|
25128
|
+
const buildWorktree = devBuildWorktree(options);
|
|
25129
|
+
if (buildWorktree === null) return null;
|
|
25130
|
+
const store = realOrResolved(dbPath);
|
|
25131
|
+
if (isWithin(realOrResolved(buildWorktree), store)) return null;
|
|
25132
|
+
if (env["VITEST"]) return null;
|
|
25133
|
+
const honourTestSandbox = options.honourTestSandbox ?? overrides?.honourTestSandbox ?? true;
|
|
25134
|
+
if (honourTestSandbox && insideTestSandbox(store)) return null;
|
|
25135
|
+
if (env[ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV] === "1") return null;
|
|
25136
|
+
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).`;
|
|
25137
|
+
}
|
|
25138
|
+
function decisionFor(dbPath) {
|
|
25139
|
+
const key = realOrResolved(dbPath);
|
|
25140
|
+
if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
|
|
25141
|
+
return decisions.get(key) ?? null;
|
|
25142
|
+
}
|
|
25143
|
+
function isWorktreeBuildSchemaError(error) {
|
|
25144
|
+
return error instanceof Error && error.message.includes(E_WORKTREE_BUILD_SCHEMA);
|
|
25145
|
+
}
|
|
25146
|
+
function codes() {
|
|
25147
|
+
if (authorizerCodes) return authorizerCodes;
|
|
25148
|
+
const sqlite = createRequire(import.meta.url)("node:sqlite").constants;
|
|
25149
|
+
authorizerCodes = {
|
|
25150
|
+
sqlite,
|
|
25151
|
+
creates: /* @__PURE__ */ new Map([
|
|
25152
|
+
[sqlite.SQLITE_CREATE_TABLE, "table"],
|
|
25153
|
+
[sqlite.SQLITE_CREATE_VTABLE, "table"],
|
|
25154
|
+
[sqlite.SQLITE_CREATE_INDEX, "index"],
|
|
25155
|
+
[sqlite.SQLITE_CREATE_TRIGGER, "trigger"],
|
|
25156
|
+
[sqlite.SQLITE_CREATE_VIEW, "view"]
|
|
25157
|
+
]),
|
|
25158
|
+
changes: /* @__PURE__ */ new Set([
|
|
25159
|
+
sqlite.SQLITE_ALTER_TABLE,
|
|
25160
|
+
sqlite.SQLITE_DROP_TABLE,
|
|
25161
|
+
sqlite.SQLITE_DROP_INDEX,
|
|
25162
|
+
sqlite.SQLITE_DROP_TRIGGER,
|
|
25163
|
+
sqlite.SQLITE_DROP_VIEW,
|
|
25164
|
+
sqlite.SQLITE_DROP_VTABLE
|
|
25165
|
+
])
|
|
25166
|
+
};
|
|
25167
|
+
return authorizerCodes;
|
|
25168
|
+
}
|
|
25169
|
+
function attachRefusal(name2) {
|
|
25170
|
+
if (name2 === "" || name2 === ":memory:") return null;
|
|
25171
|
+
if (typeof name2 !== "string" || /^file:/i.test(name2) || name2.includes("?")) {
|
|
25172
|
+
return UNKNOWN_ATTACH_REFUSAL;
|
|
25173
|
+
}
|
|
25174
|
+
return decisionFor(name2);
|
|
25175
|
+
}
|
|
25176
|
+
function readSchemas(nativeDb) {
|
|
25177
|
+
const schemas = /* @__PURE__ */ new Map();
|
|
25178
|
+
const list = nativeDb.prepare("PRAGMA database_list").all();
|
|
25179
|
+
for (const { name: name2, file } of list) {
|
|
25180
|
+
if (name2 === "temp") continue;
|
|
25181
|
+
const rows = nativeDb.prepare(`SELECT type, name FROM "${name2.replaceAll('"', '""')}".sqlite_master`).all();
|
|
25182
|
+
schemas.set(name2.toLowerCase(), {
|
|
25183
|
+
refusal: file ? decisionFor(file) : null,
|
|
25184
|
+
// '' = in-memory
|
|
25185
|
+
objects: new Set(rows.map((r) => `${r.type}:${r.name}`))
|
|
25186
|
+
});
|
|
25187
|
+
}
|
|
25188
|
+
return schemas;
|
|
25189
|
+
}
|
|
25190
|
+
function guardActive() {
|
|
25191
|
+
const env = overrides?.env ?? process.env;
|
|
25192
|
+
if (env["VITEST"]) return false;
|
|
25193
|
+
if (overrides) return devBuildWorktree() !== null;
|
|
25194
|
+
if (processBuildWorktree === void 0) processBuildWorktree = devBuildWorktree();
|
|
25195
|
+
return processBuildWorktree !== null;
|
|
25196
|
+
}
|
|
25197
|
+
function installSchemaWriteGuard(nativeDb) {
|
|
25198
|
+
if (!guardActive()) return false;
|
|
25199
|
+
const location = nativeDb.location();
|
|
25200
|
+
const mainRefusal = location ? decisionFor(location) : null;
|
|
25201
|
+
if (typeof nativeDb.setAuthorizer !== "function") {
|
|
25202
|
+
if (mainRefusal) throw new WorktreeBuildSchemaError(mainRefusal);
|
|
25203
|
+
return false;
|
|
25204
|
+
}
|
|
25205
|
+
const state = {
|
|
25206
|
+
schemas: readSchemas(nativeDb),
|
|
25207
|
+
unmappedAttachRefusal: null,
|
|
25208
|
+
stale: false,
|
|
25209
|
+
lastDenied: null
|
|
25210
|
+
};
|
|
25211
|
+
guards.set(nativeDb, state);
|
|
25212
|
+
const { sqlite, creates, changes } = codes();
|
|
25213
|
+
nativeDb.setAuthorizer((action, arg1, arg2, dbName) => {
|
|
25214
|
+
if (action === sqlite.SQLITE_ATTACH) {
|
|
25215
|
+
const refusal2 = attachRefusal(arg1);
|
|
25216
|
+
if (refusal2 && !state.unmappedAttachRefusal) state.unmappedAttachRefusal = refusal2;
|
|
25217
|
+
return sqlite.SQLITE_OK;
|
|
25218
|
+
}
|
|
25219
|
+
if (action === sqlite.SQLITE_DETACH) {
|
|
25220
|
+
state.stale = true;
|
|
25221
|
+
return sqlite.SQLITE_OK;
|
|
25222
|
+
}
|
|
25223
|
+
const createType = creates.get(action);
|
|
25224
|
+
if (createType === void 0 && !changes.has(action)) return sqlite.SQLITE_OK;
|
|
25225
|
+
const schema = ((action === sqlite.SQLITE_ALTER_TABLE ? arg1 : dbName) ?? "main").toLowerCase();
|
|
25226
|
+
if (schema === "temp") return sqlite.SQLITE_OK;
|
|
25227
|
+
const mapped = state.schemas.get(schema);
|
|
25228
|
+
const policy = state.stale ? void 0 : mapped;
|
|
25229
|
+
const refusal = policy ? policy.refusal : (mapped?.refusal ?? null) || state.unmappedAttachRefusal;
|
|
25230
|
+
if (refusal === null) return sqlite.SQLITE_OK;
|
|
25231
|
+
if (createType !== void 0 && policy?.objects.has(`${createType}:${arg1}`)) {
|
|
25232
|
+
return sqlite.SQLITE_OK;
|
|
25233
|
+
}
|
|
25234
|
+
state.lastDenied = {
|
|
25235
|
+
what: createType !== void 0 ? `CREATE ${createType} ${schema}.${arg1}` : `schema change on ${schema}.${(action === sqlite.SQLITE_ALTER_TABLE ? arg2 : arg1) ?? ""}`,
|
|
25236
|
+
refusal
|
|
25237
|
+
};
|
|
25238
|
+
return sqlite.SQLITE_DENY;
|
|
25239
|
+
});
|
|
25240
|
+
return mainRefusal !== null;
|
|
25241
|
+
}
|
|
25242
|
+
function refreshSchemaWriteGuard(nativeDb) {
|
|
25243
|
+
const state = guards.get(nativeDb);
|
|
25244
|
+
if (!state) return;
|
|
25245
|
+
state.schemas = readSchemas(nativeDb);
|
|
25246
|
+
state.unmappedAttachRefusal = null;
|
|
25247
|
+
state.stale = false;
|
|
25248
|
+
}
|
|
25249
|
+
function explainSchemaWriteDenial(nativeDb, error) {
|
|
25250
|
+
if (!(error instanceof Error) || !/not authorized/i.test(error.message)) return error;
|
|
25251
|
+
const denied = guards.get(nativeDb)?.lastDenied;
|
|
25252
|
+
if (!denied) return error;
|
|
25253
|
+
return new WorktreeBuildSchemaError(`${denied.refusal} Denied: ${denied.what}.`);
|
|
25254
|
+
}
|
|
25255
|
+
function pendingMigrations(nativeDb, migrations) {
|
|
25256
|
+
const hasJournal = nativeDb.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '__drizzle_migrations'").get();
|
|
25257
|
+
const applied = hasJournal ? new Set(
|
|
25258
|
+
nativeDb.prepare('SELECT hash FROM main."__drizzle_migrations"').all().map((row) => row.hash)
|
|
25259
|
+
) : /* @__PURE__ */ new Set();
|
|
25260
|
+
return migrations.filter((m) => !applied.has(m.hash)).map((m) => m.name ?? m.hash);
|
|
25261
|
+
}
|
|
25262
|
+
function assertNoPendingMigrationsForWorktreeBuild(nativeDb, migrations) {
|
|
25263
|
+
const dbPath = nativeDb.location();
|
|
25264
|
+
if (!dbPath) return;
|
|
25265
|
+
const refusal = decisionFor(dbPath);
|
|
25266
|
+
if (refusal === null) return;
|
|
25267
|
+
const pending = pendingMigrations(nativeDb, migrations);
|
|
25268
|
+
if (pending.length === 0) return;
|
|
25269
|
+
throw new WorktreeBuildSchemaError(`${refusal} Pending migrations: ${pending.join(", ")}.`);
|
|
25270
|
+
}
|
|
25271
|
+
var ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV, TEST_SANDBOX_MARKER, E_WORKTREE_BUILD_SCHEMA, overrides, decisions, WorktreeBuildSchemaError, authorizerCodes, guards, UNKNOWN_ATTACH_REFUSAL, processBuildWorktree;
|
|
25272
|
+
var init_worktree_build_guard = __esm({
|
|
25273
|
+
"packages/core/src/store/worktree-build-guard.ts"() {
|
|
25274
|
+
"use strict";
|
|
25275
|
+
init_src();
|
|
25276
|
+
init_errors2();
|
|
25277
|
+
init_project_scope();
|
|
25278
|
+
ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV = "CLEO_ALLOW_WORKTREE_BUILD_MIGRATIONS";
|
|
25279
|
+
TEST_SANDBOX_MARKER = ".cleo-test-sandbox";
|
|
25280
|
+
E_WORKTREE_BUILD_SCHEMA = "E_WORKTREE_BUILD_SCHEMA";
|
|
25281
|
+
overrides = null;
|
|
25282
|
+
decisions = /* @__PURE__ */ new Map();
|
|
25283
|
+
WorktreeBuildSchemaError = class extends CleoError {
|
|
25284
|
+
constructor(message) {
|
|
25285
|
+
super(8 /* CONFIG_ERROR */, `${E_WORKTREE_BUILD_SCHEMA}: ${message}`, {
|
|
25286
|
+
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.`
|
|
25287
|
+
});
|
|
25288
|
+
}
|
|
25289
|
+
};
|
|
25290
|
+
guards = /* @__PURE__ */ new WeakMap();
|
|
25291
|
+
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";
|
|
25292
|
+
}
|
|
25293
|
+
});
|
|
25294
|
+
|
|
24985
25295
|
// packages/core/src/store/migration-manager.ts
|
|
24986
|
-
import { copyFileSync, existsSync as
|
|
24987
|
-
import { dirname as
|
|
25296
|
+
import { copyFileSync, existsSync as existsSync5 } from "node:fs";
|
|
25297
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
24988
25298
|
function stripSqlComments(sql32) {
|
|
24989
25299
|
return sql32.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
24990
25300
|
}
|
|
@@ -25023,10 +25333,10 @@ function computeEliminatedTables(migrations) {
|
|
|
25023
25333
|
return eliminated;
|
|
25024
25334
|
}
|
|
25025
25335
|
function resolveConsolidationCutoverPrefix(migrationsFolder) {
|
|
25026
|
-
const parent =
|
|
25336
|
+
const parent = dirname4(migrationsFolder);
|
|
25027
25337
|
for (const setName of ["drizzle-cleo-project", "drizzle-cleo-global"]) {
|
|
25028
|
-
const folder =
|
|
25029
|
-
if (!
|
|
25338
|
+
const folder = join6(parent, setName);
|
|
25339
|
+
if (!existsSync5(folder)) continue;
|
|
25030
25340
|
try {
|
|
25031
25341
|
const consolidation = readMigrationFiles({ migrationsFolder: folder }).find(
|
|
25032
25342
|
(m) => /-consolidation-cleo-/.test(m.name ?? "")
|
|
@@ -25050,7 +25360,7 @@ function tableExists(nativeDb, tableName) {
|
|
|
25050
25360
|
}
|
|
25051
25361
|
function createSafetyBackup(dbPath) {
|
|
25052
25362
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
25053
|
-
if (!
|
|
25363
|
+
if (!existsSync5(backupPath)) {
|
|
25054
25364
|
try {
|
|
25055
25365
|
copyFileSync(dbPath, backupPath);
|
|
25056
25366
|
} catch {
|
|
@@ -25168,6 +25478,16 @@ function readSiblingMigrationHashes(siblingFolder) {
|
|
|
25168
25478
|
return /* @__PURE__ */ new Set();
|
|
25169
25479
|
}
|
|
25170
25480
|
}
|
|
25481
|
+
function readSiblingNewestMillis(siblingFolder) {
|
|
25482
|
+
try {
|
|
25483
|
+
return Math.max(
|
|
25484
|
+
0,
|
|
25485
|
+
...readMigrationFiles({ migrationsFolder: siblingFolder }).map((m) => m.folderMillis)
|
|
25486
|
+
);
|
|
25487
|
+
} catch {
|
|
25488
|
+
return 0;
|
|
25489
|
+
}
|
|
25490
|
+
}
|
|
25171
25491
|
function ensureJournalHashUnique(nativeDb) {
|
|
25172
25492
|
if (!tableExists(nativeDb, "__drizzle_migrations")) return;
|
|
25173
25493
|
try {
|
|
@@ -25216,6 +25536,7 @@ function upgradeSharedJournalFormat(nativeDb, lineageFolders) {
|
|
|
25216
25536
|
return { named, unnamed: rows.length - named };
|
|
25217
25537
|
}
|
|
25218
25538
|
function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsystem, siblingMigrationsFolders = []) {
|
|
25539
|
+
assertNoPendingMigrationsForWorktreeBuild(nativeDb, readMigrationFiles({ migrationsFolder }));
|
|
25219
25540
|
const eliminatedTables = computeEliminatedTables(readMigrationFiles({ migrationsFolder }));
|
|
25220
25541
|
const cutoverPrefix = resolveConsolidationCutoverPrefix(migrationsFolder);
|
|
25221
25542
|
if (siblingMigrationsFolders.length > 0)
|
|
@@ -25247,8 +25568,15 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
25247
25568
|
knownHashes.add(m);
|
|
25248
25569
|
}
|
|
25249
25570
|
}
|
|
25250
|
-
const
|
|
25251
|
-
|
|
25571
|
+
const newestKnownMillis = Math.max(
|
|
25572
|
+
0,
|
|
25573
|
+
...localMigrations.map((m) => m.folderMillis),
|
|
25574
|
+
...siblingMigrationsFolders.filter((folder) => folder !== migrationsFolder).map(readSiblingNewestMillis)
|
|
25575
|
+
);
|
|
25576
|
+
const dbEntries = nativeDb.prepare('SELECT id, hash, created_at FROM "__drizzle_migrations"').all();
|
|
25577
|
+
const orphanedEntries = dbEntries.filter(
|
|
25578
|
+
(e) => !knownHashes.has(e.hash) && !(Number(e.created_at) > newestKnownMillis)
|
|
25579
|
+
);
|
|
25252
25580
|
const hasOrphanedEntries = orphanedEntries.length > 0;
|
|
25253
25581
|
if (hasOrphanedEntries) {
|
|
25254
25582
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
@@ -25490,6 +25818,8 @@ function sanitizeMigrationStatements(migrations) {
|
|
|
25490
25818
|
}
|
|
25491
25819
|
function migrateSanitized(db, config) {
|
|
25492
25820
|
const raw = readMigrationFiles(config);
|
|
25821
|
+
const client = db.$client;
|
|
25822
|
+
if (client) assertNoPendingMigrationsForWorktreeBuild(client, raw);
|
|
25493
25823
|
const sanitized = sanitizeMigrationStatements(raw);
|
|
25494
25824
|
migrateSync(sanitized, db._.session, config);
|
|
25495
25825
|
}
|
|
@@ -25553,6 +25883,7 @@ var init_migration_manager = __esm({
|
|
|
25553
25883
|
init_sqlite_core();
|
|
25554
25884
|
init_logger2();
|
|
25555
25885
|
init_with_retry();
|
|
25886
|
+
init_worktree_build_guard();
|
|
25556
25887
|
MAX_MIGRATION_RETRIES = 5;
|
|
25557
25888
|
MIGRATION_RETRY_BASE_DELAY_MS = 100;
|
|
25558
25889
|
MIGRATION_RETRY_MAX_DELAY_MS = 2e3;
|
|
@@ -25562,13 +25893,13 @@ var init_migration_manager = __esm({
|
|
|
25562
25893
|
});
|
|
25563
25894
|
|
|
25564
25895
|
// packages/core/src/store/relocated-store-guard.ts
|
|
25565
|
-
import { existsSync as
|
|
25566
|
-
import { createRequire } from "node:module";
|
|
25567
|
-
import { basename as basename3, dirname as
|
|
25896
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
25897
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
25898
|
+
import { basename as basename3, dirname as dirname5 } from "node:path";
|
|
25568
25899
|
import { readDeclaredProjectIdentity as readDeclaredProjectIdentity2, readPortableProjectId } from "@cleocode/paths";
|
|
25569
25900
|
function real2(p) {
|
|
25570
25901
|
try {
|
|
25571
|
-
return
|
|
25902
|
+
return realpathSync4(p);
|
|
25572
25903
|
} catch {
|
|
25573
25904
|
return p;
|
|
25574
25905
|
}
|
|
@@ -25585,7 +25916,7 @@ function liveElsewhere(globalDbPath, projectId, root) {
|
|
|
25585
25916
|
"SELECT project_path AS projectPath FROM nexus_project_registry WHERE project_id = ?"
|
|
25586
25917
|
).get(projectId);
|
|
25587
25918
|
const live = row?.projectPath;
|
|
25588
|
-
if (!live || paths.has(live) || !
|
|
25919
|
+
if (!live || paths.has(live) || !existsSync6(live)) return null;
|
|
25589
25920
|
if (!isStrictlyInsideDir(root, live)) return null;
|
|
25590
25921
|
return readDeclaredProjectIdentity2(live)?.projectId === projectId ? live : null;
|
|
25591
25922
|
} catch {
|
|
@@ -25599,14 +25930,14 @@ function detectRelocatedRoot(root, globalDbPath) {
|
|
|
25599
25930
|
if (tombstone)
|
|
25600
25931
|
return { projectId: tombstone.projectId, movedTo: tombstone.movedTo, via: "tombstone" };
|
|
25601
25932
|
const declared = readPortableProjectId(root);
|
|
25602
|
-
if (declared.status !== "valid" || !
|
|
25933
|
+
if (declared.status !== "valid" || !existsSync6(globalDbPath)) return null;
|
|
25603
25934
|
const movedTo = liveElsewhere(globalDbPath, declared.projectId, root);
|
|
25604
25935
|
return movedTo ? { projectId: declared.projectId, movedTo, via: "registry" } : null;
|
|
25605
25936
|
}
|
|
25606
25937
|
function assertStoreNotRelocated(dbPath, globalDbPath) {
|
|
25607
|
-
if (basename3(dbPath) !== "cleo.db" || basename3(
|
|
25608
|
-
if (
|
|
25609
|
-
const root =
|
|
25938
|
+
if (basename3(dbPath) !== "cleo.db" || basename3(dirname5(dbPath)) !== ".cleo") return;
|
|
25939
|
+
if (existsSync6(dbPath) || globalDbPath === dbPath) return;
|
|
25940
|
+
const root = dirname5(dirname5(dbPath));
|
|
25610
25941
|
if (_adopted.has(root)) return;
|
|
25611
25942
|
const moved = detectRelocatedRoot(root, globalDbPath);
|
|
25612
25943
|
if (moved) throw projectMovedError(root, moved, void 0, moved.via);
|
|
@@ -25616,17 +25947,17 @@ var init_relocated_store_guard = __esm({
|
|
|
25616
25947
|
"packages/core/src/store/relocated-store-guard.ts"() {
|
|
25617
25948
|
"use strict";
|
|
25618
25949
|
init_project_tombstone();
|
|
25619
|
-
_require =
|
|
25950
|
+
_require = createRequire2(import.meta.url);
|
|
25620
25951
|
_adopted = /* @__PURE__ */ new Set();
|
|
25621
25952
|
}
|
|
25622
25953
|
});
|
|
25623
25954
|
|
|
25624
25955
|
// packages/core/src/store/resolve-migrations-folder.ts
|
|
25625
|
-
import { createRequire as
|
|
25626
|
-
import { dirname as
|
|
25627
|
-
import { fileURLToPath } from "node:url";
|
|
25956
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
25957
|
+
import { dirname as dirname6, join as join7 } from "node:path";
|
|
25958
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
25628
25959
|
function coreRootFromEntry(entryPath) {
|
|
25629
|
-
return
|
|
25960
|
+
return dirname6(dirname6(entryPath));
|
|
25630
25961
|
}
|
|
25631
25962
|
function resolveConsolidatedJournalSiblings(ownSetName) {
|
|
25632
25963
|
return CONSOLIDATED_JOURNAL_LINEAGES.filter((name2) => name2 !== ownSetName).map(
|
|
@@ -25636,14 +25967,14 @@ function resolveConsolidatedJournalSiblings(ownSetName) {
|
|
|
25636
25967
|
function resolveCorePackageMigrationsFolder(setName) {
|
|
25637
25968
|
try {
|
|
25638
25969
|
const resolved = import.meta.resolve("@cleocode/core", import.meta.url);
|
|
25639
|
-
const entryPath =
|
|
25640
|
-
return
|
|
25970
|
+
const entryPath = fileURLToPath2(resolved);
|
|
25971
|
+
return join7(coreRootFromEntry(entryPath), "migrations", setName);
|
|
25641
25972
|
} catch {
|
|
25642
25973
|
}
|
|
25643
|
-
const _require7 =
|
|
25974
|
+
const _require7 = createRequire3(import.meta.url);
|
|
25644
25975
|
try {
|
|
25645
25976
|
const entryPath = _require7.resolve("@cleocode/core");
|
|
25646
|
-
return
|
|
25977
|
+
return join7(coreRootFromEntry(entryPath), "migrations", setName);
|
|
25647
25978
|
} catch (err) {
|
|
25648
25979
|
throw new Error(
|
|
25649
25980
|
`resolveCorePackageMigrationsFolder("${setName}"): cannot locate @cleocode/core from "${import.meta.url}". Ensure @cleocode/core is installed (workspace or npm). Original error: ${err.message}`
|
|
@@ -25753,11 +26084,11 @@ var init_sqlite_pragmas = __esm({
|
|
|
25753
26084
|
});
|
|
25754
26085
|
|
|
25755
26086
|
// packages/core/src/store/worktree-isolation-guard.ts
|
|
25756
|
-
import { basename as basename4, dirname as
|
|
26087
|
+
import { basename as basename4, dirname as dirname7, join as join8, resolve as resolve3 } from "node:path";
|
|
25757
26088
|
function assertStorePathIsNotWorktreeResident(role, dbPath) {
|
|
25758
|
-
const cleoDir =
|
|
26089
|
+
const cleoDir = dirname7(dbPath);
|
|
25759
26090
|
if (basename4(cleoDir) !== ".cleo") return;
|
|
25760
|
-
const projectRoot =
|
|
26091
|
+
const projectRoot = dirname7(cleoDir);
|
|
25761
26092
|
if (!isGitLinkedCheckout(projectRoot)) return;
|
|
25762
26093
|
if (process.env["CLEO_ALLOW_WORKTREE_DB_CREATE"] === "1") {
|
|
25763
26094
|
process.stderr.write(
|
|
@@ -25782,7 +26113,7 @@ function assertDbPathIsNotWorktreeResident(role, cwd) {
|
|
|
25782
26113
|
} catch {
|
|
25783
26114
|
return;
|
|
25784
26115
|
}
|
|
25785
|
-
assertStorePathIsNotWorktreeResident(role,
|
|
26116
|
+
assertStorePathIsNotWorktreeResident(role, join8(cleoDir, PROJECT_STORE_FILENAME2));
|
|
25786
26117
|
}
|
|
25787
26118
|
var PROJECT_STORE_FILENAME2;
|
|
25788
26119
|
var init_worktree_isolation_guard = __esm({
|
|
@@ -25802,10 +26133,10 @@ __export(sqlite_native_exports, {
|
|
|
25802
26133
|
getDbSyncConstructor: () => getDbSyncConstructor,
|
|
25803
26134
|
openNativeDatabase: () => openNativeDatabase
|
|
25804
26135
|
});
|
|
25805
|
-
import { realpathSync as
|
|
25806
|
-
import { createRequire as
|
|
26136
|
+
import { realpathSync as realpathSync5 } from "node:fs";
|
|
26137
|
+
import { createRequire as createRequire4 } from "node:module";
|
|
25807
26138
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
25808
|
-
import { delimiter, dirname as
|
|
26139
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute4, join as join9, resolve as resolve4, sep as sep3 } from "node:path";
|
|
25809
26140
|
function getDbSyncConstructor() {
|
|
25810
26141
|
if (_ctor === null) {
|
|
25811
26142
|
const mod = _require2("node:sqlite");
|
|
@@ -25814,19 +26145,19 @@ function getDbSyncConstructor() {
|
|
|
25814
26145
|
return _ctor;
|
|
25815
26146
|
}
|
|
25816
26147
|
function resolveAbsoluteSafe(p) {
|
|
25817
|
-
const abs =
|
|
26148
|
+
const abs = isAbsolute4(p) ? p : resolve4(p);
|
|
25818
26149
|
try {
|
|
25819
|
-
return
|
|
26150
|
+
return realpathSync5(abs);
|
|
25820
26151
|
} catch {
|
|
25821
26152
|
const missingParts = [];
|
|
25822
26153
|
let cursor = abs;
|
|
25823
26154
|
while (true) {
|
|
25824
|
-
const parent =
|
|
26155
|
+
const parent = dirname8(cursor);
|
|
25825
26156
|
if (parent === cursor) return abs;
|
|
25826
|
-
missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(
|
|
26157
|
+
missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep3) ? 0 : 1)));
|
|
25827
26158
|
cursor = parent;
|
|
25828
26159
|
try {
|
|
25829
|
-
return
|
|
26160
|
+
return join9(realpathSync5(cursor), ...missingParts);
|
|
25830
26161
|
} catch {
|
|
25831
26162
|
}
|
|
25832
26163
|
}
|
|
@@ -25834,7 +26165,7 @@ function resolveAbsoluteSafe(p) {
|
|
|
25834
26165
|
}
|
|
25835
26166
|
function isPathUnder(child, parent) {
|
|
25836
26167
|
if (child === parent) return true;
|
|
25837
|
-
const withSep = parent.endsWith(
|
|
26168
|
+
const withSep = parent.endsWith(sep3) ? parent : parent + sep3;
|
|
25838
26169
|
return child.startsWith(withSep);
|
|
25839
26170
|
}
|
|
25840
26171
|
function assertVitestSafePath(path2) {
|
|
@@ -25857,6 +26188,7 @@ function openNativeDatabase(path2, options) {
|
|
|
25857
26188
|
assertVitestSafePath(path2);
|
|
25858
26189
|
const DatabaseSyncCtor = getDbSyncConstructor();
|
|
25859
26190
|
const db = new DatabaseSyncCtor(path2, {
|
|
26191
|
+
// schema-guard-exempt: the native chokepoint; every writable caller installs the guard
|
|
25860
26192
|
enableForeignKeyConstraints: true,
|
|
25861
26193
|
readOnly: options?.readonly ?? false,
|
|
25862
26194
|
// Default handle-open lock timeout mirrors the SSoT busy_timeout
|
|
@@ -25908,7 +26240,7 @@ var init_sqlite_native = __esm({
|
|
|
25908
26240
|
"packages/core/src/store/sqlite-native.ts"() {
|
|
25909
26241
|
"use strict";
|
|
25910
26242
|
init_sqlite_pragmas();
|
|
25911
|
-
_require2 =
|
|
26243
|
+
_require2 = createRequire4(import.meta.url);
|
|
25912
26244
|
_ctor = null;
|
|
25913
26245
|
}
|
|
25914
26246
|
});
|
|
@@ -25982,7 +26314,7 @@ var init_writer_lease_schema = __esm({
|
|
|
25982
26314
|
// packages/core/src/store/writer-lease.ts
|
|
25983
26315
|
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
25984
26316
|
import { randomUUID } from "node:crypto";
|
|
25985
|
-
import { realpathSync as
|
|
26317
|
+
import { realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
|
|
25986
26318
|
import { resolve as resolvePath } from "node:path";
|
|
25987
26319
|
function log() {
|
|
25988
26320
|
if (_log === null) _log = getLogger("writer-lease");
|
|
@@ -26072,7 +26404,7 @@ function resolveDbIdentity(db) {
|
|
|
26072
26404
|
return identity;
|
|
26073
26405
|
}
|
|
26074
26406
|
function sleepAsync(ms) {
|
|
26075
|
-
return new Promise((
|
|
26407
|
+
return new Promise((resolve16) => setTimeout(resolve16, Math.max(0, Math.round(ms))));
|
|
26076
26408
|
}
|
|
26077
26409
|
function isPidAlive(pid) {
|
|
26078
26410
|
try {
|
|
@@ -26411,7 +26743,7 @@ function assertColdOpenFile(frame) {
|
|
|
26411
26743
|
async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
|
|
26412
26744
|
opts.execution?.assertActive();
|
|
26413
26745
|
const captured = opts.requiredIdentity;
|
|
26414
|
-
const path2 =
|
|
26746
|
+
const path2 = realpathSync6(captured.dbPath);
|
|
26415
26747
|
const identity = statSync2(path2, { bigint: true });
|
|
26416
26748
|
if (captured.scope !== scope || captured.fileDevice !== String(identity.dev) || captured.fileInode !== String(identity.ino)) {
|
|
26417
26749
|
throw new LeaseUnavailableError(
|
|
@@ -26444,6 +26776,7 @@ async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
|
|
|
26444
26776
|
}
|
|
26445
26777
|
const remaining = opts.execution ? Math.max(1, opts.execution.deadlineAt - Date.now()) : ACQUIRE_DEADLINE_MS;
|
|
26446
26778
|
const owned = openNativeDatabase(path2, { timeout: Math.min(ACQUIRE_DEADLINE_MS, remaining) });
|
|
26779
|
+
installSchemaWriteGuard(owned);
|
|
26447
26780
|
try {
|
|
26448
26781
|
opts.execution?.assertActive();
|
|
26449
26782
|
const afterOpen = statSync2(path2, { bigint: true });
|
|
@@ -26637,6 +26970,7 @@ var init_writer_lease = __esm({
|
|
|
26637
26970
|
init_background_ops();
|
|
26638
26971
|
init_dual_scope_db();
|
|
26639
26972
|
init_sqlite_native();
|
|
26973
|
+
init_worktree_build_guard();
|
|
26640
26974
|
init_writer_lease_schema();
|
|
26641
26975
|
DEFAULT_TTL_MS = 3e4;
|
|
26642
26976
|
DEFAULT_PRIORITY = 100;
|
|
@@ -27179,10 +27513,10 @@ var init_monitor = __esm({
|
|
|
27179
27513
|
|
|
27180
27514
|
// packages/core/src/resources/supervisor-admit.ts
|
|
27181
27515
|
import { connect } from "node:net";
|
|
27182
|
-
import { join as
|
|
27516
|
+
import { join as join10 } from "node:path";
|
|
27183
27517
|
import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
|
|
27184
27518
|
function resolveSupervisorSocketPath() {
|
|
27185
|
-
return process.env.CLEO_SUPERVISOR_SOCKET ??
|
|
27519
|
+
return process.env.CLEO_SUPERVISOR_SOCKET ?? join10(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
|
|
27186
27520
|
}
|
|
27187
27521
|
async function sendResourceAdmit(socketPath, cls, holderId, budget) {
|
|
27188
27522
|
const result = await sendLeaseRequest(
|
|
@@ -27205,7 +27539,7 @@ async function sendResourceRelease(socketPath, cls, holderId) {
|
|
|
27205
27539
|
return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
|
|
27206
27540
|
}
|
|
27207
27541
|
function sendLeaseRequest(socketPath, request, expectedKind) {
|
|
27208
|
-
return new Promise((
|
|
27542
|
+
return new Promise((resolve16) => {
|
|
27209
27543
|
const id = `ra-${process.pid}-${request.kind}`;
|
|
27210
27544
|
const envelope = LeaseIpcRequestEnvelopeSchema.parse({
|
|
27211
27545
|
protocol_version: LEASE_IPC_PROTOCOL_VERSION,
|
|
@@ -27223,7 +27557,7 @@ function sendLeaseRequest(socketPath, request, expectedKind) {
|
|
|
27223
27557
|
settled = true;
|
|
27224
27558
|
socket.removeAllListeners();
|
|
27225
27559
|
socket.destroy();
|
|
27226
|
-
|
|
27560
|
+
resolve16(value);
|
|
27227
27561
|
};
|
|
27228
27562
|
const degrade = (reason) => done({ unavailable: true, reason });
|
|
27229
27563
|
socket.setTimeout(REQUEST_TIMEOUT_MS);
|
|
@@ -27294,9 +27628,9 @@ __export(governor_exports, {
|
|
|
27294
27628
|
resolveGovernorMode: () => resolveGovernorMode,
|
|
27295
27629
|
slotFileCount: () => slotFileCount
|
|
27296
27630
|
});
|
|
27297
|
-
import { existsSync as
|
|
27631
|
+
import { existsSync as existsSync7, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
27298
27632
|
import { availableParallelism, totalmem } from "node:os";
|
|
27299
|
-
import { join as
|
|
27633
|
+
import { join as join11 } from "node:path";
|
|
27300
27634
|
import lockfile from "proper-lockfile";
|
|
27301
27635
|
function log2() {
|
|
27302
27636
|
if (_log2 === null) _log2 = getLogger("resource-governor");
|
|
@@ -27365,14 +27699,14 @@ function clamp(lo, v, hi) {
|
|
|
27365
27699
|
return Math.max(lo, Math.min(v, hi));
|
|
27366
27700
|
}
|
|
27367
27701
|
function governorSlotDir(cls) {
|
|
27368
|
-
return
|
|
27702
|
+
return join11(getCleoHome(), "locks", `resource-${cls}`);
|
|
27369
27703
|
}
|
|
27370
27704
|
function ensureSlotFiles(dir, count) {
|
|
27371
|
-
if (!
|
|
27705
|
+
if (!existsSync7(dir)) mkdirSync(dir, { recursive: true });
|
|
27372
27706
|
const paths = [];
|
|
27373
27707
|
for (let i = 0; i < count; i++) {
|
|
27374
|
-
const p =
|
|
27375
|
-
if (!
|
|
27708
|
+
const p = join11(dir, `slot-${i}.lock`);
|
|
27709
|
+
if (!existsSync7(p)) writeFileSync3(p, "", { flag: "a" });
|
|
27376
27710
|
paths.push(p);
|
|
27377
27711
|
}
|
|
27378
27712
|
return paths;
|
|
@@ -27412,7 +27746,7 @@ function shuffledIndices(n) {
|
|
|
27412
27746
|
}
|
|
27413
27747
|
async function countHeldSlots(cls, budget) {
|
|
27414
27748
|
const dir = governorSlotDir(cls);
|
|
27415
|
-
if (!
|
|
27749
|
+
if (!existsSync7(dir)) return 0;
|
|
27416
27750
|
const slots = ensureSlotFiles(dir, budget);
|
|
27417
27751
|
let held = 0;
|
|
27418
27752
|
for (const path2 of slots) {
|
|
@@ -27427,7 +27761,7 @@ async function countHeldSlots(cls, budget) {
|
|
|
27427
27761
|
}
|
|
27428
27762
|
function slotFileCount(cls) {
|
|
27429
27763
|
const dir = governorSlotDir(cls);
|
|
27430
|
-
if (!
|
|
27764
|
+
if (!existsSync7(dir)) return 0;
|
|
27431
27765
|
return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
|
|
27432
27766
|
}
|
|
27433
27767
|
var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
|
|
@@ -27627,11 +27961,11 @@ var init_lock = __esm({
|
|
|
27627
27961
|
|
|
27628
27962
|
// packages/core/src/store/atomic.ts
|
|
27629
27963
|
import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
|
|
27630
|
-
import { dirname as
|
|
27964
|
+
import { dirname as dirname9 } from "node:path";
|
|
27631
27965
|
import writeFileAtomic from "write-file-atomic";
|
|
27632
27966
|
async function atomicWrite(filePath, data, options) {
|
|
27633
27967
|
try {
|
|
27634
|
-
await mkdir(
|
|
27968
|
+
await mkdir(dirname9(filePath), { recursive: true });
|
|
27635
27969
|
await writeFileAtomic(filePath, data, {
|
|
27636
27970
|
encoding: options?.encoding ?? "utf8",
|
|
27637
27971
|
mode: options?.mode
|
|
@@ -27664,7 +27998,7 @@ var init_atomic = __esm({
|
|
|
27664
27998
|
|
|
27665
27999
|
// packages/core/src/store/backup.ts
|
|
27666
28000
|
import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
|
|
27667
|
-
import { basename as basename5, join as
|
|
28001
|
+
import { basename as basename5, dirname as dirname10, join as join12 } from "node:path";
|
|
27668
28002
|
async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
|
|
27669
28003
|
try {
|
|
27670
28004
|
await mkdir2(backupDir, { recursive: true });
|
|
@@ -27675,14 +28009,14 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
27675
28009
|
throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
|
|
27676
28010
|
}
|
|
27677
28011
|
for (let i = maxBackups; i >= 1; i--) {
|
|
27678
|
-
const current =
|
|
28012
|
+
const current = join12(backupDir, `${fileName}.${i}`);
|
|
27679
28013
|
if (i === maxBackups) {
|
|
27680
28014
|
try {
|
|
27681
28015
|
await unlink2(current);
|
|
27682
28016
|
} catch {
|
|
27683
28017
|
}
|
|
27684
28018
|
} else {
|
|
27685
|
-
const next =
|
|
28019
|
+
const next = join12(backupDir, `${fileName}.${i + 1}`);
|
|
27686
28020
|
try {
|
|
27687
28021
|
await stat2(current);
|
|
27688
28022
|
await fsRename(current, next);
|
|
@@ -27690,7 +28024,7 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
27690
28024
|
}
|
|
27691
28025
|
}
|
|
27692
28026
|
}
|
|
27693
|
-
const backupPath =
|
|
28027
|
+
const backupPath = join12(backupDir, `${fileName}.1`);
|
|
27694
28028
|
await copyFile(filePath, backupPath);
|
|
27695
28029
|
return backupPath;
|
|
27696
28030
|
} catch (err) {
|
|
@@ -27704,6 +28038,7 @@ var init_backup = __esm({
|
|
|
27704
28038
|
"use strict";
|
|
27705
28039
|
init_src();
|
|
27706
28040
|
init_errors2();
|
|
28041
|
+
init_worktree_isolation_guard();
|
|
27707
28042
|
DEFAULT_MAX_BACKUPS = 5;
|
|
27708
28043
|
}
|
|
27709
28044
|
});
|
|
@@ -27988,7 +28323,7 @@ __export(identity_exports, {
|
|
|
27988
28323
|
import { execFile } from "node:child_process";
|
|
27989
28324
|
import { createHash as createHash2 } from "node:crypto";
|
|
27990
28325
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
27991
|
-
import { join as
|
|
28326
|
+
import { join as join13, resolve as resolve5 } from "node:path";
|
|
27992
28327
|
import { promisify } from "node:util";
|
|
27993
28328
|
import { legacyProjectId } from "@cleocode/paths";
|
|
27994
28329
|
import { legacyProjectId as legacyProjectId2 } from "@cleocode/paths";
|
|
@@ -27996,14 +28331,14 @@ async function findGitRoot(fromPath, execution) {
|
|
|
27996
28331
|
execution?.assertActive();
|
|
27997
28332
|
try {
|
|
27998
28333
|
const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
27999
|
-
cwd:
|
|
28334
|
+
cwd: resolve5(fromPath),
|
|
28000
28335
|
signal: execution?.signal,
|
|
28001
28336
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28002
28337
|
killSignal: "SIGKILL",
|
|
28003
28338
|
maxBuffer: 64 * 1024
|
|
28004
28339
|
});
|
|
28005
28340
|
execution?.assertActive();
|
|
28006
|
-
return
|
|
28341
|
+
return resolve5(stdout.trim());
|
|
28007
28342
|
} catch {
|
|
28008
28343
|
execution?.assertActive();
|
|
28009
28344
|
return null;
|
|
@@ -28013,7 +28348,7 @@ async function findGitRemoteUrl(fromPath, execution) {
|
|
|
28013
28348
|
execution?.assertActive();
|
|
28014
28349
|
try {
|
|
28015
28350
|
const { stdout } = await execFileAsync("git", ["remote", "get-url", "origin"], {
|
|
28016
|
-
cwd:
|
|
28351
|
+
cwd: resolve5(fromPath),
|
|
28017
28352
|
signal: execution?.signal,
|
|
28018
28353
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28019
28354
|
killSignal: "SIGKILL",
|
|
@@ -28043,7 +28378,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
|
|
|
28043
28378
|
try {
|
|
28044
28379
|
const args = ["--no-replace-objects", "rev-list", "--max-parents=0", "HEAD"];
|
|
28045
28380
|
const { stdout } = await execFileAsync("git", args, {
|
|
28046
|
-
cwd:
|
|
28381
|
+
cwd: resolve5(fromPath),
|
|
28047
28382
|
signal: execution?.signal,
|
|
28048
28383
|
timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
|
|
28049
28384
|
killSignal: "SIGKILL",
|
|
@@ -28066,7 +28401,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
|
|
|
28066
28401
|
async function readProjectInfoName(repoRoot, execution) {
|
|
28067
28402
|
execution?.assertActive();
|
|
28068
28403
|
try {
|
|
28069
|
-
const raw = await readFile3(
|
|
28404
|
+
const raw = await readFile3(join13(repoRoot, ".cleo", "project-info.json"), {
|
|
28070
28405
|
encoding: "utf8",
|
|
28071
28406
|
signal: execution?.signal
|
|
28072
28407
|
});
|
|
@@ -28081,7 +28416,7 @@ async function readProjectInfoName(repoRoot, execution) {
|
|
|
28081
28416
|
}
|
|
28082
28417
|
async function projectPathFingerprint(repoPath, execution) {
|
|
28083
28418
|
execution?.assertActive();
|
|
28084
|
-
const realRepoPath =
|
|
28419
|
+
const realRepoPath = resolve5(repoPath);
|
|
28085
28420
|
const results = await Promise.allSettled([
|
|
28086
28421
|
findGitRoot(realRepoPath, execution),
|
|
28087
28422
|
findGitRemoteUrl(realRepoPath, execution)
|
|
@@ -28105,9 +28440,9 @@ async function projectPathFingerprint(repoPath, execution) {
|
|
|
28105
28440
|
}
|
|
28106
28441
|
function computeLegacyAliases(repoPath, additionalPaths) {
|
|
28107
28442
|
const aliases = /* @__PURE__ */ new Set();
|
|
28108
|
-
aliases.add(legacyProjectId(
|
|
28443
|
+
aliases.add(legacyProjectId(resolve5(repoPath)));
|
|
28109
28444
|
for (const p of additionalPaths ?? []) {
|
|
28110
|
-
aliases.add(legacyProjectId(
|
|
28445
|
+
aliases.add(legacyProjectId(resolve5(p)));
|
|
28111
28446
|
}
|
|
28112
28447
|
return [...aliases];
|
|
28113
28448
|
}
|
|
@@ -28141,17 +28476,17 @@ var init_project_identity = __esm({
|
|
|
28141
28476
|
});
|
|
28142
28477
|
|
|
28143
28478
|
// packages/core/src/scaffold/ensure-config.ts
|
|
28144
|
-
import { existsSync as
|
|
28145
|
-
import { basename as basename6, dirname as
|
|
28146
|
-
import { fileURLToPath as
|
|
28479
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
28480
|
+
import { basename as basename6, dirname as dirname11, join as join14, resolve as resolve6 } from "node:path";
|
|
28481
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
28147
28482
|
function getPackageRoot() {
|
|
28148
|
-
const thisFile =
|
|
28149
|
-
return
|
|
28483
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
28484
|
+
return resolve6(dirname11(thisFile), "..", "..");
|
|
28150
28485
|
}
|
|
28151
28486
|
function getCleoVersion() {
|
|
28152
28487
|
try {
|
|
28153
|
-
const pkgPath =
|
|
28154
|
-
const pkg = JSON.parse(
|
|
28488
|
+
const pkgPath = join14(getPackageRoot(), "package.json");
|
|
28489
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
|
|
28155
28490
|
return pkg.version ?? "0.0.0";
|
|
28156
28491
|
} catch {
|
|
28157
28492
|
return "0.0.0";
|
|
@@ -28510,25 +28845,25 @@ var init_recovery = __esm({
|
|
|
28510
28845
|
// packages/core/src/store/exodus/archive.ts
|
|
28511
28846
|
import {
|
|
28512
28847
|
copyFileSync as copyFileSync2,
|
|
28513
|
-
existsSync as
|
|
28848
|
+
existsSync as existsSync9,
|
|
28514
28849
|
mkdirSync as mkdirSync2,
|
|
28515
|
-
readFileSync as
|
|
28850
|
+
readFileSync as readFileSync5,
|
|
28516
28851
|
renameSync as renameSync3,
|
|
28517
28852
|
unlinkSync,
|
|
28518
28853
|
writeFileSync as writeFileSync4
|
|
28519
28854
|
} from "node:fs";
|
|
28520
|
-
import { basename as basename7, dirname as
|
|
28855
|
+
import { basename as basename7, dirname as dirname12, join as join15, resolve as resolve7 } from "node:path";
|
|
28521
28856
|
import { z as z26 } from "zod";
|
|
28522
28857
|
function scopeBaseDir(scope, cwd, targetDbPath) {
|
|
28523
|
-
if (targetDbPath !== void 0) return
|
|
28858
|
+
if (targetDbPath !== void 0) return dirname12(targetDbPath);
|
|
28524
28859
|
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
28525
28860
|
}
|
|
28526
28861
|
function exodusArchiveDir(scope, cwd, targetDbPath) {
|
|
28527
|
-
return
|
|
28862
|
+
return join15(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
|
|
28528
28863
|
}
|
|
28529
28864
|
function exodusMarkerPath(scope, cwd, targetDbPath) {
|
|
28530
28865
|
const marker = targetDbPath !== void 0 && basename7(targetDbPath) !== "cleo.db" ? `${basename7(targetDbPath)}.${MARKER_FILENAME_BY_SCOPE[scope]}` : MARKER_FILENAME_BY_SCOPE[scope];
|
|
28531
|
-
return
|
|
28866
|
+
return join15(scopeBaseDir(scope, cwd, targetDbPath), marker);
|
|
28532
28867
|
}
|
|
28533
28868
|
function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
28534
28869
|
let markerPath;
|
|
@@ -28538,13 +28873,13 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
|
28538
28873
|
if (targetDbPath) throw error;
|
|
28539
28874
|
return false;
|
|
28540
28875
|
}
|
|
28541
|
-
if (!
|
|
28542
|
-
const marker = markerIdentity.parse(JSON.parse(
|
|
28876
|
+
if (!existsSync9(markerPath)) return false;
|
|
28877
|
+
const marker = markerIdentity.parse(JSON.parse(readFileSync5(markerPath, "utf8")));
|
|
28543
28878
|
if (nativeDb && (!marker.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker.databaseIdentity)))
|
|
28544
28879
|
throw new Error(
|
|
28545
28880
|
"Exodus completion marker does not certify this database generation; assessment required"
|
|
28546
28881
|
);
|
|
28547
|
-
return marker.scope === scope && (!targetDbPath || !marker.targetDbPath ||
|
|
28882
|
+
return marker.scope === scope && (!targetDbPath || !marker.targetDbPath || resolve7(marker.targetDbPath) === resolve7(targetDbPath));
|
|
28548
28883
|
}
|
|
28549
28884
|
function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, databaseIdentity) {
|
|
28550
28885
|
const markerPath = exodusMarkerPath(scope, cwd, targetDbPath);
|
|
@@ -28556,7 +28891,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
28556
28891
|
cleoVersion: getCleoVersion(),
|
|
28557
28892
|
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28558
28893
|
archivedSources: [...archivedSources],
|
|
28559
|
-
targetDbPath:
|
|
28894
|
+
targetDbPath: resolve7(targetDbPath ?? join15(baseDir, "cleo.db")),
|
|
28560
28895
|
...databaseIdentity ? { databaseIdentity } : {}
|
|
28561
28896
|
};
|
|
28562
28897
|
const tmpPath = `${markerPath}.tmp`;
|
|
@@ -28567,10 +28902,10 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
28567
28902
|
}
|
|
28568
28903
|
function moveFileInto(srcPath, destDir) {
|
|
28569
28904
|
mkdirSync2(destDir, { recursive: true });
|
|
28570
|
-
let dest =
|
|
28571
|
-
if (
|
|
28905
|
+
let dest = join15(destDir, basename7(srcPath));
|
|
28906
|
+
if (existsSync9(dest)) {
|
|
28572
28907
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
28573
|
-
dest =
|
|
28908
|
+
dest = join15(destDir, `${basename7(srcPath)}.${stamp}`);
|
|
28574
28909
|
}
|
|
28575
28910
|
try {
|
|
28576
28911
|
renameSync3(srcPath, dest);
|
|
@@ -28581,14 +28916,14 @@ function moveFileInto(srcPath, destDir) {
|
|
|
28581
28916
|
return dest;
|
|
28582
28917
|
}
|
|
28583
28918
|
function archiveSourceDb(source, cwd, targetDbPath) {
|
|
28584
|
-
if (!
|
|
28919
|
+
if (!existsSync9(source.path)) {
|
|
28585
28920
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
28586
28921
|
}
|
|
28587
28922
|
const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
|
|
28588
28923
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
28589
28924
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
28590
28925
|
const sidecar = `${source.path}${suffix}`;
|
|
28591
|
-
if (
|
|
28926
|
+
if (existsSync9(sidecar)) {
|
|
28592
28927
|
try {
|
|
28593
28928
|
moveFileInto(sidecar, destDir);
|
|
28594
28929
|
} catch (err) {
|
|
@@ -28636,7 +28971,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
28636
28971
|
const stranded = [];
|
|
28637
28972
|
for (const source of sources) {
|
|
28638
28973
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
28639
|
-
if (
|
|
28974
|
+
if (existsSync9(source.path)) {
|
|
28640
28975
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
28641
28976
|
}
|
|
28642
28977
|
}
|
|
@@ -28701,7 +29036,7 @@ __export(open_cleo_db_exports, {
|
|
|
28701
29036
|
openCleoDbSnapshot: () => openCleoDbSnapshot,
|
|
28702
29037
|
validateProjectIdConsistency: () => validateProjectIdConsistency
|
|
28703
29038
|
});
|
|
28704
|
-
import { createRequire as
|
|
29039
|
+
import { createRequire as createRequire5 } from "node:module";
|
|
28705
29040
|
function unwrapNativeSqliteDb(db) {
|
|
28706
29041
|
if (db && typeof db === "object" && "$client" in db) {
|
|
28707
29042
|
return db.$client ?? db;
|
|
@@ -28765,9 +29100,10 @@ async function openCleoDb(role, cwd) {
|
|
|
28765
29100
|
}
|
|
28766
29101
|
function openCleoDbSnapshot(path2, options = {}) {
|
|
28767
29102
|
const { readOnly = true, applyPragmas = true } = options;
|
|
28768
|
-
const _require7 =
|
|
29103
|
+
const _require7 = createRequire5(import.meta.url);
|
|
28769
29104
|
const { DatabaseSync: DatabaseSyncCtor } = _require7("node:sqlite");
|
|
28770
29105
|
const db = new DatabaseSyncCtor(path2, { readOnly });
|
|
29106
|
+
if (!readOnly) installSchemaWriteGuard(db);
|
|
28771
29107
|
if (applyPragmas) {
|
|
28772
29108
|
applyPerfPragmas(db, { enableWal: !readOnly });
|
|
28773
29109
|
}
|
|
@@ -28795,6 +29131,7 @@ var init_open_cleo_db = __esm({
|
|
|
28795
29131
|
init_project_info();
|
|
28796
29132
|
init_dual_scope_db();
|
|
28797
29133
|
init_sqlite_pragmas();
|
|
29134
|
+
init_worktree_build_guard();
|
|
28798
29135
|
init_worktree_isolation_guard();
|
|
28799
29136
|
PROJECT_ID_TRACKING_ROLES = /* @__PURE__ */ new Set(["global"]);
|
|
28800
29137
|
}
|
|
@@ -29134,7 +29471,7 @@ var init_table_name_map = __esm({
|
|
|
29134
29471
|
});
|
|
29135
29472
|
|
|
29136
29473
|
// packages/core/src/store/exodus/count-parity.ts
|
|
29137
|
-
import { existsSync as
|
|
29474
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
29138
29475
|
function listTables(db) {
|
|
29139
29476
|
return db.prepare(
|
|
29140
29477
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
@@ -29155,14 +29492,14 @@ function rowCount(db, tableName) {
|
|
|
29155
29492
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
29156
29493
|
const entries = [];
|
|
29157
29494
|
let skipped = 0;
|
|
29158
|
-
if (!
|
|
29495
|
+
if (!existsSync10(projectDbPath) || !existsSync10(globalDbPath)) {
|
|
29159
29496
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
29160
29497
|
}
|
|
29161
29498
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
29162
29499
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
29163
29500
|
try {
|
|
29164
29501
|
for (const src of sources) {
|
|
29165
|
-
if (!
|
|
29502
|
+
if (!existsSync10(src.path)) continue;
|
|
29166
29503
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
29167
29504
|
try {
|
|
29168
29505
|
for (const legacyTable of listTables(srcSnap.db)) {
|
|
@@ -29220,8 +29557,8 @@ var init_count_parity = __esm({
|
|
|
29220
29557
|
});
|
|
29221
29558
|
|
|
29222
29559
|
// packages/core/src/store/exodus/plan.ts
|
|
29223
|
-
import { existsSync as
|
|
29224
|
-
import { join as
|
|
29560
|
+
import { existsSync as existsSync11, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
|
|
29561
|
+
import { join as join16 } from "node:path";
|
|
29225
29562
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
29226
29563
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
29227
29564
|
}
|
|
@@ -29232,33 +29569,33 @@ function buildSourceDescriptors(cwd) {
|
|
|
29232
29569
|
// Project-tier — go into consolidated project-scope cleo.db
|
|
29233
29570
|
{
|
|
29234
29571
|
name: "tasks",
|
|
29235
|
-
path:
|
|
29572
|
+
path: join16(cleoDir, "tasks.db"),
|
|
29236
29573
|
targetScope: "project"
|
|
29237
29574
|
},
|
|
29238
29575
|
{
|
|
29239
29576
|
name: "brain (project)",
|
|
29240
|
-
path:
|
|
29577
|
+
path: join16(cleoDir, "brain.db"),
|
|
29241
29578
|
targetScope: "project"
|
|
29242
29579
|
},
|
|
29243
29580
|
{
|
|
29244
29581
|
name: "conduit",
|
|
29245
|
-
path:
|
|
29582
|
+
path: join16(cleoDir, "conduit.db"),
|
|
29246
29583
|
targetScope: "project"
|
|
29247
29584
|
},
|
|
29248
29585
|
// Global-tier — go into consolidated global-scope cleo.db
|
|
29249
29586
|
{
|
|
29250
29587
|
name: "nexus",
|
|
29251
|
-
path:
|
|
29588
|
+
path: join16(cleoHome, "nexus.db"),
|
|
29252
29589
|
targetScope: "global"
|
|
29253
29590
|
},
|
|
29254
29591
|
{
|
|
29255
29592
|
name: "signaldock",
|
|
29256
|
-
path:
|
|
29593
|
+
path: join16(cleoHome, "signaldock.db"),
|
|
29257
29594
|
targetScope: "global"
|
|
29258
29595
|
},
|
|
29259
29596
|
{
|
|
29260
29597
|
name: "skills",
|
|
29261
|
-
path:
|
|
29598
|
+
path: join16(cleoHome, "skills.db"),
|
|
29262
29599
|
targetScope: "global"
|
|
29263
29600
|
}
|
|
29264
29601
|
];
|
|
@@ -29287,7 +29624,7 @@ function findExistingStaging(cleoDir) {
|
|
|
29287
29624
|
const entries = readdirSync3(cleoDir, { withFileTypes: true });
|
|
29288
29625
|
const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
|
|
29289
29626
|
if (stagingDirs.length > 0) {
|
|
29290
|
-
return
|
|
29627
|
+
return join16(cleoDir, stagingDirs[0]);
|
|
29291
29628
|
}
|
|
29292
29629
|
} catch {
|
|
29293
29630
|
}
|
|
@@ -29303,7 +29640,7 @@ function buildExodusPlan(cwd) {
|
|
|
29303
29640
|
const availableBytes = getAvailableBytes(cleoDir);
|
|
29304
29641
|
const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
|
|
29305
29642
|
const existingStaging = findExistingStaging(cleoDir);
|
|
29306
|
-
const stagingDir = existingStaging ??
|
|
29643
|
+
const stagingDir = existingStaging ?? join16(cleoDir, deriveStagingDirName());
|
|
29307
29644
|
const resumeFromStaging = existingStaging !== null;
|
|
29308
29645
|
const projectDbPath = resolveDualScopeDbPath("project", cwd);
|
|
29309
29646
|
const globalDbPath = resolveDualScopeDbPath("global");
|
|
@@ -29322,7 +29659,7 @@ function buildExodusPlan(cwd) {
|
|
|
29322
29659
|
};
|
|
29323
29660
|
}
|
|
29324
29661
|
function sourcesPresent(sources) {
|
|
29325
|
-
return sources.some((s) =>
|
|
29662
|
+
return sources.some((s) => existsSync11(s.path));
|
|
29326
29663
|
}
|
|
29327
29664
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
29328
29665
|
var init_plan2 = __esm({
|
|
@@ -29336,18 +29673,18 @@ var init_plan2 = __esm({
|
|
|
29336
29673
|
});
|
|
29337
29674
|
|
|
29338
29675
|
// packages/core/src/store/exodus/health.ts
|
|
29339
|
-
import { existsSync as
|
|
29676
|
+
import { existsSync as existsSync12, statSync as statSync4 } from "node:fs";
|
|
29340
29677
|
function buildExodusHealth(cwd) {
|
|
29341
29678
|
const plan = buildExodusPlan(cwd);
|
|
29342
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
29679
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync12(s.path));
|
|
29343
29680
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
29344
29681
|
const consolidatedExistsByScope = {
|
|
29345
|
-
project:
|
|
29346
|
-
global:
|
|
29682
|
+
project: existsSync12(plan.projectDbPath),
|
|
29683
|
+
global: existsSync12(plan.globalDbPath)
|
|
29347
29684
|
};
|
|
29348
29685
|
const buildScope = (scope) => {
|
|
29349
29686
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
29350
|
-
const present =
|
|
29687
|
+
const present = existsSync12(s.path);
|
|
29351
29688
|
let bytes = 0;
|
|
29352
29689
|
if (present) {
|
|
29353
29690
|
try {
|
|
@@ -29699,8 +30036,8 @@ var init_types = __esm({
|
|
|
29699
30036
|
});
|
|
29700
30037
|
|
|
29701
30038
|
// packages/core/src/store/backup-sidecar.ts
|
|
29702
|
-
import { existsSync as
|
|
29703
|
-
import { join as
|
|
30039
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
30040
|
+
import { join as join17 } from "node:path";
|
|
29704
30041
|
function formatBackupTimestamp(d) {
|
|
29705
30042
|
const pad = (n, len = 2) => String(n).padStart(len, "0");
|
|
29706
30043
|
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
|
|
@@ -29711,8 +30048,8 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29711
30048
|
const ownedPattern = new RegExp(`\\.${escapedType}-`);
|
|
29712
30049
|
const files = readdirSync4(backupDir).filter((f) => !f.endsWith(".meta.json") && !f.endsWith(".tmp") && ownedPattern.test(f)).map((f) => ({
|
|
29713
30050
|
name: f,
|
|
29714
|
-
path:
|
|
29715
|
-
mtimeMs: statSync5(
|
|
30051
|
+
path: join17(backupDir, f),
|
|
30052
|
+
mtimeMs: statSync5(join17(backupDir, f)).mtimeMs
|
|
29716
30053
|
})).sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
29717
30054
|
while (files.length > maxSnapshots) {
|
|
29718
30055
|
const oldest = files.shift();
|
|
@@ -29720,7 +30057,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29720
30057
|
try {
|
|
29721
30058
|
unlinkSync2(oldest.path);
|
|
29722
30059
|
const metaPath = `${oldest.path}.meta.json`;
|
|
29723
|
-
if (
|
|
30060
|
+
if (existsSync13(metaPath)) unlinkSync2(metaPath);
|
|
29724
30061
|
} catch {
|
|
29725
30062
|
}
|
|
29726
30063
|
}
|
|
@@ -29728,7 +30065,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
|
|
|
29728
30065
|
}
|
|
29729
30066
|
}
|
|
29730
30067
|
function writeBackupSidecar(backupDir, sidecar) {
|
|
29731
|
-
const dest =
|
|
30068
|
+
const dest = join17(backupDir, `${sidecar.backupId}.meta.json`);
|
|
29732
30069
|
const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
|
|
29733
30070
|
writeFileSync5(tmp, JSON.stringify(sidecar, null, 2));
|
|
29734
30071
|
renameSync4(tmp, dest);
|
|
@@ -29740,23 +30077,23 @@ var init_backup_sidecar = __esm({
|
|
|
29740
30077
|
});
|
|
29741
30078
|
|
|
29742
30079
|
// packages/core/src/store/pre-repair-snapshot.ts
|
|
29743
|
-
import { existsSync as
|
|
29744
|
-
import { dirname as
|
|
30080
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
|
|
30081
|
+
import { dirname as dirname13, join as join18 } from "node:path";
|
|
29745
30082
|
function writePreRepairSnapshot(nativeDb, dbPath, label) {
|
|
29746
30083
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
29747
|
-
const backupDir =
|
|
30084
|
+
const backupDir = join18(dirname13(dbPath), "backups");
|
|
29748
30085
|
mkdirSync3(backupDir, { recursive: true });
|
|
29749
|
-
const snapshotPath =
|
|
30086
|
+
const snapshotPath = join18(backupDir, `cleo-pre-${label}-${stamp}.db`);
|
|
29750
30087
|
nativeDb.exec(`VACUUM INTO '${snapshotPath.replace(/'/g, "''")}'`);
|
|
29751
30088
|
return snapshotPath;
|
|
29752
30089
|
}
|
|
29753
30090
|
function existingAncestor(path2) {
|
|
29754
30091
|
let p = path2;
|
|
29755
|
-
while (!
|
|
30092
|
+
while (!existsSync14(p) && dirname13(p) !== p) p = dirname13(p);
|
|
29756
30093
|
return p;
|
|
29757
30094
|
}
|
|
29758
30095
|
function planMigrationSnapshot(nativeDb, dbPath) {
|
|
29759
|
-
const backupDir =
|
|
30096
|
+
const backupDir = join18(dirname13(dbPath), "backups", "sqlite");
|
|
29760
30097
|
const pragma = (name2) => Number(nativeDb.prepare(`PRAGMA main.${name2}`).get()[name2] ?? 0);
|
|
29761
30098
|
const liveBytes = (pragma("page_count") - pragma("freelist_count")) * pragma("page_size");
|
|
29762
30099
|
let availableBytes = null;
|
|
@@ -29768,13 +30105,13 @@ function planMigrationSnapshot(nativeDb, dbPath) {
|
|
|
29768
30105
|
}
|
|
29769
30106
|
const base = `migration-${formatBackupTimestamp(/* @__PURE__ */ new Date())}`;
|
|
29770
30107
|
let backupId = base;
|
|
29771
|
-
for (let n = 2;
|
|
30108
|
+
for (let n = 2; existsSync14(join18(backupDir, `${backupId}.meta.json`)); n++) {
|
|
29772
30109
|
backupId = `${base}-${n}`;
|
|
29773
30110
|
}
|
|
29774
30111
|
return {
|
|
29775
30112
|
backupDir,
|
|
29776
30113
|
backupId,
|
|
29777
|
-
snapshotPath:
|
|
30114
|
+
snapshotPath: join18(backupDir, `cleo.db.${backupId}`),
|
|
29778
30115
|
requiredBytes: liveBytes + SNAPSHOT_HEADROOM_BYTES,
|
|
29779
30116
|
availableBytes
|
|
29780
30117
|
};
|
|
@@ -30014,7 +30351,7 @@ var init_legacy_tasks_lineage = __esm({
|
|
|
30014
30351
|
|
|
30015
30352
|
// packages/core/src/store/ports/domain-binding.ts
|
|
30016
30353
|
import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
|
|
30017
|
-
import { resolve as
|
|
30354
|
+
import { resolve as resolve8 } from "node:path";
|
|
30018
30355
|
function getCleoRuntime() {
|
|
30019
30356
|
if (!_runtime) {
|
|
30020
30357
|
_runtime = createCleoRuntime();
|
|
@@ -30082,6 +30419,8 @@ async function bindAgainst(key, store, establish) {
|
|
|
30082
30419
|
() => establish(native, store)
|
|
30083
30420
|
);
|
|
30084
30421
|
return { store, native, db };
|
|
30422
|
+
} catch (error) {
|
|
30423
|
+
throw explainSchemaWriteDenial(native, error);
|
|
30085
30424
|
} finally {
|
|
30086
30425
|
membership.active = false;
|
|
30087
30426
|
}
|
|
@@ -30131,7 +30470,7 @@ async function bindLive(scope, key, dbPath, openStore, establish) {
|
|
|
30131
30470
|
);
|
|
30132
30471
|
}
|
|
30133
30472
|
async function bindProjectDomain(domain, cwd, establish) {
|
|
30134
|
-
const dbPath =
|
|
30473
|
+
const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
|
|
30135
30474
|
const row = await bindLive(
|
|
30136
30475
|
"project",
|
|
30137
30476
|
bindingKey("project", dbPath, domain),
|
|
@@ -30142,7 +30481,7 @@ async function bindProjectDomain(domain, cwd, establish) {
|
|
|
30142
30481
|
return row;
|
|
30143
30482
|
}
|
|
30144
30483
|
async function bindGlobalDomain(domain, establish, cwd) {
|
|
30145
|
-
const dbPath =
|
|
30484
|
+
const dbPath = resolve8(resolveDualScopeDbPath("global"));
|
|
30146
30485
|
const row = await bindLive(
|
|
30147
30486
|
"global",
|
|
30148
30487
|
bindingKey("global", dbPath, domain),
|
|
@@ -30153,7 +30492,7 @@ async function bindGlobalDomain(domain, establish, cwd) {
|
|
|
30153
30492
|
return row;
|
|
30154
30493
|
}
|
|
30155
30494
|
async function bindGlobalDomainAtPath(domain, dbPath, establish) {
|
|
30156
|
-
const normalized =
|
|
30495
|
+
const normalized = resolve8(dbPath);
|
|
30157
30496
|
const row = await bindLive(
|
|
30158
30497
|
"global",
|
|
30159
30498
|
bindingKey("global", normalized, domain),
|
|
@@ -30164,7 +30503,7 @@ async function bindGlobalDomainAtPath(domain, dbPath, establish) {
|
|
|
30164
30503
|
return row;
|
|
30165
30504
|
}
|
|
30166
30505
|
function peekDomainAtPath(scope, dbPath, domain) {
|
|
30167
|
-
const row = _bindings.get(bindingKey(scope,
|
|
30506
|
+
const row = _bindings.get(bindingKey(scope, resolve8(dbPath), domain));
|
|
30168
30507
|
if (!row?.native.isOpen) return null;
|
|
30169
30508
|
return row;
|
|
30170
30509
|
}
|
|
@@ -30173,12 +30512,12 @@ function releaseDomainBindings(filter) {
|
|
|
30173
30512
|
_bindings.clear();
|
|
30174
30513
|
return;
|
|
30175
30514
|
}
|
|
30176
|
-
const wantPath = filter.dbPath === void 0 ? void 0 :
|
|
30515
|
+
const wantPath = filter.dbPath === void 0 ? void 0 : resolve8(filter.dbPath);
|
|
30177
30516
|
for (const key of [..._bindings.keys()]) {
|
|
30178
|
-
const
|
|
30517
|
+
const sep6 = key.indexOf("::");
|
|
30179
30518
|
const lastSep = key.lastIndexOf("::");
|
|
30180
|
-
const scope = key.slice(0,
|
|
30181
|
-
const dbPath = key.slice(
|
|
30519
|
+
const scope = key.slice(0, sep6);
|
|
30520
|
+
const dbPath = key.slice(sep6 + 2, lastSep);
|
|
30182
30521
|
const domain = key.slice(lastSep + 2);
|
|
30183
30522
|
if (filter.scope !== void 0 && scope !== filter.scope) continue;
|
|
30184
30523
|
if (wantPath !== void 0 && dbPath !== wantPath) continue;
|
|
@@ -30193,7 +30532,7 @@ function boundProjectNative(domain, cwd) {
|
|
|
30193
30532
|
return peekProjectDomain(domain, cwd)?.native ?? null;
|
|
30194
30533
|
}
|
|
30195
30534
|
function peekProjectDomain(domain, cwd) {
|
|
30196
|
-
const dbPath =
|
|
30535
|
+
const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
|
|
30197
30536
|
const row = _bindings.get(bindingKey("project", dbPath, domain));
|
|
30198
30537
|
if (row?.native.isOpen) return row;
|
|
30199
30538
|
if (cwd !== void 0) return null;
|
|
@@ -30208,7 +30547,7 @@ function peekProjectDomain(domain, cwd) {
|
|
|
30208
30547
|
return sole ?? null;
|
|
30209
30548
|
}
|
|
30210
30549
|
function peekGlobalDomain(domain) {
|
|
30211
|
-
const dbPath =
|
|
30550
|
+
const dbPath = resolve8(resolveDualScopeDbPath("global"));
|
|
30212
30551
|
const row = _bindings.get(bindingKey("global", dbPath, domain));
|
|
30213
30552
|
if (!row || !row.native.isOpen) return null;
|
|
30214
30553
|
return row;
|
|
@@ -30219,6 +30558,7 @@ var init_domain_binding = __esm({
|
|
|
30219
30558
|
"use strict";
|
|
30220
30559
|
init_project_scope();
|
|
30221
30560
|
init_dual_scope_db();
|
|
30561
|
+
init_worktree_build_guard();
|
|
30222
30562
|
_runtime = null;
|
|
30223
30563
|
_bindings = /* @__PURE__ */ new Map();
|
|
30224
30564
|
_inflight = /* @__PURE__ */ new Map();
|
|
@@ -30229,9 +30569,9 @@ var init_domain_binding = __esm({
|
|
|
30229
30569
|
|
|
30230
30570
|
// packages/core/src/telemetry/sqlite.ts
|
|
30231
30571
|
import { mkdirSync as mkdirSync4 } from "node:fs";
|
|
30232
|
-
import { dirname as
|
|
30572
|
+
import { dirname as dirname14, join as join19 } from "node:path";
|
|
30233
30573
|
function getTelemetryDbPath() {
|
|
30234
|
-
return
|
|
30574
|
+
return join19(getCleoHome(), DB_FILENAME);
|
|
30235
30575
|
}
|
|
30236
30576
|
function resolveTelemetryMigrationsFolder() {
|
|
30237
30577
|
return resolveCorePackageMigrationsFolder("drizzle-telemetry");
|
|
@@ -30279,8 +30619,9 @@ async function getTelemetryDb() {
|
|
|
30279
30619
|
_initPromise = (async () => {
|
|
30280
30620
|
const dbPath = requestedPath;
|
|
30281
30621
|
_dbPath = dbPath;
|
|
30282
|
-
mkdirSync4(
|
|
30622
|
+
mkdirSync4(dirname14(dbPath), { recursive: true });
|
|
30283
30623
|
const nativeDb = openNativeDatabase(dbPath);
|
|
30624
|
+
installSchemaWriteGuard(nativeDb);
|
|
30284
30625
|
_nativeDb = nativeDb;
|
|
30285
30626
|
const db = drizzle({ client: nativeDb });
|
|
30286
30627
|
runTelemetryMigrations(nativeDb, db);
|
|
@@ -30301,6 +30642,7 @@ var init_sqlite2 = __esm({
|
|
|
30301
30642
|
init_migration_manager();
|
|
30302
30643
|
init_resolve_migrations_folder();
|
|
30303
30644
|
init_sqlite3();
|
|
30645
|
+
init_worktree_build_guard();
|
|
30304
30646
|
DB_FILENAME = "telemetry.db";
|
|
30305
30647
|
TELEMETRY_SCHEMA_VERSION = "1.0.0";
|
|
30306
30648
|
_db = null;
|
|
@@ -30311,11 +30653,11 @@ var init_sqlite2 = __esm({
|
|
|
30311
30653
|
});
|
|
30312
30654
|
|
|
30313
30655
|
// packages/core/src/store/agent-registry-store.ts
|
|
30314
|
-
import { existsSync as
|
|
30315
|
-
import { join as
|
|
30656
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
30657
|
+
import { join as join20 } from "node:path";
|
|
30316
30658
|
function getGlobalAgentRegistryDbPath() {
|
|
30317
30659
|
const cleoHome = getCleoHome();
|
|
30318
|
-
const dbPath =
|
|
30660
|
+
const dbPath = join20(cleoHome, "cleo.db");
|
|
30319
30661
|
if (!dbPath.startsWith(cleoHome)) {
|
|
30320
30662
|
throw new Error(
|
|
30321
30663
|
`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.`
|
|
@@ -30382,7 +30724,7 @@ function establishAgentRegistrySchema(native) {
|
|
|
30382
30724
|
}
|
|
30383
30725
|
async function ensureGlobalAgentRegistryDb() {
|
|
30384
30726
|
const dbPath = getGlobalAgentRegistryDbPath();
|
|
30385
|
-
const alreadyExists =
|
|
30727
|
+
const alreadyExists = existsSync15(dbPath);
|
|
30386
30728
|
let created = false;
|
|
30387
30729
|
const { native: nativeDb } = await bindGlobalDomainAtPath(
|
|
30388
30730
|
AGENT_REGISTRY_DOMAIN,
|
|
@@ -30427,8 +30769,8 @@ var init_agent_registry_store = __esm({
|
|
|
30427
30769
|
});
|
|
30428
30770
|
|
|
30429
30771
|
// packages/core/src/store/conduit-sqlite.ts
|
|
30430
|
-
import { existsSync as
|
|
30431
|
-
import { createRequire as
|
|
30772
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
30773
|
+
import { createRequire as createRequire6 } from "node:module";
|
|
30432
30774
|
function _getDrizzle() {
|
|
30433
30775
|
if (_drizzle === null) {
|
|
30434
30776
|
const mod = _require3("drizzle-orm/node-sqlite");
|
|
@@ -30456,7 +30798,7 @@ function runConduitMigrations(nativeDb) {
|
|
|
30456
30798
|
}
|
|
30457
30799
|
async function ensureConduitDb(projectRoot) {
|
|
30458
30800
|
const dbPath = getConduitDbPath(projectRoot);
|
|
30459
|
-
const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null ||
|
|
30801
|
+
const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync16(dbPath);
|
|
30460
30802
|
await bindConduitDomain(projectRoot);
|
|
30461
30803
|
return { action: alreadyExists ? "exists" : "created", path: dbPath };
|
|
30462
30804
|
}
|
|
@@ -30482,7 +30824,8 @@ var init_conduit_sqlite = __esm({
|
|
|
30482
30824
|
init_domain_binding();
|
|
30483
30825
|
init_resolve_migrations_folder();
|
|
30484
30826
|
init_sqlite_pragmas();
|
|
30485
|
-
|
|
30827
|
+
init_worktree_build_guard();
|
|
30828
|
+
_require3 = createRequire6(import.meta.url);
|
|
30486
30829
|
({ DatabaseSync: DatabaseSync2 } = _require3("node:sqlite"));
|
|
30487
30830
|
_drizzle = null;
|
|
30488
30831
|
CONDUIT_SCHEMA_VERSION = "2026.4.23";
|
|
@@ -32954,7 +33297,7 @@ __export(config_exports, {
|
|
|
32954
33297
|
parseConfigValue: () => parseConfigValue,
|
|
32955
33298
|
setConfigValue: () => setConfigValue
|
|
32956
33299
|
});
|
|
32957
|
-
import { existsSync as
|
|
33300
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
32958
33301
|
function getNestedValue(obj, path2) {
|
|
32959
33302
|
const parts = path2.split(".");
|
|
32960
33303
|
let current = obj;
|
|
@@ -33076,7 +33419,7 @@ function parseConfigValue(value) {
|
|
|
33076
33419
|
}
|
|
33077
33420
|
async function setConfigValue(key, value, cwd, opts) {
|
|
33078
33421
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
33079
|
-
if (!
|
|
33422
|
+
if (!existsSync17(configPath)) {
|
|
33080
33423
|
await atomicWriteJson(configPath, {});
|
|
33081
33424
|
}
|
|
33082
33425
|
const config = await readJson(configPath) ?? {};
|
|
@@ -33088,7 +33431,7 @@ async function setConfigValue(key, value, cwd, opts) {
|
|
|
33088
33431
|
async function applyStrictnessPreset(preset, cwd, opts) {
|
|
33089
33432
|
const definition = STRICTNESS_PRESETS[preset];
|
|
33090
33433
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
33091
|
-
if (!
|
|
33434
|
+
if (!existsSync17(configPath)) {
|
|
33092
33435
|
await atomicWriteJson(configPath, {});
|
|
33093
33436
|
}
|
|
33094
33437
|
const config = await readJson(configPath) ?? {};
|
|
@@ -33665,6 +34008,7 @@ var init_cross_db_cleanup = __esm({
|
|
|
33665
34008
|
"use strict";
|
|
33666
34009
|
init_memory_sqlite();
|
|
33667
34010
|
init_memory_schema();
|
|
34011
|
+
init_worktree_build_guard();
|
|
33668
34012
|
}
|
|
33669
34013
|
});
|
|
33670
34014
|
|
|
@@ -38357,7 +38701,7 @@ __export(sqlite_data_accessor_exports, {
|
|
|
38357
38701
|
setMetaValue: () => setMetaValue
|
|
38358
38702
|
});
|
|
38359
38703
|
import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
|
|
38360
|
-
import { resolve as
|
|
38704
|
+
import { resolve as resolve9 } from "node:path";
|
|
38361
38705
|
import {
|
|
38362
38706
|
and as and5,
|
|
38363
38707
|
eq as eq6,
|
|
@@ -38466,7 +38810,7 @@ function bindTaskAccessorScope(accessor, scope) {
|
|
|
38466
38810
|
}
|
|
38467
38811
|
async function createSqliteDataAccessor(cwd) {
|
|
38468
38812
|
const scope = captureProjectScope(
|
|
38469
|
-
|
|
38813
|
+
resolve9(cwd ?? getProjectRoot()),
|
|
38470
38814
|
worktreeScope.getStore()
|
|
38471
38815
|
);
|
|
38472
38816
|
return worktreeScope.run(
|
|
@@ -38581,7 +38925,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38581
38925
|
actor: entry.actor ?? "system",
|
|
38582
38926
|
detailsJson: entry.details ? JSON.stringify(entry.details) : "{}",
|
|
38583
38927
|
beforeJson: entry.before ? JSON.stringify(entry.before) : null,
|
|
38584
|
-
afterJson: entry.after ? JSON.stringify(entry.after) : null
|
|
38928
|
+
afterJson: entry.after ? JSON.stringify(entry.after) : null,
|
|
38929
|
+
// T12693: the session a ranking change ran in.
|
|
38930
|
+
sessionId: typeof entry.sessionId === "string" ? entry.sessionId : null
|
|
38585
38931
|
}).run()
|
|
38586
38932
|
);
|
|
38587
38933
|
});
|
|
@@ -38589,6 +38935,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38589
38935
|
async queryAuditLog(query) {
|
|
38590
38936
|
const db = await getDb(cwd);
|
|
38591
38937
|
const conditions = [];
|
|
38938
|
+
if (query.ids && query.ids.length > 0) {
|
|
38939
|
+
conditions.push(inArray4(tasksAuditLog.id, [...query.ids]));
|
|
38940
|
+
}
|
|
38592
38941
|
if (query.taskIds && query.taskIds.length > 0) {
|
|
38593
38942
|
conditions.push(inArray4(tasksAuditLog.taskId, [...query.taskIds]));
|
|
38594
38943
|
}
|
|
@@ -38607,7 +38956,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38607
38956
|
actor: tasksAuditLog.actor,
|
|
38608
38957
|
detailsJson: tasksAuditLog.detailsJson,
|
|
38609
38958
|
beforeJson: tasksAuditLog.beforeJson,
|
|
38610
|
-
afterJson: tasksAuditLog.afterJson
|
|
38959
|
+
afterJson: tasksAuditLog.afterJson,
|
|
38960
|
+
sessionId: tasksAuditLog.sessionId
|
|
38611
38961
|
}).from(tasksAuditLog).where(conditions.length > 0 ? and5(...conditions) : void 0).orderBy(sql26`${tasksAuditLog.timestamp} DESC`).limit(limit).all();
|
|
38612
38962
|
return rows.map((row) => ({
|
|
38613
38963
|
id: row.id,
|
|
@@ -38617,7 +38967,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
38617
38967
|
actor: row.actor,
|
|
38618
38968
|
detailsJson: row.detailsJson ?? null,
|
|
38619
38969
|
beforeJson: row.beforeJson ?? null,
|
|
38620
|
-
afterJson: row.afterJson ?? null
|
|
38970
|
+
afterJson: row.afterJson ?? null,
|
|
38971
|
+
sessionId: row.sessionId ?? null
|
|
38621
38972
|
}));
|
|
38622
38973
|
},
|
|
38623
38974
|
// ---- Fine-grained task operations (T5034) ----
|
|
@@ -39455,13 +39806,13 @@ var init_sqlite_data_accessor = __esm({
|
|
|
39455
39806
|
});
|
|
39456
39807
|
|
|
39457
39808
|
// packages/core/src/sequence/index.ts
|
|
39458
|
-
import { existsSync as
|
|
39459
|
-
import { join as
|
|
39809
|
+
import { existsSync as existsSync18, readFileSync as readFileSync6, renameSync as renameSync5 } from "node:fs";
|
|
39810
|
+
import { join as join21 } from "node:path";
|
|
39460
39811
|
function getLegacySequenceJsonPath(cwd) {
|
|
39461
|
-
return
|
|
39812
|
+
return join21(resolveOrCwd(cwd), ".cleo", ".sequence.json");
|
|
39462
39813
|
}
|
|
39463
39814
|
function getLegacySequencePath(cwd) {
|
|
39464
|
-
return
|
|
39815
|
+
return join21(resolveOrCwd(cwd), ".cleo", ".sequence");
|
|
39465
39816
|
}
|
|
39466
39817
|
function isValidSequenceState(value) {
|
|
39467
39818
|
if (!value || typeof value !== "object") return false;
|
|
@@ -39472,19 +39823,19 @@ function isSeedSequence(value) {
|
|
|
39472
39823
|
return value.counter === 0 && value.lastId === "T000" && value.checksum === "seed";
|
|
39473
39824
|
}
|
|
39474
39825
|
function readLegacySequenceFile(path2) {
|
|
39475
|
-
if (!
|
|
39826
|
+
if (!existsSync18(path2)) return null;
|
|
39476
39827
|
try {
|
|
39477
|
-
const parsed = JSON.parse(
|
|
39828
|
+
const parsed = JSON.parse(readFileSync6(path2, "utf-8"));
|
|
39478
39829
|
return isValidSequenceState(parsed) ? parsed : null;
|
|
39479
39830
|
} catch {
|
|
39480
39831
|
return null;
|
|
39481
39832
|
}
|
|
39482
39833
|
}
|
|
39483
39834
|
function renameLegacyFile(path2) {
|
|
39484
|
-
if (!
|
|
39835
|
+
if (!existsSync18(path2)) return;
|
|
39485
39836
|
const migratedPath = `${path2}.migrated`;
|
|
39486
39837
|
try {
|
|
39487
|
-
if (!
|
|
39838
|
+
if (!existsSync18(migratedPath)) {
|
|
39488
39839
|
renameSync5(path2, migratedPath);
|
|
39489
39840
|
return;
|
|
39490
39841
|
}
|
|
@@ -39636,9 +39987,9 @@ var init_sequence = __esm({
|
|
|
39636
39987
|
});
|
|
39637
39988
|
|
|
39638
39989
|
// packages/core/src/store/checkpoint-git-dir.ts
|
|
39639
|
-
import { join as
|
|
39990
|
+
import { join as join22 } from "node:path";
|
|
39640
39991
|
function checkpointGitDir(cleoDir) {
|
|
39641
|
-
return
|
|
39992
|
+
return join22(cleoDir, CHECKPOINT_GIT_DIRNAME);
|
|
39642
39993
|
}
|
|
39643
39994
|
var CHECKPOINT_GIT_DIRNAME;
|
|
39644
39995
|
var init_checkpoint_git_dir = __esm({
|
|
@@ -39650,12 +40001,12 @@ var init_checkpoint_git_dir = __esm({
|
|
|
39650
40001
|
|
|
39651
40002
|
// packages/core/src/store/git-checkpoint.ts
|
|
39652
40003
|
import { execFile as execFile2 } from "node:child_process";
|
|
39653
|
-
import { existsSync as
|
|
40004
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
39654
40005
|
import { readFile as readFile4, writeFile } from "node:fs/promises";
|
|
39655
|
-
import { join as
|
|
40006
|
+
import { join as join23, resolve as resolve10 } from "node:path";
|
|
39656
40007
|
import { promisify as promisify2 } from "node:util";
|
|
39657
40008
|
function makeCleoGitEnv(cleoDir) {
|
|
39658
|
-
const abs =
|
|
40009
|
+
const abs = resolve10(cleoDir);
|
|
39659
40010
|
return {
|
|
39660
40011
|
...process.env,
|
|
39661
40012
|
GIT_DIR: checkpointGitDir(abs),
|
|
@@ -39665,7 +40016,7 @@ function makeCleoGitEnv(cleoDir) {
|
|
|
39665
40016
|
async function cleoGitCommand(args, cleoDir) {
|
|
39666
40017
|
try {
|
|
39667
40018
|
const result = await execFileAsync2("git", args, {
|
|
39668
|
-
cwd:
|
|
40019
|
+
cwd: resolve10(cleoDir),
|
|
39669
40020
|
// absolute cwd so relative paths in args resolve correctly
|
|
39670
40021
|
env: makeCleoGitEnv(cleoDir),
|
|
39671
40022
|
timeout: 1e4
|
|
@@ -39676,7 +40027,7 @@ async function cleoGitCommand(args, cleoDir) {
|
|
|
39676
40027
|
}
|
|
39677
40028
|
}
|
|
39678
40029
|
function isCleoGitInitialized(cleoDir) {
|
|
39679
|
-
return
|
|
40030
|
+
return existsSync19(join23(checkpointGitDir(cleoDir), "HEAD"));
|
|
39680
40031
|
}
|
|
39681
40032
|
async function loadStateFileAllowlist(cwd) {
|
|
39682
40033
|
try {
|
|
@@ -39720,25 +40071,25 @@ async function isCleoGitRepo(cleoDir) {
|
|
|
39720
40071
|
return result.success && (result.stdout === "true" || isCleoGitInitialized(cleoDir));
|
|
39721
40072
|
}
|
|
39722
40073
|
function isMergeInProgress(cleoDir) {
|
|
39723
|
-
return
|
|
40074
|
+
return existsSync19(join23(checkpointGitDir(cleoDir), "MERGE_HEAD"));
|
|
39724
40075
|
}
|
|
39725
40076
|
async function isDetachedHead(cleoDir) {
|
|
39726
40077
|
const result = await cleoGitCommand(["symbolic-ref", "HEAD"], cleoDir);
|
|
39727
40078
|
return !result.success;
|
|
39728
40079
|
}
|
|
39729
40080
|
function isRebaseInProgress(cleoDir) {
|
|
39730
|
-
return
|
|
40081
|
+
return existsSync19(join23(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync19(join23(checkpointGitDir(cleoDir), "rebase-apply"));
|
|
39731
40082
|
}
|
|
39732
40083
|
async function recordCheckpointTime(cleoDir) {
|
|
39733
40084
|
try {
|
|
39734
|
-
const stateFile =
|
|
40085
|
+
const stateFile = join23(cleoDir, CHECKPOINT_STATE_FILE);
|
|
39735
40086
|
await writeFile(stateFile, String(Math.floor(Date.now() / 1e3)));
|
|
39736
40087
|
} catch {
|
|
39737
40088
|
}
|
|
39738
40089
|
}
|
|
39739
40090
|
async function getLastCheckpointTime(cleoDir) {
|
|
39740
40091
|
try {
|
|
39741
|
-
const stateFile =
|
|
40092
|
+
const stateFile = join23(cleoDir, CHECKPOINT_STATE_FILE);
|
|
39742
40093
|
const content = await readFile4(stateFile, "utf-8");
|
|
39743
40094
|
const epoch = parseInt(content.trim(), 10);
|
|
39744
40095
|
return Number.isNaN(epoch) ? 0 : epoch;
|
|
@@ -39750,8 +40101,8 @@ async function getChangedStateFiles(cleoDir, cwd) {
|
|
|
39750
40101
|
const changed = [];
|
|
39751
40102
|
const allStateFiles = await getAllStateFiles(cwd);
|
|
39752
40103
|
for (const stateFile of allStateFiles) {
|
|
39753
|
-
const fullPath =
|
|
39754
|
-
if (!
|
|
40104
|
+
const fullPath = join23(cleoDir, stateFile);
|
|
40105
|
+
if (!existsSync19(fullPath)) continue;
|
|
39755
40106
|
const diffResult = await cleoGitCommand(["diff", "--quiet", "--", stateFile], cleoDir);
|
|
39756
40107
|
const cachedResult = await cleoGitCommand(
|
|
39757
40108
|
["diff", "--cached", "--quiet", "--", stateFile],
|
|
@@ -39778,7 +40129,7 @@ async function shouldCheckpoint(options) {
|
|
|
39778
40129
|
const config = await loadCheckpointConfig(cwd);
|
|
39779
40130
|
if (!config.enabled) return false;
|
|
39780
40131
|
const cleoDir = getCleoDir(cwd);
|
|
39781
|
-
if (!
|
|
40132
|
+
if (!existsSync19(cleoDir)) return false;
|
|
39782
40133
|
if (!isCleoGitInitialized(cleoDir)) return false;
|
|
39783
40134
|
if (!await isCleoGitRepo(cleoDir)) return false;
|
|
39784
40135
|
if (isMergeInProgress(cleoDir)) return false;
|
|
@@ -39852,7 +40203,7 @@ var init_git_checkpoint = __esm({
|
|
|
39852
40203
|
});
|
|
39853
40204
|
|
|
39854
40205
|
// packages/core/src/store/snapshot-gate.ts
|
|
39855
|
-
import { join as
|
|
40206
|
+
import { join as join24 } from "node:path";
|
|
39856
40207
|
function readGateState(db) {
|
|
39857
40208
|
const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
|
|
39858
40209
|
const state = { generation: 0, prefixes: {} };
|
|
@@ -39917,7 +40268,7 @@ async function runGatedSnapshot(opts, snapshot) {
|
|
|
39917
40268
|
return none("debounced");
|
|
39918
40269
|
}
|
|
39919
40270
|
}
|
|
39920
|
-
const lockPath2 =
|
|
40271
|
+
const lockPath2 = join24(opts.backupDir, GATE_LOCK_BASENAME);
|
|
39921
40272
|
let release;
|
|
39922
40273
|
try {
|
|
39923
40274
|
release = await acquireLock(lockPath2, {
|
|
@@ -40473,7 +40824,7 @@ __export(data_accessor_exports, {
|
|
|
40473
40824
|
getAccessorDb: () => getAccessorDb,
|
|
40474
40825
|
getTaskAccessor: () => getTaskAccessor
|
|
40475
40826
|
});
|
|
40476
|
-
import { resolve as
|
|
40827
|
+
import { resolve as resolve11 } from "node:path";
|
|
40477
40828
|
function assertTestEnv(dbPath) {
|
|
40478
40829
|
const testMode = process.env["CLEO_TEST_MODE"];
|
|
40479
40830
|
if (testMode !== "1") return;
|
|
@@ -40494,7 +40845,7 @@ function assertTestEnv(dbPath) {
|
|
|
40494
40845
|
}
|
|
40495
40846
|
}
|
|
40496
40847
|
async function createDataAccessor(cwd) {
|
|
40497
|
-
const root =
|
|
40848
|
+
const root = resolve11(cwd ?? getProjectRoot());
|
|
40498
40849
|
const inherited = worktreeScope.getStore();
|
|
40499
40850
|
const captured = inherited ? { ...inherited } : void 0;
|
|
40500
40851
|
captured?.execution?.assertActive();
|
|
@@ -40538,7 +40889,7 @@ __export(memory_sqlite_exports, {
|
|
|
40538
40889
|
resetBrainDbState: () => resetBrainDbState,
|
|
40539
40890
|
resolveBrainMigrationsFolder: () => resolveBrainMigrationsFolder
|
|
40540
40891
|
});
|
|
40541
|
-
import { createRequire as
|
|
40892
|
+
import { createRequire as createRequire7 } from "node:module";
|
|
40542
40893
|
function _getDrizzle2() {
|
|
40543
40894
|
if (_drizzle2 === null) {
|
|
40544
40895
|
const mod = _require4("drizzle-orm/node-sqlite");
|
|
@@ -40675,7 +41026,7 @@ var init_memory_sqlite = __esm({
|
|
|
40675
41026
|
init_resolve_migrations_folder();
|
|
40676
41027
|
init_memory_schema();
|
|
40677
41028
|
init_twin_collapse();
|
|
40678
|
-
_require4 =
|
|
41029
|
+
_require4 = createRequire7(import.meta.url);
|
|
40679
41030
|
_drizzle2 = null;
|
|
40680
41031
|
BRAIN_SCHEMA_VERSION = "1.0.0";
|
|
40681
41032
|
CONSOLIDATED_BRAIN_TABLES = [
|
|
@@ -40863,11 +41214,11 @@ var init_skills_schema = __esm({
|
|
|
40863
41214
|
});
|
|
40864
41215
|
|
|
40865
41216
|
// packages/core/src/store/skills-db.ts
|
|
40866
|
-
import { join as
|
|
41217
|
+
import { join as join25 } from "node:path";
|
|
40867
41218
|
import { and as and6, eq as eq8 } from "drizzle-orm";
|
|
40868
41219
|
function getDefaultSkillsDbPath() {
|
|
40869
41220
|
const cleoHome = getCleoHome();
|
|
40870
|
-
const dbPath =
|
|
41221
|
+
const dbPath = join25(cleoHome, "cleo.db");
|
|
40871
41222
|
if (!dbPath.startsWith(cleoHome)) {
|
|
40872
41223
|
throw new Error(
|
|
40873
41224
|
`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.`
|
|
@@ -40915,19 +41266,19 @@ import {
|
|
|
40915
41266
|
chmodSync,
|
|
40916
41267
|
closeSync,
|
|
40917
41268
|
copyFileSync as copyFileSync3,
|
|
40918
|
-
existsSync as
|
|
41269
|
+
existsSync as existsSync20,
|
|
40919
41270
|
fsyncSync,
|
|
40920
41271
|
linkSync,
|
|
40921
41272
|
mkdirSync as mkdirSync5,
|
|
40922
41273
|
openSync,
|
|
40923
41274
|
readdirSync as readdirSync5,
|
|
40924
|
-
realpathSync as
|
|
41275
|
+
realpathSync as realpathSync7,
|
|
40925
41276
|
renameSync as renameSync6,
|
|
40926
41277
|
rmSync,
|
|
40927
41278
|
statSync as statSync6,
|
|
40928
41279
|
unlinkSync as unlinkSync3
|
|
40929
41280
|
} from "node:fs";
|
|
40930
|
-
import { dirname as
|
|
41281
|
+
import { dirname as dirname15, join as join26, sep as sep4 } from "node:path";
|
|
40931
41282
|
function resolveInventoryPath(entry, cwd) {
|
|
40932
41283
|
try {
|
|
40933
41284
|
if (entry.tier === "global") {
|
|
@@ -40963,8 +41314,8 @@ async function openAgentRegistryDbForSnapshot() {
|
|
|
40963
41314
|
}
|
|
40964
41315
|
async function openTelemetryDbForSnapshot() {
|
|
40965
41316
|
try {
|
|
40966
|
-
const path2 =
|
|
40967
|
-
if (!
|
|
41317
|
+
const path2 = join26(getCleoHome(), "telemetry.db");
|
|
41318
|
+
if (!existsSync20(path2)) return null;
|
|
40968
41319
|
} catch {
|
|
40969
41320
|
return null;
|
|
40970
41321
|
}
|
|
@@ -41076,7 +41427,7 @@ function rotateSnapshots(backupDir, prefix, justWritten) {
|
|
|
41076
41427
|
for (const name2 of names) {
|
|
41077
41428
|
if (keep.has(name2)) continue;
|
|
41078
41429
|
try {
|
|
41079
|
-
unlinkSync3(
|
|
41430
|
+
unlinkSync3(join26(backupDir, name2));
|
|
41080
41431
|
} catch {
|
|
41081
41432
|
}
|
|
41082
41433
|
}
|
|
@@ -41098,7 +41449,7 @@ async function snapshotProjectTargetsGated(targets, opts) {
|
|
|
41098
41449
|
let backupDir;
|
|
41099
41450
|
try {
|
|
41100
41451
|
const cleoDir = getCleoDir(cwd);
|
|
41101
|
-
backupDir =
|
|
41452
|
+
backupDir = join26(cleoDir, "backups", "sqlite");
|
|
41102
41453
|
mkdirSync5(backupDir, { recursive: true });
|
|
41103
41454
|
} catch {
|
|
41104
41455
|
return null;
|
|
@@ -41130,7 +41481,7 @@ function sourceFileOf(db) {
|
|
|
41130
41481
|
const location = db.location();
|
|
41131
41482
|
if (!location) return null;
|
|
41132
41483
|
try {
|
|
41133
|
-
return
|
|
41484
|
+
return realpathSync7(location);
|
|
41134
41485
|
} catch {
|
|
41135
41486
|
return location;
|
|
41136
41487
|
}
|
|
@@ -41141,10 +41492,10 @@ function hasLocation(db) {
|
|
|
41141
41492
|
function assertOwnedByProject(source, prefix, cwd) {
|
|
41142
41493
|
let cleoDir = getCleoDir(cwd);
|
|
41143
41494
|
try {
|
|
41144
|
-
cleoDir =
|
|
41495
|
+
cleoDir = realpathSync7(cleoDir);
|
|
41145
41496
|
} catch {
|
|
41146
41497
|
}
|
|
41147
|
-
if (!source.startsWith(cleoDir +
|
|
41498
|
+
if (!source.startsWith(cleoDir + sep4)) {
|
|
41148
41499
|
throw new Error(
|
|
41149
41500
|
`refusing to snapshot ${prefix}: its database ${source} is not inside ${cleoDir}`
|
|
41150
41501
|
);
|
|
@@ -41173,7 +41524,7 @@ function commitSnapshotFile(tmp, dest) {
|
|
|
41173
41524
|
}
|
|
41174
41525
|
renameSync6(tmp, dest);
|
|
41175
41526
|
try {
|
|
41176
|
-
const dirFd = openSync(
|
|
41527
|
+
const dirFd = openSync(dirname15(dest), "r");
|
|
41177
41528
|
try {
|
|
41178
41529
|
fsyncSync(dirFd);
|
|
41179
41530
|
} finally {
|
|
@@ -41196,7 +41547,7 @@ function removeDeadTempSnapshots(backupDir) {
|
|
|
41196
41547
|
const m = TEMP_SNAPSHOT_RE.exec(name2);
|
|
41197
41548
|
if (!m) continue;
|
|
41198
41549
|
const pid = Number(m[1]);
|
|
41199
|
-
const path2 =
|
|
41550
|
+
const path2 = join26(backupDir, name2);
|
|
41200
41551
|
const stale = pid !== process.pid && (!isPidAlive2(pid) || Date.now() - statSync6(path2).mtimeMs > TEMP_SNAPSHOT_MAX_AGE_MS);
|
|
41201
41552
|
if (stale) rmSync(path2, { force: true });
|
|
41202
41553
|
}
|
|
@@ -41206,7 +41557,7 @@ function removeDeadTempSnapshots(backupDir) {
|
|
|
41206
41557
|
async function freeSnapshotName(backupDir, prefix) {
|
|
41207
41558
|
for (let attempt = 0; attempt < SNAPSHOT_NAME_ATTEMPTS; attempt++) {
|
|
41208
41559
|
const name2 = `${prefix}-${formatTimestamp(/* @__PURE__ */ new Date())}.db`;
|
|
41209
|
-
if (!
|
|
41560
|
+
if (!existsSync20(join26(backupDir, name2))) return name2;
|
|
41210
41561
|
await new Promise((r) => setTimeout(r, 1e3 - Date.now() % 1e3 + 5));
|
|
41211
41562
|
}
|
|
41212
41563
|
throw new Error(`no free snapshot filename for ${prefix} in ${backupDir}`);
|
|
@@ -41234,7 +41585,7 @@ async function snapshotOne(target, backupDir, writtenBySource, cwd) {
|
|
|
41234
41585
|
if (opened && target.closeDb) target.closeDb(opened);
|
|
41235
41586
|
throw err;
|
|
41236
41587
|
}
|
|
41237
|
-
const dest =
|
|
41588
|
+
const dest = join26(backupDir, destName);
|
|
41238
41589
|
removeDeadTempSnapshots(backupDir);
|
|
41239
41590
|
const existing = source !== null ? writtenBySource.get(source) : void 0;
|
|
41240
41591
|
if (existing !== void 0) {
|
|
@@ -41288,13 +41639,13 @@ async function vacuumIntoBackup(opts = {}) {
|
|
|
41288
41639
|
function listSqliteBackupsForPrefix(prefix, cwd) {
|
|
41289
41640
|
try {
|
|
41290
41641
|
const cleoDir = getCleoDir(cwd);
|
|
41291
|
-
const backupDir =
|
|
41292
|
-
if (!
|
|
41642
|
+
const backupDir = join26(cleoDir, "backups", "sqlite");
|
|
41643
|
+
if (!existsSync20(backupDir)) return [];
|
|
41293
41644
|
const pattern = snapshotPattern(prefix);
|
|
41294
41645
|
return readdirSync5(backupDir).filter((f) => pattern.test(f)).map((f) => ({
|
|
41295
41646
|
name: f,
|
|
41296
|
-
path:
|
|
41297
|
-
mtimeMs: statSync6(
|
|
41647
|
+
path: join26(backupDir, f),
|
|
41648
|
+
mtimeMs: statSync6(join26(backupDir, f)).mtimeMs
|
|
41298
41649
|
})).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
41299
41650
|
} catch {
|
|
41300
41651
|
return [];
|
|
@@ -41367,13 +41718,13 @@ __export(sqlite_exports, {
|
|
|
41367
41718
|
seedTasksMeta: () => seedTasksMeta,
|
|
41368
41719
|
worktreeRecoveryRefusal: () => worktreeRecoveryRefusal
|
|
41369
41720
|
});
|
|
41370
|
-
import { copyFileSync as copyFileSync4, existsSync as
|
|
41371
|
-
import { createRequire as
|
|
41372
|
-
import { basename as basename8, dirname as
|
|
41721
|
+
import { copyFileSync as copyFileSync4, existsSync as existsSync21, realpathSync as realpathSync8, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
41722
|
+
import { createRequire as createRequire8 } from "node:module";
|
|
41723
|
+
import { basename as basename8, dirname as dirname16, resolve as resolve12 } from "node:path";
|
|
41373
41724
|
import { eq as eq9 } from "drizzle-orm";
|
|
41374
41725
|
function _getDrizzle3() {
|
|
41375
41726
|
if (_drizzle3 === null) {
|
|
41376
|
-
const _require7 =
|
|
41727
|
+
const _require7 = createRequire8(import.meta.url);
|
|
41377
41728
|
const mod = _require7("drizzle-orm/node-sqlite");
|
|
41378
41729
|
_drizzle3 = mod.drizzle;
|
|
41379
41730
|
}
|
|
@@ -41409,16 +41760,16 @@ function countBackupTasks(backupDb) {
|
|
|
41409
41760
|
return 0;
|
|
41410
41761
|
}
|
|
41411
41762
|
function isSameDirectory(a, b) {
|
|
41412
|
-
if (
|
|
41763
|
+
if (resolve12(a) === resolve12(b)) return true;
|
|
41413
41764
|
try {
|
|
41414
|
-
return
|
|
41765
|
+
return realpathSync8(a) === realpathSync8(b);
|
|
41415
41766
|
} catch {
|
|
41416
41767
|
return false;
|
|
41417
41768
|
}
|
|
41418
41769
|
}
|
|
41419
41770
|
function worktreeRecoveryRefusal(dbPath) {
|
|
41420
|
-
const storeCleoDir =
|
|
41421
|
-
const root =
|
|
41771
|
+
const storeCleoDir = dirname16(dbPath);
|
|
41772
|
+
const root = dirname16(storeCleoDir);
|
|
41422
41773
|
if (basename8(storeCleoDir) !== ".cleo" || !isGitLinkedCheckout(root)) return null;
|
|
41423
41774
|
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).`;
|
|
41424
41775
|
}
|
|
@@ -41430,7 +41781,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
41430
41781
|
const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks_tasks").get();
|
|
41431
41782
|
const taskCount = countResult?.cnt ?? 0;
|
|
41432
41783
|
if (taskCount > 0) return false;
|
|
41433
|
-
const storeCleoDir =
|
|
41784
|
+
const storeCleoDir = dirname16(dbPath);
|
|
41434
41785
|
const worktreeRefusal = worktreeRecoveryRefusal(dbPath);
|
|
41435
41786
|
if (worktreeRefusal !== null) {
|
|
41436
41787
|
log15.warn({ dbPath }, worktreeRefusal);
|
|
@@ -41441,7 +41792,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
41441
41792
|
return false;
|
|
41442
41793
|
}
|
|
41443
41794
|
const newestBackup = backups[0];
|
|
41444
|
-
const backupCleoDir =
|
|
41795
|
+
const backupCleoDir = dirname16(dirname16(dirname16(newestBackup.path)));
|
|
41445
41796
|
if (!isSameDirectory(backupCleoDir, storeCleoDir)) {
|
|
41446
41797
|
log15.warn(
|
|
41447
41798
|
{ dbPath, backupPath: newestBackup.path },
|
|
@@ -41563,6 +41914,7 @@ function runMigrations(nativeDb, db, dbPath) {
|
|
|
41563
41914
|
try {
|
|
41564
41915
|
migrateWithRetry(db, migrationsFolder, nativeDb, "tasks", "sqlite");
|
|
41565
41916
|
} catch (error) {
|
|
41917
|
+
if (isWorktreeBuildSchemaError(error)) throw error;
|
|
41566
41918
|
if (isSqliteBusy(error) || !tableExists(nativeDb, "tasks_tasks")) throw error;
|
|
41567
41919
|
try {
|
|
41568
41920
|
rebuildLegacyTasksLineage(
|
|
@@ -41604,7 +41956,7 @@ async function getSchemaVersion(cwd) {
|
|
|
41604
41956
|
return result[0]?.value ?? null;
|
|
41605
41957
|
}
|
|
41606
41958
|
function dbExists(cwd) {
|
|
41607
|
-
return
|
|
41959
|
+
return existsSync21(resolveDualScopeDbPath("project", cwd));
|
|
41608
41960
|
}
|
|
41609
41961
|
function getNativeDb(cwd) {
|
|
41610
41962
|
return boundProjectNative("tasks", cwd);
|
|
@@ -41640,6 +41992,7 @@ var init_sqlite3 = __esm({
|
|
|
41640
41992
|
init_resolve_migrations_folder();
|
|
41641
41993
|
init_sqlite_backup();
|
|
41642
41994
|
init_twin_collapse();
|
|
41995
|
+
init_worktree_build_guard();
|
|
41643
41996
|
init_worktree_isolation_guard();
|
|
41644
41997
|
init_sqlite_native();
|
|
41645
41998
|
init_tasks_schema();
|
|
@@ -41668,15 +42021,15 @@ var init_sqlite3 = __esm({
|
|
|
41668
42021
|
// packages/core/src/store/exodus/migrate.ts
|
|
41669
42022
|
import {
|
|
41670
42023
|
copyFileSync as copyFileSync5,
|
|
41671
|
-
existsSync as
|
|
42024
|
+
existsSync as existsSync22,
|
|
41672
42025
|
mkdirSync as mkdirSync6,
|
|
41673
|
-
readFileSync as
|
|
42026
|
+
readFileSync as readFileSync7,
|
|
41674
42027
|
renameSync as renameSync8,
|
|
41675
42028
|
statSync as statSync7,
|
|
41676
42029
|
unlinkSync as unlinkSync5,
|
|
41677
42030
|
writeFileSync as writeFileSync6
|
|
41678
42031
|
} from "node:fs";
|
|
41679
|
-
import { join as
|
|
42032
|
+
import { join as join27 } from "node:path";
|
|
41680
42033
|
function getSqliteVersion(db) {
|
|
41681
42034
|
try {
|
|
41682
42035
|
const row = db.prepare("SELECT sqlite_version() AS v").get();
|
|
@@ -41707,24 +42060,24 @@ function restoreGrandfatheredGuards(db, suspended) {
|
|
|
41707
42060
|
}
|
|
41708
42061
|
}
|
|
41709
42062
|
function writeJournal(stagingDir, journal) {
|
|
41710
|
-
const journalPath =
|
|
42063
|
+
const journalPath = join27(stagingDir, JOURNAL_FILENAME);
|
|
41711
42064
|
const tmpPath = `${journalPath}.tmp`;
|
|
41712
42065
|
writeFileSync6(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
|
|
41713
42066
|
renameSync8(tmpPath, journalPath);
|
|
41714
42067
|
}
|
|
41715
42068
|
function readJournal(stagingDir) {
|
|
41716
|
-
const journalPath =
|
|
41717
|
-
if (!
|
|
42069
|
+
const journalPath = join27(stagingDir, JOURNAL_FILENAME);
|
|
42070
|
+
if (!existsSync22(journalPath)) return null;
|
|
41718
42071
|
try {
|
|
41719
|
-
return JSON.parse(
|
|
42072
|
+
return JSON.parse(readFileSync7(journalPath, "utf8"));
|
|
41720
42073
|
} catch {
|
|
41721
42074
|
return null;
|
|
41722
42075
|
}
|
|
41723
42076
|
}
|
|
41724
42077
|
function clearExodusJournal(stagingDir) {
|
|
41725
|
-
const journalPath =
|
|
42078
|
+
const journalPath = join27(stagingDir, JOURNAL_FILENAME);
|
|
41726
42079
|
try {
|
|
41727
|
-
if (!
|
|
42080
|
+
if (!existsSync22(journalPath)) return false;
|
|
41728
42081
|
unlinkSync5(journalPath);
|
|
41729
42082
|
log10.info(
|
|
41730
42083
|
{ stagingDir },
|
|
@@ -42020,7 +42373,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42020
42373
|
mkdirSync6(stagingDir, { recursive: true });
|
|
42021
42374
|
let sqliteVersion = "unknown";
|
|
42022
42375
|
for (const src of sources) {
|
|
42023
|
-
if (
|
|
42376
|
+
if (existsSync22(src.path)) {
|
|
42024
42377
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
42025
42378
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
42026
42379
|
snap.close();
|
|
@@ -42050,15 +42403,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42050
42403
|
let reseedProject = null;
|
|
42051
42404
|
try {
|
|
42052
42405
|
for (const src of sources) {
|
|
42053
|
-
if (!
|
|
42054
|
-
const backupDest =
|
|
42406
|
+
if (!existsSync22(src.path)) continue;
|
|
42407
|
+
const backupDest = join27(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
42055
42408
|
const srcBytes = safeStatBytes(src.path);
|
|
42056
42409
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
42057
42410
|
if (skipStagingCopy) {
|
|
42058
42411
|
onProgress?.(
|
|
42059
42412
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
42060
42413
|
);
|
|
42061
|
-
} else if (!
|
|
42414
|
+
} else if (!existsSync22(backupDest)) {
|
|
42062
42415
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
42063
42416
|
copyFileSync5(src.path, backupDest);
|
|
42064
42417
|
backupPaths.push(backupDest);
|
|
@@ -42091,8 +42444,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
42091
42444
|
}
|
|
42092
42445
|
prepareExodusRecovery(projectNative, stagingDir);
|
|
42093
42446
|
if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
|
|
42094
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
42095
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
42447
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync22(s.path));
|
|
42448
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync22(s.path));
|
|
42096
42449
|
if (globalNative === null && globalSources.length > 0)
|
|
42097
42450
|
throw new Error("A projectOnly exodus run was given global-scope sources");
|
|
42098
42451
|
await migrateScope(
|
|
@@ -42400,9 +42753,9 @@ __export(reconcile_exports, {
|
|
|
42400
42753
|
reconcileSupersededStores: () => reconcileSupersededStores,
|
|
42401
42754
|
unmigratedBareSources: () => unmigratedBareSources
|
|
42402
42755
|
});
|
|
42403
|
-
import { copyFileSync as copyFileSync6, existsSync as
|
|
42756
|
+
import { copyFileSync as copyFileSync6, existsSync as existsSync23, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
42404
42757
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
42405
|
-
import { basename as basename9, join as
|
|
42758
|
+
import { basename as basename9, join as join28 } from "node:path";
|
|
42406
42759
|
function ident2(name2) {
|
|
42407
42760
|
return `"${name2.replace(/"/g, '""')}"`;
|
|
42408
42761
|
}
|
|
@@ -42471,7 +42824,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
|
|
|
42471
42824
|
}
|
|
42472
42825
|
function legacySourcesHoldRows(sources) {
|
|
42473
42826
|
for (const src of sources) {
|
|
42474
|
-
if (!
|
|
42827
|
+
if (!existsSync23(src.path)) continue;
|
|
42475
42828
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
42476
42829
|
try {
|
|
42477
42830
|
for (const table of orderTablesForCopy(snap.db)) {
|
|
@@ -42502,8 +42855,8 @@ async function bareTaskCoreSource(liveStorePath, resolveTarget, outDir) {
|
|
|
42502
42855
|
live.close();
|
|
42503
42856
|
}
|
|
42504
42857
|
if (tables.length === 0) return null;
|
|
42505
|
-
const seedPath = await buildFreshProjectStore(
|
|
42506
|
-
const path2 =
|
|
42858
|
+
const seedPath = await buildFreshProjectStore(join28(outDir, "fresh-project-seed.db"));
|
|
42859
|
+
const path2 = join28(outDir, "cleo-bare-task-core.db");
|
|
42507
42860
|
const snap = openCleoDbSnapshot(path2, { readOnly: false });
|
|
42508
42861
|
let kept = 0;
|
|
42509
42862
|
try {
|
|
@@ -42551,7 +42904,7 @@ async function buildFreshProjectStore(path2) {
|
|
|
42551
42904
|
}
|
|
42552
42905
|
function snapshotFresherBareRows(barePath, legacyTasksPath, stagingDir) {
|
|
42553
42906
|
if (legacyTasksPath === void 0) return null;
|
|
42554
|
-
const path2 =
|
|
42907
|
+
const path2 = join28(stagingDir, "cleo-bare-task-core-fresher.db");
|
|
42555
42908
|
const snap = openCleoDbSnapshot(barePath, { readOnly: true });
|
|
42556
42909
|
try {
|
|
42557
42910
|
snap.db.exec(`VACUUM INTO '${path2.replace(/'/g, "''")}'`);
|
|
@@ -42702,7 +43055,7 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
42702
43055
|
const additive = options.additive === true;
|
|
42703
43056
|
const plan = buildExodusPlan(projectRoot);
|
|
42704
43057
|
const resolveTarget = await buildRuntimeTargetResolver();
|
|
42705
|
-
const scratch = mkdtempSync(
|
|
43058
|
+
const scratch = mkdtempSync(join28(tmpdir3(), "cleo-reconcile-"));
|
|
42706
43059
|
try {
|
|
42707
43060
|
return await reconcileWithScratch(
|
|
42708
43061
|
projectRoot,
|
|
@@ -42718,8 +43071,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
42718
43071
|
}
|
|
42719
43072
|
}
|
|
42720
43073
|
async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
|
|
42721
|
-
const fileSources = plan.sources.filter((s) => s.targetScope === "project" &&
|
|
42722
|
-
const bare = !additive &&
|
|
43074
|
+
const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync23(s.path));
|
|
43075
|
+
const bare = !additive && existsSync23(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
|
|
42723
43076
|
const copyResolver = additive ? (sourceName, legacyTable) => {
|
|
42724
43077
|
const r = resolveTarget(sourceName, legacyTable);
|
|
42725
43078
|
return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
|
|
@@ -42738,7 +43091,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42738
43091
|
stagingDir: null,
|
|
42739
43092
|
receiptPath: null
|
|
42740
43093
|
};
|
|
42741
|
-
if (sources.length === 0 || !
|
|
43094
|
+
if (sources.length === 0 || !existsSync23(liveStorePath)) {
|
|
42742
43095
|
return {
|
|
42743
43096
|
...base,
|
|
42744
43097
|
outcome: "nothing-to-reconcile",
|
|
@@ -42778,11 +43131,11 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42778
43131
|
};
|
|
42779
43132
|
}
|
|
42780
43133
|
const iso = (/* @__PURE__ */ new Date()).toISOString().replace(/[:]/g, "").replace(/\..+Z$/, "Z");
|
|
42781
|
-
const stagingDir =
|
|
43134
|
+
const stagingDir = join28(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
|
|
42782
43135
|
mkdirSync7(stagingDir, { recursive: true });
|
|
42783
43136
|
const copySources = sources.map((s) => {
|
|
42784
43137
|
if (s !== bare) return s;
|
|
42785
|
-
const kept =
|
|
43138
|
+
const kept = join28(stagingDir, basename9(s.path));
|
|
42786
43139
|
copyFileSync6(s.path, kept);
|
|
42787
43140
|
return { ...s, path: kept };
|
|
42788
43141
|
});
|
|
@@ -42802,7 +43155,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42802
43155
|
const result = await withLock(
|
|
42803
43156
|
`${liveStorePath}.exodus-on-open.lock`,
|
|
42804
43157
|
async () => {
|
|
42805
|
-
const liveBefore =
|
|
43158
|
+
const liveBefore = join28(scratch, "live-before.db");
|
|
42806
43159
|
snapshotLive(liveStorePath, liveBefore);
|
|
42807
43160
|
const migrated = await runExodusMigrate(reconcilePlan, false, (msg) => log11.debug(msg), {
|
|
42808
43161
|
projectOnly: true,
|
|
@@ -42852,7 +43205,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
42852
43205
|
},
|
|
42853
43206
|
{ stale: 6e5, retries: 30 }
|
|
42854
43207
|
);
|
|
42855
|
-
const receiptPath =
|
|
43208
|
+
const receiptPath = join28(stagingDir, RECEIPT_FILENAME);
|
|
42856
43209
|
const receipt2 = { ...result, receiptPath };
|
|
42857
43210
|
writeFileSync7(receiptPath, `${JSON.stringify(receipt2, null, 2)}
|
|
42858
43211
|
`, "utf8");
|
|
@@ -42929,20 +43282,20 @@ var init_seal = __esm({
|
|
|
42929
43282
|
});
|
|
42930
43283
|
|
|
42931
43284
|
// packages/core/src/store/exodus/status.ts
|
|
42932
|
-
import { existsSync as
|
|
42933
|
-
import { join as
|
|
43285
|
+
import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync8, statSync as statSync8 } from "node:fs";
|
|
43286
|
+
import { join as join29 } from "node:path";
|
|
42934
43287
|
function readJournal2(stagingDir) {
|
|
42935
|
-
const p =
|
|
42936
|
-
if (!
|
|
43288
|
+
const p = join29(stagingDir, JOURNAL_FILENAME2);
|
|
43289
|
+
if (!existsSync24(p)) return null;
|
|
42937
43290
|
try {
|
|
42938
|
-
return JSON.parse(
|
|
43291
|
+
return JSON.parse(readFileSync8(p, "utf8"));
|
|
42939
43292
|
} catch {
|
|
42940
43293
|
return null;
|
|
42941
43294
|
}
|
|
42942
43295
|
}
|
|
42943
43296
|
function findStagingDirs(cleoDir) {
|
|
42944
43297
|
try {
|
|
42945
|
-
return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) =>
|
|
43298
|
+
return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join29(cleoDir, e.name)).sort().reverse();
|
|
42946
43299
|
} catch {
|
|
42947
43300
|
return [];
|
|
42948
43301
|
}
|
|
@@ -42965,15 +43318,15 @@ function runExodusStatus(cwd) {
|
|
|
42965
43318
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
42966
43319
|
name: s.name,
|
|
42967
43320
|
path: s.path,
|
|
42968
|
-
exists:
|
|
43321
|
+
exists: existsSync24(s.path),
|
|
42969
43322
|
bytes: safeBytes(s.path)
|
|
42970
43323
|
}));
|
|
42971
43324
|
return {
|
|
42972
43325
|
hasStaging: latestStaging !== null,
|
|
42973
43326
|
stagingDir: latestStaging,
|
|
42974
43327
|
journal,
|
|
42975
|
-
projectDbExists:
|
|
42976
|
-
globalDbExists:
|
|
43328
|
+
projectDbExists: existsSync24(projectDbPath),
|
|
43329
|
+
globalDbExists: existsSync24(globalDbPath),
|
|
42977
43330
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
42978
43331
|
sources: sourcesInfo
|
|
42979
43332
|
};
|
|
@@ -42990,8 +43343,8 @@ var init_status = __esm({
|
|
|
42990
43343
|
});
|
|
42991
43344
|
|
|
42992
43345
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
42993
|
-
import { existsSync as
|
|
42994
|
-
import { createRequire as
|
|
43346
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
43347
|
+
import { createRequire as createRequire9 } from "node:module";
|
|
42995
43348
|
function orderByClause(db, tableName) {
|
|
42996
43349
|
try {
|
|
42997
43350
|
const pragma = db.prepare(`PRAGMA table_info("${tableName}")`).all();
|
|
@@ -43255,7 +43608,7 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
|
|
|
43255
43608
|
const anyFeeder = (targetTable, probe) => {
|
|
43256
43609
|
for (const feeder of feedersOf(targetTable)) {
|
|
43257
43610
|
const src = sources.find((s) => s.name === feeder.sourceName);
|
|
43258
|
-
if (src === void 0 || !
|
|
43611
|
+
if (src === void 0 || !existsSync25(src.path)) continue;
|
|
43259
43612
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
43260
43613
|
try {
|
|
43261
43614
|
if (!tableExists3(snap.db, feeder.legacyTable)) continue;
|
|
@@ -43310,7 +43663,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43310
43663
|
const preExistingForeignKeyViolations = [];
|
|
43311
43664
|
const failureLines = [];
|
|
43312
43665
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
43313
|
-
if (!
|
|
43666
|
+
if (!existsSync25(projectDbPath)) {
|
|
43314
43667
|
return {
|
|
43315
43668
|
ok: false,
|
|
43316
43669
|
tables: [],
|
|
@@ -43321,7 +43674,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43321
43674
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
43322
43675
|
};
|
|
43323
43676
|
}
|
|
43324
|
-
if (!
|
|
43677
|
+
if (!existsSync25(globalDbPath)) {
|
|
43325
43678
|
return {
|
|
43326
43679
|
ok: false,
|
|
43327
43680
|
tables: [],
|
|
@@ -43336,7 +43689,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
43336
43689
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
43337
43690
|
try {
|
|
43338
43691
|
for (const src of sources) {
|
|
43339
|
-
if (!
|
|
43692
|
+
if (!existsSync25(src.path)) {
|
|
43340
43693
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
43341
43694
|
continue;
|
|
43342
43695
|
}
|
|
@@ -43531,7 +43884,7 @@ var init_verify_migration = __esm({
|
|
|
43531
43884
|
init_column_transforms();
|
|
43532
43885
|
init_table_name_map();
|
|
43533
43886
|
log13 = getLogger("verify-migration");
|
|
43534
|
-
_require5 =
|
|
43887
|
+
_require5 = createRequire9(import.meta.url);
|
|
43535
43888
|
CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
|
|
43536
43889
|
}
|
|
43537
43890
|
});
|
|
@@ -43627,11 +43980,11 @@ __export(on_open_exports, {
|
|
|
43627
43980
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
|
|
43628
43981
|
withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
|
|
43629
43982
|
});
|
|
43630
|
-
import { existsSync as
|
|
43983
|
+
import { existsSync as existsSync26, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
43631
43984
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
43632
|
-
import { join as
|
|
43985
|
+
import { join as join30, resolve as resolve13 } from "node:path";
|
|
43633
43986
|
async function withExodusOnOpenSuppressed(dbPath, fn) {
|
|
43634
|
-
const key =
|
|
43987
|
+
const key = resolve13(dbPath);
|
|
43635
43988
|
_reconcileInProgress.set(key, (_reconcileInProgress.get(key) ?? 0) + 1);
|
|
43636
43989
|
try {
|
|
43637
43990
|
return await fn();
|
|
@@ -43669,7 +44022,7 @@ function remedyFor(scope) {
|
|
|
43669
44022
|
}
|
|
43670
44023
|
async function strandedLegacySources(scope, cwd) {
|
|
43671
44024
|
const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
43672
|
-
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope &&
|
|
44025
|
+
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync26(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
|
|
43673
44026
|
}
|
|
43674
44027
|
async function rollbackBothScopes(plan) {
|
|
43675
44028
|
const { getDualScopeNativeDb: getDualScopeNativeDb2, openDualScopeDbAtPath: openDualScopeDbAtPath2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
|
|
@@ -43747,7 +44100,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43747
44100
|
if (_exodusInProgress) {
|
|
43748
44101
|
return { outcome: "skipped", reason: "re-entrant open during active migration" };
|
|
43749
44102
|
}
|
|
43750
|
-
if (_reconcileInProgress.has(
|
|
44103
|
+
if (_reconcileInProgress.has(resolve13(dbPath))) {
|
|
43751
44104
|
return {
|
|
43752
44105
|
outcome: "skipped",
|
|
43753
44106
|
reason: "an explicit superseded-store reconcile of this store is in progress"
|
|
@@ -43780,14 +44133,14 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43780
44133
|
const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
43781
44134
|
const plan = buildExodusPlan2(cwd);
|
|
43782
44135
|
const plannedTarget = scope === "project" ? plan.projectDbPath : plan.globalDbPath;
|
|
43783
|
-
if (
|
|
44136
|
+
if (resolve13(plannedTarget) !== resolve13(dbPath)) {
|
|
43784
44137
|
return {
|
|
43785
44138
|
outcome: "aborted",
|
|
43786
44139
|
reason: `migration plan target ${plannedTarget} does not match opened database ${dbPath}; no migration applied`
|
|
43787
44140
|
};
|
|
43788
44141
|
}
|
|
43789
44142
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
43790
|
-
if (!scopeSources.some((s) =>
|
|
44143
|
+
if (!scopeSources.some((s) => existsSync26(s.path))) {
|
|
43791
44144
|
return {
|
|
43792
44145
|
outcome: "skipped",
|
|
43793
44146
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -43804,12 +44157,12 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43804
44157
|
{
|
|
43805
44158
|
scope,
|
|
43806
44159
|
dbPath,
|
|
43807
|
-
sources: plan.sources.filter((s) =>
|
|
44160
|
+
sources: plan.sources.filter((s) => existsSync26(s.path)).map((s) => s.name)
|
|
43808
44161
|
},
|
|
43809
44162
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
43810
44163
|
);
|
|
43811
44164
|
_exodusInProgress = true;
|
|
43812
|
-
const bareScratch = mkdtempSync2(
|
|
44165
|
+
const bareScratch = mkdtempSync2(join30(tmpdir4(), "cleo-exodus-bare-"));
|
|
43813
44166
|
try {
|
|
43814
44167
|
const { buildRuntimeTargetResolver: buildRuntimeTargetResolver2 } = await Promise.resolve().then(() => (init_runtime_targets(), runtime_targets_exports));
|
|
43815
44168
|
const resolveTarget = await buildRuntimeTargetResolver2();
|
|
@@ -43817,7 +44170,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43817
44170
|
const bare = scope === "project" ? await unmigratedBareSources2(
|
|
43818
44171
|
dbPath,
|
|
43819
44172
|
resolveTarget,
|
|
43820
|
-
plan.sources.find((s) => s.name === "tasks" &&
|
|
44173
|
+
plan.sources.find((s) => s.name === "tasks" && existsSync26(s.path))?.path,
|
|
43821
44174
|
bareScratch
|
|
43822
44175
|
) : { first: [], last: [] };
|
|
43823
44176
|
const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
|
|
@@ -43881,7 +44234,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
43881
44234
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
43882
44235
|
);
|
|
43883
44236
|
try {
|
|
43884
|
-
const consumed = plan.sources.filter((s) =>
|
|
44237
|
+
const consumed = plan.sources.filter((s) => existsSync26(s.path));
|
|
43885
44238
|
const identities = await sealTargets(plan, consumed);
|
|
43886
44239
|
const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
|
|
43887
44240
|
log14.info(
|
|
@@ -43956,9 +44309,9 @@ __export(dual_scope_db_exports, {
|
|
|
43956
44309
|
upsertIdempotent: () => upsertIdempotent,
|
|
43957
44310
|
withStoreSchemaOwnership: () => withStoreSchemaOwnership
|
|
43958
44311
|
});
|
|
43959
|
-
import { existsSync as
|
|
43960
|
-
import { createRequire as
|
|
43961
|
-
import { dirname as
|
|
44312
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync8 } from "node:fs";
|
|
44313
|
+
import { createRequire as createRequire10 } from "node:module";
|
|
44314
|
+
import { dirname as dirname17, join as join31, resolve as resolve14 } from "node:path";
|
|
43962
44315
|
function getDualScopeNativeDb(handle) {
|
|
43963
44316
|
const db = handle.db;
|
|
43964
44317
|
if ("$client" in db && db.$client instanceof getDatabaseSyncCtor()) return db.$client;
|
|
@@ -43980,9 +44333,9 @@ function cacheKey(scope, dbPath) {
|
|
|
43980
44333
|
}
|
|
43981
44334
|
function resolveDualScopeDbPath(scope, cwd, capturedGlobalHome) {
|
|
43982
44335
|
if (scope === "project") {
|
|
43983
|
-
return
|
|
44336
|
+
return join31(resolveCleoDir(cwd), "cleo.db");
|
|
43984
44337
|
}
|
|
43985
|
-
return
|
|
44338
|
+
return join31(capturedGlobalHome ?? getCleoHome(), "cleo.db");
|
|
43986
44339
|
}
|
|
43987
44340
|
function migrationsSetName(scope) {
|
|
43988
44341
|
return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
|
|
@@ -44032,8 +44385,8 @@ async function openDualScopeDb(scope, cwd, options) {
|
|
|
44032
44385
|
async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
44033
44386
|
execution?.assertActive();
|
|
44034
44387
|
log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
44035
|
-
const dir =
|
|
44036
|
-
if (!
|
|
44388
|
+
const dir = dirname17(dbPath);
|
|
44389
|
+
if (!existsSync27(dir)) {
|
|
44037
44390
|
mkdirSync8(dir, { recursive: true });
|
|
44038
44391
|
}
|
|
44039
44392
|
execution?.assertActive();
|
|
@@ -44041,6 +44394,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
44041
44394
|
const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
|
|
44042
44395
|
try {
|
|
44043
44396
|
applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
|
|
44397
|
+
installSchemaWriteGuard(nativeDb);
|
|
44044
44398
|
const drizzle2 = getDrizzle();
|
|
44045
44399
|
const db = drizzle2({ client: nativeDb });
|
|
44046
44400
|
const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
|
|
@@ -44089,11 +44443,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
44089
44443
|
execution?.assertActive();
|
|
44090
44444
|
return handle;
|
|
44091
44445
|
} catch (err) {
|
|
44446
|
+
const explained = explainSchemaWriteDenial(nativeDb, err);
|
|
44092
44447
|
try {
|
|
44093
44448
|
nativeDb.close();
|
|
44094
44449
|
} catch {
|
|
44095
44450
|
}
|
|
44096
|
-
throw
|
|
44451
|
+
throw explained;
|
|
44097
44452
|
}
|
|
44098
44453
|
}
|
|
44099
44454
|
async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
@@ -44114,7 +44469,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44114
44469
|
);
|
|
44115
44470
|
}
|
|
44116
44471
|
const dedicated = options?.dedicated === true;
|
|
44117
|
-
const normalizedPath =
|
|
44472
|
+
const normalizedPath = resolve14(dbPath);
|
|
44118
44473
|
const key = cacheKey(scope, normalizedPath);
|
|
44119
44474
|
if (!dedicated) {
|
|
44120
44475
|
const existing = _cache.get(key);
|
|
@@ -44151,8 +44506,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44151
44506
|
}
|
|
44152
44507
|
let initResolve = null;
|
|
44153
44508
|
let initReject = null;
|
|
44154
|
-
const initPromise = new Promise((
|
|
44155
|
-
initResolve =
|
|
44509
|
+
const initPromise = new Promise((resolve16, reject) => {
|
|
44510
|
+
initResolve = resolve16;
|
|
44156
44511
|
initReject = reject;
|
|
44157
44512
|
});
|
|
44158
44513
|
_cache.set(key, {
|
|
@@ -44173,8 +44528,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44173
44528
|
try {
|
|
44174
44529
|
execution?.assertActive();
|
|
44175
44530
|
log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
|
|
44176
|
-
const dir =
|
|
44177
|
-
if (!
|
|
44531
|
+
const dir = dirname17(normalizedPath);
|
|
44532
|
+
if (!existsSync27(dir)) {
|
|
44178
44533
|
mkdirSync8(dir, { recursive: true });
|
|
44179
44534
|
}
|
|
44180
44535
|
execution?.assertActive();
|
|
@@ -44182,6 +44537,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44182
44537
|
const nativeDb = new DatabaseSyncCtor(normalizedPath, { allowExtension: true });
|
|
44183
44538
|
openingNative = nativeDb;
|
|
44184
44539
|
applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
|
|
44540
|
+
installSchemaWriteGuard(nativeDb);
|
|
44185
44541
|
const drizzle2 = getDrizzle();
|
|
44186
44542
|
const db = drizzle2({ client: nativeDb });
|
|
44187
44543
|
const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
|
|
@@ -44312,12 +44668,13 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
44312
44668
|
execution?.assertActive();
|
|
44313
44669
|
initResolve(finalHandle);
|
|
44314
44670
|
} catch (err) {
|
|
44671
|
+
const explained = openingNative ? explainSchemaWriteDenial(openingNative, err) : err;
|
|
44315
44672
|
try {
|
|
44316
44673
|
if (!published && openingNative?.isOpen) openingNative.close();
|
|
44317
44674
|
} catch (closeError) {
|
|
44318
44675
|
log15.warn({ closeError }, "failed to close unpublished database initializer");
|
|
44319
44676
|
}
|
|
44320
|
-
initReject(
|
|
44677
|
+
initReject(explained);
|
|
44321
44678
|
}
|
|
44322
44679
|
})();
|
|
44323
44680
|
return initPromise;
|
|
@@ -44390,6 +44747,7 @@ var init_dual_scope_db = __esm({
|
|
|
44390
44747
|
init_relocated_store_guard();
|
|
44391
44748
|
init_resolve_migrations_folder();
|
|
44392
44749
|
init_sqlite_pragmas();
|
|
44750
|
+
init_worktree_build_guard();
|
|
44393
44751
|
init_worktree_isolation_guard();
|
|
44394
44752
|
init_writer_lease();
|
|
44395
44753
|
ExodusAbortWriteUnsafeError = class extends Error {
|
|
@@ -44412,7 +44770,7 @@ var init_dual_scope_db = __esm({
|
|
|
44412
44770
|
}
|
|
44413
44771
|
};
|
|
44414
44772
|
_cache = /* @__PURE__ */ new Map();
|
|
44415
|
-
_require6 =
|
|
44773
|
+
_require6 = createRequire10(import.meta.url);
|
|
44416
44774
|
_drizzle4 = null;
|
|
44417
44775
|
_DatabaseSyncCtor = null;
|
|
44418
44776
|
EntryCancelledError = class extends Error {
|
|
@@ -44443,7 +44801,7 @@ var init_dual_scope_db = __esm({
|
|
|
44443
44801
|
}
|
|
44444
44802
|
/** @inheritdoc */
|
|
44445
44803
|
async openProject(dbPath, options) {
|
|
44446
|
-
const normalized =
|
|
44804
|
+
const normalized = resolve14(dbPath);
|
|
44447
44805
|
if (options?.dedicated) {
|
|
44448
44806
|
const handle = await openDualScopeDbAtPath("project", normalized, options?.exodusCwd, {
|
|
44449
44807
|
dedicated: true
|
|
@@ -44455,7 +44813,7 @@ var init_dual_scope_db = __esm({
|
|
|
44455
44813
|
/** @inheritdoc */
|
|
44456
44814
|
async openGlobal(options) {
|
|
44457
44815
|
const dbPath = resolveDualScopeDbPath("global");
|
|
44458
|
-
const normalized =
|
|
44816
|
+
const normalized = resolve14(dbPath);
|
|
44459
44817
|
if (options?.dedicated) {
|
|
44460
44818
|
const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
|
|
44461
44819
|
dedicated: true
|
|
@@ -44466,7 +44824,7 @@ var init_dual_scope_db = __esm({
|
|
|
44466
44824
|
}
|
|
44467
44825
|
/** @inheritdoc */
|
|
44468
44826
|
async openGlobalAt(dbPath, options) {
|
|
44469
|
-
const normalized =
|
|
44827
|
+
const normalized = resolve14(dbPath);
|
|
44470
44828
|
if (options?.dedicated) {
|
|
44471
44829
|
const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
|
|
44472
44830
|
dedicated: true
|
|
@@ -44477,7 +44835,7 @@ var init_dual_scope_db = __esm({
|
|
|
44477
44835
|
}
|
|
44478
44836
|
/** @inheritdoc */
|
|
44479
44837
|
closeProject(dbPath) {
|
|
44480
|
-
const normalized =
|
|
44838
|
+
const normalized = resolve14(dbPath);
|
|
44481
44839
|
this.closeEntry("project", normalized);
|
|
44482
44840
|
}
|
|
44483
44841
|
/** @inheritdoc */
|
|
@@ -44514,8 +44872,8 @@ var init_dual_scope_db = __esm({
|
|
|
44514
44872
|
const entryId = ++this._nextId;
|
|
44515
44873
|
let initResolve;
|
|
44516
44874
|
let initReject;
|
|
44517
|
-
const initPromise = new Promise((
|
|
44518
|
-
initResolve =
|
|
44875
|
+
const initPromise = new Promise((resolve16, reject) => {
|
|
44876
|
+
initResolve = resolve16;
|
|
44519
44877
|
initReject = reject;
|
|
44520
44878
|
});
|
|
44521
44879
|
this._registry.set(key, { id: entryId, store: null, initPromise });
|
|
@@ -45308,8 +45666,8 @@ __export(nexus_sqlite_exports, {
|
|
|
45308
45666
|
resetNexusDbState: () => resetNexusDbState,
|
|
45309
45667
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
45310
45668
|
});
|
|
45311
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
45312
|
-
import { join as
|
|
45669
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync28 } from "node:fs";
|
|
45670
|
+
import { join as join32 } from "node:path";
|
|
45313
45671
|
function getNexusDbPath(cwd) {
|
|
45314
45672
|
return resolveDualScopeDbPath("project", cwd);
|
|
45315
45673
|
}
|
|
@@ -45345,12 +45703,13 @@ function ensureGlobalRegistryAttached(nativeDb) {
|
|
|
45345
45703
|
}
|
|
45346
45704
|
}
|
|
45347
45705
|
nativeDb.exec(`ATTACH DATABASE '${escaped}' AS ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
|
|
45706
|
+
refreshSchemaWriteGuard(nativeDb);
|
|
45348
45707
|
}
|
|
45349
45708
|
function resolveNexusMigrationsFolder() {
|
|
45350
45709
|
return resolveCorePackageMigrationsFolder("drizzle-nexus");
|
|
45351
45710
|
}
|
|
45352
45711
|
function getNestedNexusSentinelPath() {
|
|
45353
|
-
return
|
|
45712
|
+
return join32(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
|
|
45354
45713
|
}
|
|
45355
45714
|
function detectAndWarnOnNestedNexus() {
|
|
45356
45715
|
let nestedPath;
|
|
@@ -45359,7 +45718,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
45359
45718
|
} catch {
|
|
45360
45719
|
return false;
|
|
45361
45720
|
}
|
|
45362
|
-
if (!
|
|
45721
|
+
if (!existsSync28(nestedPath)) return false;
|
|
45363
45722
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
45364
45723
|
_warnedNestedPaths.add(nestedPath);
|
|
45365
45724
|
const canonicalPath = getNexusDbPath();
|
|
@@ -45518,7 +45877,7 @@ function runNexusMigrations(nativeDb, db, dbPath) {
|
|
|
45518
45877
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
45519
45878
|
if (tableExists4(nativeDb, "nexus_nodes")) {
|
|
45520
45879
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
45521
|
-
if (!
|
|
45880
|
+
if (!existsSync28(backupPath)) {
|
|
45522
45881
|
try {
|
|
45523
45882
|
copyFileSync7(dbPath, backupPath);
|
|
45524
45883
|
} catch {
|
|
@@ -45613,6 +45972,7 @@ var init_nexus_sqlite = __esm({
|
|
|
45613
45972
|
init_resolve_migrations_folder();
|
|
45614
45973
|
init_nexus_schema();
|
|
45615
45974
|
init_with_retry();
|
|
45975
|
+
init_worktree_build_guard();
|
|
45616
45976
|
NEXUS_SCHEMA_VERSION = "1.0.0";
|
|
45617
45977
|
NEXUS_GLOBAL_ATTACH_ALIAS = "nexus_global";
|
|
45618
45978
|
NESTED_NEXUS_SENTINEL = "nexus.db";
|
|
@@ -45647,15 +46007,15 @@ var init_legacy_alias = __esm({
|
|
|
45647
46007
|
|
|
45648
46008
|
// packages/core/src/llm/stable-device-id.ts
|
|
45649
46009
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
45650
|
-
import { existsSync as
|
|
45651
|
-
import { dirname as
|
|
46010
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync9, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
|
|
46011
|
+
import { dirname as dirname18 } from "node:path";
|
|
45652
46012
|
import { resolveStableDeviceIdPath } from "@cleocode/paths";
|
|
45653
46013
|
function getStableDeviceId() {
|
|
45654
46014
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
45655
46015
|
const path2 = resolveStableDeviceIdPath();
|
|
45656
|
-
if (
|
|
46016
|
+
if (existsSync29(path2)) {
|
|
45657
46017
|
try {
|
|
45658
|
-
const raw =
|
|
46018
|
+
const raw = readFileSync9(path2, "utf-8").trim();
|
|
45659
46019
|
if (raw.length > 0) {
|
|
45660
46020
|
_cachedDeviceId = raw;
|
|
45661
46021
|
return raw;
|
|
@@ -45665,8 +46025,8 @@ function getStableDeviceId() {
|
|
|
45665
46025
|
}
|
|
45666
46026
|
const fresh = randomUUID3();
|
|
45667
46027
|
try {
|
|
45668
|
-
const dir =
|
|
45669
|
-
if (!
|
|
46028
|
+
const dir = dirname18(path2);
|
|
46029
|
+
if (!existsSync29(dir)) {
|
|
45670
46030
|
mkdirSync9(dir, { recursive: true });
|
|
45671
46031
|
}
|
|
45672
46032
|
const tmpPath = `${path2}.tmp.${process.pid}`;
|
|
@@ -45703,8 +46063,8 @@ var init_registry_roots = __esm({
|
|
|
45703
46063
|
// packages/core/src/nexus/projects-scan.ts
|
|
45704
46064
|
async function withinBudget(promise, ms) {
|
|
45705
46065
|
let timer;
|
|
45706
|
-
const expiry = new Promise((
|
|
45707
|
-
timer = setTimeout(() =>
|
|
46066
|
+
const expiry = new Promise((resolve16) => {
|
|
46067
|
+
timer = setTimeout(() => resolve16("timeout"), ms);
|
|
45708
46068
|
timer.unref();
|
|
45709
46069
|
});
|
|
45710
46070
|
try {
|
|
@@ -45742,9 +46102,9 @@ __export(path_map_exports, {
|
|
|
45742
46102
|
supersededRegistryPath: () => supersededRegistryPath,
|
|
45743
46103
|
touchProjectLocation: () => touchProjectLocation
|
|
45744
46104
|
});
|
|
45745
|
-
import { existsSync as
|
|
46105
|
+
import { existsSync as existsSync30, lstatSync, readdirSync as readdirSync7 } from "node:fs";
|
|
45746
46106
|
import { lstat, readdir as readdir2 } from "node:fs/promises";
|
|
45747
|
-
import { isAbsolute as
|
|
46107
|
+
import { isAbsolute as isAbsolute5, join as join33, relative as relative3, sep as sep5 } from "node:path";
|
|
45748
46108
|
import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity3 } from "@cleocode/paths";
|
|
45749
46109
|
import { and as and7, desc as desc3, eq as eq11, inArray as inArray5, ne as ne3 } from "drizzle-orm";
|
|
45750
46110
|
function holdingKey(projectId, path2) {
|
|
@@ -45760,7 +46120,7 @@ function isSupersededRegistryPath(projectPath) {
|
|
|
45760
46120
|
return projectPath.startsWith(SUPERSEDED_PATH_PREFIX);
|
|
45761
46121
|
}
|
|
45762
46122
|
function projectHolding(path2, projectId) {
|
|
45763
|
-
const cleoDir =
|
|
46123
|
+
const cleoDir = join33(path2, ".cleo");
|
|
45764
46124
|
try {
|
|
45765
46125
|
lstatSync(cleoDir);
|
|
45766
46126
|
readdirSync7(cleoDir);
|
|
@@ -45772,7 +46132,7 @@ function projectHolding(path2, projectId) {
|
|
|
45772
46132
|
return declared === null || declared.projectId === projectId ? "yes" : "no";
|
|
45773
46133
|
}
|
|
45774
46134
|
async function probeProjectHolding(path2, projectId, timeoutMs) {
|
|
45775
|
-
const cleoDir =
|
|
46135
|
+
const cleoDir = join33(path2, ".cleo");
|
|
45776
46136
|
const probe = async () => {
|
|
45777
46137
|
try {
|
|
45778
46138
|
await lstat(cleoDir);
|
|
@@ -45790,8 +46150,8 @@ async function probeProjectHolding(path2, projectId, timeoutMs) {
|
|
|
45790
46150
|
return declared === null || declared.projectId === projectId ? "yes" : "no";
|
|
45791
46151
|
}
|
|
45792
46152
|
function isStrictlyInside(outer, inner) {
|
|
45793
|
-
const rel =
|
|
45794
|
-
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${
|
|
46153
|
+
const rel = relative3(canonicalizePath3(outer), canonicalizePath3(inner));
|
|
46154
|
+
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep5}`) && !isAbsolute5(rel);
|
|
45795
46155
|
}
|
|
45796
46156
|
function locationKey(projectId, deviceId, path2) {
|
|
45797
46157
|
return and7(
|
|
@@ -45953,7 +46313,7 @@ function hasOtherLiveLocation(db, record, deviceId) {
|
|
|
45953
46313
|
ne3(projectLocations.path, record.projectPath)
|
|
45954
46314
|
)
|
|
45955
46315
|
).all().some(
|
|
45956
|
-
(location) => isStrictlyInside(record.projectPath, location.path) &&
|
|
46316
|
+
(location) => isStrictlyInside(record.projectPath, location.path) && existsSync30(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record.projectId
|
|
45957
46317
|
);
|
|
45958
46318
|
}
|
|
45959
46319
|
function demoteProjectLocation(db, record, state) {
|
|
@@ -46004,7 +46364,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
|
|
|
46004
46364
|
).orderBy(desc3(projectLocations.lastSeen)).all();
|
|
46005
46365
|
const present = (path2) => {
|
|
46006
46366
|
const holding = probed?.get(holdingKey(row.projectId, path2));
|
|
46007
|
-
return holding === void 0 ?
|
|
46367
|
+
return holding === void 0 ? existsSync30(path2) : holding === "yes";
|
|
46008
46368
|
};
|
|
46009
46369
|
const home = candidates.find(
|
|
46010
46370
|
(c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq11(projectRegistry.projectPath, c.path)).all().length === 0
|
|
@@ -46033,7 +46393,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
|
|
|
46033
46393
|
projectHash: generateProjectHash(row.path),
|
|
46034
46394
|
firstSeen: row.firstSeen,
|
|
46035
46395
|
lastSeen: row.lastSeen,
|
|
46036
|
-
exists: local &&
|
|
46396
|
+
exists: local && existsSync30(row.path),
|
|
46037
46397
|
deviceId: local ? deviceId : row.deviceId,
|
|
46038
46398
|
state: row.state
|
|
46039
46399
|
});
|
|
@@ -46062,13 +46422,13 @@ __export(checkout_nonce_exports, {
|
|
|
46062
46422
|
readCheckoutNonce: () => readCheckoutNonce
|
|
46063
46423
|
});
|
|
46064
46424
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
46065
|
-
import { existsSync as
|
|
46066
|
-
import { join as
|
|
46425
|
+
import { existsSync as existsSync31, readFileSync as readFileSync10, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
|
|
46426
|
+
import { join as join34 } from "node:path";
|
|
46067
46427
|
function readInfo(projectRoot) {
|
|
46068
|
-
const path2 =
|
|
46069
|
-
if (!
|
|
46428
|
+
const path2 = join34(projectRoot, ".cleo", "project-info.json");
|
|
46429
|
+
if (!existsSync31(path2)) return null;
|
|
46070
46430
|
try {
|
|
46071
|
-
const parsed = JSON.parse(
|
|
46431
|
+
const parsed = JSON.parse(readFileSync10(path2, "utf-8"));
|
|
46072
46432
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
46073
46433
|
} catch {
|
|
46074
46434
|
return null;
|
|
@@ -46084,7 +46444,7 @@ function ensureCheckoutNonce(projectRoot) {
|
|
|
46084
46444
|
const info = readInfo(projectRoot);
|
|
46085
46445
|
if (!info) return null;
|
|
46086
46446
|
const nonce = randomBytes2(16).toString("hex");
|
|
46087
|
-
const path2 =
|
|
46447
|
+
const path2 = join34(projectRoot, ".cleo", "project-info.json");
|
|
46088
46448
|
const temp = `${path2}.${randomBytes2(6).toString("hex")}.tmp`;
|
|
46089
46449
|
writeFileSync9(temp, `${JSON.stringify({ ...info, [CHECKOUT_NONCE_FIELD]: nonce }, null, 2)}
|
|
46090
46450
|
`);
|
|
@@ -46159,10 +46519,10 @@ __export(paths_exports, {
|
|
|
46159
46519
|
validateProjectRoot: () => validateProjectRoot,
|
|
46160
46520
|
worktreeScope: () => worktreeScope
|
|
46161
46521
|
});
|
|
46162
|
-
import { existsSync as
|
|
46163
|
-
import { createRequire as
|
|
46522
|
+
import { existsSync as existsSync32, readFileSync as readFileSync11, statSync as statSync9 } from "node:fs";
|
|
46523
|
+
import { createRequire as createRequire11 } from "node:module";
|
|
46164
46524
|
import { homedir as homedir2 } from "node:os";
|
|
46165
|
-
import { basename as basename10, dirname as
|
|
46525
|
+
import { basename as basename10, dirname as dirname19, join as join35, resolve as resolve15 } from "node:path";
|
|
46166
46526
|
import {
|
|
46167
46527
|
getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
|
|
46168
46528
|
getCleoTemplatesTildePath as _getCleoTemplatesTildePath,
|
|
@@ -46172,7 +46532,7 @@ import {
|
|
|
46172
46532
|
resolveCanonicalCleoDir as _resolveCanonicalCleoDir
|
|
46173
46533
|
} from "@cleocode/paths";
|
|
46174
46534
|
function _getDatabaseSyncCtor() {
|
|
46175
|
-
const _require7 =
|
|
46535
|
+
const _require7 = createRequire11(import.meta.url);
|
|
46176
46536
|
const mod = _require7("node:sqlite");
|
|
46177
46537
|
return mod.DatabaseSync;
|
|
46178
46538
|
}
|
|
@@ -46184,20 +46544,20 @@ function runWithWorktreeScopeFromEnv(fn) {
|
|
|
46184
46544
|
}
|
|
46185
46545
|
function isProjectInitialized(projectRoot) {
|
|
46186
46546
|
const root = projectRoot ?? getProjectRoot();
|
|
46187
|
-
const cleoDir =
|
|
46188
|
-
return
|
|
46547
|
+
const cleoDir = join35(root, ".cleo");
|
|
46548
|
+
return existsSync32(cleoDir) && existsSync32(join35(cleoDir, "tasks.db"));
|
|
46189
46549
|
}
|
|
46190
46550
|
function getCleoHome() {
|
|
46191
46551
|
return getPlatformPaths().data;
|
|
46192
46552
|
}
|
|
46193
46553
|
function getCleoTemplatesDir() {
|
|
46194
|
-
return
|
|
46554
|
+
return join35(getCleoHome(), "templates");
|
|
46195
46555
|
}
|
|
46196
46556
|
function getCleoSchemasDir() {
|
|
46197
|
-
return
|
|
46557
|
+
return join35(getCleoHome(), "schemas");
|
|
46198
46558
|
}
|
|
46199
46559
|
function getCleoDocsDir() {
|
|
46200
|
-
return
|
|
46560
|
+
return join35(getCleoHome(), "docs");
|
|
46201
46561
|
}
|
|
46202
46562
|
function getCleoDir(cwd) {
|
|
46203
46563
|
if (cwd) {
|
|
@@ -46246,24 +46606,24 @@ function getCleoDirAbsolute(cwd, opts) {
|
|
|
46246
46606
|
try {
|
|
46247
46607
|
const projectRoot = getProjectRoot(cwd);
|
|
46248
46608
|
const canonical = _resolveCanonicalCleoDir(project.projectId);
|
|
46249
|
-
if (canonical !== null && canonical ===
|
|
46609
|
+
if (canonical !== null && canonical === resolve15(projectRoot, cleoDir)) {
|
|
46250
46610
|
return canonical;
|
|
46251
46611
|
}
|
|
46252
|
-
return
|
|
46612
|
+
return resolve15(projectRoot, cleoDir);
|
|
46253
46613
|
} catch {
|
|
46254
|
-
return
|
|
46614
|
+
return resolve15(project.projectRoot, cleoDir);
|
|
46255
46615
|
}
|
|
46256
46616
|
}
|
|
46257
46617
|
try {
|
|
46258
|
-
return
|
|
46618
|
+
return resolve15(getProjectRoot(cwd), cleoDir);
|
|
46259
46619
|
} catch (err) {
|
|
46260
46620
|
if (opts?.bootstrap) {
|
|
46261
|
-
return
|
|
46621
|
+
return resolve15(cwd ?? process.cwd(), cleoDir);
|
|
46262
46622
|
}
|
|
46263
46623
|
if (_cwdHasGitAncestor(cwd)) {
|
|
46264
46624
|
throw err;
|
|
46265
46625
|
}
|
|
46266
|
-
return
|
|
46626
|
+
return resolve15(cwd ?? process.cwd(), cleoDir);
|
|
46267
46627
|
}
|
|
46268
46628
|
}
|
|
46269
46629
|
function resolveCanonicalCleoDir(projectId) {
|
|
@@ -46290,9 +46650,9 @@ function resolveCanonicalCleoDir(projectId) {
|
|
|
46290
46650
|
function _resolveProjectByCwdFromNexus(cwd) {
|
|
46291
46651
|
try {
|
|
46292
46652
|
const cleoHome = getCleoHome();
|
|
46293
|
-
const globalDbPath =
|
|
46294
|
-
if (!
|
|
46295
|
-
const start =
|
|
46653
|
+
const globalDbPath = join35(cleoHome, "cleo.db");
|
|
46654
|
+
if (!existsSync32(globalDbPath)) return null;
|
|
46655
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46296
46656
|
let current = start;
|
|
46297
46657
|
const DatabaseSync3 = _getDatabaseSyncCtor();
|
|
46298
46658
|
const db = new DatabaseSync3(globalDbPath, { readOnly: true });
|
|
@@ -46305,7 +46665,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
46305
46665
|
if (row && typeof row.project_id === "string" && row.project_id.length > 0) {
|
|
46306
46666
|
return row.project_id;
|
|
46307
46667
|
}
|
|
46308
|
-
const parent =
|
|
46668
|
+
const parent = dirname19(current);
|
|
46309
46669
|
if (parent === current) break;
|
|
46310
46670
|
current = parent;
|
|
46311
46671
|
}
|
|
@@ -46325,18 +46685,18 @@ function _cleoDirEnvOverride() {
|
|
|
46325
46685
|
}
|
|
46326
46686
|
function _findCleoDirRoot(cwd) {
|
|
46327
46687
|
const homeRoot = homedir2();
|
|
46328
|
-
let current =
|
|
46688
|
+
let current = resolve15(cwd ?? process.cwd());
|
|
46329
46689
|
while (true) {
|
|
46330
46690
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
46331
46691
|
if (!isDangerousRoot) {
|
|
46332
46692
|
try {
|
|
46333
|
-
if (statSync9(
|
|
46693
|
+
if (statSync9(join35(current, ".cleo")).isDirectory()) {
|
|
46334
46694
|
return current;
|
|
46335
46695
|
}
|
|
46336
46696
|
} catch {
|
|
46337
46697
|
}
|
|
46338
46698
|
}
|
|
46339
|
-
const parent =
|
|
46699
|
+
const parent = dirname19(current);
|
|
46340
46700
|
if (parent === current) break;
|
|
46341
46701
|
current = parent;
|
|
46342
46702
|
}
|
|
@@ -46355,7 +46715,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46355
46715
|
if (pathsResult !== null) {
|
|
46356
46716
|
return pathsResult.projectId;
|
|
46357
46717
|
}
|
|
46358
|
-
const start =
|
|
46718
|
+
const start = resolve15(from ?? process.cwd());
|
|
46359
46719
|
let current = start;
|
|
46360
46720
|
while (true) {
|
|
46361
46721
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
@@ -46366,7 +46726,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46366
46726
|
}
|
|
46367
46727
|
break;
|
|
46368
46728
|
}
|
|
46369
|
-
const parent =
|
|
46729
|
+
const parent = dirname19(current);
|
|
46370
46730
|
if (parent === current) break;
|
|
46371
46731
|
current = parent;
|
|
46372
46732
|
}
|
|
@@ -46385,7 +46745,7 @@ function resolveProjectByCwd(cwd) {
|
|
|
46385
46745
|
function resolveCleoDir(cwd) {
|
|
46386
46746
|
const scope = worktreeScope.getStore();
|
|
46387
46747
|
if (scope !== void 0) {
|
|
46388
|
-
return
|
|
46748
|
+
return join35(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
|
|
46389
46749
|
}
|
|
46390
46750
|
const override = _cleoDirEnvOverride();
|
|
46391
46751
|
if (override !== null) {
|
|
@@ -46393,16 +46753,16 @@ function resolveCleoDir(cwd) {
|
|
|
46393
46753
|
}
|
|
46394
46754
|
const root = _findCleoDirRoot(cwd);
|
|
46395
46755
|
if (root !== null) {
|
|
46396
|
-
return
|
|
46756
|
+
return join35(resolveStoreOwnerRoot(root), ".cleo");
|
|
46397
46757
|
}
|
|
46398
|
-
const start =
|
|
46758
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46399
46759
|
let current = start;
|
|
46400
46760
|
while (true) {
|
|
46401
46761
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
46402
46762
|
if (mainRepo !== null) {
|
|
46403
|
-
return
|
|
46763
|
+
return join35(mainRepo, ".cleo");
|
|
46404
46764
|
}
|
|
46405
|
-
const parent =
|
|
46765
|
+
const parent = dirname19(current);
|
|
46406
46766
|
if (parent === current) {
|
|
46407
46767
|
break;
|
|
46408
46768
|
}
|
|
@@ -46441,25 +46801,25 @@ function _resolveCleoDir(cwd) {
|
|
|
46441
46801
|
const project = _pathsResolveProjectByCwd(cwd);
|
|
46442
46802
|
if (project !== null) {
|
|
46443
46803
|
try {
|
|
46444
|
-
return
|
|
46804
|
+
return resolve15(getProjectRoot(cwd), cleoDir);
|
|
46445
46805
|
} catch {
|
|
46446
|
-
return
|
|
46806
|
+
return resolve15(project.projectRoot, cleoDir);
|
|
46447
46807
|
}
|
|
46448
46808
|
}
|
|
46449
46809
|
return getCleoDirAbsolute(cwd);
|
|
46450
46810
|
}
|
|
46451
46811
|
function _cwdHasGitAncestor(cwd) {
|
|
46452
|
-
const start =
|
|
46812
|
+
const start = resolve15(cwd ?? process.cwd());
|
|
46453
46813
|
let current = start;
|
|
46454
46814
|
while (true) {
|
|
46455
|
-
const gitMarker =
|
|
46815
|
+
const gitMarker = join35(current, ".git");
|
|
46456
46816
|
try {
|
|
46457
|
-
if (
|
|
46817
|
+
if (existsSync32(gitMarker)) {
|
|
46458
46818
|
return true;
|
|
46459
46819
|
}
|
|
46460
46820
|
} catch {
|
|
46461
46821
|
}
|
|
46462
|
-
const parent =
|
|
46822
|
+
const parent = dirname19(current);
|
|
46463
46823
|
if (parent === current) return false;
|
|
46464
46824
|
current = parent;
|
|
46465
46825
|
}
|
|
@@ -46486,55 +46846,55 @@ function resolveProjectPath(relativePath, cwd) {
|
|
|
46486
46846
|
return relativePath;
|
|
46487
46847
|
}
|
|
46488
46848
|
if (relativePath.startsWith("~/") || relativePath.startsWith("~\\") || relativePath === "~") {
|
|
46489
|
-
return
|
|
46849
|
+
return resolve15(homedir2(), relativePath.slice(2));
|
|
46490
46850
|
}
|
|
46491
|
-
return
|
|
46851
|
+
return resolve15(getProjectRoot(cwd), relativePath);
|
|
46492
46852
|
}
|
|
46493
46853
|
function getTaskPath(cwd) {
|
|
46494
|
-
return
|
|
46854
|
+
return join35(_resolveCleoDir(cwd), "tasks.db");
|
|
46495
46855
|
}
|
|
46496
46856
|
function getConfigPath(cwd) {
|
|
46497
|
-
return
|
|
46857
|
+
return join35(_resolveCleoDir(cwd), "config.json");
|
|
46498
46858
|
}
|
|
46499
46859
|
function getSessionsPath(cwd) {
|
|
46500
|
-
return
|
|
46860
|
+
return join35(_resolveCleoDir(cwd), "sessions.json");
|
|
46501
46861
|
}
|
|
46502
46862
|
function getArchivePath(cwd) {
|
|
46503
|
-
return
|
|
46863
|
+
return join35(_resolveCleoDir(cwd), "tasks-archive.json");
|
|
46504
46864
|
}
|
|
46505
46865
|
function getLogPath(cwd) {
|
|
46506
|
-
return
|
|
46866
|
+
return join35(_resolveCleoDir(cwd), "logs", "cleo.log");
|
|
46507
46867
|
}
|
|
46508
46868
|
function getBackupDir(cwd) {
|
|
46509
|
-
return
|
|
46869
|
+
return join35(_resolveCleoDir(cwd), "backups", "operational");
|
|
46510
46870
|
}
|
|
46511
46871
|
function getGlobalConfigPath() {
|
|
46512
|
-
return
|
|
46872
|
+
return join35(getCleoHome(), "config.json");
|
|
46513
46873
|
}
|
|
46514
46874
|
function getCleoGlobalRecipesDir() {
|
|
46515
|
-
return
|
|
46875
|
+
return join35(getCleoHome(), "global-recipes");
|
|
46516
46876
|
}
|
|
46517
46877
|
function getCleoGlobalJustfilePath() {
|
|
46518
|
-
return
|
|
46878
|
+
return join35(getCleoGlobalRecipesDir(), "justfile");
|
|
46519
46879
|
}
|
|
46520
46880
|
function getCleoPiExtensionsDir() {
|
|
46521
|
-
return
|
|
46881
|
+
return join35(getCleoHome(), "pi-extensions");
|
|
46522
46882
|
}
|
|
46523
46883
|
function getCleoCantWorkflowsDir() {
|
|
46524
|
-
return
|
|
46884
|
+
return join35(getCleoHome(), "cant-workflows");
|
|
46525
46885
|
}
|
|
46526
46886
|
function getCleoGlobalAgentsDir() {
|
|
46527
|
-
return
|
|
46887
|
+
return join35(getCleoHome(), "agents");
|
|
46528
46888
|
}
|
|
46529
46889
|
function getCleoGlobalCantAgentsDir() {
|
|
46530
|
-
return
|
|
46890
|
+
return join35(getCleoHome(), "cant", "agents");
|
|
46531
46891
|
}
|
|
46532
46892
|
function getAgentOutputsDir(cwd) {
|
|
46533
46893
|
const projectRoot = getProjectRoot(cwd);
|
|
46534
|
-
const configPath =
|
|
46535
|
-
if (
|
|
46894
|
+
const configPath = join35(projectRoot, ".cleo", "config.json");
|
|
46895
|
+
if (existsSync32(configPath)) {
|
|
46536
46896
|
try {
|
|
46537
|
-
const config = JSON.parse(
|
|
46897
|
+
const config = JSON.parse(readFileSync11(configPath, "utf-8"));
|
|
46538
46898
|
if (typeof config.agentOutputs === "object" && config.agentOutputs?.directory) {
|
|
46539
46899
|
return config.agentOutputs.directory;
|
|
46540
46900
|
}
|
|
@@ -46557,17 +46917,17 @@ function getAgentOutputsAbsolute(cwd) {
|
|
|
46557
46917
|
if (isAbsolutePath2(dir)) {
|
|
46558
46918
|
return dir;
|
|
46559
46919
|
}
|
|
46560
|
-
return
|
|
46920
|
+
return resolve15(getProjectRoot(cwd), dir);
|
|
46561
46921
|
}
|
|
46562
46922
|
function getManifestPath(cwd) {
|
|
46563
46923
|
const outputDir = getAgentOutputsDir(cwd);
|
|
46564
46924
|
const projectRoot = getProjectRoot(cwd);
|
|
46565
|
-
const configPath =
|
|
46925
|
+
const configPath = join35(projectRoot, ".cleo", "config.json");
|
|
46566
46926
|
const legacyFileName = ["MANIFEST", "jsonl"].join(".");
|
|
46567
46927
|
let manifestFile = legacyFileName;
|
|
46568
|
-
if (
|
|
46928
|
+
if (existsSync32(configPath)) {
|
|
46569
46929
|
try {
|
|
46570
|
-
const config = JSON.parse(
|
|
46930
|
+
const config = JSON.parse(readFileSync11(configPath, "utf-8"));
|
|
46571
46931
|
const customFile = config.agentOutputs?.manifestFile ?? config.research?.manifestFile;
|
|
46572
46932
|
if (customFile) {
|
|
46573
46933
|
manifestFile = customFile;
|
|
@@ -46575,12 +46935,12 @@ function getManifestPath(cwd) {
|
|
|
46575
46935
|
} catch {
|
|
46576
46936
|
}
|
|
46577
46937
|
}
|
|
46578
|
-
return
|
|
46938
|
+
return resolve15(projectRoot, outputDir, manifestFile);
|
|
46579
46939
|
}
|
|
46580
46940
|
function getManifestArchivePath(cwd) {
|
|
46581
46941
|
const outputDir = getAgentOutputsDir(cwd);
|
|
46582
46942
|
const projectRoot = getProjectRoot(cwd);
|
|
46583
|
-
return
|
|
46943
|
+
return resolve15(projectRoot, outputDir, "MANIFEST.archive.jsonl");
|
|
46584
46944
|
}
|
|
46585
46945
|
function isAbsolutePath2(path2) {
|
|
46586
46946
|
return _isAbsolutePath(path2);
|
|
@@ -46604,24 +46964,24 @@ function getCanonicalTemplatesTildePath() {
|
|
|
46604
46964
|
return _getCanonicalTemplatesTildePath();
|
|
46605
46965
|
}
|
|
46606
46966
|
function getAgentsHome() {
|
|
46607
|
-
return process.env["AGENTS_HOME"] ??
|
|
46967
|
+
return process.env["AGENTS_HOME"] ?? join35(homedir2(), ".agents");
|
|
46608
46968
|
}
|
|
46609
46969
|
function getClaudeAgentsDir() {
|
|
46610
|
-
const claudeDir = process.env["CLAUDE_HOME"] ??
|
|
46611
|
-
return
|
|
46970
|
+
const claudeDir = process.env["CLAUDE_HOME"] ?? join35(homedir2(), ".claude");
|
|
46971
|
+
return join35(claudeDir, "agents");
|
|
46612
46972
|
}
|
|
46613
46973
|
function getClaudeMemDbPath() {
|
|
46614
|
-
return process.env["CLAUDE_MEM_DB"] ??
|
|
46974
|
+
return process.env["CLAUDE_MEM_DB"] ?? join35(homedir2(), ".claude-mem", "claude-mem.db");
|
|
46615
46975
|
}
|
|
46616
46976
|
function resolveWorktreeRouting(cwdOverride) {
|
|
46617
|
-
const cwd =
|
|
46977
|
+
const cwd = resolve15(cwdOverride ?? process.cwd());
|
|
46618
46978
|
const home = homedir2();
|
|
46619
46979
|
let worktreePath;
|
|
46620
46980
|
let current = cwd;
|
|
46621
46981
|
while (current !== home && current !== "/" && current !== "") {
|
|
46622
|
-
const gitPath =
|
|
46982
|
+
const gitPath = join35(current, ".git");
|
|
46623
46983
|
try {
|
|
46624
|
-
if (
|
|
46984
|
+
if (existsSync32(gitPath)) {
|
|
46625
46985
|
const stat3 = statSync9(gitPath);
|
|
46626
46986
|
if (stat3.isFile()) {
|
|
46627
46987
|
worktreePath = current;
|
|
@@ -46633,7 +46993,7 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
46633
46993
|
}
|
|
46634
46994
|
} catch {
|
|
46635
46995
|
}
|
|
46636
|
-
const parent =
|
|
46996
|
+
const parent = dirname19(current);
|
|
46637
46997
|
if (parent === current) break;
|
|
46638
46998
|
current = parent;
|
|
46639
46999
|
}
|
|
@@ -46650,17 +47010,17 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
46650
47010
|
}
|
|
46651
47011
|
function resolveWorktreeFilePath(filePath, routing) {
|
|
46652
47012
|
if (!routing.isWorktree || routing.worktreePath === void 0) {
|
|
46653
|
-
return
|
|
47013
|
+
return resolve15(filePath);
|
|
46654
47014
|
}
|
|
46655
|
-
return
|
|
47015
|
+
return resolve15(routing.cwd, filePath);
|
|
46656
47016
|
}
|
|
46657
47017
|
function detectStrayCleoDb(routing) {
|
|
46658
47018
|
if (!routing.isWorktree || routing.worktreePath === void 0) {
|
|
46659
47019
|
return void 0;
|
|
46660
47020
|
}
|
|
46661
|
-
const tasksDbPath =
|
|
47021
|
+
const tasksDbPath = join35(routing.worktreePath, ".cleo", "tasks.db");
|
|
46662
47022
|
try {
|
|
46663
|
-
if (
|
|
47023
|
+
if (existsSync32(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
|
|
46664
47024
|
return tasksDbPath;
|
|
46665
47025
|
}
|
|
46666
47026
|
} catch {
|
|
@@ -46670,7 +47030,7 @@ function detectStrayCleoDb(routing) {
|
|
|
46670
47030
|
async function resolveProjectById(projectId) {
|
|
46671
47031
|
try {
|
|
46672
47032
|
const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
46673
|
-
if (!
|
|
47033
|
+
if (!existsSync32(getNexusRegistryDbPath2())) return null;
|
|
46674
47034
|
const { eq: eq14 } = await import("drizzle-orm");
|
|
46675
47035
|
const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
46676
47036
|
const db = await getNexusDb2();
|
|
@@ -46705,9 +47065,9 @@ function _rowToRegistryEntry(row) {
|
|
|
46705
47065
|
};
|
|
46706
47066
|
}
|
|
46707
47067
|
function _readProjectNameFromInfo(projectRoot) {
|
|
46708
|
-
const infoPath =
|
|
46709
|
-
if (!
|
|
46710
|
-
const raw =
|
|
47068
|
+
const infoPath = join35(projectRoot, ".cleo", "project-info.json");
|
|
47069
|
+
if (!existsSync32(infoPath)) return void 0;
|
|
47070
|
+
const raw = readFileSync11(infoPath, "utf-8");
|
|
46711
47071
|
const data = JSON.parse(raw);
|
|
46712
47072
|
return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
|
|
46713
47073
|
}
|
|
@@ -46758,7 +47118,7 @@ async function recordProjectEncounter(cwd) {
|
|
|
46758
47118
|
if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
|
|
46759
47119
|
const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
|
|
46760
47120
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
46761
|
-
if (
|
|
47121
|
+
if (existsSync32(getNexusRegistryDbPath2(cleoHome))) {
|
|
46762
47122
|
const { and: and10, eq: eq14 } = await import("drizzle-orm");
|
|
46763
47123
|
const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
46764
47124
|
const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
|