@cleocode/core 2026.9.25 → 2026.9.26
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/admin/import-tasks.d.ts.map +1 -1
- package/dist/admin/import-tasks.js +5 -2
- package/dist/admin/import-tasks.js.map +1 -1
- package/dist/admin/import.d.ts.map +1 -1
- package/dist/admin/import.js +7 -2
- package/dist/admin/import.js.map +1 -1
- package/dist/build-provenance.json +2 -2
- package/dist/cloud/index.d.ts +1 -0
- package/dist/cloud/index.d.ts.map +1 -1
- package/dist/cloud/index.js +1 -0
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/nexus-auth.d.ts +26 -1
- package/dist/cloud/nexus-auth.d.ts.map +1 -1
- package/dist/cloud/nexus-auth.js +61 -32
- package/dist/cloud/nexus-auth.js.map +1 -1
- package/dist/cloud/nexus-credentials.js +2 -2
- package/dist/cloud/nexus-credentials.js.map +1 -1
- package/dist/cloud/nexus-device.d.ts +809 -0
- package/dist/cloud/nexus-device.d.ts.map +1 -0
- package/dist/cloud/nexus-device.js +1680 -0
- package/dist/cloud/nexus-device.js.map +1 -0
- package/dist/cloud/nexus-enrol.d.ts +210 -0
- package/dist/cloud/nexus-enrol.d.ts.map +1 -0
- package/dist/cloud/nexus-enrol.js +1023 -0
- package/dist/cloud/nexus-enrol.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +3 -0
- package/dist/cloud/nexus-link.d.ts.map +1 -1
- package/dist/cloud/nexus-link.js +38 -4
- package/dist/cloud/nexus-link.js.map +1 -1
- package/dist/cloud/signing.d.ts +20 -0
- package/dist/cloud/signing.d.ts.map +1 -1
- package/dist/cloud/signing.js +14 -0
- package/dist/cloud/signing.js.map +1 -1
- package/dist/crypto/credentials.d.ts +61 -0
- package/dist/crypto/credentials.d.ts.map +1 -1
- package/dist/crypto/credentials.js +154 -58
- package/dist/crypto/credentials.js.map +1 -1
- package/dist/docs/export-document.js +830 -190
- package/dist/docs/export-document.js.map +3 -3
- package/dist/doctor/dependency-cycles.d.ts +41 -0
- package/dist/doctor/dependency-cycles.d.ts.map +1 -0
- package/dist/doctor/dependency-cycles.js +39 -0
- package/dist/doctor/dependency-cycles.js.map +1 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.d.ts.map +1 -1
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/index.js.map +1 -1
- package/dist/doctor/row-identity.d.ts +11 -0
- package/dist/doctor/row-identity.d.ts.map +1 -1
- package/dist/doctor/row-identity.js +67 -9
- package/dist/doctor/row-identity.js.map +1 -1
- package/dist/error-catalog.d.ts.map +1 -1
- package/dist/error-catalog.js +4 -0
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.d.ts.map +1 -1
- package/dist/error-registry.js +8 -0
- package/dist/error-registry.js.map +1 -1
- package/dist/llm/plugin-facade.js +857 -217
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/nexus/workspace.d.ts.map +1 -1
- package/dist/nexus/workspace.js +54 -4
- package/dist/nexus/workspace.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +1 -1
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +4 -2
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +3 -3
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.js +1 -1
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +3 -3
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/parallel.js +1 -1
- package/dist/orchestration/parallel.js.map +1 -1
- package/dist/orchestration/wave-topic.d.ts +4 -2
- package/dist/orchestration/wave-topic.d.ts.map +1 -1
- package/dist/orchestration/wave-topic.js +6 -4
- package/dist/orchestration/wave-topic.js.map +1 -1
- package/dist/orchestration/waves.d.ts +2 -1
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +4 -3
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +4 -2
- package/dist/phases/index.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +856 -216
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +77 -49
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +69 -23
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +113 -27
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/handoff.js +1 -1
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +24 -13
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/terminal-identity.d.ts +165 -17
- package/dist/sessions/terminal-identity.d.ts.map +1 -1
- package/dist/sessions/terminal-identity.js +341 -32
- package/dist/sessions/terminal-identity.js.map +1 -1
- package/dist/skills/orchestrator/startup.js +2 -2
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/snapshot/index.d.ts +4 -0
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +50 -3
- package/dist/snapshot/index.js.map +1 -1
- package/dist/store/db-helpers.d.ts +15 -2
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +84 -3
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dependency-cycles.d.ts +164 -0
- package/dist/store/dependency-cycles.d.ts.map +1 -0
- package/dist/store/dependency-cycles.js +360 -0
- package/dist/store/dependency-cycles.js.map +1 -0
- package/dist/store/display-id-alias.d.ts +93 -37
- package/dist/store/display-id-alias.d.ts.map +1 -1
- package/dist/store/display-id-alias.js +590 -115
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +34 -7
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +8 -1
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/global-salt.d.ts +35 -0
- package/dist/store/global-salt.d.ts.map +1 -1
- package/dist/store/global-salt.js +136 -16
- package/dist/store/global-salt.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +19 -11
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +6 -0
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +11 -3
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts +91 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +276 -7
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/safety-data-accessor.d.ts +3 -2
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +5 -2
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/session-store.d.ts +63 -3
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +121 -8
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/split-brain-import.d.ts.map +1 -1
- package/dist/store/split-brain-import.js +36 -0
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +50 -3
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +246 -13
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +14 -2
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +3 -2
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +5 -2
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/system/health.d.ts +2 -0
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +54 -0
- package/dist/system/health.js.map +1 -1
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +9 -6
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +3 -2
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/evidence.d.ts +19 -1
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +79 -18
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/infer-add-params.js +1 -1
- package/dist/tasks/infer-add-params.js.map +1 -1
- package/dist/tasks/task-context.d.ts.map +1 -1
- package/dist/tasks/task-context.js +3 -1
- package/dist/tasks/task-context.js.map +1 -1
- package/dist/tasks/task-import.d.ts.map +1 -1
- package/dist/tasks/task-import.js +11 -3
- package/dist/tasks/task-import.js.map +1 -1
- package/dist/tasks/task-next.d.ts +5 -1
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +7 -2
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +3 -2
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
- package/dist/workgraph/scaffold-apply.js +14 -5
- package/dist/workgraph/scaffold-apply.js.map +1 -1
- package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/migration.sql +76 -0
- package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/revert.sql +7 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +2 -2
- package/templates/CLEO-REFERENCE.md +1 -1
|
@@ -1874,7 +1874,7 @@ var init_output_contracts_data = __esm({
|
|
|
1874
1874
|
// T12503: the optimistic-concurrency version agents pass to --if-match.
|
|
1875
1875
|
updatedAt: {
|
|
1876
1876
|
type: ["string", "null"],
|
|
1877
|
-
description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`."
|
|
1877
|
+
description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`. A stale version fails with E_CONFLICT (23); E_TASK_RENAMED (26) when sync re-numbered the task you read (details.expected is its new id)."
|
|
1878
1878
|
},
|
|
1879
1879
|
// T12502: the human assignee and the agent claim lease are separate.
|
|
1880
1880
|
assignee: {
|
|
@@ -13135,6 +13135,7 @@ var init_exit_codes = __esm({
|
|
|
13135
13135
|
ExitCode2[ExitCode2["VERSION_CONFLICT"] = 23] = "VERSION_CONFLICT";
|
|
13136
13136
|
ExitCode2[ExitCode2["SESSION_UNBOUND"] = 24] = "SESSION_UNBOUND";
|
|
13137
13137
|
ExitCode2[ExitCode2["WORKTREE_LOCKED"] = 25] = "WORKTREE_LOCKED";
|
|
13138
|
+
ExitCode2[ExitCode2["TASK_RENAMED"] = 26] = "TASK_RENAMED";
|
|
13138
13139
|
ExitCode2[ExitCode2["SESSION_EXISTS"] = 30] = "SESSION_EXISTS";
|
|
13139
13140
|
ExitCode2[ExitCode2["SESSION_NOT_FOUND"] = 31] = "SESSION_NOT_FOUND";
|
|
13140
13141
|
ExitCode2[ExitCode2["SCOPE_CONFLICT"] = 32] = "SCOPE_CONFLICT";
|
|
@@ -17890,6 +17891,19 @@ var init_error_catalog = __esm({
|
|
|
17890
17891
|
`Bind a session: run 'cleo session start --scope global --name "<name>"', 'cleo session resume <id>', or set CLEO_SESSION_ID=<id>.`
|
|
17891
17892
|
)
|
|
17892
17893
|
],
|
|
17894
|
+
[
|
|
17895
|
+
26 /* TASK_RENAMED */,
|
|
17896
|
+
def(
|
|
17897
|
+
26 /* TASK_RENAMED */,
|
|
17898
|
+
"TASK_RENAMED",
|
|
17899
|
+
"CONFLICT",
|
|
17900
|
+
"Task was re-numbered by sync",
|
|
17901
|
+
409,
|
|
17902
|
+
true,
|
|
17903
|
+
"E_TASK_RENAMED",
|
|
17904
|
+
"The task you addressed now has another id (a display-id collision re-numbered it). Re-read it with 'cleo show <new id>' and retry against that id."
|
|
17905
|
+
)
|
|
17906
|
+
],
|
|
17893
17907
|
[
|
|
17894
17908
|
25 /* WORKTREE_LOCKED */,
|
|
17895
17909
|
def(
|
|
@@ -19837,10 +19851,10 @@ var init_table2 = __esm({
|
|
|
19837
19851
|
[IsDrizzleTable] = true;
|
|
19838
19852
|
/** @internal */
|
|
19839
19853
|
[ExtraConfigBuilder] = void 0;
|
|
19840
|
-
constructor(name15, schema,
|
|
19854
|
+
constructor(name15, schema, baseName2) {
|
|
19841
19855
|
this[TableName] = this[OriginalName] = name15;
|
|
19842
19856
|
this[TableSchema] = schema;
|
|
19843
|
-
this[BaseName] =
|
|
19857
|
+
this[BaseName] = baseName2;
|
|
19844
19858
|
}
|
|
19845
19859
|
};
|
|
19846
19860
|
}
|
|
@@ -21770,9 +21784,9 @@ var init_casing = __esm({
|
|
|
21770
21784
|
});
|
|
21771
21785
|
|
|
21772
21786
|
// node_modules/.pnpm/drizzle-orm@1.0.0-rc.4_@opentelemetry+api@1.9.0_@sinclair+typebox@0.34.49_@types+mssql@_b4e81f2ea693a7363d3e5dc2205249c6/node_modules/drizzle-orm/sqlite-core/table.js
|
|
21773
|
-
function sqliteTableBase(name15, columns, extraConfig, schema, casing,
|
|
21787
|
+
function sqliteTableBase(name15, columns, extraConfig, schema, casing, baseName2 = name15) {
|
|
21774
21788
|
const casingFn = getCasingFn(casing);
|
|
21775
|
-
const rawTable = new SQLiteTable(name15, schema,
|
|
21789
|
+
const rawTable = new SQLiteTable(name15, schema, baseName2);
|
|
21776
21790
|
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
21777
21791
|
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name16, colBuilderBase]) => {
|
|
21778
21792
|
const colBuilder = colBuilderBase;
|
|
@@ -25561,6 +25575,10 @@ function decisionFor(dbPath) {
|
|
|
25561
25575
|
if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
|
|
25562
25576
|
return decisions.get(key) ?? null;
|
|
25563
25577
|
}
|
|
25578
|
+
function schemaWritesAllowed(nativeDb) {
|
|
25579
|
+
const dbPath = nativeDb.location();
|
|
25580
|
+
return !dbPath || decisionFor(dbPath) === null;
|
|
25581
|
+
}
|
|
25564
25582
|
function isWorktreeBuildSchemaError(error48) {
|
|
25565
25583
|
return error48 instanceof Error && error48.message.includes(E_WORKTREE_BUILD_SCHEMA);
|
|
25566
25584
|
}
|
|
@@ -26599,7 +26617,10 @@ var init_row_identity_registry = __esm({
|
|
|
26599
26617
|
key: ["id"],
|
|
26600
26618
|
birth: "recorded_at",
|
|
26601
26619
|
content: ["ac_id", "previous_text", "reason"],
|
|
26602
|
-
|
|
26620
|
+
// v2 (T12802): no @refFp: the criterion's fingerprint is unknowable when
|
|
26621
|
+
// it was gone before this row got its identity, so it made the value
|
|
26622
|
+
// depend on fill timing. ac_id is always known.
|
|
26623
|
+
birthFacts: ["ac_id", "previous_text", "reason"],
|
|
26603
26624
|
storedRefUids: [{ column: "ac_uid", from: "ac_id", table: ACS }],
|
|
26604
26625
|
task: "T12341"
|
|
26605
26626
|
},
|
|
@@ -26608,7 +26629,10 @@ var init_row_identity_registry = __esm({
|
|
|
26608
26629
|
kind: "minted",
|
|
26609
26630
|
key: ["id"],
|
|
26610
26631
|
birth: "created_at",
|
|
26611
|
-
|
|
26632
|
+
// v2 (T12802): ac_id in place of @refFp:ac_uid and ac_text_hash. Both
|
|
26633
|
+
// were filled from the criterion, so a backfilled binding whose
|
|
26634
|
+
// criterion was already gone got a different value (see AC history).
|
|
26635
|
+
birthFacts: ["evidence_atom_id", "binding_type", "ac_id"],
|
|
26612
26636
|
storedRefUids: [
|
|
26613
26637
|
{ column: "ac_uid", from: "ac_id", table: ACS },
|
|
26614
26638
|
{ column: "ac_text_hash", from: "ac_id", table: ACS, source: "text_hash" }
|
|
@@ -26650,7 +26674,9 @@ var init_row_identity_registry = __esm({
|
|
|
26650
26674
|
// The uid IS the primary key: display-id-alias.ts computes it on write.
|
|
26651
26675
|
table: "tasks_display_id_aliases",
|
|
26652
26676
|
kind: "natural",
|
|
26653
|
-
|
|
26677
|
+
// T12800: the reason is part of the key (collision-remint and
|
|
26678
|
+
// remint-assigned of one id and row are distinct facts).
|
|
26679
|
+
key: ["entity_table", "display_id", "entity_uid", "reason"],
|
|
26654
26680
|
task: "T12341"
|
|
26655
26681
|
},
|
|
26656
26682
|
{
|
|
@@ -27232,6 +27258,20 @@ function installRowUidTriggers(db, scope) {
|
|
|
27232
27258
|
);
|
|
27233
27259
|
}
|
|
27234
27260
|
}
|
|
27261
|
+
function v1ReleaseBirthFp(db, table, row) {
|
|
27262
|
+
const col = (c) => row[c] ?? null;
|
|
27263
|
+
const facts = table === "tasks_task_acceptance_criteria_history" ? [col("ac_id"), col("previous_text"), col("reason")] : table === "tasks_evidence_ac_bindings" ? [col("evidence_atom_id"), col("binding_type"), col("ac_text_hash")] : [];
|
|
27264
|
+
if (facts.length === 0) return null;
|
|
27265
|
+
const acUid = col("ac_uid");
|
|
27266
|
+
let ref = "ref:none";
|
|
27267
|
+
if (acUid !== null) {
|
|
27268
|
+
const ac = db.prepare("SELECT birth_fp AS fp FROM main.tasks_task_acceptance_criteria WHERE uid = ?").get(acUid);
|
|
27269
|
+
ref = ac === void 0 ? "ref:missing" : ac.fp;
|
|
27270
|
+
if (ref === null) return null;
|
|
27271
|
+
}
|
|
27272
|
+
const spec = rowIdentitySpec("project", table);
|
|
27273
|
+
return birthFingerprint(table, spec?.birth ? col(spec.birth) : null, [...facts, ref]);
|
|
27274
|
+
}
|
|
27235
27275
|
function hasObject(db, type, name15) {
|
|
27236
27276
|
return db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = ? AND name = ?").get(type, name15) !== void 0;
|
|
27237
27277
|
}
|
|
@@ -27315,24 +27355,41 @@ function preReleaseBirthFp(db, table, row) {
|
|
|
27315
27355
|
function resetStaleIdentity(db, scope, writers) {
|
|
27316
27356
|
if (scope !== "project" || !hasTable(db, ROW_IDENTITY_META_TABLE)) return "none";
|
|
27317
27357
|
if (readMeta(db, ROW_IDENTITY_RECIPE_KEY) === ROW_IDENTITY_RECIPE) return "none";
|
|
27318
|
-
const minted = ROW_IDENTITY.project.filter(
|
|
27319
|
-
(spec) =>
|
|
27358
|
+
const minted = fingerprintOrder("project", ROW_IDENTITY.project).filter(
|
|
27359
|
+
(spec) => hasTable(db, spec.table) && columnsOf(db, spec.table).has(BIRTH_FP_COLUMN)
|
|
27320
27360
|
);
|
|
27321
27361
|
const stale = [];
|
|
27362
|
+
const cleared = /* @__PURE__ */ new Map();
|
|
27363
|
+
const mark = (table, column, value) => {
|
|
27364
|
+
if (value === null || value === void 0) return;
|
|
27365
|
+
const key = `${table}.${column}`;
|
|
27366
|
+
const set2 = cleared.get(key) ?? /* @__PURE__ */ new Set();
|
|
27367
|
+
set2.add(String(value));
|
|
27368
|
+
cleared.set(key, set2);
|
|
27369
|
+
};
|
|
27322
27370
|
for (const spec of minted) {
|
|
27371
|
+
const deps = (spec.birthFacts ?? []).map((fact) => fingerprintRef("project", spec, fact)).filter((d) => d !== null);
|
|
27372
|
+
const keyColumn = targetKey("project", spec.table);
|
|
27323
27373
|
const rows = db.prepare(
|
|
27324
27374
|
`SELECT rowid AS _rowid, * FROM main.${q(spec.table)} WHERE ${q(BIRTH_FP_COLUMN)} IS NOT NULL`
|
|
27325
27375
|
).all();
|
|
27326
27376
|
for (const row of rows) {
|
|
27327
|
-
|
|
27377
|
+
const derivedFromStale = deps.some(
|
|
27378
|
+
(d) => cleared.get(`${d.table}.${d.key}`)?.has(String(row[d.column] ?? ""))
|
|
27379
|
+
);
|
|
27380
|
+
if (derivedFromStale || row[BIRTH_FP_COLUMN] === preReleaseBirthFp(db, spec.table, row) || row[BIRTH_FP_COLUMN] === v1ReleaseBirthFp(db, spec.table, row)) {
|
|
27328
27381
|
stale.push({ table: spec.table, rowid: row._rowid });
|
|
27382
|
+
mark(spec.table, keyColumn, row[keyColumn]);
|
|
27383
|
+
mark(spec.table, UID_COLUMN, row[UID_COLUMN]);
|
|
27329
27384
|
}
|
|
27330
27385
|
}
|
|
27331
27386
|
}
|
|
27332
|
-
|
|
27387
|
+
const graveyardRows = scope === "project" && hasTable(db, AC_UID_GRAVEYARD) ? db.prepare(`SELECT count(*) AS n FROM main.${AC_UID_GRAVEYARD}`).get().n : 0;
|
|
27388
|
+
if (stale.length === 0 && graveyardRows === 0) return "none";
|
|
27333
27389
|
if (readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0) return "refused";
|
|
27334
27390
|
db.exec("SAVEPOINT row_identity_reset");
|
|
27335
27391
|
try {
|
|
27392
|
+
if (graveyardRows > 0) writers.clearAcUidGraveyardNative(db);
|
|
27336
27393
|
for (const { table, rowid } of stale) {
|
|
27337
27394
|
writers.clearBirthFpNative(db, table, rowid);
|
|
27338
27395
|
}
|
|
@@ -27348,6 +27405,106 @@ function writeRecipeMarker(db, writers = requireWriters()) {
|
|
|
27348
27405
|
if (!hasTable(db, ROW_IDENTITY_META_TABLE)) return;
|
|
27349
27406
|
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_RECIPE);
|
|
27350
27407
|
}
|
|
27408
|
+
function rowIdentityShared(db) {
|
|
27409
|
+
return readMeta(db, ROW_IDENTITY_SYNCED_KEY) !== void 0;
|
|
27410
|
+
}
|
|
27411
|
+
function healRowIdentitySchema(db, scope, writers = registeredWriters) {
|
|
27412
|
+
const log15 = getLogger("row-identity");
|
|
27413
|
+
if (ROW_IDENTITY[scope].length === 0) {
|
|
27414
|
+
return [];
|
|
27415
|
+
}
|
|
27416
|
+
if (!schemaWritesAllowed(db)) {
|
|
27417
|
+
log15.debug({ scope }, "row identity schema heal skipped: schema writes refused for this build");
|
|
27418
|
+
return [];
|
|
27419
|
+
}
|
|
27420
|
+
try {
|
|
27421
|
+
db.exec("SAVEPOINT row_identity_heal");
|
|
27422
|
+
try {
|
|
27423
|
+
const healed = [
|
|
27424
|
+
...scope === "project" ? ensureIdentityTables(db) : [],
|
|
27425
|
+
...ensureRowIdentitySchema(db, scope)
|
|
27426
|
+
];
|
|
27427
|
+
if (healed.length > 0) recordHealReceipt(db, scope, healed, writers);
|
|
27428
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27429
|
+
if (healed.length > 0)
|
|
27430
|
+
log15.info({ scope, healed: healed.length }, "row identity schema healed");
|
|
27431
|
+
return healed;
|
|
27432
|
+
} catch (error48) {
|
|
27433
|
+
db.exec("ROLLBACK TO SAVEPOINT row_identity_heal");
|
|
27434
|
+
db.exec("RELEASE SAVEPOINT row_identity_heal");
|
|
27435
|
+
throw error48;
|
|
27436
|
+
}
|
|
27437
|
+
} catch (error48) {
|
|
27438
|
+
log15.error({ scope, error: error48 }, "row identity schema heal failed");
|
|
27439
|
+
return [];
|
|
27440
|
+
}
|
|
27441
|
+
}
|
|
27442
|
+
function recordHealReceipt(db, scope, healed, writers) {
|
|
27443
|
+
const table = HEAL_RECEIPT_TABLE[scope];
|
|
27444
|
+
const log15 = getLogger("row-identity");
|
|
27445
|
+
if (table === null || !hasTable(db, table) || !writers) {
|
|
27446
|
+
log15.warn({ scope, healed: healed.length }, "row identity schema healed; no receipt table");
|
|
27447
|
+
return;
|
|
27448
|
+
}
|
|
27449
|
+
const objects = healed.map((stmt) => {
|
|
27450
|
+
const col = /ALTER TABLE main\.("?)(\w+)\1 ADD COLUMN ("?)(\w+)\3/.exec(stmt);
|
|
27451
|
+
if (col) return `${col[2]}.${col[4]}`;
|
|
27452
|
+
const obj = /(TABLE|INDEX|TRIGGER) IF NOT EXISTS main\.("?)(\w+)\2/.exec(stmt);
|
|
27453
|
+
return obj ? `${obj[1].toLowerCase()} ${obj[3]}` : stmt.slice(0, 60);
|
|
27454
|
+
});
|
|
27455
|
+
const receipt2 = {
|
|
27456
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27457
|
+
scope,
|
|
27458
|
+
statements: healed.length,
|
|
27459
|
+
objects
|
|
27460
|
+
};
|
|
27461
|
+
const history = [...readRowIdentityHealHistory(db), receipt2].slice(-HEAL_RECEIPTS_KEPT);
|
|
27462
|
+
writers.writeRowIdentityMetaNative(db, ROW_IDENTITY_HEAL_KEY, JSON.stringify(history));
|
|
27463
|
+
}
|
|
27464
|
+
function readRowIdentityHealHistory(db) {
|
|
27465
|
+
const raw = readMeta(db, ROW_IDENTITY_HEAL_KEY);
|
|
27466
|
+
if (raw === void 0) return [];
|
|
27467
|
+
try {
|
|
27468
|
+
const parsed = JSON.parse(raw);
|
|
27469
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
27470
|
+
} catch {
|
|
27471
|
+
return [];
|
|
27472
|
+
}
|
|
27473
|
+
}
|
|
27474
|
+
function missingRowIdentitySchema(db) {
|
|
27475
|
+
if (!hasTable(db, "tasks_task_acceptance_criteria")) return [];
|
|
27476
|
+
const missing = [];
|
|
27477
|
+
for (const table of Object.keys(IDENTITY_TABLE_DDL)) {
|
|
27478
|
+
if (!hasTable(db, table)) missing.push(`table ${table}`);
|
|
27479
|
+
}
|
|
27480
|
+
for (const [table, column] of [
|
|
27481
|
+
["tasks_display_id_aliases", "displaced_hlc"],
|
|
27482
|
+
["tasks_display_id_aliases", "entity_birth_fp"],
|
|
27483
|
+
[AC_UID_GRAVEYARD, "birth_fp"]
|
|
27484
|
+
]) {
|
|
27485
|
+
if (hasTable(db, table) && !columnsOf(db, table).has(column)) {
|
|
27486
|
+
missing.push(`column ${table}.${column}`);
|
|
27487
|
+
}
|
|
27488
|
+
}
|
|
27489
|
+
if (!hasObject(db, "trigger", "trg_tasks_ac_uid_graveyard")) {
|
|
27490
|
+
missing.push("trigger trg_tasks_ac_uid_graveyard");
|
|
27491
|
+
}
|
|
27492
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
27493
|
+
if (!hasTable(db, spec.table)) continue;
|
|
27494
|
+
const cols = columnsOf(db, spec.table);
|
|
27495
|
+
for (const column of rowIdentityColumns("project", spec.table)) {
|
|
27496
|
+
if (!cols.has(column)) missing.push(`column ${spec.table}.${column}`);
|
|
27497
|
+
}
|
|
27498
|
+
if (!uidIsPrimaryKey(db, spec.table) && !hasObject(db, "index", `uq_${spec.table}_uid`)) {
|
|
27499
|
+
missing.push(`index uq_${spec.table}_uid`);
|
|
27500
|
+
}
|
|
27501
|
+
for (const ref of spec.storedRefUids ?? []) {
|
|
27502
|
+
const index2 = `idx_${spec.table}_${ref.column}`;
|
|
27503
|
+
if (!hasObject(db, "index", index2)) missing.push(`index ${index2}`);
|
|
27504
|
+
}
|
|
27505
|
+
}
|
|
27506
|
+
return missing;
|
|
27507
|
+
}
|
|
27351
27508
|
function prepareRowIdentity(db, scope, options = {}) {
|
|
27352
27509
|
if (ROW_IDENTITY[scope].length === 0) return null;
|
|
27353
27510
|
if (!rowUidFillEnabled()) return null;
|
|
@@ -27386,7 +27543,7 @@ function prepareRowIdentity(db, scope, options = {}) {
|
|
|
27386
27543
|
return null;
|
|
27387
27544
|
}
|
|
27388
27545
|
}
|
|
27389
|
-
var ROW_UID_DOMAIN, ROW_BIRTH_DOMAIN, ROW_UID_SQL_FUNCTION, ROW_BIRTH_FP_SQL_FUNCTION, ROW_RANDOM_UID_SQL_FUNCTION, AC_TEXT_HASH_SQL_FUNCTION, AC_UID_GRAVEYARD, registeredWriters, STORE_TIMESTAMP, MAX_UUID_MS, ROW_IDENTITY_RECIPE, ROW_IDENTITY_META_TABLE, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_SYNCED_KEY, IDENTITY_TABLE_DDL, AC_UID_GRAVEYARD_TRIGGER;
|
|
27546
|
+
var ROW_UID_DOMAIN, ROW_BIRTH_DOMAIN, ROW_UID_SQL_FUNCTION, ROW_BIRTH_FP_SQL_FUNCTION, ROW_RANDOM_UID_SQL_FUNCTION, AC_TEXT_HASH_SQL_FUNCTION, AC_UID_GRAVEYARD, registeredWriters, STORE_TIMESTAMP, MAX_UUID_MS, ROW_IDENTITY_RECIPE, ROW_IDENTITY_META_TABLE, ROW_IDENTITY_RECIPE_KEY, ROW_IDENTITY_SYNCED_KEY, IDENTITY_TABLE_DDL, AC_UID_GRAVEYARD_TRIGGER, ROW_IDENTITY_HEAL_KEY, HEAL_RECEIPT_TABLE, HEAL_RECEIPTS_KEPT;
|
|
27390
27547
|
var init_row_identity = __esm({
|
|
27391
27548
|
"packages/core/src/store/row-identity.ts"() {
|
|
27392
27549
|
"use strict";
|
|
@@ -27395,6 +27552,7 @@ var init_row_identity = __esm({
|
|
|
27395
27552
|
init_ac_table();
|
|
27396
27553
|
init_row_identity_flag();
|
|
27397
27554
|
init_row_identity_registry();
|
|
27555
|
+
init_worktree_build_guard();
|
|
27398
27556
|
ROW_UID_DOMAIN = "cleo/row-uid/v1";
|
|
27399
27557
|
ROW_BIRTH_DOMAIN = "cleo/row-birth/v1";
|
|
27400
27558
|
ROW_UID_SQL_FUNCTION = "cleo_row_uid";
|
|
@@ -27404,7 +27562,7 @@ var init_row_identity = __esm({
|
|
|
27404
27562
|
AC_UID_GRAVEYARD = "tasks_ac_uid_graveyard";
|
|
27405
27563
|
STORE_TIMESTAMP = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
27406
27564
|
MAX_UUID_MS = 2 ** 48 - 1;
|
|
27407
|
-
ROW_IDENTITY_RECIPE = "cleo/row-identity/
|
|
27565
|
+
ROW_IDENTITY_RECIPE = "cleo/row-identity/v2";
|
|
27408
27566
|
ROW_IDENTITY_META_TABLE = "tasks_row_identity_meta";
|
|
27409
27567
|
ROW_IDENTITY_RECIPE_KEY = "row_identity_recipe";
|
|
27410
27568
|
ROW_IDENTITY_SYNCED_KEY = "row_identity_synced";
|
|
@@ -27449,6 +27607,15 @@ BEGIN
|
|
|
27449
27607
|
INSERT INTO ${AC_UID_GRAVEYARD} (ac_id, uid, task_id, ordinal, text, birth_fp, deleted_at)
|
|
27450
27608
|
VALUES (OLD.id, OLD.uid, OLD.task_id, OLD.ordinal, OLD.text, OLD.birth_fp, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
27451
27609
|
END`;
|
|
27610
|
+
ROW_IDENTITY_HEAL_KEY = "row_identity_schema_healed";
|
|
27611
|
+
HEAL_RECEIPT_TABLE = {
|
|
27612
|
+
project: ROW_IDENTITY_META_TABLE,
|
|
27613
|
+
// The global store declares no identity table yet (ROW_IDENTITY.global is
|
|
27614
|
+
// empty, so its heal never runs); the change that declares one adds its
|
|
27615
|
+
// meta table here.
|
|
27616
|
+
global: null
|
|
27617
|
+
};
|
|
27618
|
+
HEAL_RECEIPTS_KEPT = 20;
|
|
27452
27619
|
}
|
|
27453
27620
|
});
|
|
27454
27621
|
|
|
@@ -40995,12 +41162,12 @@ var init_safety_data_accessor = __esm({
|
|
|
40995
41162
|
this.getSafetyOptions()
|
|
40996
41163
|
);
|
|
40997
41164
|
}
|
|
40998
|
-
async insertNewTask(task) {
|
|
41165
|
+
async insertNewTask(task, identity) {
|
|
40999
41166
|
this.logVerbose(`Inserting new task ${task.id}`);
|
|
41000
41167
|
await safeSingleTaskWrite(
|
|
41001
41168
|
this.inner,
|
|
41002
41169
|
task.id,
|
|
41003
|
-
() => this.inner.insertNewTask(task),
|
|
41170
|
+
() => this.inner.insertNewTask(task, identity),
|
|
41004
41171
|
this.cwd,
|
|
41005
41172
|
this.getSafetyOptions()
|
|
41006
41173
|
);
|
|
@@ -41048,6 +41215,9 @@ var init_safety_data_accessor = __esm({
|
|
|
41048
41215
|
return this.inner.findOrphanAcBindings();
|
|
41049
41216
|
}
|
|
41050
41217
|
// ---- Metadata (pass-through to inner) ----
|
|
41218
|
+
async getTaskIdentities(taskIds) {
|
|
41219
|
+
return await this.inner.getTaskIdentities?.(taskIds) ?? [];
|
|
41220
|
+
}
|
|
41051
41221
|
async getMetaValue(key) {
|
|
41052
41222
|
return this.inner.getMetaValue(key);
|
|
41053
41223
|
}
|
|
@@ -41421,13 +41591,147 @@ var init_cross_db_cleanup = __esm({
|
|
|
41421
41591
|
}
|
|
41422
41592
|
});
|
|
41423
41593
|
|
|
41594
|
+
// packages/core/src/store/dependency-cycles.ts
|
|
41595
|
+
function formatDependencyCycle(cycle) {
|
|
41596
|
+
return cycle.join(" \u2192 ");
|
|
41597
|
+
}
|
|
41598
|
+
function buildAdjacency(edges) {
|
|
41599
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
41600
|
+
for (const { taskId, dependsOn } of edges) {
|
|
41601
|
+
const next = adjacency.get(taskId);
|
|
41602
|
+
if (next) next.push(dependsOn);
|
|
41603
|
+
else adjacency.set(taskId, [dependsOn]);
|
|
41604
|
+
}
|
|
41605
|
+
for (const next of adjacency.values()) next.sort();
|
|
41606
|
+
return adjacency;
|
|
41607
|
+
}
|
|
41608
|
+
function shortestPath(adjacency, from, to) {
|
|
41609
|
+
if (from === to) return [from];
|
|
41610
|
+
const previous = /* @__PURE__ */ new Map([[from, from]]);
|
|
41611
|
+
const queue = [from];
|
|
41612
|
+
for (let head = 0; head < queue.length; head++) {
|
|
41613
|
+
const id = queue[head];
|
|
41614
|
+
for (const next of adjacency.get(id) ?? []) {
|
|
41615
|
+
if (previous.has(next)) continue;
|
|
41616
|
+
previous.set(next, id);
|
|
41617
|
+
if (next === to) {
|
|
41618
|
+
const path = [to];
|
|
41619
|
+
let cursor = id;
|
|
41620
|
+
while (cursor !== from) {
|
|
41621
|
+
path.push(cursor);
|
|
41622
|
+
cursor = previous.get(cursor);
|
|
41623
|
+
}
|
|
41624
|
+
path.push(from);
|
|
41625
|
+
return path.reverse();
|
|
41626
|
+
}
|
|
41627
|
+
queue.push(next);
|
|
41628
|
+
}
|
|
41629
|
+
}
|
|
41630
|
+
return null;
|
|
41631
|
+
}
|
|
41632
|
+
function findClosedCycle(existing, edge) {
|
|
41633
|
+
if (edge.taskId === edge.dependsOn) return [edge.taskId, edge.taskId];
|
|
41634
|
+
const path = shortestPath(buildAdjacency(existing), edge.dependsOn, edge.taskId);
|
|
41635
|
+
return path ? [edge.taskId, ...path] : null;
|
|
41636
|
+
}
|
|
41637
|
+
function dependencyCycleError(edge, cycle) {
|
|
41638
|
+
const self = edge.taskId === edge.dependsOn;
|
|
41639
|
+
const message = self ? `${DEPENDENCY_CYCLE_CODE}: task ${edge.taskId} cannot depend on itself` : `${DEPENDENCY_CYCLE_CODE}: ${edge.taskId} depends on ${edge.dependsOn} would close a dependency cycle: ${formatDependencyCycle(cycle)}`;
|
|
41640
|
+
const closing = cycle.length >= 3 ? cycle[cycle.length - 2] : void 0;
|
|
41641
|
+
const fix = self ? `Drop ${edge.taskId} from its own --depends list` : `Drop this dependency, or first remove another edge of the cycle, e.g. cleo update ${closing} --remove-depends ${edge.taskId}`;
|
|
41642
|
+
return new CleoError(14 /* CIRCULAR_REFERENCE */, message, {
|
|
41643
|
+
fix,
|
|
41644
|
+
details: {
|
|
41645
|
+
field: "depends",
|
|
41646
|
+
actual: edge.dependsOn,
|
|
41647
|
+
taskId: edge.taskId,
|
|
41648
|
+
cycle: [...cycle]
|
|
41649
|
+
}
|
|
41650
|
+
});
|
|
41651
|
+
}
|
|
41652
|
+
function isDependencyCycleAbort(err) {
|
|
41653
|
+
for (let e = err, depth = 0; e instanceof Error && depth < 8; depth++) {
|
|
41654
|
+
if (e.message.includes(DEPENDENCY_CYCLE_CODE)) return true;
|
|
41655
|
+
e = e.cause;
|
|
41656
|
+
}
|
|
41657
|
+
return false;
|
|
41658
|
+
}
|
|
41659
|
+
function readDependencyEdges(db) {
|
|
41660
|
+
return db.select({
|
|
41661
|
+
taskId: tasksTaskDependencies.taskId,
|
|
41662
|
+
dependsOn: tasksTaskDependencies.dependsOn
|
|
41663
|
+
}).from(tasksTaskDependencies).all();
|
|
41664
|
+
}
|
|
41665
|
+
function rethrowDependencyCycle(db, err, attempted) {
|
|
41666
|
+
if (!isDependencyCycleAbort(err)) throw err;
|
|
41667
|
+
const edges = readDependencyEdges(db);
|
|
41668
|
+
for (const edge of attempted) {
|
|
41669
|
+
const cycle = findClosedCycle(edges, edge);
|
|
41670
|
+
if (cycle) throw dependencyCycleError(edge, cycle);
|
|
41671
|
+
edges.push(edge);
|
|
41672
|
+
}
|
|
41673
|
+
throw err;
|
|
41674
|
+
}
|
|
41675
|
+
var DEPENDENCY_CYCLE_CODE;
|
|
41676
|
+
var init_dependency_cycles = __esm({
|
|
41677
|
+
"packages/core/src/store/dependency-cycles.ts"() {
|
|
41678
|
+
"use strict";
|
|
41679
|
+
init_src();
|
|
41680
|
+
init_errors2();
|
|
41681
|
+
init_tasks_schema();
|
|
41682
|
+
DEPENDENCY_CYCLE_CODE = "E_TASK_DEPENDENCY_CYCLE";
|
|
41683
|
+
}
|
|
41684
|
+
});
|
|
41685
|
+
|
|
41424
41686
|
// packages/core/src/store/db-helpers.ts
|
|
41425
41687
|
import { and as and5, eq as eq7, inArray as inArray3, sql as sql27 } from "drizzle-orm";
|
|
41426
41688
|
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
41427
41689
|
await writeTaskRow(db, row, archiveFields, allowOrphanParent, false);
|
|
41428
41690
|
}
|
|
41429
|
-
async function insertNewTask(db, row) {
|
|
41430
|
-
await writeTaskRow(
|
|
41691
|
+
async function insertNewTask(db, row, identity = { origin: "new" }) {
|
|
41692
|
+
await writeTaskRow(
|
|
41693
|
+
db,
|
|
41694
|
+
{ ...row, ...await importedIdentity(db, identity, row) },
|
|
41695
|
+
void 0,
|
|
41696
|
+
false,
|
|
41697
|
+
true
|
|
41698
|
+
);
|
|
41699
|
+
}
|
|
41700
|
+
async function tableExists2(db, table) {
|
|
41701
|
+
const rows = await db.all(
|
|
41702
|
+
sql27`SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ${table}`
|
|
41703
|
+
);
|
|
41704
|
+
return rows.length > 0;
|
|
41705
|
+
}
|
|
41706
|
+
async function importedIdentity(db, identity, row) {
|
|
41707
|
+
if (identity.origin === "new" || !rowUidFillEnabled()) return {};
|
|
41708
|
+
const fp = identity.birthFp ?? null;
|
|
41709
|
+
const carried2 = identity.uid ?? null;
|
|
41710
|
+
if (carried2 !== null && fp !== null) {
|
|
41711
|
+
let uid = carried2;
|
|
41712
|
+
if (await tableExists2(db, "tasks_uid_aliases")) {
|
|
41713
|
+
for (let hop = 0; hop < 32; hop++) {
|
|
41714
|
+
const found = await db.all(
|
|
41715
|
+
sql27`SELECT new_uid AS uid FROM tasks_uid_aliases
|
|
41716
|
+
WHERE entity_table = 'tasks_tasks' AND old_uid = ${uid} AND old_birth_fp = ${fp}`
|
|
41717
|
+
);
|
|
41718
|
+
const next = found[0];
|
|
41719
|
+
if (!next) break;
|
|
41720
|
+
uid = next.uid;
|
|
41721
|
+
}
|
|
41722
|
+
}
|
|
41723
|
+
const [holder] = await db.select({ id: tasksTasks.id, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(eq7(tasksTasks.uid, uid)).limit(1).all();
|
|
41724
|
+
if (holder && holder.birthFp === fp) throw new SameRowPresentError(row.id, holder.id);
|
|
41725
|
+
if (await tableExists2(db, "tasks_identity_quarantine")) {
|
|
41726
|
+
const [held] = await db.all(
|
|
41727
|
+
sql27`SELECT 1 AS x FROM tasks_identity_quarantine
|
|
41728
|
+
WHERE entity_table = 'tasks_tasks' AND uid = ${uid} AND birth_fp = ${fp}`
|
|
41729
|
+
);
|
|
41730
|
+
if (held) throw new SameRowPresentError(row.id, "held");
|
|
41731
|
+
}
|
|
41732
|
+
if (!holder) return { uid, birthFp: fp };
|
|
41733
|
+
}
|
|
41734
|
+
return { uid: null, birthFp: null };
|
|
41431
41735
|
}
|
|
41432
41736
|
async function writeTaskRow(db, row, archiveFields, allowOrphanParent, insertOnly) {
|
|
41433
41737
|
if (row.parentId && row.parentId === row.id) {
|
|
@@ -41578,7 +41882,11 @@ async function batchUpdateDependencies(db, tasks2, validIds) {
|
|
|
41578
41882
|
for (const depId of want) if (!have.has(depId)) added.push({ taskId, dependsOn: depId });
|
|
41579
41883
|
}
|
|
41580
41884
|
if (added.length > 0) {
|
|
41581
|
-
|
|
41885
|
+
try {
|
|
41886
|
+
await db.insert(tasksTaskDependencies).values(added).onConflictDoNothing().run();
|
|
41887
|
+
} catch (err) {
|
|
41888
|
+
rethrowDependencyCycle(db, err, added);
|
|
41889
|
+
}
|
|
41582
41890
|
}
|
|
41583
41891
|
}
|
|
41584
41892
|
async function loadDependenciesForTasks(db, tasks2, _validationIds) {
|
|
@@ -41623,15 +41931,29 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
41623
41931
|
task.relates = relations && relations.length > 0 ? relations : [];
|
|
41624
41932
|
}
|
|
41625
41933
|
}
|
|
41626
|
-
var log6;
|
|
41934
|
+
var log6, SameRowPresentError;
|
|
41627
41935
|
var init_db_helpers = __esm({
|
|
41628
41936
|
"packages/core/src/store/db-helpers.ts"() {
|
|
41629
41937
|
"use strict";
|
|
41630
41938
|
init_src();
|
|
41631
41939
|
init_errors2();
|
|
41632
41940
|
init_logger2();
|
|
41941
|
+
init_dependency_cycles();
|
|
41942
|
+
init_row_identity_flag();
|
|
41633
41943
|
init_tasks_schema();
|
|
41634
41944
|
log6 = getLogger("db-helpers");
|
|
41945
|
+
SameRowPresentError = class extends CleoError {
|
|
41946
|
+
/** Where the row already is: its display id, or `held` when quarantined. */
|
|
41947
|
+
presentAs;
|
|
41948
|
+
constructor(taskId, presentAs) {
|
|
41949
|
+
super(
|
|
41950
|
+
22 /* ID_COLLISION */,
|
|
41951
|
+
`Task ${taskId} is already in this store (${presentAs === "held" ? "held for sync" : `as ${presentAs}`}): same uid and birth fingerprint; not written again`,
|
|
41952
|
+
{ details: { field: "taskId", actual: taskId, expected: presentAs } }
|
|
41953
|
+
);
|
|
41954
|
+
this.presentAs = presentAs;
|
|
41955
|
+
}
|
|
41956
|
+
};
|
|
41635
41957
|
}
|
|
41636
41958
|
});
|
|
41637
41959
|
|
|
@@ -41716,46 +42038,133 @@ function readProcessEntry(pid) {
|
|
|
41716
42038
|
return null;
|
|
41717
42039
|
}
|
|
41718
42040
|
}
|
|
41719
|
-
function
|
|
42041
|
+
function readProcessArgs(pid) {
|
|
42042
|
+
if (process.platform === "win32" || !Number.isInteger(pid) || pid <= 1) return null;
|
|
42043
|
+
try {
|
|
42044
|
+
const out = execFileSync("ps", ["-o", "args=", "-p", String(pid)], {
|
|
42045
|
+
encoding: "utf8",
|
|
42046
|
+
timeout: 1e3,
|
|
42047
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
42048
|
+
env: { ...process.env, ...PS_STABLE_ENV }
|
|
42049
|
+
}).trim();
|
|
42050
|
+
return out === "" ? null : out;
|
|
42051
|
+
} catch {
|
|
42052
|
+
return null;
|
|
42053
|
+
}
|
|
42054
|
+
}
|
|
42055
|
+
function baseName(token) {
|
|
42056
|
+
return token.slice(token.lastIndexOf("/") + 1).replace(/^-/, "");
|
|
42057
|
+
}
|
|
42058
|
+
function programName(commandLine) {
|
|
42059
|
+
const tokens = commandLine.trim().split(/\s+/);
|
|
42060
|
+
const head = baseName(tokens[0] ?? "");
|
|
42061
|
+
if (!RUNTIME_PATTERN.test(head)) return head;
|
|
42062
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
42063
|
+
const token = tokens[i] ?? "";
|
|
42064
|
+
if (token === "-m") return (tokens[i + 1] ?? head).split(".")[0] ?? head;
|
|
42065
|
+
if (token.startsWith("-")) continue;
|
|
42066
|
+
return baseName(token).replace(/\.(c|m)?(js|ts)$|\.py$/, "");
|
|
42067
|
+
}
|
|
42068
|
+
return head;
|
|
42069
|
+
}
|
|
42070
|
+
function isCommandStringShell(args) {
|
|
42071
|
+
const tokens = args.trim().split(/\s+/);
|
|
42072
|
+
const shell = programName(args);
|
|
42073
|
+
let first = 1;
|
|
42074
|
+
if (RUNTIME_PATTERN.test(baseName(tokens[0] ?? ""))) {
|
|
42075
|
+
while (first < tokens.length && (tokens[first] ?? "").startsWith("-")) first++;
|
|
42076
|
+
first++;
|
|
42077
|
+
}
|
|
42078
|
+
const rest = tokens.slice(first);
|
|
42079
|
+
if (shell === "pwsh" || shell === "powershell") {
|
|
42080
|
+
return rest.some((t) => PWSH_COMMAND_SWITCHES.has(t.toLowerCase()));
|
|
42081
|
+
}
|
|
42082
|
+
for (let i = 0; i < rest.length; i++) {
|
|
42083
|
+
const token = rest[i] ?? "";
|
|
42084
|
+
if (token === "--") return false;
|
|
42085
|
+
if (token === "--command" || token === "--commands") return true;
|
|
42086
|
+
if (SHELL_OPTIONS_WITH_ARGUMENT.has(token)) {
|
|
42087
|
+
i++;
|
|
42088
|
+
continue;
|
|
42089
|
+
}
|
|
42090
|
+
if (token.startsWith("--")) continue;
|
|
42091
|
+
if (!/^[-+][A-Za-z]+$/.test(token)) return false;
|
|
42092
|
+
if (token.startsWith("-") && token.slice(1).includes("c")) return true;
|
|
42093
|
+
}
|
|
42094
|
+
return false;
|
|
42095
|
+
}
|
|
42096
|
+
function resolveAncestor(ppid, lookupProcess, lookupArgs, agentId = null) {
|
|
41720
42097
|
let pid = ppid;
|
|
41721
|
-
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH
|
|
42098
|
+
for (let depth = 0; depth < PPID_CHAIN_MAX_DEPTH; depth++) {
|
|
42099
|
+
if (pid <= 1) return null;
|
|
41722
42100
|
const entry = lookupProcess(pid);
|
|
41723
|
-
if (!entry) return null;
|
|
41724
|
-
|
|
41725
|
-
|
|
42101
|
+
if (!entry || entry.pid <= 1) return null;
|
|
42102
|
+
const args = lookupArgs(entry.pid);
|
|
42103
|
+
const program = programName(args ?? entry.command);
|
|
42104
|
+
if (INIT_PROCESSES.has(program) || INIT_PROCESSES.has(entry.command)) return null;
|
|
42105
|
+
if (OWNER_PROCESS_SHELLS.has(program)) {
|
|
42106
|
+
if (args === null) return null;
|
|
42107
|
+
if (!isCommandStringShell(args)) return { entry, program, type: "shell" };
|
|
42108
|
+
} else if (!ANCESTOR_WRAPPERS.has(program)) {
|
|
42109
|
+
if (KNOWN_HARNESSES.has(program)) return { entry, program, type: "harness" };
|
|
42110
|
+
return agentId ? { entry, program, type: "host" } : null;
|
|
41726
42111
|
}
|
|
41727
42112
|
pid = entry.ppid;
|
|
41728
42113
|
}
|
|
41729
42114
|
return null;
|
|
41730
42115
|
}
|
|
42116
|
+
function anchorKey(anchor, agentId, under) {
|
|
42117
|
+
const proc = `${anchor.entry.pid}@${anchor.entry.startedAt}`;
|
|
42118
|
+
if (anchor.type === "shell" && !agentId) {
|
|
42119
|
+
return { key: `proc:${proc}`, source: "process", kind: "process" };
|
|
42120
|
+
}
|
|
42121
|
+
const agent = agentId ? `#agent=${agentId}` : "";
|
|
42122
|
+
const scope = under ? `|${under.key}` : "";
|
|
42123
|
+
return {
|
|
42124
|
+
key: `harness:${anchor.program}:${proc}${agent}${scope}`,
|
|
42125
|
+
source: "process",
|
|
42126
|
+
kind: "harness"
|
|
42127
|
+
};
|
|
42128
|
+
}
|
|
41731
42129
|
function resolveTerminalKeys(options = {}) {
|
|
41732
42130
|
const env = options.env ?? process.env;
|
|
41733
42131
|
const keys = [];
|
|
41734
42132
|
for (const source of TERMINAL_KEY_SOURCES) {
|
|
41735
42133
|
const value = envValue(env, source.envVar);
|
|
41736
42134
|
if (value === null) continue;
|
|
41737
|
-
const
|
|
42135
|
+
const qualifiers = [source.qualifierEnvVar, ...source.extraQualifierEnvVars ?? []].map((name15) => envValue(env, name15)).filter((q2) => q2 !== null);
|
|
41738
42136
|
keys.push({
|
|
41739
|
-
key: `env:${source.envVar}=${
|
|
42137
|
+
key: `env:${source.envVar}=${[...qualifiers, value].join("|")}`,
|
|
41740
42138
|
source: source.envVar,
|
|
41741
42139
|
kind: source.kind
|
|
41742
42140
|
});
|
|
41743
42141
|
}
|
|
41744
|
-
if (keys.
|
|
41745
|
-
const
|
|
41746
|
-
|
|
42142
|
+
if (keys.some((k) => k.kind === "provider")) return keys;
|
|
42143
|
+
const agentId = envValue(env, "CLEO_AGENT_ID");
|
|
42144
|
+
const live = options.ppid === void 0 && options.lookupProcess === void 0 && options.lookupArgs === void 0;
|
|
42145
|
+
let anchor;
|
|
41747
42146
|
if (live) {
|
|
41748
|
-
|
|
41749
|
-
|
|
42147
|
+
const memoKey2 = agentId ?? "";
|
|
42148
|
+
if (!liveAnchors.has(memoKey2))
|
|
42149
|
+
liveAnchors.set(
|
|
42150
|
+
memoKey2,
|
|
42151
|
+
resolveAncestor(process.ppid, readProcessEntry, readProcessArgs, agentId)
|
|
42152
|
+
);
|
|
42153
|
+
anchor = liveAnchors.get(memoKey2) ?? null;
|
|
41750
42154
|
} else {
|
|
41751
|
-
|
|
42155
|
+
anchor = resolveAncestor(
|
|
41752
42156
|
options.ppid ?? process.ppid,
|
|
41753
|
-
options.lookupProcess ?? readProcessEntry
|
|
42157
|
+
options.lookupProcess ?? readProcessEntry,
|
|
42158
|
+
options.lookupArgs ?? readProcessArgs,
|
|
42159
|
+
agentId
|
|
41754
42160
|
);
|
|
41755
42161
|
}
|
|
41756
|
-
|
|
42162
|
+
if (!anchor) return keys;
|
|
42163
|
+
if (keys.length === 0) return [anchorKey(anchor, agentId, void 0)];
|
|
42164
|
+
if (anchor.type === "shell" && !agentId) return keys;
|
|
42165
|
+
return [...keys, anchorKey(anchor, agentId, keys[0])];
|
|
41757
42166
|
}
|
|
41758
|
-
var TERMINAL_KEY_SOURCES,
|
|
42167
|
+
var TERMINAL_KEY_SOURCES, PPID_CHAIN_MAX_DEPTH, KNOWN_HARNESSES, RUNTIME_PATTERN, ANCESTOR_WRAPPERS, INIT_PROCESSES, SHELL_OPTIONS_WITH_ARGUMENT, PWSH_COMMAND_SWITCHES, OWNER_PROCESS_SHELLS, liveAnchors;
|
|
41759
42168
|
var init_terminal_identity = __esm({
|
|
41760
42169
|
"packages/core/src/sessions/terminal-identity.ts"() {
|
|
41761
42170
|
"use strict";
|
|
@@ -41787,24 +42196,100 @@ var init_terminal_identity = __esm({
|
|
|
41787
42196
|
kind: "terminal",
|
|
41788
42197
|
origin: "konsole",
|
|
41789
42198
|
qualifierEnvVar: "KONSOLE_DBUS_SERVICE"
|
|
42199
|
+
},
|
|
42200
|
+
// T12864 — non-terminal callers whose platform exports a per-job / per-login id.
|
|
42201
|
+
// GitHub Actions: GITHUB_RUN_ID is per run and shared by its jobs, so it is
|
|
42202
|
+
// qualified by GITHUB_RUN_ATTEMPT and GITHUB_JOB ("Variables reference",
|
|
42203
|
+
// docs.github.com/en/actions/reference/workflows-and-actions/variables).
|
|
42204
|
+
// Every step of one job shares the key; the steps run sequentially.
|
|
42205
|
+
{
|
|
42206
|
+
envVar: "GITHUB_RUN_ID",
|
|
42207
|
+
kind: "terminal",
|
|
42208
|
+
origin: "github-actions",
|
|
42209
|
+
qualifierEnvVar: "GITHUB_RUN_ATTEMPT",
|
|
42210
|
+
extraQualifierEnvVars: ["GITHUB_JOB"]
|
|
42211
|
+
},
|
|
42212
|
+
// GitLab CI: CI_JOB_ID is unique per job across the instance ("Predefined
|
|
42213
|
+
// CI/CD variables reference", docs.gitlab.com/ci/variables/predefined_variables).
|
|
42214
|
+
{ envVar: "CI_JOB_ID", kind: "terminal", origin: "gitlab-ci" },
|
|
42215
|
+
// OpenSSH login with a tty: SSH_TTY names the login's tty and is set only
|
|
42216
|
+
// when one was allocated; SSH_CONNECTION ("client-ip client-port server-ip
|
|
42217
|
+
// server-port", ssh(1) ENVIRONMENT) disambiguates it across connections. A
|
|
42218
|
+
// one-shot `ssh host 'cmd'` has no tty and falls through to the ancestor walk.
|
|
42219
|
+
{
|
|
42220
|
+
envVar: "SSH_TTY",
|
|
42221
|
+
kind: "terminal",
|
|
42222
|
+
origin: "openssh",
|
|
42223
|
+
qualifierEnvVar: "SSH_CONNECTION"
|
|
41790
42224
|
}
|
|
41791
42225
|
];
|
|
41792
|
-
|
|
41793
|
-
|
|
42226
|
+
PPID_CHAIN_MAX_DEPTH = 12;
|
|
42227
|
+
KNOWN_HARNESSES = /* @__PURE__ */ new Set([
|
|
42228
|
+
"claude",
|
|
42229
|
+
"codex",
|
|
42230
|
+
"aider",
|
|
42231
|
+
"gemini",
|
|
42232
|
+
"kimi",
|
|
42233
|
+
"cursor-agent",
|
|
42234
|
+
"amp"
|
|
42235
|
+
]);
|
|
42236
|
+
RUNTIME_PATTERN = /^(node|nodejs|bun|deno|python[0-9.]*|pypy[0-9.]*|ruby|java|php|perl)$/;
|
|
42237
|
+
ANCESTOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
42238
|
+
"env",
|
|
42239
|
+
"timeout",
|
|
42240
|
+
"gtimeout",
|
|
42241
|
+
"nohup",
|
|
42242
|
+
"nice",
|
|
42243
|
+
"time",
|
|
42244
|
+
"xargs",
|
|
42245
|
+
"stdbuf",
|
|
42246
|
+
"sudo",
|
|
42247
|
+
"doas",
|
|
41794
42248
|
"npm",
|
|
42249
|
+
"npm-cli",
|
|
41795
42250
|
"npx",
|
|
42251
|
+
"npx-cli",
|
|
41796
42252
|
"pnpm",
|
|
41797
42253
|
"pnpx",
|
|
41798
42254
|
"yarn",
|
|
41799
|
-
"bun",
|
|
41800
42255
|
"bunx",
|
|
41801
|
-
"tsx",
|
|
41802
42256
|
"corepack",
|
|
41803
42257
|
"mise",
|
|
41804
|
-
"env",
|
|
41805
42258
|
"cleo"
|
|
41806
42259
|
]);
|
|
41807
|
-
|
|
42260
|
+
INIT_PROCESSES = /* @__PURE__ */ new Set(["launchd", "systemd", "init"]);
|
|
42261
|
+
SHELL_OPTIONS_WITH_ARGUMENT = /* @__PURE__ */ new Set([
|
|
42262
|
+
"-o",
|
|
42263
|
+
"+o",
|
|
42264
|
+
"-O",
|
|
42265
|
+
"+O",
|
|
42266
|
+
"--rcfile",
|
|
42267
|
+
"--init-file"
|
|
42268
|
+
]);
|
|
42269
|
+
PWSH_COMMAND_SWITCHES = /* @__PURE__ */ new Set([
|
|
42270
|
+
"-c",
|
|
42271
|
+
"-command",
|
|
42272
|
+
"-commandwithargs",
|
|
42273
|
+
"-cwa",
|
|
42274
|
+
"-e",
|
|
42275
|
+
"-ec",
|
|
42276
|
+
"-encodedcommand"
|
|
42277
|
+
]);
|
|
42278
|
+
OWNER_PROCESS_SHELLS = /* @__PURE__ */ new Set([
|
|
42279
|
+
"sh",
|
|
42280
|
+
"bash",
|
|
42281
|
+
"zsh",
|
|
42282
|
+
"dash",
|
|
42283
|
+
"fish",
|
|
42284
|
+
"ksh",
|
|
42285
|
+
"tcsh",
|
|
42286
|
+
"csh",
|
|
42287
|
+
"pwsh",
|
|
42288
|
+
"powershell",
|
|
42289
|
+
"nu",
|
|
42290
|
+
"xonsh"
|
|
42291
|
+
]);
|
|
42292
|
+
liveAnchors = /* @__PURE__ */ new Map();
|
|
41808
42293
|
}
|
|
41809
42294
|
});
|
|
41810
42295
|
|
|
@@ -41844,7 +42329,8 @@ var init_session_binding_schema = __esm({
|
|
|
41844
42329
|
});
|
|
41845
42330
|
|
|
41846
42331
|
// packages/core/src/store/session-store.ts
|
|
41847
|
-
import {
|
|
42332
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
42333
|
+
import { and as and6, desc as desc2, eq as eq8, inArray as inArray4, isNull as isNull3, lte as lte2, or as or4 } from "drizzle-orm";
|
|
41848
42334
|
async function getSession(sessionId, cwd) {
|
|
41849
42335
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
41850
42336
|
return worktreeScope.run(scope, async () => {
|
|
@@ -41866,8 +42352,9 @@ async function getActiveSession(cwd) {
|
|
|
41866
42352
|
function splitTerminalKeys(keys) {
|
|
41867
42353
|
return {
|
|
41868
42354
|
provider: keys.find((k) => k.kind === "provider"),
|
|
41869
|
-
|
|
41870
|
-
|
|
42355
|
+
// A harness / CLEO_AGENT_ID agent (T12864) is more specific than a pane.
|
|
42356
|
+
pane: keys.find((k) => k.kind === "harness") ?? keys.find((k) => k.kind === "multiplexer"),
|
|
42357
|
+
tab: keys.find((k) => k.kind === "terminal" || k.kind === "process" || k.kind === "ppid")
|
|
41871
42358
|
};
|
|
41872
42359
|
}
|
|
41873
42360
|
async function readBinding(db, key) {
|
|
@@ -41947,6 +42434,7 @@ async function resolveCurrentSession(cwd) {
|
|
|
41947
42434
|
async function resolveBoundSession(cwd) {
|
|
41948
42435
|
const scope = captureProjectScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
|
|
41949
42436
|
return worktreeScope.run(scope, async () => {
|
|
42437
|
+
if (!existsSync19(getDbPath(scope.worktreeRoot))) return null;
|
|
41950
42438
|
const connId = getCurrentConnectionSessionId();
|
|
41951
42439
|
if (connId) {
|
|
41952
42440
|
const byConn = await getSession(connId, scope.worktreeRoot);
|
|
@@ -42098,7 +42586,7 @@ __export(registry_exports2, {
|
|
|
42098
42586
|
updateAgentStatus: () => updateAgentStatus
|
|
42099
42587
|
});
|
|
42100
42588
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
42101
|
-
import { and as and7, eq as eq9, inArray as
|
|
42589
|
+
import { and as and7, eq as eq9, inArray as inArray5, lt as lt2, sql as sql29 } from "drizzle-orm";
|
|
42102
42590
|
function generateAgentId() {
|
|
42103
42591
|
const now = /* @__PURE__ */ new Date();
|
|
42104
42592
|
const ts = now.toISOString().replace(/[-:T]/g, "").substring(0, 14);
|
|
@@ -42187,11 +42675,11 @@ async function listAgentInstances(filters, cwd) {
|
|
|
42187
42675
|
const conditions = [];
|
|
42188
42676
|
if (filters?.status) {
|
|
42189
42677
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
42190
|
-
conditions.push(
|
|
42678
|
+
conditions.push(inArray5(agentInstances.status, statuses));
|
|
42191
42679
|
}
|
|
42192
42680
|
if (filters?.agentType) {
|
|
42193
42681
|
const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
|
|
42194
|
-
conditions.push(
|
|
42682
|
+
conditions.push(inArray5(agentInstances.agentType, types));
|
|
42195
42683
|
}
|
|
42196
42684
|
if (filters?.sessionId) {
|
|
42197
42685
|
conditions.push(eq9(agentInstances.sessionId, filters.sessionId));
|
|
@@ -42228,7 +42716,7 @@ async function checkAgentHealth(thresholdMs = 3e4, cwd) {
|
|
|
42228
42716
|
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
42229
42717
|
return db.select().from(agentInstances).where(
|
|
42230
42718
|
and7(
|
|
42231
|
-
|
|
42719
|
+
inArray5(agentInstances.status, ["active", "idle", "starting"]),
|
|
42232
42720
|
lt2(agentInstances.lastHeartbeat, cutoff)
|
|
42233
42721
|
)
|
|
42234
42722
|
).all();
|
|
@@ -42323,12 +42811,14 @@ var init_registry2 = __esm({
|
|
|
42323
42811
|
// packages/core/src/store/sqlite-data-accessor.ts
|
|
42324
42812
|
var sqlite_data_accessor_exports = {};
|
|
42325
42813
|
__export(sqlite_data_accessor_exports, {
|
|
42814
|
+
RENAMED_RECENT_MS: () => RENAMED_RECENT_MS,
|
|
42326
42815
|
addTaskLabelsNative: () => addTaskLabelsNative,
|
|
42327
42816
|
advanceTaskIdSequence: () => advanceTaskIdSequence,
|
|
42328
42817
|
bindTaskAccessorScope: () => bindTaskAccessorScope,
|
|
42329
42818
|
captureTaskAccessorScope: () => captureProjectScope,
|
|
42330
42819
|
clearAcUidGraveyardNative: () => clearAcUidGraveyardNative,
|
|
42331
42820
|
clearBirthFpNative: () => clearBirthFpNative,
|
|
42821
|
+
clearReplacedTaskIdentityNative: () => clearReplacedTaskIdentityNative,
|
|
42332
42822
|
clearRowUidNative: () => clearRowUidNative,
|
|
42333
42823
|
createSqliteDataAccessor: () => createSqliteDataAccessor,
|
|
42334
42824
|
deleteDisplayIdAliasNative: () => deleteDisplayIdAliasNative,
|
|
@@ -42339,6 +42829,7 @@ __export(sqlite_data_accessor_exports, {
|
|
|
42339
42829
|
insertIdentityRowNative: () => insertIdentityRowNative,
|
|
42340
42830
|
insertQuarantineNative: () => insertQuarantineNative,
|
|
42341
42831
|
insertUidAliasNative: () => insertUidAliasNative,
|
|
42832
|
+
readReplacedTaskBirthNative: () => readReplacedTaskBirthNative,
|
|
42342
42833
|
rederiveAcIdsNative: () => rederiveAcIdsNative,
|
|
42343
42834
|
rekeyQuarantineNative: () => rekeyQuarantineNative,
|
|
42344
42835
|
relinkAcUidNative: () => relinkAcUidNative,
|
|
@@ -42355,7 +42846,7 @@ import {
|
|
|
42355
42846
|
and as and8,
|
|
42356
42847
|
eq as eq10,
|
|
42357
42848
|
getTableColumns as getTableColumns2,
|
|
42358
|
-
inArray as
|
|
42849
|
+
inArray as inArray6,
|
|
42359
42850
|
isNull as isNull4,
|
|
42360
42851
|
like as like2,
|
|
42361
42852
|
lte as lte3,
|
|
@@ -42379,8 +42870,8 @@ async function selectAcBindings(db, acIds) {
|
|
|
42379
42870
|
bindingType: b.bindingType,
|
|
42380
42871
|
createdAt: b.createdAt
|
|
42381
42872
|
};
|
|
42382
|
-
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
42383
|
-
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(
|
|
42873
|
+
const byUid = await db.select(columns).from(b).innerJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(ac.id, ids)).all();
|
|
42874
|
+
const byId = await db.select(columns).from(b).leftJoin(ac, eq10(ac.uid, b.acUid)).where(inArray6(b.acId, ids)).all();
|
|
42384
42875
|
const rows = [...byUid, ...byId];
|
|
42385
42876
|
const wanted = new Set(ids);
|
|
42386
42877
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -42473,6 +42964,7 @@ function renameTaskDisplayIdNative(nativeDb, uid, toId, refs, guard = {}) {
|
|
|
42473
42964
|
if (Number(changed) !== 1) {
|
|
42474
42965
|
throw taskConflictError(current.id, taskVersion(current), null);
|
|
42475
42966
|
}
|
|
42967
|
+
recordLocalRename(nativeDb, uid, current.id, toId, taskVersion(current));
|
|
42476
42968
|
const rewritten = {};
|
|
42477
42969
|
const q2 = (name15) => `"${name15.replaceAll('"', '""')}"`;
|
|
42478
42970
|
for (const ref of refs) {
|
|
@@ -42528,23 +43020,39 @@ function rederiveAcIdsNative(nativeDb, fromId, toId) {
|
|
|
42528
43020
|
}
|
|
42529
43021
|
return count;
|
|
42530
43022
|
}
|
|
42531
|
-
function insertDisplayIdAliasNative(nativeDb, row) {
|
|
43023
|
+
function insertDisplayIdAliasNative(nativeDb, row, precedes) {
|
|
43024
|
+
const stored = nativeDb.prepare(
|
|
43025
|
+
`SELECT uid, entity_table AS entityTable, display_id AS displayId, entity_uid AS entityUid,
|
|
43026
|
+
reason, origin, displaced_hlc AS displacedHlc, created_at AS createdAt,
|
|
43027
|
+
entity_birth_fp AS entityBirthFp
|
|
43028
|
+
FROM tasks_display_id_aliases WHERE uid = ?`
|
|
43029
|
+
).get(row.uid);
|
|
43030
|
+
if (!stored) {
|
|
43031
|
+
nativeDb.prepare(
|
|
43032
|
+
`INSERT INTO tasks_display_id_aliases
|
|
43033
|
+
(uid, entity_table, display_id, entity_uid, reason, origin, displaced_hlc, created_at,
|
|
43034
|
+
entity_birth_fp)
|
|
43035
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
43036
|
+
).run(
|
|
43037
|
+
row.uid,
|
|
43038
|
+
row.entityTable,
|
|
43039
|
+
row.displayId,
|
|
43040
|
+
row.entityUid,
|
|
43041
|
+
row.reason,
|
|
43042
|
+
row.origin,
|
|
43043
|
+
row.displacedHlc,
|
|
43044
|
+
row.createdAt,
|
|
43045
|
+
row.entityBirthFp
|
|
43046
|
+
);
|
|
43047
|
+
return;
|
|
43048
|
+
}
|
|
43049
|
+
if (!precedes(row, stored)) return;
|
|
42532
43050
|
nativeDb.prepare(
|
|
42533
|
-
`
|
|
42534
|
-
|
|
42535
|
-
|
|
42536
|
-
|
|
42537
|
-
).run(
|
|
42538
|
-
row.uid,
|
|
42539
|
-
row.entityTable,
|
|
42540
|
-
row.displayId,
|
|
42541
|
-
row.entityUid,
|
|
42542
|
-
row.reason,
|
|
42543
|
-
row.origin,
|
|
42544
|
-
row.displacedHlc,
|
|
42545
|
-
row.createdAt,
|
|
42546
|
-
row.entityBirthFp
|
|
42547
|
-
);
|
|
43051
|
+
`UPDATE tasks_display_id_aliases
|
|
43052
|
+
SET origin = ?, displaced_hlc = ?, created_at = ?,
|
|
43053
|
+
entity_birth_fp = coalesce(entity_birth_fp, ?)
|
|
43054
|
+
WHERE uid = ?`
|
|
43055
|
+
).run(row.origin, row.displacedHlc, row.createdAt, row.entityBirthFp, row.uid);
|
|
42548
43056
|
}
|
|
42549
43057
|
function deleteDisplayIdAliasNative(nativeDb, uid) {
|
|
42550
43058
|
nativeDb.prepare("DELETE FROM tasks_display_id_aliases WHERE uid = ?").run(uid);
|
|
@@ -42606,6 +43114,63 @@ function relinkAcUidNative(nativeDb, acId, uid, birthFp) {
|
|
|
42606
43114
|
function clearAcUidGraveyardNative(nativeDb) {
|
|
42607
43115
|
nativeDb.exec("DELETE FROM tasks_ac_uid_graveyard");
|
|
42608
43116
|
}
|
|
43117
|
+
function readReplacedTaskBirthNative(nativeDb, taskId) {
|
|
43118
|
+
return nativeDb.prepare("SELECT created_at AS createdAt, uid FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43119
|
+
}
|
|
43120
|
+
function clearReplacedTaskIdentityNative(nativeDb, taskId, before) {
|
|
43121
|
+
const row = nativeDb.prepare("SELECT uid, birth_fp AS fp, created_at AS createdAt FROM tasks_tasks WHERE id = ?").get(taskId);
|
|
43122
|
+
if (!row || row.uid === null && row.fp === null) return;
|
|
43123
|
+
if (before) {
|
|
43124
|
+
const was = parseStoreTimestamp(before.createdAt);
|
|
43125
|
+
if (was !== null && was === parseStoreTimestamp(row.createdAt)) {
|
|
43126
|
+
return;
|
|
43127
|
+
}
|
|
43128
|
+
}
|
|
43129
|
+
if (rowIdentityShared(nativeDb)) {
|
|
43130
|
+
throw new CleoError(
|
|
43131
|
+
6 /* VALIDATION_ERROR */,
|
|
43132
|
+
`Task ${taskId} cannot be overwritten by an import: its identity is shared with other devices`,
|
|
43133
|
+
{
|
|
43134
|
+
fix: "Import it under a new id (the default duplicate strategy), or edit the task instead of overwriting it.",
|
|
43135
|
+
details: { field: "taskId", actual: taskId }
|
|
43136
|
+
}
|
|
43137
|
+
);
|
|
43138
|
+
}
|
|
43139
|
+
const has = (table) => nativeDb.prepare("SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== void 0;
|
|
43140
|
+
nativeDb.prepare("UPDATE tasks_tasks SET uid = NULL, birth_fp = NULL WHERE id = ?").run(taskId);
|
|
43141
|
+
for (const spec of ROW_IDENTITY.project) {
|
|
43142
|
+
if (spec.kind !== "natural" || !has(spec.table)) continue;
|
|
43143
|
+
const cols = (spec.keyRefs ?? []).filter((r) => r.table === "tasks_tasks").map((r) => r.column);
|
|
43144
|
+
if (cols.length === 0) continue;
|
|
43145
|
+
nativeDb.prepare(
|
|
43146
|
+
`UPDATE main.${quoteIdent2(spec.table)} SET uid = NULL WHERE ${cols.map((c) => `${quoteIdent2(c)} = ?`).join(" OR ")}`
|
|
43147
|
+
).run(...cols.map(() => taskId));
|
|
43148
|
+
}
|
|
43149
|
+
const children = ["tasks_task_acceptance_criteria_history", "tasks_evidence_ac_bindings"].filter(
|
|
43150
|
+
has
|
|
43151
|
+
);
|
|
43152
|
+
const criteria = has("tasks_task_acceptance_criteria") ? nativeDb.prepare("SELECT id, uid FROM tasks_task_acceptance_criteria WHERE task_id = ?").all(taskId) : [];
|
|
43153
|
+
if (criteria.length > 0) {
|
|
43154
|
+
nativeDb.prepare(
|
|
43155
|
+
"UPDATE tasks_task_acceptance_criteria SET uid = NULL, birth_fp = NULL WHERE task_id = ?"
|
|
43156
|
+
).run(taskId);
|
|
43157
|
+
}
|
|
43158
|
+
fillRowUids(nativeDb, "project");
|
|
43159
|
+
const newUid = nativeDb.prepare("SELECT uid FROM tasks_task_acceptance_criteria WHERE id = ?");
|
|
43160
|
+
let rekeyed = 0;
|
|
43161
|
+
for (const ac of criteria) {
|
|
43162
|
+
const now = newUid.get(ac.id)?.uid ?? null;
|
|
43163
|
+
for (const table of children) {
|
|
43164
|
+
rekeyed += Number(
|
|
43165
|
+
nativeDb.prepare(
|
|
43166
|
+
`UPDATE main.${quoteIdent2(table)} SET ac_uid = ?, birth_fp = NULL
|
|
43167
|
+
WHERE ac_id = ? OR (? IS NOT NULL AND ac_uid = ?)`
|
|
43168
|
+
).run(now, ac.id, ac.uid, ac.uid).changes
|
|
43169
|
+
);
|
|
43170
|
+
}
|
|
43171
|
+
}
|
|
43172
|
+
if (rekeyed > 0) fillRowUids(nativeDb, "project");
|
|
43173
|
+
}
|
|
42609
43174
|
function quoteIdent2(name15) {
|
|
42610
43175
|
return `"${name15.replaceAll('"', '""')}"`;
|
|
42611
43176
|
}
|
|
@@ -42693,10 +43258,50 @@ function claimPredicate(guard, allowedHolders) {
|
|
|
42693
43258
|
if (guard.mode === "force") return void 0;
|
|
42694
43259
|
const mine = guard.sessionId === null ? void 0 : eq10(holder, guard.sessionId);
|
|
42695
43260
|
if (guard.mode === "renew" || guard.mode === "release") return mine ?? sql30`0`;
|
|
42696
|
-
const related = allowedHolders.length > 0 ?
|
|
43261
|
+
const related = allowedHolders.length > 0 ? inArray6(holder, [...allowedHolders]) : void 0;
|
|
42697
43262
|
const expired = guard.mode === "take-over" ? or5(isNull4(tasksTasks.leaseExpiresAt), lte3(tasksTasks.leaseExpiresAt, guard.now)) : void 0;
|
|
42698
43263
|
return or5(isNull4(holder), mine, related, expired);
|
|
42699
43264
|
}
|
|
43265
|
+
function renameRecordKey(fromId) {
|
|
43266
|
+
return `renamed_from:tasks_tasks:${fromId}`;
|
|
43267
|
+
}
|
|
43268
|
+
function hasIdentityMeta(nativeDb) {
|
|
43269
|
+
return nativeDb.prepare(
|
|
43270
|
+
"SELECT 1 AS x FROM sqlite_master WHERE type = 'table' AND name = 'tasks_row_identity_meta'"
|
|
43271
|
+
).get() !== void 0;
|
|
43272
|
+
}
|
|
43273
|
+
function recordLocalRename(nativeDb, uid, fromId, toId, fromVersion) {
|
|
43274
|
+
if (!hasIdentityMeta(nativeDb)) return;
|
|
43275
|
+
const record2 = { uid, fromVersion, toId, at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
43276
|
+
writeRowIdentityMetaNative(nativeDb, renameRecordKey(fromId), JSON.stringify(record2));
|
|
43277
|
+
}
|
|
43278
|
+
function assertNotRenamed(nativeDb, taskId, guard, current) {
|
|
43279
|
+
if (!nativeDb || !hasIdentityMeta(nativeDb)) return;
|
|
43280
|
+
const raw = nativeDb.prepare("SELECT value FROM tasks_row_identity_meta WHERE key = ?").get(renameRecordKey(taskId));
|
|
43281
|
+
if (!raw) return;
|
|
43282
|
+
let record2;
|
|
43283
|
+
try {
|
|
43284
|
+
record2 = JSON.parse(raw.value);
|
|
43285
|
+
} catch {
|
|
43286
|
+
return;
|
|
43287
|
+
}
|
|
43288
|
+
if (Date.now() - Date.parse(record2.at) > RENAMED_RECENT_MS) return;
|
|
43289
|
+
const renamed = nativeDb.prepare("SELECT id, claimed_by_session AS claimedBySession FROM tasks_tasks WHERE uid = ?").get(record2.uid);
|
|
43290
|
+
if (!renamed || renamed.id === taskId) return;
|
|
43291
|
+
const expected = guard.expectedUpdatedAt;
|
|
43292
|
+
const session = guard.claim?.sessionId ?? null;
|
|
43293
|
+
const holdsRenamedClaim = session !== null && (guard.claim?.mode === "renew" || guard.claim?.mode === "release") && renamed.claimedBySession === session && current?.claimedBySession !== session;
|
|
43294
|
+
const readRenamed = expected !== void 0 && expected === record2.fromVersion && (current === void 0 || taskVersion(current) !== expected);
|
|
43295
|
+
if (!(current === void 0 || holdsRenamedClaim || readRenamed)) return;
|
|
43296
|
+
throw new CleoError(
|
|
43297
|
+
26 /* TASK_RENAMED */,
|
|
43298
|
+
`Task ${taskId} is now ${renamed.id}: sync re-numbered it after a display-id collision, and ${taskId} ${current ? "names another task" : "names no task"}; nothing was written`,
|
|
43299
|
+
{
|
|
43300
|
+
fix: `Re-read it with 'cleo show ${renamed.id}' and retry against ${renamed.id}.`,
|
|
43301
|
+
details: { field: "taskId", actual: taskId, expected: renamed.id }
|
|
43302
|
+
}
|
|
43303
|
+
);
|
|
43304
|
+
}
|
|
42700
43305
|
function assertClaimAllowed(taskId, row, guard, allowedHolders) {
|
|
42701
43306
|
const stored = claimFromColumns(row);
|
|
42702
43307
|
if (claimAllows(stored, guard.mode, guard.sessionId, guard.now, allowedHolders)) return;
|
|
@@ -42871,13 +43476,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
42871
43476
|
const db = await getDb(cwd);
|
|
42872
43477
|
const conditions = [];
|
|
42873
43478
|
if (query.ids && query.ids.length > 0) {
|
|
42874
|
-
conditions.push(
|
|
43479
|
+
conditions.push(inArray6(tasksAuditLog.id, [...query.ids]));
|
|
42875
43480
|
}
|
|
42876
43481
|
if (query.taskIds && query.taskIds.length > 0) {
|
|
42877
|
-
conditions.push(
|
|
43482
|
+
conditions.push(inArray6(tasksAuditLog.taskId, [...query.taskIds]));
|
|
42878
43483
|
}
|
|
42879
43484
|
if (query.actions && query.actions.length > 0) {
|
|
42880
|
-
conditions.push(
|
|
43485
|
+
conditions.push(inArray6(tasksAuditLog.action, [...query.actions]));
|
|
42881
43486
|
}
|
|
42882
43487
|
if (query.since) {
|
|
42883
43488
|
conditions.push(sql30`${tasksAuditLog.timestamp} >= ${query.since}`);
|
|
@@ -42910,8 +43515,13 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
42910
43515
|
async upsertSingleTask(task) {
|
|
42911
43516
|
await accessor.transaction((tx) => tx.upsertSingleTask(task));
|
|
42912
43517
|
},
|
|
42913
|
-
async insertNewTask(task) {
|
|
42914
|
-
await accessor.transaction((tx) => tx.insertNewTask(task));
|
|
43518
|
+
async insertNewTask(task, identity) {
|
|
43519
|
+
await accessor.transaction((tx) => tx.insertNewTask(task, identity));
|
|
43520
|
+
},
|
|
43521
|
+
async getTaskIdentities(taskIds) {
|
|
43522
|
+
if (taskIds.length === 0) return [];
|
|
43523
|
+
const db = await getDb(cwd);
|
|
43524
|
+
return db.select({ id: tasksTasks.id, uid: tasksTasks.uid, birthFp: tasksTasks.birthFp }).from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
42915
43525
|
},
|
|
42916
43526
|
async addRelation(taskId, relatedTo, relationType, reason) {
|
|
42917
43527
|
return accessor.transaction(async () => {
|
|
@@ -43088,7 +43698,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43088
43698
|
if (!statuses.includes("archived")) {
|
|
43089
43699
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43090
43700
|
}
|
|
43091
|
-
conditions.push(
|
|
43701
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43092
43702
|
} else if (filters.excludeStatus) {
|
|
43093
43703
|
const excluded = Array.isArray(filters.excludeStatus) ? filters.excludeStatus : [filters.excludeStatus];
|
|
43094
43704
|
for (const s of excluded) {
|
|
@@ -43102,11 +43712,11 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43102
43712
|
if (filters.phase) conditions.push(eq10(tasksTasks.phase, filters.phase));
|
|
43103
43713
|
if (filters.severity) {
|
|
43104
43714
|
const severities = Array.isArray(filters.severity) ? filters.severity : [filters.severity];
|
|
43105
|
-
conditions.push(
|
|
43715
|
+
conditions.push(inArray6(tasksTasks.severity, severities));
|
|
43106
43716
|
}
|
|
43107
43717
|
if (filters.kind) {
|
|
43108
43718
|
const kinds = Array.isArray(filters.kind) ? filters.kind : [filters.kind];
|
|
43109
|
-
conditions.push(
|
|
43719
|
+
conditions.push(inArray6(tasksTasks.kind, kinds));
|
|
43110
43720
|
}
|
|
43111
43721
|
if (filters.parentId !== void 0) {
|
|
43112
43722
|
if (filters.parentId === null) {
|
|
@@ -43127,7 +43737,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43127
43737
|
}
|
|
43128
43738
|
if (filters.label) {
|
|
43129
43739
|
const labelMatchIds = db.select({ taskId: tasksTaskLabels.taskId }).from(tasksTaskLabels).where(eq10(tasksTaskLabels.label, filters.label));
|
|
43130
|
-
conditions.push(
|
|
43740
|
+
conditions.push(inArray6(tasksTasks.id, labelMatchIds));
|
|
43131
43741
|
}
|
|
43132
43742
|
const where = conditions.length > 0 ? and8(...conditions) : void 0;
|
|
43133
43743
|
const countResult = await db.select({ count: sql30`count(*)` }).from(tasksTasks).where(where).get();
|
|
@@ -43170,7 +43780,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43170
43780
|
const conditions = [];
|
|
43171
43781
|
if (filters?.status) {
|
|
43172
43782
|
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
43173
|
-
conditions.push(
|
|
43783
|
+
conditions.push(inArray6(tasksTasks.status, statuses));
|
|
43174
43784
|
} else {
|
|
43175
43785
|
conditions.push(ne2(tasksTasks.status, "archived"));
|
|
43176
43786
|
}
|
|
@@ -43235,7 +43845,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43235
43845
|
if (idRows.length === 0) return [];
|
|
43236
43846
|
const db = await getDb(cwd);
|
|
43237
43847
|
const ids = idRows.map((r) => r.id);
|
|
43238
|
-
const taskRows = await db.select().from(tasksTasks).where(
|
|
43848
|
+
const taskRows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43239
43849
|
const tasks2 = taskRows.map(rowToTask);
|
|
43240
43850
|
if (tasks2.length > 0) {
|
|
43241
43851
|
const allIds = await getAllTaskIds();
|
|
@@ -43264,7 +43874,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43264
43874
|
if (idRows.length === 0) return [];
|
|
43265
43875
|
const db = await getDb(cwd);
|
|
43266
43876
|
const ids = idRows.map((r) => r.id);
|
|
43267
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
43877
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, ids)).all();
|
|
43268
43878
|
const tasks2 = rows.map(rowToTask);
|
|
43269
43879
|
if (tasks2.length > 0) {
|
|
43270
43880
|
const allIds = await getAllTaskIds();
|
|
@@ -43278,7 +43888,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43278
43888
|
const depRows = await db.select().from(tasksTaskDependencies).where(eq10(tasksTaskDependencies.dependsOn, taskId)).all();
|
|
43279
43889
|
if (depRows.length === 0) return [];
|
|
43280
43890
|
const dependentIds = depRows.map((r) => r.taskId);
|
|
43281
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
43891
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, dependentIds)).all();
|
|
43282
43892
|
const tasks2 = rows.map(rowToTask);
|
|
43283
43893
|
if (tasks2.length > 0) {
|
|
43284
43894
|
const allIds = await getAllTaskIds();
|
|
@@ -43308,7 +43918,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43308
43918
|
async loadTasks(taskIds) {
|
|
43309
43919
|
if (taskIds.length === 0) return [];
|
|
43310
43920
|
const db = await getDb(cwd);
|
|
43311
|
-
const rows = await db.select().from(tasksTasks).where(
|
|
43921
|
+
const rows = await db.select().from(tasksTasks).where(inArray6(tasksTasks.id, taskIds)).all();
|
|
43312
43922
|
const tasks2 = rows.map(rowToTask);
|
|
43313
43923
|
if (tasks2.length > 0) {
|
|
43314
43924
|
const allIds = await getAllTaskIds();
|
|
@@ -43362,6 +43972,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43362
43972
|
createdAt: tasksTasks.createdAt,
|
|
43363
43973
|
...CLAIM_COLUMNS
|
|
43364
43974
|
}).from(tasksTasks).where(eq10(tasksTasks.id, taskId)).limit(1).all();
|
|
43975
|
+
if (guard?.claim || guard?.expectedUpdatedAt !== void 0) {
|
|
43976
|
+
assertNotRenamed(getNativeTasksDb(cwd), taskId, guard, current);
|
|
43977
|
+
}
|
|
43365
43978
|
if (!current) throw new Error(`Task not found: ${taskId}`);
|
|
43366
43979
|
const claimGuard = guard?.claim;
|
|
43367
43980
|
const allowedHolders = claimGuard ? await claimAllowedHolders(db, claimGuard) : [];
|
|
@@ -43439,24 +44052,37 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43439
44052
|
nativeDb.prepare(`SAVEPOINT ${spName}`).run();
|
|
43440
44053
|
}
|
|
43441
44054
|
try {
|
|
44055
|
+
const replacedBirths = /* @__PURE__ */ new Map();
|
|
43442
44056
|
const tx = {
|
|
43443
44057
|
async upsertSingleTask(task) {
|
|
43444
44058
|
scope.assertActive();
|
|
43445
44059
|
return accessor.transaction(async () => {
|
|
43446
44060
|
scope.assertActive();
|
|
44061
|
+
if (rowUidFillEnabled() && !replacedBirths.has(task.id)) {
|
|
44062
|
+
const before = readReplacedTaskBirthNative(nativeDb, task.id);
|
|
44063
|
+
if (before) replacedBirths.set(task.id, before);
|
|
44064
|
+
}
|
|
43447
44065
|
const row = taskToRow(task);
|
|
43448
44066
|
await upsertTask(db, row);
|
|
43449
44067
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43450
44068
|
});
|
|
43451
44069
|
},
|
|
43452
|
-
async insertNewTask(task) {
|
|
44070
|
+
async insertNewTask(task, identity) {
|
|
43453
44071
|
scope.assertActive();
|
|
43454
44072
|
return accessor.transaction(async () => {
|
|
43455
44073
|
scope.assertActive();
|
|
43456
|
-
await insertNewTask(db, taskToRow(task));
|
|
44074
|
+
await insertNewTask(db, taskToRow(task), identity);
|
|
43457
44075
|
await updateDependencies(db, task.id, task.depends ?? []);
|
|
43458
44076
|
});
|
|
43459
44077
|
},
|
|
44078
|
+
async clearTaskIdentity(taskId) {
|
|
44079
|
+
scope.assertActive();
|
|
44080
|
+
if (!rowUidFillEnabled()) return;
|
|
44081
|
+
return accessor.transaction(async () => {
|
|
44082
|
+
scope.assertActive();
|
|
44083
|
+
clearReplacedTaskIdentityNative(nativeDb, taskId, replacedBirths.get(taskId));
|
|
44084
|
+
});
|
|
44085
|
+
},
|
|
43460
44086
|
async archiveSingleTask(taskId, fields) {
|
|
43461
44087
|
scope.assertActive();
|
|
43462
44088
|
return accessor.transaction(async () => {
|
|
@@ -43603,7 +44229,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43603
44229
|
const owned = await db.select({ id: tasksTaskAcceptanceCriteria.id }).from(tasksTaskAcceptanceCriteria).where(
|
|
43604
44230
|
and8(
|
|
43605
44231
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43606
|
-
|
|
44232
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43607
44233
|
)
|
|
43608
44234
|
).all();
|
|
43609
44235
|
await pruneAcBindingsForAcIds(
|
|
@@ -43616,7 +44242,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43616
44242
|
await db.delete(tasksTaskAcceptanceCriteria).where(
|
|
43617
44243
|
and8(
|
|
43618
44244
|
eq10(tasksTaskAcceptanceCriteria.taskId, taskId),
|
|
43619
|
-
|
|
44245
|
+
inArray6(tasksTaskAcceptanceCriteria.id, ids)
|
|
43620
44246
|
)
|
|
43621
44247
|
).run();
|
|
43622
44248
|
});
|
|
@@ -43875,7 +44501,7 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
|
|
|
43875
44501
|
};
|
|
43876
44502
|
return accessor;
|
|
43877
44503
|
}
|
|
43878
|
-
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS;
|
|
44504
|
+
var _txSavepointCounter, taskTransactionQueue, TaskTransactionScope, taskTransactionContext, CLAIM_COLUMNS, RENAMED_RECENT_MS;
|
|
43879
44505
|
var init_sqlite_data_accessor = __esm({
|
|
43880
44506
|
"packages/core/src/store/sqlite-data-accessor.ts"() {
|
|
43881
44507
|
"use strict";
|
|
@@ -43889,6 +44515,8 @@ var init_sqlite_data_accessor = __esm({
|
|
|
43889
44515
|
init_cross_db_cleanup();
|
|
43890
44516
|
init_db_helpers();
|
|
43891
44517
|
init_row_identity();
|
|
44518
|
+
init_row_identity_flag();
|
|
44519
|
+
init_row_identity_registry();
|
|
43892
44520
|
init_audit2();
|
|
43893
44521
|
init_session_store();
|
|
43894
44522
|
init_sqlite3();
|
|
@@ -43921,6 +44549,7 @@ var init_sqlite_data_accessor = __esm({
|
|
|
43921
44549
|
claimedAt: tasksTasks.claimedAt,
|
|
43922
44550
|
leaseExpiresAt: tasksTasks.leaseExpiresAt
|
|
43923
44551
|
};
|
|
44552
|
+
RENAMED_RECENT_MS = 24 * 60 * 60 * 1e3;
|
|
43924
44553
|
registerRowIdentityWriters({
|
|
43925
44554
|
relinkAcUidNative,
|
|
43926
44555
|
clearAcUidGraveyardNative,
|
|
@@ -44391,7 +45020,7 @@ __export(governor_exports, {
|
|
|
44391
45020
|
resolveGovernorMode: () => resolveGovernorMode,
|
|
44392
45021
|
slotFileCount: () => slotFileCount
|
|
44393
45022
|
});
|
|
44394
|
-
import { existsSync as
|
|
45023
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync6, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
44395
45024
|
import { availableParallelism, totalmem } from "node:os";
|
|
44396
45025
|
import { join as join25 } from "node:path";
|
|
44397
45026
|
import lockfile2 from "proper-lockfile";
|
|
@@ -44465,11 +45094,11 @@ function governorSlotDir(cls) {
|
|
|
44465
45094
|
return join25(getCleoHome(), "locks", `resource-${cls}`);
|
|
44466
45095
|
}
|
|
44467
45096
|
function ensureSlotFiles(dir, count) {
|
|
44468
|
-
if (!
|
|
45097
|
+
if (!existsSync20(dir)) mkdirSync6(dir, { recursive: true });
|
|
44469
45098
|
const paths = [];
|
|
44470
45099
|
for (let i = 0; i < count; i++) {
|
|
44471
45100
|
const p = join25(dir, `slot-${i}.lock`);
|
|
44472
|
-
if (!
|
|
45101
|
+
if (!existsSync20(p)) writeFileSync5(p, "", { flag: "a" });
|
|
44473
45102
|
paths.push(p);
|
|
44474
45103
|
}
|
|
44475
45104
|
return paths;
|
|
@@ -44509,7 +45138,7 @@ function shuffledIndices(n) {
|
|
|
44509
45138
|
}
|
|
44510
45139
|
async function countHeldSlots(cls, budget) {
|
|
44511
45140
|
const dir = governorSlotDir(cls);
|
|
44512
|
-
if (!
|
|
45141
|
+
if (!existsSync20(dir)) return 0;
|
|
44513
45142
|
const slots = ensureSlotFiles(dir, budget);
|
|
44514
45143
|
let held = 0;
|
|
44515
45144
|
for (const path of slots) {
|
|
@@ -44524,7 +45153,7 @@ async function countHeldSlots(cls, budget) {
|
|
|
44524
45153
|
}
|
|
44525
45154
|
function slotFileCount(cls) {
|
|
44526
45155
|
const dir = governorSlotDir(cls);
|
|
44527
|
-
if (!
|
|
45156
|
+
if (!existsSync20(dir)) return 0;
|
|
44528
45157
|
return readdirSync5(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
|
|
44529
45158
|
}
|
|
44530
45159
|
var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
|
|
@@ -45022,7 +45651,7 @@ var init_recovery = __esm({
|
|
|
45022
45651
|
// packages/core/src/store/exodus/archive.ts
|
|
45023
45652
|
import {
|
|
45024
45653
|
copyFileSync as copyFileSync5,
|
|
45025
|
-
existsSync as
|
|
45654
|
+
existsSync as existsSync21,
|
|
45026
45655
|
mkdirSync as mkdirSync7,
|
|
45027
45656
|
readFileSync as readFileSync8,
|
|
45028
45657
|
renameSync as renameSync7,
|
|
@@ -45050,7 +45679,7 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
|
|
|
45050
45679
|
if (targetDbPath) throw error48;
|
|
45051
45680
|
return false;
|
|
45052
45681
|
}
|
|
45053
|
-
if (!
|
|
45682
|
+
if (!existsSync21(markerPath)) return false;
|
|
45054
45683
|
const marker16 = markerIdentity.parse(JSON.parse(readFileSync8(markerPath, "utf8")));
|
|
45055
45684
|
if (nativeDb && (!marker16.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker16.databaseIdentity)))
|
|
45056
45685
|
throw new Error(
|
|
@@ -45080,7 +45709,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
|
|
|
45080
45709
|
function moveFileInto(srcPath, destDir) {
|
|
45081
45710
|
mkdirSync7(destDir, { recursive: true });
|
|
45082
45711
|
let dest = join26(destDir, basename9(srcPath));
|
|
45083
|
-
if (
|
|
45712
|
+
if (existsSync21(dest)) {
|
|
45084
45713
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
45085
45714
|
dest = join26(destDir, `${basename9(srcPath)}.${stamp}`);
|
|
45086
45715
|
}
|
|
@@ -45093,14 +45722,14 @@ function moveFileInto(srcPath, destDir) {
|
|
|
45093
45722
|
return dest;
|
|
45094
45723
|
}
|
|
45095
45724
|
function archiveSourceDb(source, cwd, targetDbPath) {
|
|
45096
|
-
if (!
|
|
45725
|
+
if (!existsSync21(source.path)) {
|
|
45097
45726
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
45098
45727
|
}
|
|
45099
45728
|
const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
|
|
45100
45729
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
45101
45730
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
45102
45731
|
const sidecar = `${source.path}${suffix}`;
|
|
45103
|
-
if (
|
|
45732
|
+
if (existsSync21(sidecar)) {
|
|
45104
45733
|
try {
|
|
45105
45734
|
moveFileInto(sidecar, destDir);
|
|
45106
45735
|
} catch (err) {
|
|
@@ -45148,7 +45777,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
45148
45777
|
const stranded = [];
|
|
45149
45778
|
for (const source of sources) {
|
|
45150
45779
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
45151
|
-
if (
|
|
45780
|
+
if (existsSync21(source.path)) {
|
|
45152
45781
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
45153
45782
|
}
|
|
45154
45783
|
}
|
|
@@ -45189,13 +45818,13 @@ var init_archive2 = __esm({
|
|
|
45189
45818
|
});
|
|
45190
45819
|
|
|
45191
45820
|
// packages/core/src/store/exodus/count-parity.ts
|
|
45192
|
-
import { existsSync as
|
|
45821
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
45193
45822
|
function listTables2(db) {
|
|
45194
45823
|
return db.prepare(
|
|
45195
45824
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
45196
45825
|
).all().map((r) => r.name);
|
|
45197
45826
|
}
|
|
45198
|
-
function
|
|
45827
|
+
function tableExists3(db, tableName) {
|
|
45199
45828
|
const escaped = tableName.replace(/'/g, "''");
|
|
45200
45829
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
45201
45830
|
}
|
|
@@ -45210,14 +45839,14 @@ function rowCount(db, tableName) {
|
|
|
45210
45839
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
45211
45840
|
const entries = [];
|
|
45212
45841
|
let skipped = 0;
|
|
45213
|
-
if (!
|
|
45842
|
+
if (!existsSync22(projectDbPath) || !existsSync22(globalDbPath)) {
|
|
45214
45843
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45215
45844
|
}
|
|
45216
45845
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
45217
45846
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
45218
45847
|
try {
|
|
45219
45848
|
for (const src of sources) {
|
|
45220
|
-
if (!
|
|
45849
|
+
if (!existsSync22(src.path)) continue;
|
|
45221
45850
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
45222
45851
|
try {
|
|
45223
45852
|
for (const legacyTable of listTables2(srcSnap.db)) {
|
|
@@ -45234,7 +45863,7 @@ function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
|
45234
45863
|
skipped++;
|
|
45235
45864
|
continue;
|
|
45236
45865
|
}
|
|
45237
|
-
const targetCount =
|
|
45866
|
+
const targetCount = tableExists3(targetSnap.db, targetTable) ? rowCount(targetSnap.db, targetTable) ?? 0 : 0;
|
|
45238
45867
|
const deficit = targetCount < sourceCount ? sourceCount - targetCount : 0;
|
|
45239
45868
|
entries.push({
|
|
45240
45869
|
sourceDb: src.name,
|
|
@@ -45275,7 +45904,7 @@ var init_count_parity = __esm({
|
|
|
45275
45904
|
});
|
|
45276
45905
|
|
|
45277
45906
|
// packages/core/src/store/exodus/plan.ts
|
|
45278
|
-
import { existsSync as
|
|
45907
|
+
import { existsSync as existsSync23, readdirSync as readdirSync6, statfsSync as statfsSync2, statSync as statSync6 } from "node:fs";
|
|
45279
45908
|
import { join as join27 } from "node:path";
|
|
45280
45909
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
45281
45910
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
@@ -45377,7 +46006,7 @@ function buildExodusPlan(cwd) {
|
|
|
45377
46006
|
};
|
|
45378
46007
|
}
|
|
45379
46008
|
function sourcesPresent(sources) {
|
|
45380
|
-
return sources.some((s) =>
|
|
46009
|
+
return sources.some((s) => existsSync23(s.path));
|
|
45381
46010
|
}
|
|
45382
46011
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
45383
46012
|
var init_plan2 = __esm({
|
|
@@ -45391,18 +46020,18 @@ var init_plan2 = __esm({
|
|
|
45391
46020
|
});
|
|
45392
46021
|
|
|
45393
46022
|
// packages/core/src/store/exodus/health.ts
|
|
45394
|
-
import { existsSync as
|
|
46023
|
+
import { existsSync as existsSync24, statSync as statSync7 } from "node:fs";
|
|
45395
46024
|
function buildExodusHealth(cwd) {
|
|
45396
46025
|
const plan = buildExodusPlan(cwd);
|
|
45397
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
46026
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync24(s.path));
|
|
45398
46027
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
45399
46028
|
const consolidatedExistsByScope = {
|
|
45400
|
-
project:
|
|
45401
|
-
global:
|
|
46029
|
+
project: existsSync24(plan.projectDbPath),
|
|
46030
|
+
global: existsSync24(plan.globalDbPath)
|
|
45402
46031
|
};
|
|
45403
46032
|
const buildScope = (scope) => {
|
|
45404
46033
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
45405
|
-
const present =
|
|
46034
|
+
const present = existsSync24(s.path);
|
|
45406
46035
|
let bytes = 0;
|
|
45407
46036
|
if (present) {
|
|
45408
46037
|
try {
|
|
@@ -45507,7 +46136,7 @@ var init_types = __esm({
|
|
|
45507
46136
|
// packages/core/src/store/exodus/migrate.ts
|
|
45508
46137
|
import {
|
|
45509
46138
|
copyFileSync as copyFileSync6,
|
|
45510
|
-
existsSync as
|
|
46139
|
+
existsSync as existsSync25,
|
|
45511
46140
|
mkdirSync as mkdirSync8,
|
|
45512
46141
|
readFileSync as readFileSync9,
|
|
45513
46142
|
renameSync as renameSync8,
|
|
@@ -45553,7 +46182,7 @@ function writeJournal(stagingDir, journal) {
|
|
|
45553
46182
|
}
|
|
45554
46183
|
function readJournal(stagingDir) {
|
|
45555
46184
|
const journalPath = join28(stagingDir, JOURNAL_FILENAME);
|
|
45556
|
-
if (!
|
|
46185
|
+
if (!existsSync25(journalPath)) return null;
|
|
45557
46186
|
try {
|
|
45558
46187
|
return JSON.parse(readFileSync9(journalPath, "utf8"));
|
|
45559
46188
|
} catch {
|
|
@@ -45563,7 +46192,7 @@ function readJournal(stagingDir) {
|
|
|
45563
46192
|
function clearExodusJournal(stagingDir) {
|
|
45564
46193
|
const journalPath = join28(stagingDir, JOURNAL_FILENAME);
|
|
45565
46194
|
try {
|
|
45566
|
-
if (!
|
|
46195
|
+
if (!existsSync25(journalPath)) return false;
|
|
45567
46196
|
unlinkSync5(journalPath);
|
|
45568
46197
|
log10.info(
|
|
45569
46198
|
{ stagingDir },
|
|
@@ -45859,7 +46488,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45859
46488
|
mkdirSync8(stagingDir, { recursive: true });
|
|
45860
46489
|
let sqliteVersion = "unknown";
|
|
45861
46490
|
for (const src of sources) {
|
|
45862
|
-
if (
|
|
46491
|
+
if (existsSync25(src.path)) {
|
|
45863
46492
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
45864
46493
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
45865
46494
|
snap.close();
|
|
@@ -45889,7 +46518,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45889
46518
|
let reseedProject = null;
|
|
45890
46519
|
try {
|
|
45891
46520
|
for (const src of sources) {
|
|
45892
|
-
if (!
|
|
46521
|
+
if (!existsSync25(src.path)) continue;
|
|
45893
46522
|
const backupDest = join28(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
45894
46523
|
const srcBytes = safeStatBytes(src.path);
|
|
45895
46524
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
@@ -45897,7 +46526,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45897
46526
|
onProgress?.(
|
|
45898
46527
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
45899
46528
|
);
|
|
45900
|
-
} else if (!
|
|
46529
|
+
} else if (!existsSync25(backupDest)) {
|
|
45901
46530
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
45902
46531
|
copyFileSync6(src.path, backupDest);
|
|
45903
46532
|
backupPaths.push(backupDest);
|
|
@@ -45930,8 +46559,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
|
|
|
45930
46559
|
}
|
|
45931
46560
|
prepareExodusRecovery(projectNative, stagingDir);
|
|
45932
46561
|
if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
|
|
45933
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
45934
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
46562
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync25(s.path));
|
|
46563
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync25(s.path));
|
|
45935
46564
|
if (globalNative === null && globalSources.length > 0)
|
|
45936
46565
|
throw new Error("A projectOnly exodus run was given global-scope sources");
|
|
45937
46566
|
await migrateScope(
|
|
@@ -46180,7 +46809,8 @@ var init_migrate = __esm({
|
|
|
46180
46809
|
GRANDFATHERED_GUARD_TRIGGERS = [
|
|
46181
46810
|
"tasks_tasks_parent_type_matrix_insert",
|
|
46182
46811
|
"tasks_task_relations_non_containment_insert",
|
|
46183
|
-
"tasks_task_acceptance_child_target_insert"
|
|
46812
|
+
"tasks_task_acceptance_child_target_insert",
|
|
46813
|
+
"tasks_task_dependencies_cycle_guard_insert"
|
|
46184
46814
|
];
|
|
46185
46815
|
SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
|
|
46186
46816
|
["conduit", "seconds"],
|
|
@@ -46239,7 +46869,7 @@ __export(reconcile_exports, {
|
|
|
46239
46869
|
reconcileSupersededStores: () => reconcileSupersededStores,
|
|
46240
46870
|
unmigratedBareSources: () => unmigratedBareSources
|
|
46241
46871
|
});
|
|
46242
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
46872
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync26, mkdirSync as mkdirSync9, mkdtempSync, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
|
|
46243
46873
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
46244
46874
|
import { basename as basename10, join as join29 } from "node:path";
|
|
46245
46875
|
function ident2(name15) {
|
|
@@ -46310,7 +46940,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
|
|
|
46310
46940
|
}
|
|
46311
46941
|
function legacySourcesHoldRows(sources) {
|
|
46312
46942
|
for (const src of sources) {
|
|
46313
|
-
if (!
|
|
46943
|
+
if (!existsSync26(src.path)) continue;
|
|
46314
46944
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
46315
46945
|
try {
|
|
46316
46946
|
for (const table of orderTablesForCopy(snap.db)) {
|
|
@@ -46558,8 +47188,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
|
|
|
46558
47188
|
}
|
|
46559
47189
|
}
|
|
46560
47190
|
async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
|
|
46561
|
-
const fileSources = plan.sources.filter((s) => s.targetScope === "project" &&
|
|
46562
|
-
const bare = !additive &&
|
|
47191
|
+
const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync26(s.path));
|
|
47192
|
+
const bare = !additive && existsSync26(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
|
|
46563
47193
|
const copyResolver = additive ? (sourceName, legacyTable) => {
|
|
46564
47194
|
const r = resolveTarget(sourceName, legacyTable);
|
|
46565
47195
|
return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
|
|
@@ -46578,7 +47208,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
|
|
|
46578
47208
|
stagingDir: null,
|
|
46579
47209
|
receiptPath: null
|
|
46580
47210
|
};
|
|
46581
|
-
if (sources.length === 0 || !
|
|
47211
|
+
if (sources.length === 0 || !existsSync26(liveStorePath)) {
|
|
46582
47212
|
return {
|
|
46583
47213
|
...base,
|
|
46584
47214
|
outcome: "nothing-to-reconcile",
|
|
@@ -46770,11 +47400,11 @@ var init_seal = __esm({
|
|
|
46770
47400
|
});
|
|
46771
47401
|
|
|
46772
47402
|
// packages/core/src/store/exodus/status.ts
|
|
46773
|
-
import { existsSync as
|
|
47403
|
+
import { existsSync as existsSync27, readdirSync as readdirSync7, readFileSync as readFileSync10, statSync as statSync9 } from "node:fs";
|
|
46774
47404
|
import { join as join30 } from "node:path";
|
|
46775
47405
|
function readJournal2(stagingDir) {
|
|
46776
47406
|
const p = join30(stagingDir, JOURNAL_FILENAME2);
|
|
46777
|
-
if (!
|
|
47407
|
+
if (!existsSync27(p)) return null;
|
|
46778
47408
|
try {
|
|
46779
47409
|
return JSON.parse(readFileSync10(p, "utf8"));
|
|
46780
47410
|
} catch {
|
|
@@ -46806,15 +47436,15 @@ function runExodusStatus(cwd) {
|
|
|
46806
47436
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
46807
47437
|
name: s.name,
|
|
46808
47438
|
path: s.path,
|
|
46809
|
-
exists:
|
|
47439
|
+
exists: existsSync27(s.path),
|
|
46810
47440
|
bytes: safeBytes(s.path)
|
|
46811
47441
|
}));
|
|
46812
47442
|
return {
|
|
46813
47443
|
hasStaging: latestStaging !== null,
|
|
46814
47444
|
stagingDir: latestStaging,
|
|
46815
47445
|
journal,
|
|
46816
|
-
projectDbExists:
|
|
46817
|
-
globalDbExists:
|
|
47446
|
+
projectDbExists: existsSync27(projectDbPath),
|
|
47447
|
+
globalDbExists: existsSync27(globalDbPath),
|
|
46818
47448
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
46819
47449
|
sources: sourcesInfo
|
|
46820
47450
|
};
|
|
@@ -46831,7 +47461,7 @@ var init_status = __esm({
|
|
|
46831
47461
|
});
|
|
46832
47462
|
|
|
46833
47463
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
46834
|
-
import { existsSync as
|
|
47464
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
46835
47465
|
import { createRequire as createRequire10 } from "node:module";
|
|
46836
47466
|
function orderByClause(db, tableName) {
|
|
46837
47467
|
try {
|
|
@@ -46946,7 +47576,7 @@ function listTables3(db) {
|
|
|
46946
47576
|
).all();
|
|
46947
47577
|
return rows.map((r) => r.name);
|
|
46948
47578
|
}
|
|
46949
|
-
function
|
|
47579
|
+
function tableExists4(db, tableName) {
|
|
46950
47580
|
try {
|
|
46951
47581
|
const escaped = tableName.replace(/'/g, "''");
|
|
46952
47582
|
return db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='${escaped}'`).get() !== void 0;
|
|
@@ -47096,10 +47726,10 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
|
|
|
47096
47726
|
const anyFeeder = (targetTable, probe) => {
|
|
47097
47727
|
for (const feeder of feedersOf(targetTable)) {
|
|
47098
47728
|
const src = sources.find((s) => s.name === feeder.sourceName);
|
|
47099
|
-
if (src === void 0 || !
|
|
47729
|
+
if (src === void 0 || !existsSync28(src.path)) continue;
|
|
47100
47730
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
47101
47731
|
try {
|
|
47102
|
-
if (!
|
|
47732
|
+
if (!tableExists4(snap.db, feeder.legacyTable)) continue;
|
|
47103
47733
|
const cols = new Set(
|
|
47104
47734
|
snap.db.prepare(`PRAGMA table_info("${feeder.legacyTable}")`).all().map((c) => c.name)
|
|
47105
47735
|
);
|
|
@@ -47151,7 +47781,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47151
47781
|
const preExistingForeignKeyViolations = [];
|
|
47152
47782
|
const failureLines = [];
|
|
47153
47783
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
47154
|
-
if (!
|
|
47784
|
+
if (!existsSync28(projectDbPath)) {
|
|
47155
47785
|
return {
|
|
47156
47786
|
ok: false,
|
|
47157
47787
|
tables: [],
|
|
@@ -47162,7 +47792,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47162
47792
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
47163
47793
|
};
|
|
47164
47794
|
}
|
|
47165
|
-
if (!
|
|
47795
|
+
if (!existsSync28(globalDbPath)) {
|
|
47166
47796
|
return {
|
|
47167
47797
|
ok: false,
|
|
47168
47798
|
tables: [],
|
|
@@ -47177,7 +47807,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47177
47807
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
47178
47808
|
try {
|
|
47179
47809
|
for (const src of sources) {
|
|
47180
|
-
if (!
|
|
47810
|
+
if (!existsSync28(src.path)) {
|
|
47181
47811
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
47182
47812
|
continue;
|
|
47183
47813
|
}
|
|
@@ -47302,7 +47932,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
|
|
|
47302
47932
|
targetOrphans.push(...foreignKeyCheck(globalSnap.db, "global"));
|
|
47303
47933
|
foreignKeyViolations.push(...targetOrphans);
|
|
47304
47934
|
for (const fk of targetOrphans) {
|
|
47305
|
-
const orphanDb =
|
|
47935
|
+
const orphanDb = tableExists4(projectSnap.db, fk.table) ? projectSnap.db : globalSnap.db;
|
|
47306
47936
|
const sig = orphanSignature(orphanDb, fk);
|
|
47307
47937
|
const preExisting = sourceOrphanSigs.has(sig) || orphanAlreadyInSource(orphanDb, fk, sources, resolveTarget);
|
|
47308
47938
|
if (preExisting) {
|
|
@@ -47468,7 +48098,7 @@ __export(on_open_exports, {
|
|
|
47468
48098
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
|
|
47469
48099
|
withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
|
|
47470
48100
|
});
|
|
47471
|
-
import { existsSync as
|
|
48101
|
+
import { existsSync as existsSync29, mkdtempSync as mkdtempSync2, rmSync as rmSync4 } from "node:fs";
|
|
47472
48102
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
47473
48103
|
import { join as join31, resolve as resolve13 } from "node:path";
|
|
47474
48104
|
async function withExodusOnOpenSuppressed(dbPath, fn) {
|
|
@@ -47510,7 +48140,7 @@ function remedyFor(scope) {
|
|
|
47510
48140
|
}
|
|
47511
48141
|
async function strandedLegacySources(scope, cwd) {
|
|
47512
48142
|
const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
47513
|
-
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope &&
|
|
48143
|
+
return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync29(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
|
|
47514
48144
|
}
|
|
47515
48145
|
async function exodusStoreRewriteRefusal(dbPath, cwd) {
|
|
47516
48146
|
const { assertOwnerStoreRewriteConfirmed: assertOwnerStoreRewriteConfirmed2, invocationDirectory: invocationDirectory2 } = await Promise.resolve().then(() => (init_worktree_isolation_guard(), worktree_isolation_guard_exports));
|
|
@@ -47642,7 +48272,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47642
48272
|
};
|
|
47643
48273
|
}
|
|
47644
48274
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
47645
|
-
if (!scopeSources.some((s) =>
|
|
48275
|
+
if (!scopeSources.some((s) => existsSync29(s.path))) {
|
|
47646
48276
|
return {
|
|
47647
48277
|
outcome: "skipped",
|
|
47648
48278
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -47667,7 +48297,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47667
48297
|
{
|
|
47668
48298
|
scope,
|
|
47669
48299
|
dbPath,
|
|
47670
|
-
sources: plan.sources.filter((s) =>
|
|
48300
|
+
sources: plan.sources.filter((s) => existsSync29(s.path)).map((s) => s.name)
|
|
47671
48301
|
},
|
|
47672
48302
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
47673
48303
|
);
|
|
@@ -47680,7 +48310,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47680
48310
|
const bare = scope === "project" ? await unmigratedBareSources2(
|
|
47681
48311
|
dbPath,
|
|
47682
48312
|
resolveTarget,
|
|
47683
|
-
plan.sources.find((s) => s.name === "tasks" &&
|
|
48313
|
+
plan.sources.find((s) => s.name === "tasks" && existsSync29(s.path))?.path,
|
|
47684
48314
|
bareScratch
|
|
47685
48315
|
) : { first: [], last: [] };
|
|
47686
48316
|
const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
|
|
@@ -47744,7 +48374,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
47744
48374
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
47745
48375
|
);
|
|
47746
48376
|
try {
|
|
47747
|
-
const consumed = plan.sources.filter((s) =>
|
|
48377
|
+
const consumed = plan.sources.filter((s) => existsSync29(s.path));
|
|
47748
48378
|
const identities = await sealTargets(plan, consumed);
|
|
47749
48379
|
const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
|
|
47750
48380
|
log14.info(
|
|
@@ -47819,7 +48449,7 @@ __export(dual_scope_db_exports, {
|
|
|
47819
48449
|
upsertIdempotent: () => upsertIdempotent,
|
|
47820
48450
|
withStoreSchemaOwnership: () => withStoreSchemaOwnership
|
|
47821
48451
|
});
|
|
47822
|
-
import { existsSync as
|
|
48452
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync10 } from "node:fs";
|
|
47823
48453
|
import { createRequire as createRequire11 } from "node:module";
|
|
47824
48454
|
import { dirname as dirname20, join as join32, resolve as resolve14 } from "node:path";
|
|
47825
48455
|
function getDualScopeNativeDb(handle) {
|
|
@@ -47892,11 +48522,15 @@ async function openDualScopeDb(scope, cwd, options) {
|
|
|
47892
48522
|
open
|
|
47893
48523
|
) : open();
|
|
47894
48524
|
}
|
|
48525
|
+
function identityWorkOnOpen(nativeDb, scope) {
|
|
48526
|
+
if (ROW_IDENTITY[scope].length === 0) return false;
|
|
48527
|
+
return rowUidFillEnabled() || missingRowIdentitySchema(nativeDb).length > 0;
|
|
48528
|
+
}
|
|
47895
48529
|
async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
47896
48530
|
execution?.assertActive();
|
|
47897
48531
|
log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
47898
48532
|
const dir = dirname20(dbPath);
|
|
47899
|
-
if (!
|
|
48533
|
+
if (!existsSync30(dir)) {
|
|
47900
48534
|
mkdirSync10(dir, { recursive: true });
|
|
47901
48535
|
}
|
|
47902
48536
|
execution?.assertActive();
|
|
@@ -47929,9 +48563,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
|
|
|
47929
48563
|
`dual-scope-db[${scope}]`
|
|
47930
48564
|
);
|
|
47931
48565
|
execution?.assertActive();
|
|
47932
|
-
if (
|
|
48566
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
47933
48567
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
47934
|
-
|
|
48568
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
48569
|
+
if (rowUidFillEnabled()) {
|
|
48570
|
+
prepareRowIdentity(nativeDb, scope, { triggers: false });
|
|
48571
|
+
}
|
|
47935
48572
|
}
|
|
47936
48573
|
execution?.assertActive();
|
|
47937
48574
|
log15.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
|
|
@@ -48044,7 +48681,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48044
48681
|
execution?.assertActive();
|
|
48045
48682
|
log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
|
|
48046
48683
|
const dir = dirname20(normalizedPath);
|
|
48047
|
-
if (!
|
|
48684
|
+
if (!existsSync30(dir)) {
|
|
48048
48685
|
mkdirSync10(dir, { recursive: true });
|
|
48049
48686
|
}
|
|
48050
48687
|
execution?.assertActive();
|
|
@@ -48077,9 +48714,12 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
48077
48714
|
`dual-scope-db[${scope}]`
|
|
48078
48715
|
);
|
|
48079
48716
|
execution?.assertActive();
|
|
48080
|
-
if (
|
|
48717
|
+
if (identityWorkOnOpen(nativeDb, scope)) {
|
|
48081
48718
|
await Promise.resolve().then(() => (init_sqlite_data_accessor(), sqlite_data_accessor_exports));
|
|
48082
|
-
|
|
48719
|
+
healRowIdentitySchema(nativeDb, scope);
|
|
48720
|
+
if (rowUidFillEnabled()) {
|
|
48721
|
+
prepareRowIdentity(nativeDb, scope);
|
|
48722
|
+
}
|
|
48083
48723
|
}
|
|
48084
48724
|
execution?.assertActive();
|
|
48085
48725
|
log15.debug({ scope, dbPath: normalizedPath }, "dual-scope cleo.db ready");
|
|
@@ -49209,7 +49849,7 @@ __export(nexus_sqlite_exports, {
|
|
|
49209
49849
|
resetNexusDbState: () => resetNexusDbState,
|
|
49210
49850
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
49211
49851
|
});
|
|
49212
|
-
import { copyFileSync as copyFileSync8, existsSync as
|
|
49852
|
+
import { copyFileSync as copyFileSync8, existsSync as existsSync31 } from "node:fs";
|
|
49213
49853
|
import { join as join33 } from "node:path";
|
|
49214
49854
|
function getNexusDbPath(cwd) {
|
|
49215
49855
|
return resolveDualScopeDbPath("project", cwd);
|
|
@@ -49261,7 +49901,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49261
49901
|
} catch {
|
|
49262
49902
|
return false;
|
|
49263
49903
|
}
|
|
49264
|
-
if (!
|
|
49904
|
+
if (!existsSync31(nestedPath)) return false;
|
|
49265
49905
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
49266
49906
|
_warnedNestedPaths.add(nestedPath);
|
|
49267
49907
|
const canonicalPath = getNexusDbPath();
|
|
@@ -49281,7 +49921,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
49281
49921
|
function _resetNestedNexusWarningGate() {
|
|
49282
49922
|
_warnedNestedPaths.clear();
|
|
49283
49923
|
}
|
|
49284
|
-
function
|
|
49924
|
+
function tableExists5(nativeDb, tableName) {
|
|
49285
49925
|
const result = nativeDb.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(tableName);
|
|
49286
49926
|
return !!result;
|
|
49287
49927
|
}
|
|
@@ -49290,7 +49930,7 @@ function objectExists(nativeDb, type, name15) {
|
|
|
49290
49930
|
return !!result;
|
|
49291
49931
|
}
|
|
49292
49932
|
function ensureNexusFts5(nativeDb) {
|
|
49293
|
-
if (!
|
|
49933
|
+
if (!tableExists5(nativeDb, "nexus_nodes")) return;
|
|
49294
49934
|
if (!objectExists(nativeDb, "table", "nexus_symbols_fts")) {
|
|
49295
49935
|
nativeDb.exec(`
|
|
49296
49936
|
CREATE VIRTUAL TABLE nexus_symbols_fts USING fts5(
|
|
@@ -49336,7 +49976,7 @@ function ensureNexusFts5(nativeDb) {
|
|
|
49336
49976
|
`);
|
|
49337
49977
|
}
|
|
49338
49978
|
function ensureNexusRelationWeights(nativeDb) {
|
|
49339
|
-
if (!
|
|
49979
|
+
if (!tableExists5(nativeDb, "nexus_relations")) return;
|
|
49340
49980
|
nativeDb.exec(`
|
|
49341
49981
|
CREATE TABLE IF NOT EXISTS nexus_relation_weights (
|
|
49342
49982
|
relation_id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -49418,9 +50058,9 @@ function ensureNexusRelationWeights(nativeDb) {
|
|
|
49418
50058
|
}
|
|
49419
50059
|
function runNexusMigrations(nativeDb, db, dbPath) {
|
|
49420
50060
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
49421
|
-
if (
|
|
50061
|
+
if (tableExists5(nativeDb, "nexus_nodes")) {
|
|
49422
50062
|
const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
49423
|
-
if (!
|
|
50063
|
+
if (!existsSync31(backupPath)) {
|
|
49424
50064
|
try {
|
|
49425
50065
|
copyFileSync8(dbPath, backupPath);
|
|
49426
50066
|
} catch {
|
|
@@ -49550,13 +50190,13 @@ var init_legacy_alias = __esm({
|
|
|
49550
50190
|
|
|
49551
50191
|
// packages/core/src/llm/stable-device-id.ts
|
|
49552
50192
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
49553
|
-
import { existsSync as
|
|
50193
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync11, readFileSync as readFileSync11, renameSync as renameSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
49554
50194
|
import { dirname as dirname21 } from "node:path";
|
|
49555
50195
|
import { resolveStableDeviceIdPath } from "@cleocode/paths";
|
|
49556
50196
|
function getStableDeviceId() {
|
|
49557
50197
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
49558
50198
|
const path = resolveStableDeviceIdPath();
|
|
49559
|
-
if (
|
|
50199
|
+
if (existsSync32(path)) {
|
|
49560
50200
|
try {
|
|
49561
50201
|
const raw = readFileSync11(path, "utf-8").trim();
|
|
49562
50202
|
if (raw.length > 0) {
|
|
@@ -49569,7 +50209,7 @@ function getStableDeviceId() {
|
|
|
49569
50209
|
const fresh = randomUUID3();
|
|
49570
50210
|
try {
|
|
49571
50211
|
const dir = dirname21(path);
|
|
49572
|
-
if (!
|
|
50212
|
+
if (!existsSync32(dir)) {
|
|
49573
50213
|
mkdirSync11(dir, { recursive: true });
|
|
49574
50214
|
}
|
|
49575
50215
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
@@ -49645,11 +50285,11 @@ __export(path_map_exports, {
|
|
|
49645
50285
|
supersededRegistryPath: () => supersededRegistryPath,
|
|
49646
50286
|
touchProjectLocation: () => touchProjectLocation
|
|
49647
50287
|
});
|
|
49648
|
-
import { existsSync as
|
|
50288
|
+
import { existsSync as existsSync33, lstatSync, readdirSync as readdirSync8 } from "node:fs";
|
|
49649
50289
|
import { lstat, readdir as readdir2 } from "node:fs/promises";
|
|
49650
50290
|
import { isAbsolute as isAbsolute5, join as join34, relative as relative3, sep as sep5 } from "node:path";
|
|
49651
50291
|
import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity4 } from "@cleocode/paths";
|
|
49652
|
-
import { and as and9, desc as desc3, eq as eq12, inArray as
|
|
50292
|
+
import { and as and9, desc as desc3, eq as eq12, inArray as inArray7, ne as ne3 } from "drizzle-orm";
|
|
49653
50293
|
function holdingKey(projectId, path) {
|
|
49654
50294
|
return `${projectId}\0${path}`;
|
|
49655
50295
|
}
|
|
@@ -49797,7 +50437,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49797
50437
|
const here = db.select({ state: projectLocations.state, checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49798
50438
|
and9(
|
|
49799
50439
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49800
|
-
|
|
50440
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49801
50441
|
eq12(projectLocations.path, record2.projectPath)
|
|
49802
50442
|
)
|
|
49803
50443
|
).all();
|
|
@@ -49808,7 +50448,7 @@ function decideEncounterBinding(db, record2) {
|
|
|
49808
50448
|
const previous = () => db.select({ checkoutNonce: projectLocations.checkoutNonce }).from(projectLocations).where(
|
|
49809
50449
|
and9(
|
|
49810
50450
|
eq12(projectLocations.projectId, record2.projectId),
|
|
49811
|
-
|
|
50451
|
+
inArray7(projectLocations.deviceId, [deviceId, LOCAL_DEVICE_SENTINEL]),
|
|
49812
50452
|
eq12(projectLocations.path, oldPath)
|
|
49813
50453
|
)
|
|
49814
50454
|
).all();
|
|
@@ -49856,7 +50496,7 @@ function hasOtherLiveLocation(db, record2, deviceId) {
|
|
|
49856
50496
|
ne3(projectLocations.path, record2.projectPath)
|
|
49857
50497
|
)
|
|
49858
50498
|
).all().some(
|
|
49859
|
-
(location) => isStrictlyInside(record2.projectPath, location.path) &&
|
|
50499
|
+
(location) => isStrictlyInside(record2.projectPath, location.path) && existsSync33(location.path) && readDeclaredProjectIdentity4(location.path)?.projectId === record2.projectId
|
|
49860
50500
|
);
|
|
49861
50501
|
}
|
|
49862
50502
|
function demoteProjectLocation(db, record2, state) {
|
|
@@ -49907,7 +50547,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
|
|
|
49907
50547
|
).orderBy(desc3(projectLocations.lastSeen)).all();
|
|
49908
50548
|
const present = (path) => {
|
|
49909
50549
|
const holding = probed?.get(holdingKey(row.projectId, path));
|
|
49910
|
-
return holding === void 0 ?
|
|
50550
|
+
return holding === void 0 ? existsSync33(path) : holding === "yes";
|
|
49911
50551
|
};
|
|
49912
50552
|
const home = candidates.find(
|
|
49913
50553
|
(c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq12(projectRegistry.projectPath, c.path)).all().length === 0
|
|
@@ -49936,7 +50576,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
|
|
|
49936
50576
|
projectHash: generateProjectHash(row.path),
|
|
49937
50577
|
firstSeen: row.firstSeen,
|
|
49938
50578
|
lastSeen: row.lastSeen,
|
|
49939
|
-
exists: local &&
|
|
50579
|
+
exists: local && existsSync33(row.path),
|
|
49940
50580
|
deviceId: local ? deviceId : row.deviceId,
|
|
49941
50581
|
state: row.state
|
|
49942
50582
|
});
|
|
@@ -49969,7 +50609,7 @@ __export(project_activity_exports, {
|
|
|
49969
50609
|
projectLastActivitySql: () => projectLastActivitySql,
|
|
49970
50610
|
projectLastActivitySqlText: () => projectLastActivitySqlText
|
|
49971
50611
|
});
|
|
49972
|
-
import { eq as eq13, inArray as
|
|
50612
|
+
import { eq as eq13, inArray as inArray8, sql as sql32 } from "drizzle-orm";
|
|
49973
50613
|
function normalizeRegistryTimestamp(value) {
|
|
49974
50614
|
if (value === null || value === void 0 || value.length === 0) return null;
|
|
49975
50615
|
const iso = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value) ? `${value.replace(" ", "T")}Z` : value;
|
|
@@ -49998,7 +50638,7 @@ function markProjectsProbed(db, projectIds, now = /* @__PURE__ */ new Date()) {
|
|
|
49998
50638
|
for (let i = 0; i < ids.length; i += PROBED_CHUNK) {
|
|
49999
50639
|
const chunk = ids.slice(i, i + PROBED_CHUNK);
|
|
50000
50640
|
changed += Number(
|
|
50001
|
-
db.update(projectRegistry).set({ lastProbedAt: at }).where(
|
|
50641
|
+
db.update(projectRegistry).set({ lastProbedAt: at }).where(inArray8(projectRegistry.projectId, chunk)).run().changes
|
|
50002
50642
|
);
|
|
50003
50643
|
}
|
|
50004
50644
|
return changed;
|
|
@@ -50031,11 +50671,11 @@ __export(checkout_nonce_exports, {
|
|
|
50031
50671
|
readCheckoutNonce: () => readCheckoutNonce
|
|
50032
50672
|
});
|
|
50033
50673
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
50034
|
-
import { existsSync as
|
|
50674
|
+
import { existsSync as existsSync34, readFileSync as readFileSync12, renameSync as renameSync10, writeFileSync as writeFileSync10 } from "node:fs";
|
|
50035
50675
|
import { join as join35 } from "node:path";
|
|
50036
50676
|
function readInfo(projectRoot) {
|
|
50037
50677
|
const path = join35(projectRoot, ".cleo", "project-info.json");
|
|
50038
|
-
if (!
|
|
50678
|
+
if (!existsSync34(path)) return null;
|
|
50039
50679
|
try {
|
|
50040
50680
|
const parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
50041
50681
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
@@ -50128,7 +50768,7 @@ __export(paths_exports, {
|
|
|
50128
50768
|
validateProjectRoot: () => validateProjectRoot,
|
|
50129
50769
|
worktreeScope: () => worktreeScope
|
|
50130
50770
|
});
|
|
50131
|
-
import { existsSync as
|
|
50771
|
+
import { existsSync as existsSync35, readFileSync as readFileSync13, statSync as statSync10 } from "node:fs";
|
|
50132
50772
|
import { createRequire as createRequire12 } from "node:module";
|
|
50133
50773
|
import { homedir as homedir2 } from "node:os";
|
|
50134
50774
|
import { dirname as dirname22, join as join36, resolve as resolve15 } from "node:path";
|
|
@@ -50154,7 +50794,7 @@ function runWithWorktreeScopeFromEnv(fn) {
|
|
|
50154
50794
|
function isProjectInitialized(projectRoot) {
|
|
50155
50795
|
const root = projectRoot ?? getProjectRoot();
|
|
50156
50796
|
const cleoDir = join36(root, ".cleo");
|
|
50157
|
-
return
|
|
50797
|
+
return existsSync35(cleoDir) && existsSync35(join36(cleoDir, "tasks.db"));
|
|
50158
50798
|
}
|
|
50159
50799
|
function getCleoHome() {
|
|
50160
50800
|
return getPlatformPaths().data;
|
|
@@ -50260,7 +50900,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
50260
50900
|
try {
|
|
50261
50901
|
const cleoHome = getCleoHome();
|
|
50262
50902
|
const globalDbPath = join36(cleoHome, "cleo.db");
|
|
50263
|
-
if (!
|
|
50903
|
+
if (!existsSync35(globalDbPath)) return null;
|
|
50264
50904
|
const start = resolve15(cwd ?? process.cwd());
|
|
50265
50905
|
let current = start;
|
|
50266
50906
|
const DatabaseSync3 = _getDatabaseSyncCtor();
|
|
@@ -50423,7 +51063,7 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
50423
51063
|
while (true) {
|
|
50424
51064
|
const gitMarker = join36(current, ".git");
|
|
50425
51065
|
try {
|
|
50426
|
-
if (
|
|
51066
|
+
if (existsSync35(gitMarker)) {
|
|
50427
51067
|
return true;
|
|
50428
51068
|
}
|
|
50429
51069
|
} catch {
|
|
@@ -50501,7 +51141,7 @@ function getCleoGlobalCantAgentsDir() {
|
|
|
50501
51141
|
function getAgentOutputsDir(cwd) {
|
|
50502
51142
|
const projectRoot = getProjectRoot(cwd);
|
|
50503
51143
|
const configPath = join36(projectRoot, ".cleo", "config.json");
|
|
50504
|
-
if (
|
|
51144
|
+
if (existsSync35(configPath)) {
|
|
50505
51145
|
try {
|
|
50506
51146
|
const config2 = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
50507
51147
|
if (typeof config2.agentOutputs === "object" && config2.agentOutputs?.directory) {
|
|
@@ -50534,7 +51174,7 @@ function getManifestPath(cwd) {
|
|
|
50534
51174
|
const configPath = join36(projectRoot, ".cleo", "config.json");
|
|
50535
51175
|
const legacyFileName = ["MANIFEST", "jsonl"].join(".");
|
|
50536
51176
|
let manifestFile = legacyFileName;
|
|
50537
|
-
if (
|
|
51177
|
+
if (existsSync35(configPath)) {
|
|
50538
51178
|
try {
|
|
50539
51179
|
const config2 = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
50540
51180
|
const customFile = config2.agentOutputs?.manifestFile ?? config2.research?.manifestFile;
|
|
@@ -50590,7 +51230,7 @@ function resolveWorktreeRouting(cwdOverride) {
|
|
|
50590
51230
|
while (current !== home && current !== "/" && current !== "") {
|
|
50591
51231
|
const gitPath = join36(current, ".git");
|
|
50592
51232
|
try {
|
|
50593
|
-
if (
|
|
51233
|
+
if (existsSync35(gitPath)) {
|
|
50594
51234
|
const stat3 = statSync10(gitPath);
|
|
50595
51235
|
if (stat3.isFile()) {
|
|
50596
51236
|
worktreePath = current;
|
|
@@ -50629,7 +51269,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50629
51269
|
}
|
|
50630
51270
|
const tasksDbPath = join36(routing.worktreePath, ".cleo", "tasks.db");
|
|
50631
51271
|
try {
|
|
50632
|
-
if (
|
|
51272
|
+
if (existsSync35(tasksDbPath) && statSync10(tasksDbPath).isFile()) {
|
|
50633
51273
|
return tasksDbPath;
|
|
50634
51274
|
}
|
|
50635
51275
|
} catch {
|
|
@@ -50639,7 +51279,7 @@ function detectStrayCleoDb(routing) {
|
|
|
50639
51279
|
async function resolveProjectById(projectId) {
|
|
50640
51280
|
try {
|
|
50641
51281
|
const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50642
|
-
if (!
|
|
51282
|
+
if (!existsSync35(getNexusRegistryDbPath2())) return null;
|
|
50643
51283
|
const { eq: eq14 } = await import("drizzle-orm");
|
|
50644
51284
|
const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50645
51285
|
const db = await getNexusDb2();
|
|
@@ -50675,7 +51315,7 @@ function _rowToRegistryEntry(row) {
|
|
|
50675
51315
|
}
|
|
50676
51316
|
function _assertProjectInfoReadable(projectRoot) {
|
|
50677
51317
|
const infoPath = join36(projectRoot, ".cleo", "project-info.json");
|
|
50678
|
-
if (
|
|
51318
|
+
if (existsSync35(infoPath)) JSON.parse(readFileSync13(infoPath, "utf-8"));
|
|
50679
51319
|
}
|
|
50680
51320
|
function startProjectEncounter(key, projectRoot, infoProjectId) {
|
|
50681
51321
|
const inFlight2 = _encountersInFlight.get(key);
|
|
@@ -50724,7 +51364,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50724
51364
|
if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
|
|
50725
51365
|
const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
|
|
50726
51366
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50727
|
-
if (
|
|
51367
|
+
if (existsSync35(getNexusRegistryDbPath2(cleoHome))) {
|
|
50728
51368
|
const { and: and10, eq: eq14 } = await import("drizzle-orm");
|
|
50729
51369
|
const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
|
|
50730
51370
|
const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
|
|
@@ -50750,7 +51390,7 @@ async function recordProjectEncounter(cwd, options = {}) {
|
|
|
50750
51390
|
}
|
|
50751
51391
|
async function markEncounterOpened(cleoHome, projectId) {
|
|
50752
51392
|
const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
50753
|
-
if (!
|
|
51393
|
+
if (!existsSync35(getNexusRegistryDbPath2(cleoHome))) return;
|
|
50754
51394
|
const { markProjectOpened: markProjectOpened2 } = await Promise.resolve().then(() => (init_project_activity(), project_activity_exports));
|
|
50755
51395
|
markProjectOpened2(await getNexusRegistryDb2(cleoHome), projectId);
|
|
50756
51396
|
}
|
|
@@ -50912,7 +51552,7 @@ var init_paths = __esm({
|
|
|
50912
51552
|
// packages/core/src/store/file-utils.ts
|
|
50913
51553
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
50914
51554
|
import {
|
|
50915
|
-
existsSync as
|
|
51555
|
+
existsSync as existsSync36,
|
|
50916
51556
|
mkdirSync as mkdirSync12,
|
|
50917
51557
|
readdirSync as readdirSync9,
|
|
50918
51558
|
readFileSync as readFileSync14,
|
|
@@ -50927,7 +51567,7 @@ function rotateBackup(filePath, mode) {
|
|
|
50927
51567
|
const name15 = basename11(filePath);
|
|
50928
51568
|
const backupDir = join37(dir, ".backups");
|
|
50929
51569
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
50930
|
-
if (!
|
|
51570
|
+
if (!existsSync36(backupDir)) {
|
|
50931
51571
|
mkdirSync12(backupDir, { recursive: true, mode: dirMode });
|
|
50932
51572
|
}
|
|
50933
51573
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
@@ -50940,7 +51580,7 @@ function rotateBackup(filePath, mode) {
|
|
|
50940
51580
|
} else {
|
|
50941
51581
|
const next = join37(backupDir, `${name15}.${i + 1}`);
|
|
50942
51582
|
try {
|
|
50943
|
-
if (
|
|
51583
|
+
if (existsSync36(current)) renameSync11(current, next);
|
|
50944
51584
|
} catch {
|
|
50945
51585
|
}
|
|
50946
51586
|
}
|
|
@@ -50976,7 +51616,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
50976
51616
|
writeFileSync11(tempPath, content, "utf-8");
|
|
50977
51617
|
}
|
|
50978
51618
|
try {
|
|
50979
|
-
if (
|
|
51619
|
+
if (existsSync36(filePath)) {
|
|
50980
51620
|
rotateBackup(filePath, mode);
|
|
50981
51621
|
}
|
|
50982
51622
|
renameSync11(tempPath, filePath);
|
|
@@ -51002,10 +51642,10 @@ function readJsonFile(filePath) {
|
|
|
51002
51642
|
async function withLock2(filePath, transform2, opts = {}) {
|
|
51003
51643
|
const dir = dirname23(filePath);
|
|
51004
51644
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
51005
|
-
if (!
|
|
51645
|
+
if (!existsSync36(dir)) {
|
|
51006
51646
|
mkdirSync12(dir, { recursive: true, mode: dirMode });
|
|
51007
51647
|
}
|
|
51008
|
-
if (!
|
|
51648
|
+
if (!existsSync36(filePath)) {
|
|
51009
51649
|
if (typeof opts.mode === "number") {
|
|
51010
51650
|
writeFileSync11(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
51011
51651
|
} else {
|
|
@@ -51027,10 +51667,10 @@ async function withLock2(filePath, transform2, opts = {}) {
|
|
|
51027
51667
|
}
|
|
51028
51668
|
async function withFileLock(filePath, operation) {
|
|
51029
51669
|
const dir = dirname23(filePath);
|
|
51030
|
-
if (!
|
|
51670
|
+
if (!existsSync36(dir)) {
|
|
51031
51671
|
mkdirSync12(dir, { recursive: true });
|
|
51032
51672
|
}
|
|
51033
|
-
if (!
|
|
51673
|
+
if (!existsSync36(filePath)) {
|
|
51034
51674
|
writeFileSync11(filePath, "", "utf-8");
|
|
51035
51675
|
}
|
|
51036
51676
|
let release;
|
|
@@ -51402,7 +52042,7 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
51402
52042
|
});
|
|
51403
52043
|
|
|
51404
52044
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
51405
|
-
import { existsSync as
|
|
52045
|
+
import { existsSync as existsSync37, readFileSync as readFileSync17 } from "node:fs";
|
|
51406
52046
|
import { homedir as homedir4 } from "node:os";
|
|
51407
52047
|
import { join as join41 } from "node:path";
|
|
51408
52048
|
function getCodexAuthPath() {
|
|
@@ -51427,7 +52067,7 @@ var init_codex_cli_seeder = __esm({
|
|
|
51427
52067
|
*/
|
|
51428
52068
|
async seed() {
|
|
51429
52069
|
const authPath = getCodexAuthPath();
|
|
51430
|
-
if (!
|
|
52070
|
+
if (!existsSync37(authPath)) {
|
|
51431
52071
|
return { entries: [] };
|
|
51432
52072
|
}
|
|
51433
52073
|
let raw;
|
|
@@ -51622,7 +52262,7 @@ var init_google_pkce = __esm({
|
|
|
51622
52262
|
});
|
|
51623
52263
|
|
|
51624
52264
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
51625
|
-
import { existsSync as
|
|
52265
|
+
import { existsSync as existsSync38, readFileSync as readFileSync18 } from "node:fs";
|
|
51626
52266
|
import { join as join42 } from "node:path";
|
|
51627
52267
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
51628
52268
|
function getGoogleOauthPath() {
|
|
@@ -51671,7 +52311,7 @@ var init_gemini_cli_seeder = __esm({
|
|
|
51671
52311
|
*/
|
|
51672
52312
|
async seed() {
|
|
51673
52313
|
const path = getGoogleOauthPath();
|
|
51674
|
-
if (!
|
|
52314
|
+
if (!existsSync38(path)) {
|
|
51675
52315
|
return { entries: [] };
|
|
51676
52316
|
}
|
|
51677
52317
|
let raw;
|
|
@@ -51896,7 +52536,7 @@ var init_credential_seeders = __esm({
|
|
|
51896
52536
|
|
|
51897
52537
|
// packages/core/src/llm/global-config-migration.ts
|
|
51898
52538
|
import {
|
|
51899
|
-
existsSync as
|
|
52539
|
+
existsSync as existsSync39,
|
|
51900
52540
|
mkdirSync as mkdirSync13,
|
|
51901
52541
|
readFileSync as readFileSync19,
|
|
51902
52542
|
renameSync as renameSync12,
|
|
@@ -51922,12 +52562,12 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
51922
52562
|
const source = legacyGlobalConfigPath();
|
|
51923
52563
|
const target = configDirGlobalConfigPath();
|
|
51924
52564
|
const marker16 = migrationMarkerPath();
|
|
51925
|
-
if (
|
|
51926
|
-
if (!
|
|
52565
|
+
if (existsSync39(marker16)) return false;
|
|
52566
|
+
if (!existsSync39(source)) {
|
|
51927
52567
|
stampMarker(marker16);
|
|
51928
52568
|
return false;
|
|
51929
52569
|
}
|
|
51930
|
-
if (
|
|
52570
|
+
if (existsSync39(target)) {
|
|
51931
52571
|
backupSourceQuiet(source);
|
|
51932
52572
|
stampMarker(marker16);
|
|
51933
52573
|
return false;
|
|
@@ -51960,7 +52600,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
51960
52600
|
} catch (err) {
|
|
51961
52601
|
try {
|
|
51962
52602
|
const temp = tempTargetPath();
|
|
51963
|
-
if (
|
|
52603
|
+
if (existsSync39(temp)) unlinkSync8(temp);
|
|
51964
52604
|
} catch {
|
|
51965
52605
|
}
|
|
51966
52606
|
console.error(
|
|
@@ -51980,7 +52620,7 @@ function stampMarker(markerPath) {
|
|
|
51980
52620
|
function backupSourceQuiet(source) {
|
|
51981
52621
|
try {
|
|
51982
52622
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
51983
|
-
if (
|
|
52623
|
+
if (existsSync39(backup)) return;
|
|
51984
52624
|
renameSync12(source, backup);
|
|
51985
52625
|
} catch {
|
|
51986
52626
|
}
|
|
@@ -52003,7 +52643,7 @@ var init_global_config_migration = __esm({
|
|
|
52003
52643
|
});
|
|
52004
52644
|
|
|
52005
52645
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
52006
|
-
import { existsSync as
|
|
52646
|
+
import { existsSync as existsSync40, readFileSync as readFileSync20, renameSync as renameSync13, writeFileSync as writeFileSync13 } from "node:fs";
|
|
52007
52647
|
import { join as join44 } from "node:path";
|
|
52008
52648
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
52009
52649
|
function migrationPaths() {
|
|
@@ -52032,7 +52672,7 @@ function writeMarker(markerPath) {
|
|
|
52032
52672
|
}
|
|
52033
52673
|
function readFlatKey(flatPath) {
|
|
52034
52674
|
try {
|
|
52035
|
-
if (!
|
|
52675
|
+
if (!existsSync40(flatPath)) return null;
|
|
52036
52676
|
const raw = readFileSync20(flatPath, "utf-8").trim();
|
|
52037
52677
|
return raw || null;
|
|
52038
52678
|
} catch (err) {
|
|
@@ -52045,7 +52685,7 @@ function readFlatKey(flatPath) {
|
|
|
52045
52685
|
}
|
|
52046
52686
|
async function importLegacyFlatAnthropicKey() {
|
|
52047
52687
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
52048
|
-
if (
|
|
52688
|
+
if (existsSync40(markerPath)) {
|
|
52049
52689
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
52050
52690
|
}
|
|
52051
52691
|
let existing = null;
|
|
@@ -52062,7 +52702,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
52062
52702
|
writeMarker(markerPath);
|
|
52063
52703
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
52064
52704
|
}
|
|
52065
|
-
if (!
|
|
52705
|
+
if (!existsSync40(flatPath)) {
|
|
52066
52706
|
writeMarker(markerPath);
|
|
52067
52707
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
52068
52708
|
}
|
|
@@ -52139,7 +52779,7 @@ __export(credentials_exports, {
|
|
|
52139
52779
|
resolveProviderStatus: () => resolveProviderStatus,
|
|
52140
52780
|
storeAnthropicApiKey: () => storeAnthropicApiKey
|
|
52141
52781
|
});
|
|
52142
|
-
import { existsSync as
|
|
52782
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, readFileSync as readFileSync21, writeFileSync as writeFileSync14 } from "node:fs";
|
|
52143
52783
|
import { join as join45 } from "node:path";
|
|
52144
52784
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
52145
52785
|
function globalConfigPath() {
|
|
@@ -52158,7 +52798,7 @@ function readGlobalProviderKey(provider) {
|
|
|
52158
52798
|
function readFlatAnthropicKey() {
|
|
52159
52799
|
try {
|
|
52160
52800
|
const keyFile = join45(getCleoHome8(), "anthropic-key");
|
|
52161
|
-
if (!
|
|
52801
|
+
if (!existsSync41(keyFile)) return null;
|
|
52162
52802
|
const stored = readFileSync21(keyFile, "utf-8").trim();
|
|
52163
52803
|
return stored || null;
|
|
52164
52804
|
} catch {
|
|
@@ -52167,7 +52807,7 @@ function readFlatAnthropicKey() {
|
|
|
52167
52807
|
}
|
|
52168
52808
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
52169
52809
|
try {
|
|
52170
|
-
if (!
|
|
52810
|
+
if (!existsSync41(configFile)) return null;
|
|
52171
52811
|
const raw = readFileSync21(configFile, "utf-8");
|
|
52172
52812
|
const config2 = JSON.parse(raw);
|
|
52173
52813
|
const llm = config2["llm"];
|
|
@@ -52340,7 +52980,7 @@ function resolveProviderStatus(provider) {
|
|
|
52340
52980
|
}
|
|
52341
52981
|
function storeAnthropicApiKey(apiKey) {
|
|
52342
52982
|
const dir = getCleoHome8();
|
|
52343
|
-
if (!
|
|
52983
|
+
if (!existsSync41(dir)) {
|
|
52344
52984
|
mkdirSync14(dir, { recursive: true });
|
|
52345
52985
|
}
|
|
52346
52986
|
const keyFile = join45(dir, "anthropic-key");
|
|
@@ -52408,16 +53048,16 @@ __export(credentials_store_exports, {
|
|
|
52408
53048
|
pickCredentialForProviderSync: () => pickCredentialForProviderSync,
|
|
52409
53049
|
removeCredential: () => removeCredential
|
|
52410
53050
|
});
|
|
52411
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
53051
|
+
import { chmodSync as chmodSync2, existsSync as existsSync42, mkdirSync as mkdirSync15, readFileSync as readFileSync22, statSync as statSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
52412
53052
|
import { dirname as dirname24, join as join46 } from "node:path";
|
|
52413
53053
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
52414
53054
|
function credentialsStorePath() {
|
|
52415
53055
|
return join46(getCleoHome9(), "llm-credentials.json");
|
|
52416
53056
|
}
|
|
52417
53057
|
function ensureFileInitialized(path) {
|
|
52418
|
-
if (
|
|
53058
|
+
if (existsSync42(path)) return;
|
|
52419
53059
|
const dir = dirname24(path);
|
|
52420
|
-
if (!
|
|
53060
|
+
if (!existsSync42(dir)) {
|
|
52421
53061
|
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
52422
53062
|
} else {
|
|
52423
53063
|
try {
|
|
@@ -53213,7 +53853,7 @@ var init_provider_registry = __esm({
|
|
|
53213
53853
|
});
|
|
53214
53854
|
|
|
53215
53855
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
53216
|
-
import { existsSync as
|
|
53856
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9 } from "node:fs";
|
|
53217
53857
|
import { join as join48 } from "node:path";
|
|
53218
53858
|
import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
|
|
53219
53859
|
function sanitize(value) {
|
|
@@ -53269,7 +53909,7 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
53269
53909
|
}
|
|
53270
53910
|
const filePath = rateLimitStatePath(provider, label);
|
|
53271
53911
|
const dir = join48(getCleoHome10(), "rate-limit-state");
|
|
53272
|
-
if (!
|
|
53912
|
+
if (!existsSync43(dir)) {
|
|
53273
53913
|
mkdirSync16(dir, { recursive: true });
|
|
53274
53914
|
}
|
|
53275
53915
|
const state = { resetAt, recordedAt: now, source };
|
|
@@ -54170,7 +54810,7 @@ var init_error_classifier = __esm({
|
|
|
54170
54810
|
|
|
54171
54811
|
// packages/core/src/llm/catalog-cache.ts
|
|
54172
54812
|
import {
|
|
54173
|
-
existsSync as
|
|
54813
|
+
existsSync as existsSync44,
|
|
54174
54814
|
mkdirSync as mkdirSync17,
|
|
54175
54815
|
readdirSync as readdirSync11,
|
|
54176
54816
|
readFileSync as readFileSync23,
|
|
@@ -54188,7 +54828,7 @@ function getCatalogDir() {
|
|
|
54188
54828
|
return join49(getCleoHome11(), "llm-catalog");
|
|
54189
54829
|
}
|
|
54190
54830
|
function findLatestCacheFile(dir) {
|
|
54191
|
-
if (!
|
|
54831
|
+
if (!existsSync44(dir)) return null;
|
|
54192
54832
|
const files = readdirSync11(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync13(join49(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
54193
54833
|
return files.length > 0 ? join49(dir, files[0].name) : null;
|
|
54194
54834
|
}
|