@cleocode/cleo 2026.4.45 → 2026.4.46
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/cli/index.js +108 -100
- package/dist/cli/index.js.map +3 -3
- package/package.json +8 -8
package/dist/cli/index.js
CHANGED
|
@@ -11473,14 +11473,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11473
11473
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
11474
11474
|
const allLocalHashesPresentInDb = localMigrations.every((m2) => dbHashes.has(m2.hash));
|
|
11475
11475
|
if (allLocalHashesPresentInDb) {
|
|
11476
|
-
const
|
|
11477
|
-
|
|
11476
|
+
const log13 = getLogger(logSubsystem);
|
|
11477
|
+
log13.debug(
|
|
11478
11478
|
{ extra: orphanedEntries.length },
|
|
11479
11479
|
`Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
|
|
11480
11480
|
);
|
|
11481
11481
|
} else {
|
|
11482
|
-
const
|
|
11483
|
-
|
|
11482
|
+
const log13 = getLogger(logSubsystem);
|
|
11483
|
+
log13.warn(
|
|
11484
11484
|
{ orphaned: orphanedEntries.length },
|
|
11485
11485
|
`Detected stale migration journal entries from a previous CLEO version. Reconciling.`
|
|
11486
11486
|
);
|
|
@@ -11511,8 +11511,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11511
11511
|
return cols.some((c) => c.name === column);
|
|
11512
11512
|
});
|
|
11513
11513
|
if (allColumnsExist) {
|
|
11514
|
-
const
|
|
11515
|
-
|
|
11514
|
+
const log13 = getLogger(logSubsystem);
|
|
11515
|
+
log13.warn(
|
|
11516
11516
|
{ migration: migration.name, columns: alterMatches },
|
|
11517
11517
|
`Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
|
|
11518
11518
|
);
|
|
@@ -11530,8 +11530,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11530
11530
|
for (const entry of unnamedEntries) {
|
|
11531
11531
|
const migrationName = hashToName.get(entry.hash);
|
|
11532
11532
|
if (!migrationName) continue;
|
|
11533
|
-
const
|
|
11534
|
-
|
|
11533
|
+
const log13 = getLogger(logSubsystem);
|
|
11534
|
+
log13.warn(
|
|
11535
11535
|
{ id: entry.id, hash: entry.hash, name: migrationName },
|
|
11536
11536
|
`Backfilling missing name on journal entry id=${entry.id} \u2014 Drizzle v1 beta requires name for applied-migration detection.`
|
|
11537
11537
|
);
|
|
@@ -11575,8 +11575,8 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem) {
|
|
|
11575
11575
|
const existingCols = new Set(columns.map((c) => c.name));
|
|
11576
11576
|
for (const req of requiredColumns) {
|
|
11577
11577
|
if (!existingCols.has(req.name)) {
|
|
11578
|
-
const
|
|
11579
|
-
|
|
11578
|
+
const log13 = getLogger(logSubsystem);
|
|
11579
|
+
log13.warn(
|
|
11580
11580
|
{ column: req.name },
|
|
11581
11581
|
`Adding missing column ${tableName}.${req.name} via ALTER TABLE`
|
|
11582
11582
|
);
|
|
@@ -13974,7 +13974,7 @@ function getDbPath(cwd) {
|
|
|
13974
13974
|
return join10(getCleoDirAbsolute(cwd), DB_FILENAME2);
|
|
13975
13975
|
}
|
|
13976
13976
|
async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
13977
|
-
const
|
|
13977
|
+
const log13 = getLogger("sqlite");
|
|
13978
13978
|
try {
|
|
13979
13979
|
const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks").get();
|
|
13980
13980
|
const taskCount = countResult?.cnt ?? 0;
|
|
@@ -13995,7 +13995,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
13995
13995
|
if (backupTaskCount < MIN_BACKUP_TASK_COUNT) {
|
|
13996
13996
|
return;
|
|
13997
13997
|
}
|
|
13998
|
-
|
|
13998
|
+
log13.warn(
|
|
13999
13999
|
{ dbPath, backupPath: newestBackup.path, backupTasks: backupTaskCount },
|
|
14000
14000
|
`Empty database detected with ${backupTaskCount}-task backup available. Auto-recovering from backup. This likely happened because git-tracked WAL/SHM files were overwritten during a branch switch (T5188).`
|
|
14001
14001
|
);
|
|
@@ -14013,7 +14013,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
14013
14013
|
const tempPath = dbPath + ".recovery-tmp";
|
|
14014
14014
|
copyFileSync4(newestBackup.path, tempPath);
|
|
14015
14015
|
renameSync(tempPath, dbPath);
|
|
14016
|
-
|
|
14016
|
+
log13.info(
|
|
14017
14017
|
{ dbPath, backupPath: newestBackup.path, restoredTasks: backupTaskCount },
|
|
14018
14018
|
"Database auto-recovered from backup successfully."
|
|
14019
14019
|
);
|
|
@@ -14023,7 +14023,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
14023
14023
|
runMigrations(restoredNativeDb, restoredDb);
|
|
14024
14024
|
_db = restoredDb;
|
|
14025
14025
|
} catch (err) {
|
|
14026
|
-
|
|
14026
|
+
log13.error({ err, dbPath }, "Auto-recovery from backup failed. Continuing with empty database.");
|
|
14027
14027
|
}
|
|
14028
14028
|
}
|
|
14029
14029
|
async function getDb(cwd) {
|
|
@@ -14057,7 +14057,7 @@ async function getDb(cwd) {
|
|
|
14057
14057
|
const { execFileSync: execFileSync19 } = await import("node:child_process");
|
|
14058
14058
|
const gitCwd = resolve3(dbPath, "..", "..");
|
|
14059
14059
|
const filesToCheck = [dbPath, dbPath + "-wal", dbPath + "-shm"];
|
|
14060
|
-
const
|
|
14060
|
+
const log13 = getLogger("sqlite");
|
|
14061
14061
|
for (const fileToCheck of filesToCheck) {
|
|
14062
14062
|
try {
|
|
14063
14063
|
execFileSync19("git", ["ls-files", "--error-unmatch", fileToCheck], {
|
|
@@ -14066,7 +14066,7 @@ async function getDb(cwd) {
|
|
|
14066
14066
|
});
|
|
14067
14067
|
const basename19 = fileToCheck.split(/[\\/]/).pop();
|
|
14068
14068
|
const relPath = fileToCheck.replace(gitCwd + sep, "");
|
|
14069
|
-
|
|
14069
|
+
log13.warn(
|
|
14070
14070
|
{ path: fileToCheck },
|
|
14071
14071
|
`${basename19} is tracked by project git \u2014 this risks data loss on branch switch. Resolution (ADR-013 \xA79): \`git rm --cached ${relPath}\` and rely on \`.cleo/backups/sqlite/\` snapshots + \`cleo backup add\` for recovery.`
|
|
14072
14072
|
);
|
|
@@ -15260,11 +15260,18 @@ var init_cross_db_cleanup = __esm({
|
|
|
15260
15260
|
|
|
15261
15261
|
// packages/core/src/store/db-helpers.ts
|
|
15262
15262
|
import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
|
|
15263
|
-
async function upsertTask(db, row, archiveFields) {
|
|
15263
|
+
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
15264
15264
|
if (row.parentId) {
|
|
15265
15265
|
const parent = await db.select({ id: tasks.id }).from(tasks).where(eq4(tasks.id, row.parentId)).limit(1).all();
|
|
15266
15266
|
if (parent.length === 0) {
|
|
15267
|
-
|
|
15267
|
+
if (allowOrphanParent) {
|
|
15268
|
+
row = { ...row, parentId: null };
|
|
15269
|
+
} else {
|
|
15270
|
+
log2.warn(
|
|
15271
|
+
{ taskId: row.id, parentId: row.parentId },
|
|
15272
|
+
"upsertTask: parentId references a non-existent task \u2014 parent relationship may be lost"
|
|
15273
|
+
);
|
|
15274
|
+
}
|
|
15268
15275
|
}
|
|
15269
15276
|
}
|
|
15270
15277
|
const values = archiveFields ? { ...row, ...archiveFields, status: "archived" } : row;
|
|
@@ -15408,10 +15415,13 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
15408
15415
|
}
|
|
15409
15416
|
}
|
|
15410
15417
|
}
|
|
15418
|
+
var log2;
|
|
15411
15419
|
var init_db_helpers = __esm({
|
|
15412
15420
|
"packages/core/src/store/db-helpers.ts"() {
|
|
15413
15421
|
"use strict";
|
|
15422
|
+
init_logger();
|
|
15414
15423
|
init_tasks_schema();
|
|
15424
|
+
log2 = getLogger("db-helpers");
|
|
15415
15425
|
}
|
|
15416
15426
|
});
|
|
15417
15427
|
|
|
@@ -15745,7 +15755,7 @@ async function createSqliteDataAccessor(cwd) {
|
|
|
15745
15755
|
archiveReason: taskAny.archiveReason ?? "completed",
|
|
15746
15756
|
cycleTimeDays: taskAny.cycleTimeDays ?? null
|
|
15747
15757
|
};
|
|
15748
|
-
await upsertTask(db, row, archiveFields);
|
|
15758
|
+
await upsertTask(db, row, archiveFields, true);
|
|
15749
15759
|
depBatch.push({ taskId: task.id, deps: task.depends ?? [] });
|
|
15750
15760
|
}
|
|
15751
15761
|
await batchUpdateDependencies(db, depBatch, validDepIds);
|
|
@@ -16758,7 +16768,7 @@ async function ensureSequenceValid(cwd, options) {
|
|
|
16758
16768
|
if (!options?.validateSequence) return;
|
|
16759
16769
|
const check2 = await checkSequence(cwd);
|
|
16760
16770
|
if (!check2.valid) {
|
|
16761
|
-
|
|
16771
|
+
log3.warn({ counter: check2.counter, maxId: check2.maxIdInData }, "Sequence behind, repairing");
|
|
16762
16772
|
const repair = await repairSequence(cwd);
|
|
16763
16773
|
if (!repair.repaired && options.strict) {
|
|
16764
16774
|
throw new DataSafetyError(`Sequence repair failed: ${repair.message}`, "SEQUENCE_INVALID", {
|
|
@@ -16775,7 +16785,7 @@ async function checkpoint(context, cwd, options) {
|
|
|
16775
16785
|
stats.checkpoints++;
|
|
16776
16786
|
stats.lastCheckpoint = /* @__PURE__ */ new Date();
|
|
16777
16787
|
} catch (err) {
|
|
16778
|
-
|
|
16788
|
+
log3.warn({ err }, "Checkpoint failed (non-fatal)");
|
|
16779
16789
|
}
|
|
16780
16790
|
vacuumIntoBackup({ cwd }).catch(() => {
|
|
16781
16791
|
});
|
|
@@ -16837,7 +16847,7 @@ async function safeAppendLog(accessor, entry, cwd, options) {
|
|
|
16837
16847
|
stats.writes++;
|
|
16838
16848
|
await checkpoint("log entry", cwd, opts);
|
|
16839
16849
|
}
|
|
16840
|
-
var
|
|
16850
|
+
var log3, DataSafetyError, DEFAULT_SAFETY, stats;
|
|
16841
16851
|
var init_data_safety_central = __esm({
|
|
16842
16852
|
"packages/core/src/store/data-safety-central.ts"() {
|
|
16843
16853
|
"use strict";
|
|
@@ -16845,7 +16855,7 @@ var init_data_safety_central = __esm({
|
|
|
16845
16855
|
init_sequence();
|
|
16846
16856
|
init_git_checkpoint();
|
|
16847
16857
|
init_sqlite_backup();
|
|
16848
|
-
|
|
16858
|
+
log3 = getLogger("data-safety");
|
|
16849
16859
|
DataSafetyError = class extends Error {
|
|
16850
16860
|
constructor(message, code, context) {
|
|
16851
16861
|
super(message);
|
|
@@ -16885,7 +16895,7 @@ function isSafetyDisabled() {
|
|
|
16885
16895
|
}
|
|
16886
16896
|
function wrapWithSafety(accessor, cwd) {
|
|
16887
16897
|
if (isSafetyDisabled()) {
|
|
16888
|
-
|
|
16898
|
+
log4.warn(
|
|
16889
16899
|
"Safety disabled - emergency mode (CLEO_DISABLE_SAFETY=true). Data integrity checks bypassed."
|
|
16890
16900
|
);
|
|
16891
16901
|
return accessor;
|
|
@@ -16906,13 +16916,13 @@ function getSafetyStatus() {
|
|
|
16906
16916
|
enabled: true
|
|
16907
16917
|
};
|
|
16908
16918
|
}
|
|
16909
|
-
var
|
|
16919
|
+
var log4, SafetyDataAccessor;
|
|
16910
16920
|
var init_safety_data_accessor = __esm({
|
|
16911
16921
|
"packages/core/src/store/safety-data-accessor.ts"() {
|
|
16912
16922
|
"use strict";
|
|
16913
16923
|
init_logger();
|
|
16914
16924
|
init_data_safety_central();
|
|
16915
|
-
|
|
16925
|
+
log4 = getLogger("data-safety");
|
|
16916
16926
|
SafetyDataAccessor = class {
|
|
16917
16927
|
/** The underlying accessor being wrapped. */
|
|
16918
16928
|
inner;
|
|
@@ -16936,7 +16946,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16936
16946
|
...config2
|
|
16937
16947
|
};
|
|
16938
16948
|
if (this.config.verbose) {
|
|
16939
|
-
|
|
16949
|
+
log4.debug({ engine: inner.engine }, "SafetyDataAccessor initialized");
|
|
16940
16950
|
}
|
|
16941
16951
|
}
|
|
16942
16952
|
/** The storage engine backing this accessor. */
|
|
@@ -16948,7 +16958,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16948
16958
|
*/
|
|
16949
16959
|
logVerbose(message) {
|
|
16950
16960
|
if (this.config.verbose) {
|
|
16951
|
-
|
|
16961
|
+
log4.debug(message);
|
|
16952
16962
|
}
|
|
16953
16963
|
}
|
|
16954
16964
|
/**
|
|
@@ -24069,16 +24079,16 @@ async function queryAudit(options) {
|
|
|
24069
24079
|
error: row.errorMessage ?? void 0
|
|
24070
24080
|
}));
|
|
24071
24081
|
} catch (err) {
|
|
24072
|
-
|
|
24082
|
+
log5.warn({ err }, "Failed to query audit entries from SQLite");
|
|
24073
24083
|
return [];
|
|
24074
24084
|
}
|
|
24075
24085
|
}
|
|
24076
|
-
var
|
|
24086
|
+
var log5;
|
|
24077
24087
|
var init_audit = __esm({
|
|
24078
24088
|
"packages/core/src/audit.ts"() {
|
|
24079
24089
|
"use strict";
|
|
24080
24090
|
init_logger();
|
|
24081
|
-
|
|
24091
|
+
log5 = getLogger("audit");
|
|
24082
24092
|
}
|
|
24083
24093
|
});
|
|
24084
24094
|
|
|
@@ -57107,7 +57117,7 @@ async function recordEvidence(epicId, stage, uri, type, options) {
|
|
|
57107
57117
|
description: options?.description ?? null
|
|
57108
57118
|
}).run();
|
|
57109
57119
|
} catch (err) {
|
|
57110
|
-
|
|
57120
|
+
log6.warn({ err }, "Failed to write evidence to SQLite");
|
|
57111
57121
|
}
|
|
57112
57122
|
return record2;
|
|
57113
57123
|
}
|
|
@@ -57120,14 +57130,14 @@ async function linkProvenance(epicId, stage, filePath, cwd) {
|
|
|
57120
57130
|
cwd
|
|
57121
57131
|
});
|
|
57122
57132
|
}
|
|
57123
|
-
var
|
|
57133
|
+
var log6;
|
|
57124
57134
|
var init_evidence = __esm({
|
|
57125
57135
|
"packages/core/src/lifecycle/evidence.ts"() {
|
|
57126
57136
|
"use strict";
|
|
57127
57137
|
init_logger();
|
|
57128
57138
|
init_paths();
|
|
57129
57139
|
init_tasks_schema();
|
|
57130
|
-
|
|
57140
|
+
log6 = getLogger("lifecycle:evidence");
|
|
57131
57141
|
}
|
|
57132
57142
|
});
|
|
57133
57143
|
|
|
@@ -65581,7 +65591,7 @@ async function ensureExternalTaskLinksTable(cwd) {
|
|
|
65581
65591
|
)
|
|
65582
65592
|
);
|
|
65583
65593
|
} catch (err) {
|
|
65584
|
-
|
|
65594
|
+
log7.warn({ err }, "Failed to ensure external_task_links table exists");
|
|
65585
65595
|
throw err;
|
|
65586
65596
|
}
|
|
65587
65597
|
}
|
|
@@ -65649,14 +65659,14 @@ function rowToLink(row) {
|
|
|
65649
65659
|
lastSyncAt: row.lastSyncAt
|
|
65650
65660
|
};
|
|
65651
65661
|
}
|
|
65652
|
-
var
|
|
65662
|
+
var log7;
|
|
65653
65663
|
var init_link_store = __esm({
|
|
65654
65664
|
"packages/core/src/reconciliation/link-store.ts"() {
|
|
65655
65665
|
"use strict";
|
|
65656
65666
|
init_logger();
|
|
65657
65667
|
init_sqlite2();
|
|
65658
65668
|
init_tasks_schema();
|
|
65659
|
-
|
|
65669
|
+
log7 = getLogger("link-store");
|
|
65660
65670
|
}
|
|
65661
65671
|
});
|
|
65662
65672
|
|
|
@@ -65802,7 +65812,7 @@ async function executeTransferInternal(params) {
|
|
|
65802
65812
|
}
|
|
65803
65813
|
}
|
|
65804
65814
|
} catch (err) {
|
|
65805
|
-
|
|
65815
|
+
log8.warn(
|
|
65806
65816
|
{ err, linksCreated },
|
|
65807
65817
|
"Failed to create external_task_links during transfer \u2014 tasks were transferred successfully but provenance links could not be written"
|
|
65808
65818
|
);
|
|
@@ -65830,7 +65840,7 @@ async function executeTransferInternal(params) {
|
|
|
65830
65840
|
})
|
|
65831
65841
|
});
|
|
65832
65842
|
} catch (err) {
|
|
65833
|
-
|
|
65843
|
+
log8.warn({ err }, "nexus transfer audit write failed");
|
|
65834
65844
|
}
|
|
65835
65845
|
if (mode === "move") {
|
|
65836
65846
|
let archived = 0;
|
|
@@ -65843,7 +65853,7 @@ async function executeTransferInternal(params) {
|
|
|
65843
65853
|
});
|
|
65844
65854
|
archived++;
|
|
65845
65855
|
} catch (err) {
|
|
65846
|
-
|
|
65856
|
+
log8.warn({ err, taskId: entry.sourceId }, "failed to archive source task after transfer");
|
|
65847
65857
|
}
|
|
65848
65858
|
}
|
|
65849
65859
|
}
|
|
@@ -65881,14 +65891,14 @@ async function executeTransferInternal(params) {
|
|
|
65881
65891
|
}
|
|
65882
65892
|
}
|
|
65883
65893
|
} catch (err) {
|
|
65884
|
-
|
|
65894
|
+
log8.warn({ err }, "brain observation transfer failed");
|
|
65885
65895
|
}
|
|
65886
65896
|
result.brainObservationsTransferred = brainTransferred;
|
|
65887
65897
|
result.manifest.brainObservationsTransferred = brainTransferred;
|
|
65888
65898
|
}
|
|
65889
65899
|
return result;
|
|
65890
65900
|
}
|
|
65891
|
-
var
|
|
65901
|
+
var log8;
|
|
65892
65902
|
var init_transfer = __esm({
|
|
65893
65903
|
"packages/core/src/nexus/transfer.ts"() {
|
|
65894
65904
|
"use strict";
|
|
@@ -65901,7 +65911,7 @@ var init_transfer = __esm({
|
|
|
65901
65911
|
init_export2();
|
|
65902
65912
|
init_permissions();
|
|
65903
65913
|
init_registry3();
|
|
65904
|
-
|
|
65914
|
+
log8 = getLogger("nexus:transfer");
|
|
65905
65915
|
}
|
|
65906
65916
|
});
|
|
65907
65917
|
|
|
@@ -66182,9 +66192,7 @@ async function completeTask(options, cwd, accessor) {
|
|
|
66182
66192
|
const parent = await acc.loadSingleTask(task.parentId);
|
|
66183
66193
|
if (parent && parent.type === "epic" && !parent.noAutoComplete) {
|
|
66184
66194
|
const siblings = await acc.getChildren(parent.id);
|
|
66185
|
-
const allDone = siblings.every(
|
|
66186
|
-
(c) => c.id === task.id || c.status === "done" || c.status === "cancelled"
|
|
66187
|
-
);
|
|
66195
|
+
const allDone = siblings.length > 0 && siblings.every((c) => c.id === task.id || c.status === "done" || c.status === "cancelled");
|
|
66188
66196
|
if (allDone) {
|
|
66189
66197
|
parent.status = "done";
|
|
66190
66198
|
parent.completedAt = now2;
|
|
@@ -66843,8 +66851,8 @@ async function loadProjectACL(projectPath) {
|
|
|
66843
66851
|
async function logAclFailure(projectPath) {
|
|
66844
66852
|
try {
|
|
66845
66853
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
66846
|
-
const
|
|
66847
|
-
|
|
66854
|
+
const log13 = getLogger2("nexus.acl");
|
|
66855
|
+
log13.warn({ projectPath }, "Failed to load ACL configuration, defaulting to deny-all");
|
|
66848
66856
|
} catch {
|
|
66849
66857
|
}
|
|
66850
66858
|
}
|
|
@@ -66989,9 +66997,9 @@ async function executeOperation(operation, taskId, projectPath, accessor, direct
|
|
|
66989
66997
|
async function logRouteAudit(directive, projectName, taskId, operation, success2, error48) {
|
|
66990
66998
|
try {
|
|
66991
66999
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
66992
|
-
const
|
|
67000
|
+
const log13 = getLogger2("nexus.route");
|
|
66993
67001
|
const level = success2 ? "info" : "warn";
|
|
66994
|
-
|
|
67002
|
+
log13[level](
|
|
66995
67003
|
{
|
|
66996
67004
|
directive: directive.verb,
|
|
66997
67005
|
agentId: directive.agentId,
|
|
@@ -76084,7 +76092,7 @@ async function queryTasks(cwd, since) {
|
|
|
76084
76092
|
}).from(tasks2).where(conditions.length > 0 ? and14(...conditions) : void 0).all();
|
|
76085
76093
|
return rows;
|
|
76086
76094
|
} catch (err) {
|
|
76087
|
-
|
|
76095
|
+
log9.warn({ err }, "Failed to query tasks for workflow telemetry");
|
|
76088
76096
|
return [];
|
|
76089
76097
|
}
|
|
76090
76098
|
}
|
|
@@ -76118,7 +76126,7 @@ async function queryCompletionAuditRows(cwd, since) {
|
|
|
76118
76126
|
return isComplete;
|
|
76119
76127
|
});
|
|
76120
76128
|
} catch (err) {
|
|
76121
|
-
|
|
76129
|
+
log9.warn({ err }, "Failed to query audit log for workflow telemetry");
|
|
76122
76130
|
return [];
|
|
76123
76131
|
}
|
|
76124
76132
|
}
|
|
@@ -76343,12 +76351,12 @@ async function getWorkflowComplianceReport(opts) {
|
|
|
76343
76351
|
}
|
|
76344
76352
|
};
|
|
76345
76353
|
}
|
|
76346
|
-
var
|
|
76354
|
+
var log9;
|
|
76347
76355
|
var init_workflow_telemetry = __esm({
|
|
76348
76356
|
"packages/core/src/stats/workflow-telemetry.ts"() {
|
|
76349
76357
|
"use strict";
|
|
76350
76358
|
init_logger();
|
|
76351
|
-
|
|
76359
|
+
log9 = getLogger("workflow-telemetry");
|
|
76352
76360
|
}
|
|
76353
76361
|
});
|
|
76354
76362
|
|
|
@@ -77665,7 +77673,7 @@ import { createGzip } from "node:zlib";
|
|
|
77665
77673
|
async function pruneAuditLog(cleoDir, config2) {
|
|
77666
77674
|
try {
|
|
77667
77675
|
if (!config2.auditRetentionDays || config2.auditRetentionDays <= 0) {
|
|
77668
|
-
|
|
77676
|
+
log10.debug("auditRetentionDays is 0 or unset; skipping audit prune");
|
|
77669
77677
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
77670
77678
|
}
|
|
77671
77679
|
const cutoff = new Date(Date.now() - config2.auditRetentionDays * 864e5).toISOString();
|
|
@@ -77676,7 +77684,7 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
77676
77684
|
const db = await getDb4(projectRoot);
|
|
77677
77685
|
const oldRows = await db.select().from(auditLog2).where(lt4(auditLog2.timestamp, cutoff));
|
|
77678
77686
|
if (oldRows.length === 0) {
|
|
77679
|
-
|
|
77687
|
+
log10.debug("No audit_log rows older than cutoff; nothing to prune");
|
|
77680
77688
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
77681
77689
|
}
|
|
77682
77690
|
let archivePath;
|
|
@@ -77694,17 +77702,17 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
77694
77702
|
const inStream = Readable.from([jsonlContent]);
|
|
77695
77703
|
await pipeline(inStream, gzip, outStream);
|
|
77696
77704
|
rowsArchived = oldRows.length;
|
|
77697
|
-
|
|
77705
|
+
log10.info(
|
|
77698
77706
|
{ archivePath, rowsArchived },
|
|
77699
77707
|
`Archived ${rowsArchived} audit rows to ${archivePath}`
|
|
77700
77708
|
);
|
|
77701
77709
|
} catch (archiveErr) {
|
|
77702
|
-
|
|
77710
|
+
log10.warn({ err: archiveErr }, "Failed to archive audit rows; continuing with deletion");
|
|
77703
77711
|
archivePath = void 0;
|
|
77704
77712
|
}
|
|
77705
77713
|
}
|
|
77706
77714
|
await db.delete(auditLog2).where(lt4(auditLog2.timestamp, cutoff)).run();
|
|
77707
|
-
|
|
77715
|
+
log10.info(
|
|
77708
77716
|
{ rowsDeleted: oldRows.length, cutoff },
|
|
77709
77717
|
`Pruned ${oldRows.length} audit_log rows older than ${cutoff}`
|
|
77710
77718
|
);
|
|
@@ -77714,16 +77722,16 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
77714
77722
|
archivePath
|
|
77715
77723
|
};
|
|
77716
77724
|
} catch (err) {
|
|
77717
|
-
|
|
77725
|
+
log10.warn({ err }, "audit log pruning failed");
|
|
77718
77726
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
77719
77727
|
}
|
|
77720
77728
|
}
|
|
77721
|
-
var
|
|
77729
|
+
var log10;
|
|
77722
77730
|
var init_audit_prune = __esm({
|
|
77723
77731
|
"packages/core/src/audit-prune.ts"() {
|
|
77724
77732
|
"use strict";
|
|
77725
77733
|
init_logger();
|
|
77726
|
-
|
|
77734
|
+
log10 = getLogger("prune");
|
|
77727
77735
|
}
|
|
77728
77736
|
});
|
|
77729
77737
|
|
|
@@ -96752,7 +96760,7 @@ var init_backup_pack = __esm({
|
|
|
96752
96760
|
import fs5 from "node:fs";
|
|
96753
96761
|
import path5 from "node:path";
|
|
96754
96762
|
function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
|
|
96755
|
-
const
|
|
96763
|
+
const log13 = getLogger("cleanup-legacy");
|
|
96756
96764
|
const cleoHome = cleoHomeOverride ?? getCleoHome();
|
|
96757
96765
|
const removed = [];
|
|
96758
96766
|
const errors = [];
|
|
@@ -96762,30 +96770,30 @@ function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
|
|
|
96762
96770
|
if (fs5.existsSync(fullPath)) {
|
|
96763
96771
|
fs5.unlinkSync(fullPath);
|
|
96764
96772
|
removed.push(fileName);
|
|
96765
|
-
|
|
96773
|
+
log13.info({ file: fullPath }, "Removed legacy global file");
|
|
96766
96774
|
}
|
|
96767
96775
|
} catch (err) {
|
|
96768
96776
|
const message = err instanceof Error ? err.message : String(err);
|
|
96769
96777
|
errors.push({ file: fileName, error: message });
|
|
96770
|
-
|
|
96778
|
+
log13.warn({ file: fullPath, error: message }, "Failed to remove legacy global file");
|
|
96771
96779
|
}
|
|
96772
96780
|
}
|
|
96773
96781
|
return { removed, errors };
|
|
96774
96782
|
}
|
|
96775
96783
|
function detectAndRemoveStrayProjectNexus(projectRoot) {
|
|
96776
|
-
const
|
|
96784
|
+
const log13 = getLogger("cleanup-legacy");
|
|
96777
96785
|
const strayPath = path5.join(projectRoot, ".cleo", "nexus.db");
|
|
96778
96786
|
if (fs5.existsSync(strayPath)) {
|
|
96779
96787
|
try {
|
|
96780
96788
|
fs5.unlinkSync(strayPath);
|
|
96781
|
-
|
|
96789
|
+
log13.warn(
|
|
96782
96790
|
{ path: strayPath },
|
|
96783
96791
|
"Removed stray project-tier nexus.db (violates ADR-036 global-only contract)"
|
|
96784
96792
|
);
|
|
96785
96793
|
return { removed: true, path: strayPath };
|
|
96786
96794
|
} catch (err) {
|
|
96787
96795
|
const message = err instanceof Error ? err.message : String(err);
|
|
96788
|
-
|
|
96796
|
+
log13.warn(
|
|
96789
96797
|
{ path: strayPath, error: message },
|
|
96790
96798
|
"Failed to remove stray project-tier nexus.db \u2014 manual deletion may be required"
|
|
96791
96799
|
);
|
|
@@ -96856,7 +96864,7 @@ function brokenTimestamp() {
|
|
|
96856
96864
|
return `${now2.getFullYear()}${pad2(now2.getMonth() + 1)}${pad2(now2.getDate())}-${pad2(now2.getHours())}${pad2(now2.getMinutes())}${pad2(now2.getSeconds())}-${pad3(now2.getMilliseconds())}`;
|
|
96857
96865
|
}
|
|
96858
96866
|
function migrateSignaldockToConduit(projectRoot) {
|
|
96859
|
-
const
|
|
96867
|
+
const log13 = getLogger("migrate-signaldock-to-conduit");
|
|
96860
96868
|
const legacyPath = join113(projectRoot, ".cleo", "signaldock.db");
|
|
96861
96869
|
const conduitPath = join113(projectRoot, ".cleo", "conduit.db");
|
|
96862
96870
|
const globalSignaldockPath = join113(getCleoHome(), "signaldock.db");
|
|
@@ -96873,13 +96881,13 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96873
96881
|
if (!needsSignaldockToConduitMigration(projectRoot)) {
|
|
96874
96882
|
return result;
|
|
96875
96883
|
}
|
|
96876
|
-
|
|
96884
|
+
log13.info({ projectRoot, legacyPath }, "T310 migration: starting signaldock.db \u2192 conduit.db");
|
|
96877
96885
|
let legacy = null;
|
|
96878
96886
|
try {
|
|
96879
96887
|
legacy = new DatabaseSync7(legacyPath, { readOnly: true });
|
|
96880
96888
|
} catch (err) {
|
|
96881
96889
|
const message = err instanceof Error ? err.message : String(err);
|
|
96882
|
-
|
|
96890
|
+
log13.error({ legacyPath, error: message }, "T310 migration: cannot open legacy signaldock.db");
|
|
96883
96891
|
result.errors.push({ step: "step-2-open-legacy", error: message });
|
|
96884
96892
|
result.status = "failed";
|
|
96885
96893
|
return result;
|
|
@@ -96887,7 +96895,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96887
96895
|
try {
|
|
96888
96896
|
if (!integrityCheckPasses(legacy)) {
|
|
96889
96897
|
const msg = "Legacy signaldock.db failed PRAGMA integrity_check. Migration aborted \u2014 no changes written. Recovery: inspect the database with sqlite3 and attempt manual repair before re-running.";
|
|
96890
|
-
|
|
96898
|
+
log13.error({ legacyPath }, msg);
|
|
96891
96899
|
result.errors.push({ step: "step-3-legacy-integrity", error: msg });
|
|
96892
96900
|
result.status = "failed";
|
|
96893
96901
|
legacy.close();
|
|
@@ -96895,7 +96903,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96895
96903
|
}
|
|
96896
96904
|
} catch (err) {
|
|
96897
96905
|
const message = err instanceof Error ? err.message : String(err);
|
|
96898
|
-
|
|
96906
|
+
log13.error({ legacyPath, error: message }, "T310 migration: integrity_check threw on legacy DB");
|
|
96899
96907
|
result.errors.push({ step: "step-3-legacy-integrity", error: message });
|
|
96900
96908
|
result.status = "failed";
|
|
96901
96909
|
legacy.close();
|
|
@@ -96913,7 +96921,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96913
96921
|
getGlobalSalt();
|
|
96914
96922
|
} catch (err) {
|
|
96915
96923
|
const message = err instanceof Error ? err.message : String(err);
|
|
96916
|
-
|
|
96924
|
+
log13.error({ error: message }, "T310 migration: getGlobalSalt failed \u2014 migration aborted");
|
|
96917
96925
|
result.errors.push({ step: "step-6-global-salt", error: message });
|
|
96918
96926
|
result.status = "failed";
|
|
96919
96927
|
legacy.close();
|
|
@@ -96927,7 +96935,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96927
96935
|
conduit.exec("PRAGMA foreign_keys = OFF");
|
|
96928
96936
|
} catch (err) {
|
|
96929
96937
|
const message = err instanceof Error ? err.message : String(err);
|
|
96930
|
-
|
|
96938
|
+
log13.error({ conduitPath, error: message }, "T310 migration: failed to create conduit.db");
|
|
96931
96939
|
result.errors.push({ step: "step-7-create-conduit", error: message });
|
|
96932
96940
|
result.status = "failed";
|
|
96933
96941
|
legacy.close();
|
|
@@ -96973,7 +96981,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96973
96981
|
result.agentsCopied = agentsCountForConduit;
|
|
96974
96982
|
} catch (err) {
|
|
96975
96983
|
const message = err instanceof Error ? err.message : String(err);
|
|
96976
|
-
|
|
96984
|
+
log13.error({ error: message }, "T310 migration: conduit.db write failed \u2014 rolling back");
|
|
96977
96985
|
result.errors.push({ step: "step-8-conduit-write", error: message });
|
|
96978
96986
|
result.status = "failed";
|
|
96979
96987
|
try {
|
|
@@ -96994,7 +97002,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
96994
97002
|
try {
|
|
96995
97003
|
if (!integrityCheckPasses(conduit)) {
|
|
96996
97004
|
const msg = "conduit.db failed PRAGMA integrity_check after write";
|
|
96997
|
-
|
|
97005
|
+
log13.error({ conduitPath }, msg);
|
|
96998
97006
|
result.errors.push({ step: "step-10-conduit-integrity", error: msg });
|
|
96999
97007
|
result.status = "failed";
|
|
97000
97008
|
conduit.close();
|
|
@@ -97009,7 +97017,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97009
97017
|
}
|
|
97010
97018
|
} catch (err) {
|
|
97011
97019
|
const message = err instanceof Error ? err.message : String(err);
|
|
97012
|
-
|
|
97020
|
+
log13.error({ error: message }, "T310 migration: conduit.db integrity_check threw");
|
|
97013
97021
|
result.errors.push({ step: "step-10-conduit-integrity", error: message });
|
|
97014
97022
|
result.status = "failed";
|
|
97015
97023
|
if (conduit) {
|
|
@@ -97031,7 +97039,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97031
97039
|
globalDb.exec("PRAGMA foreign_keys = OFF");
|
|
97032
97040
|
} catch (err) {
|
|
97033
97041
|
const message = err instanceof Error ? err.message : String(err);
|
|
97034
|
-
|
|
97042
|
+
log13.error(
|
|
97035
97043
|
{ globalSignaldockPath, error: message },
|
|
97036
97044
|
"T310 migration: cannot open global signaldock.db"
|
|
97037
97045
|
);
|
|
@@ -97070,7 +97078,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97070
97078
|
result.agentsCopied = agentsCopiedToGlobal;
|
|
97071
97079
|
} catch (err) {
|
|
97072
97080
|
const message = err instanceof Error ? err.message : String(err);
|
|
97073
|
-
|
|
97081
|
+
log13.error(
|
|
97074
97082
|
{ error: message },
|
|
97075
97083
|
"T310 migration: global signaldock.db write failed \u2014 rolling back"
|
|
97076
97084
|
);
|
|
@@ -97088,7 +97096,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97088
97096
|
try {
|
|
97089
97097
|
if (!integrityCheckPasses(globalDb)) {
|
|
97090
97098
|
const msg = "Global signaldock.db failed PRAGMA integrity_check after write";
|
|
97091
|
-
|
|
97099
|
+
log13.error({ globalSignaldockPath }, msg);
|
|
97092
97100
|
result.errors.push({ step: "step-14-global-integrity", error: msg });
|
|
97093
97101
|
result.status = "failed";
|
|
97094
97102
|
globalDb.close();
|
|
@@ -97103,7 +97111,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97103
97111
|
}
|
|
97104
97112
|
} catch (err) {
|
|
97105
97113
|
const message = err instanceof Error ? err.message : String(err);
|
|
97106
|
-
|
|
97114
|
+
log13.error({ error: message }, "T310 migration: global signaldock.db integrity_check threw");
|
|
97107
97115
|
result.errors.push({ step: "step-14-global-integrity", error: message });
|
|
97108
97116
|
result.status = "failed";
|
|
97109
97117
|
if (globalDb) {
|
|
@@ -97122,21 +97130,21 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
97122
97130
|
result.bakPath = bakPath;
|
|
97123
97131
|
} catch (err) {
|
|
97124
97132
|
const message = err instanceof Error ? err.message : String(err);
|
|
97125
|
-
|
|
97133
|
+
log13.error(
|
|
97126
97134
|
{ legacyPath, bakPath, error: message },
|
|
97127
97135
|
"T310 migration: rename to .pre-t310.bak failed \u2014 legacy file left in place (harmless)"
|
|
97128
97136
|
);
|
|
97129
97137
|
result.errors.push({ step: "step-16-rename-bak", error: message });
|
|
97130
97138
|
}
|
|
97131
|
-
|
|
97139
|
+
log13.info(
|
|
97132
97140
|
{ projectRoot, agentsCopied: result.agentsCopied, conduitPath, bakPath: result.bakPath },
|
|
97133
97141
|
`T310 migration complete: ${result.agentsCopied} agents migrated to global, conduit.db created`
|
|
97134
97142
|
);
|
|
97135
|
-
|
|
97143
|
+
log13.warn(
|
|
97136
97144
|
{},
|
|
97137
97145
|
"T310 migration: API keys have been re-keyed. External systems holding old API keys (CI env vars, remote agent configs) must be updated."
|
|
97138
97146
|
);
|
|
97139
|
-
|
|
97147
|
+
log13.info(
|
|
97140
97148
|
{ legacyPath, bakPath: result.bakPath, conduitPath },
|
|
97141
97149
|
"T310 migration recovery: if problems occur, rename .pre-t310.bak to signaldock.db and delete conduit.db to re-run migration."
|
|
97142
97150
|
);
|
|
@@ -97370,7 +97378,7 @@ async function validateAndRepairSequence(cwd, config2 = {}) {
|
|
|
97370
97378
|
}
|
|
97371
97379
|
const repair = await repairSequence(cwd);
|
|
97372
97380
|
if (repair.repaired) {
|
|
97373
|
-
|
|
97381
|
+
log11.warn(
|
|
97374
97382
|
{ oldCounter: repair.oldCounter, newCounter: repair.newCounter },
|
|
97375
97383
|
"Sequence repaired"
|
|
97376
97384
|
);
|
|
@@ -97399,7 +97407,7 @@ async function triggerCheckpoint(context, cwd, config2 = {}) {
|
|
|
97399
97407
|
try {
|
|
97400
97408
|
await gitCheckpoint("auto", context, cwd);
|
|
97401
97409
|
} catch (err) {
|
|
97402
|
-
|
|
97410
|
+
log11.warn({ err }, "Checkpoint failed (non-fatal)");
|
|
97403
97411
|
}
|
|
97404
97412
|
vacuumIntoBackup({ cwd }).catch(() => {
|
|
97405
97413
|
});
|
|
@@ -97437,16 +97445,16 @@ async function safeDeleteTask(deleteFn, taskId, cwd, config2 = {}) {
|
|
|
97437
97445
|
return result;
|
|
97438
97446
|
}
|
|
97439
97447
|
async function forceCheckpointBeforeOperation(operation, cwd) {
|
|
97440
|
-
|
|
97448
|
+
log11.info({ operation }, "Forcing checkpoint before operation");
|
|
97441
97449
|
try {
|
|
97442
97450
|
await gitCheckpoint("manual", `pre-${operation}`, cwd);
|
|
97443
97451
|
} catch (err) {
|
|
97444
|
-
|
|
97452
|
+
log11.error({ err }, "Failed to create pre-operation checkpoint");
|
|
97445
97453
|
}
|
|
97446
97454
|
vacuumIntoBackup({ cwd, force: true }).catch(() => {
|
|
97447
97455
|
});
|
|
97448
97456
|
}
|
|
97449
|
-
var
|
|
97457
|
+
var log11, DEFAULT_CONFIG2, SafetyError;
|
|
97450
97458
|
var init_data_safety = __esm({
|
|
97451
97459
|
"packages/core/src/store/data-safety.ts"() {
|
|
97452
97460
|
"use strict";
|
|
@@ -97456,7 +97464,7 @@ var init_data_safety = __esm({
|
|
|
97456
97464
|
init_sqlite2();
|
|
97457
97465
|
init_sqlite_backup();
|
|
97458
97466
|
init_tasks_schema();
|
|
97459
|
-
|
|
97467
|
+
log11 = getLogger("data-safety");
|
|
97460
97468
|
DEFAULT_CONFIG2 = {
|
|
97461
97469
|
verifyWrites: true,
|
|
97462
97470
|
detectCollisions: true,
|
|
@@ -107330,11 +107338,11 @@ var require_core = __commonJS({
|
|
|
107330
107338
|
Ajv4.ValidationError = validation_error_1.default;
|
|
107331
107339
|
Ajv4.MissingRefError = ref_error_1.default;
|
|
107332
107340
|
exports.default = Ajv4;
|
|
107333
|
-
function checkOptions(checkOpts, options, msg,
|
|
107341
|
+
function checkOptions(checkOpts, options, msg, log13 = "error") {
|
|
107334
107342
|
for (const key in checkOpts) {
|
|
107335
107343
|
const opt = key;
|
|
107336
107344
|
if (opt in options)
|
|
107337
|
-
this.logger[
|
|
107345
|
+
this.logger[log13](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
107338
107346
|
}
|
|
107339
107347
|
}
|
|
107340
107348
|
function getSchEnv(keyRef) {
|
|
@@ -130134,7 +130142,7 @@ async function writeToSqlite(entry, requestId) {
|
|
|
130134
130142
|
};
|
|
130135
130143
|
const parsed = AuditLogInsertSchema2.safeParse(payload);
|
|
130136
130144
|
if (!parsed.success) {
|
|
130137
|
-
|
|
130145
|
+
log12.warn(
|
|
130138
130146
|
{ issues: parsed.error.issues },
|
|
130139
130147
|
"Audit payload failed Zod validation; skipping insert"
|
|
130140
130148
|
);
|
|
@@ -130143,7 +130151,7 @@ async function writeToSqlite(entry, requestId) {
|
|
|
130143
130151
|
const db = await getDb4(process.cwd());
|
|
130144
130152
|
await db.insert(auditLog2).values(parsed.data).run();
|
|
130145
130153
|
} catch (err) {
|
|
130146
|
-
|
|
130154
|
+
log12.warn({ err }, "Failed to write audit entry to SQLite");
|
|
130147
130155
|
}
|
|
130148
130156
|
}
|
|
130149
130157
|
function createAudit() {
|
|
@@ -130174,7 +130182,7 @@ function createAudit() {
|
|
|
130174
130182
|
},
|
|
130175
130183
|
error: response.error?.message
|
|
130176
130184
|
};
|
|
130177
|
-
|
|
130185
|
+
log12.info(
|
|
130178
130186
|
{
|
|
130179
130187
|
domain: entry.domain,
|
|
130180
130188
|
operation: entry.operation,
|
|
@@ -130191,20 +130199,20 @@ function createAudit() {
|
|
|
130191
130199
|
await writeToSqlite(entry, req.requestId);
|
|
130192
130200
|
} else {
|
|
130193
130201
|
writeToSqlite(entry, req.requestId).catch((err) => {
|
|
130194
|
-
|
|
130202
|
+
log12.error({ err }, "Failed to persist audit entry to SQLite");
|
|
130195
130203
|
});
|
|
130196
130204
|
}
|
|
130197
130205
|
return response;
|
|
130198
130206
|
};
|
|
130199
130207
|
}
|
|
130200
|
-
var
|
|
130208
|
+
var log12, cachedProjectHash;
|
|
130201
130209
|
var init_audit3 = __esm({
|
|
130202
130210
|
"packages/cleo/src/dispatch/middleware/audit.ts"() {
|
|
130203
130211
|
"use strict";
|
|
130204
130212
|
init_internal();
|
|
130205
130213
|
init_config3();
|
|
130206
130214
|
init_internal();
|
|
130207
|
-
|
|
130215
|
+
log12 = getLogger("audit");
|
|
130208
130216
|
}
|
|
130209
130217
|
});
|
|
130210
130218
|
|