@cleocode/core 2026.4.45 → 2026.4.47
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/index.js +84 -77
- package/dist/index.js.map +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +128 -109
- package/dist/internal.js.map +3 -3
- package/dist/memory/brain-lifecycle.d.ts +13 -6
- package/dist/memory/brain-lifecycle.d.ts.map +1 -1
- package/dist/memory/brain-maintenance.d.ts +11 -0
- package/dist/memory/brain-maintenance.d.ts.map +1 -1
- package/dist/store/db-helpers.d.ts +8 -3
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/package.json +18 -8
- package/src/internal.ts +16 -3
- package/src/memory/__tests__/brain-automation.test.ts +1 -0
- package/src/memory/__tests__/brain-lifecycle-tier-promotion.test.ts +367 -0
- package/src/memory/brain-lifecycle.ts +43 -32
- package/src/memory/brain-maintenance.ts +27 -2
- package/src/store/__tests__/db-helpers.test.ts +46 -6
- package/src/store/db-helpers.ts +25 -4
- package/src/store/sqlite-data-accessor.ts +2 -1
- package/src/tasks/__tests__/epic-auto-complete.test.ts +331 -0
- package/src/tasks/complete.ts +7 -4
package/dist/index.js
CHANGED
|
@@ -11448,14 +11448,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11448
11448
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
11449
11449
|
const allLocalHashesPresentInDb = localMigrations.every((m) => dbHashes.has(m.hash));
|
|
11450
11450
|
if (allLocalHashesPresentInDb) {
|
|
11451
|
-
const
|
|
11452
|
-
|
|
11451
|
+
const log11 = getLogger(logSubsystem);
|
|
11452
|
+
log11.debug(
|
|
11453
11453
|
{ extra: orphanedEntries.length },
|
|
11454
11454
|
`Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
|
|
11455
11455
|
);
|
|
11456
11456
|
} else {
|
|
11457
|
-
const
|
|
11458
|
-
|
|
11457
|
+
const log11 = getLogger(logSubsystem);
|
|
11458
|
+
log11.warn(
|
|
11459
11459
|
{ orphaned: orphanedEntries.length },
|
|
11460
11460
|
`Detected stale migration journal entries from a previous CLEO version. Reconciling.`
|
|
11461
11461
|
);
|
|
@@ -11486,8 +11486,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11486
11486
|
return cols.some((c) => c.name === column);
|
|
11487
11487
|
});
|
|
11488
11488
|
if (allColumnsExist) {
|
|
11489
|
-
const
|
|
11490
|
-
|
|
11489
|
+
const log11 = getLogger(logSubsystem);
|
|
11490
|
+
log11.warn(
|
|
11491
11491
|
{ migration: migration.name, columns: alterMatches },
|
|
11492
11492
|
`Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
|
|
11493
11493
|
);
|
|
@@ -11505,8 +11505,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11505
11505
|
for (const entry of unnamedEntries) {
|
|
11506
11506
|
const migrationName = hashToName.get(entry.hash);
|
|
11507
11507
|
if (!migrationName) continue;
|
|
11508
|
-
const
|
|
11509
|
-
|
|
11508
|
+
const log11 = getLogger(logSubsystem);
|
|
11509
|
+
log11.warn(
|
|
11510
11510
|
{ id: entry.id, hash: entry.hash, name: migrationName },
|
|
11511
11511
|
`Backfilling missing name on journal entry id=${entry.id} \u2014 Drizzle v1 beta requires name for applied-migration detection.`
|
|
11512
11512
|
);
|
|
@@ -11550,8 +11550,8 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem) {
|
|
|
11550
11550
|
const existingCols = new Set(columns.map((c) => c.name));
|
|
11551
11551
|
for (const req of requiredColumns) {
|
|
11552
11552
|
if (!existingCols.has(req.name)) {
|
|
11553
|
-
const
|
|
11554
|
-
|
|
11553
|
+
const log11 = getLogger(logSubsystem);
|
|
11554
|
+
log11.warn(
|
|
11555
11555
|
{ column: req.name },
|
|
11556
11556
|
`Adding missing column ${tableName}.${req.name} via ALTER TABLE`
|
|
11557
11557
|
);
|
|
@@ -13511,7 +13511,7 @@ function getDbPath(cwd) {
|
|
|
13511
13511
|
return join9(getCleoDirAbsolute(cwd), DB_FILENAME2);
|
|
13512
13512
|
}
|
|
13513
13513
|
async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
13514
|
-
const
|
|
13514
|
+
const log11 = getLogger("sqlite");
|
|
13515
13515
|
try {
|
|
13516
13516
|
const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks").get();
|
|
13517
13517
|
const taskCount = countResult?.cnt ?? 0;
|
|
@@ -13532,7 +13532,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
13532
13532
|
if (backupTaskCount < MIN_BACKUP_TASK_COUNT) {
|
|
13533
13533
|
return;
|
|
13534
13534
|
}
|
|
13535
|
-
|
|
13535
|
+
log11.warn(
|
|
13536
13536
|
{ dbPath, backupPath: newestBackup.path, backupTasks: backupTaskCount },
|
|
13537
13537
|
`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).`
|
|
13538
13538
|
);
|
|
@@ -13550,7 +13550,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
13550
13550
|
const tempPath = dbPath + ".recovery-tmp";
|
|
13551
13551
|
copyFileSync4(newestBackup.path, tempPath);
|
|
13552
13552
|
renameSync(tempPath, dbPath);
|
|
13553
|
-
|
|
13553
|
+
log11.info(
|
|
13554
13554
|
{ dbPath, backupPath: newestBackup.path, restoredTasks: backupTaskCount },
|
|
13555
13555
|
"Database auto-recovered from backup successfully."
|
|
13556
13556
|
);
|
|
@@ -13560,7 +13560,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
13560
13560
|
runMigrations(restoredNativeDb, restoredDb);
|
|
13561
13561
|
_db = restoredDb;
|
|
13562
13562
|
} catch (err) {
|
|
13563
|
-
|
|
13563
|
+
log11.error({ err, dbPath }, "Auto-recovery from backup failed. Continuing with empty database.");
|
|
13564
13564
|
}
|
|
13565
13565
|
}
|
|
13566
13566
|
async function getDb(cwd) {
|
|
@@ -13594,7 +13594,7 @@ async function getDb(cwd) {
|
|
|
13594
13594
|
const { execFileSync: execFileSync12 } = await import("node:child_process");
|
|
13595
13595
|
const gitCwd = resolve3(dbPath, "..", "..");
|
|
13596
13596
|
const filesToCheck = [dbPath, dbPath + "-wal", dbPath + "-shm"];
|
|
13597
|
-
const
|
|
13597
|
+
const log11 = getLogger("sqlite");
|
|
13598
13598
|
for (const fileToCheck of filesToCheck) {
|
|
13599
13599
|
try {
|
|
13600
13600
|
execFileSync12("git", ["ls-files", "--error-unmatch", fileToCheck], {
|
|
@@ -13603,7 +13603,7 @@ async function getDb(cwd) {
|
|
|
13603
13603
|
});
|
|
13604
13604
|
const basename18 = fileToCheck.split(/[\\/]/).pop();
|
|
13605
13605
|
const relPath = fileToCheck.replace(gitCwd + sep, "");
|
|
13606
|
-
|
|
13606
|
+
log11.warn(
|
|
13607
13607
|
{ path: fileToCheck },
|
|
13608
13608
|
`${basename18} 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.`
|
|
13609
13609
|
);
|
|
@@ -14589,11 +14589,18 @@ var init_cross_db_cleanup = __esm({
|
|
|
14589
14589
|
|
|
14590
14590
|
// packages/core/src/store/db-helpers.ts
|
|
14591
14591
|
import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
|
|
14592
|
-
async function upsertTask(db, row, archiveFields) {
|
|
14592
|
+
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
14593
14593
|
if (row.parentId) {
|
|
14594
14594
|
const parent = await db.select({ id: tasks.id }).from(tasks).where(eq4(tasks.id, row.parentId)).limit(1).all();
|
|
14595
14595
|
if (parent.length === 0) {
|
|
14596
|
-
|
|
14596
|
+
if (allowOrphanParent) {
|
|
14597
|
+
row = { ...row, parentId: null };
|
|
14598
|
+
} else {
|
|
14599
|
+
log2.warn(
|
|
14600
|
+
{ taskId: row.id, parentId: row.parentId },
|
|
14601
|
+
"upsertTask: parentId references a non-existent task \u2014 parent relationship may be lost"
|
|
14602
|
+
);
|
|
14603
|
+
}
|
|
14597
14604
|
}
|
|
14598
14605
|
}
|
|
14599
14606
|
const values = archiveFields ? { ...row, ...archiveFields, status: "archived" } : row;
|
|
@@ -14737,10 +14744,13 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
14737
14744
|
}
|
|
14738
14745
|
}
|
|
14739
14746
|
}
|
|
14747
|
+
var log2;
|
|
14740
14748
|
var init_db_helpers = __esm({
|
|
14741
14749
|
"packages/core/src/store/db-helpers.ts"() {
|
|
14742
14750
|
"use strict";
|
|
14751
|
+
init_logger();
|
|
14743
14752
|
init_tasks_schema();
|
|
14753
|
+
log2 = getLogger("db-helpers");
|
|
14744
14754
|
}
|
|
14745
14755
|
});
|
|
14746
14756
|
|
|
@@ -15074,7 +15084,7 @@ async function createSqliteDataAccessor(cwd) {
|
|
|
15074
15084
|
archiveReason: taskAny.archiveReason ?? "completed",
|
|
15075
15085
|
cycleTimeDays: taskAny.cycleTimeDays ?? null
|
|
15076
15086
|
};
|
|
15077
|
-
await upsertTask(db, row, archiveFields);
|
|
15087
|
+
await upsertTask(db, row, archiveFields, true);
|
|
15078
15088
|
depBatch.push({ taskId: task.id, deps: task.depends ?? [] });
|
|
15079
15089
|
}
|
|
15080
15090
|
await batchUpdateDependencies(db, depBatch, validDepIds);
|
|
@@ -16061,7 +16071,7 @@ async function ensureSequenceValid(cwd, options) {
|
|
|
16061
16071
|
if (!options?.validateSequence) return;
|
|
16062
16072
|
const check2 = await checkSequence(cwd);
|
|
16063
16073
|
if (!check2.valid) {
|
|
16064
|
-
|
|
16074
|
+
log3.warn({ counter: check2.counter, maxId: check2.maxIdInData }, "Sequence behind, repairing");
|
|
16065
16075
|
const repair = await repairSequence(cwd);
|
|
16066
16076
|
if (!repair.repaired && options.strict) {
|
|
16067
16077
|
throw new DataSafetyError(`Sequence repair failed: ${repair.message}`, "SEQUENCE_INVALID", {
|
|
@@ -16078,7 +16088,7 @@ async function checkpoint(context, cwd, options) {
|
|
|
16078
16088
|
stats.checkpoints++;
|
|
16079
16089
|
stats.lastCheckpoint = /* @__PURE__ */ new Date();
|
|
16080
16090
|
} catch (err) {
|
|
16081
|
-
|
|
16091
|
+
log3.warn({ err }, "Checkpoint failed (non-fatal)");
|
|
16082
16092
|
}
|
|
16083
16093
|
vacuumIntoBackup({ cwd }).catch(() => {
|
|
16084
16094
|
});
|
|
@@ -16140,7 +16150,7 @@ async function safeAppendLog(accessor, entry, cwd, options) {
|
|
|
16140
16150
|
stats.writes++;
|
|
16141
16151
|
await checkpoint("log entry", cwd, opts);
|
|
16142
16152
|
}
|
|
16143
|
-
var
|
|
16153
|
+
var log3, DataSafetyError, DEFAULT_SAFETY, stats;
|
|
16144
16154
|
var init_data_safety_central = __esm({
|
|
16145
16155
|
"packages/core/src/store/data-safety-central.ts"() {
|
|
16146
16156
|
"use strict";
|
|
@@ -16148,7 +16158,7 @@ var init_data_safety_central = __esm({
|
|
|
16148
16158
|
init_sequence();
|
|
16149
16159
|
init_git_checkpoint();
|
|
16150
16160
|
init_sqlite_backup();
|
|
16151
|
-
|
|
16161
|
+
log3 = getLogger("data-safety");
|
|
16152
16162
|
DataSafetyError = class extends Error {
|
|
16153
16163
|
constructor(message, code, context) {
|
|
16154
16164
|
super(message);
|
|
@@ -16188,7 +16198,7 @@ function isSafetyDisabled() {
|
|
|
16188
16198
|
}
|
|
16189
16199
|
function wrapWithSafety(accessor, cwd) {
|
|
16190
16200
|
if (isSafetyDisabled()) {
|
|
16191
|
-
|
|
16201
|
+
log4.warn(
|
|
16192
16202
|
"Safety disabled - emergency mode (CLEO_DISABLE_SAFETY=true). Data integrity checks bypassed."
|
|
16193
16203
|
);
|
|
16194
16204
|
return accessor;
|
|
@@ -16209,13 +16219,13 @@ function getSafetyStatus() {
|
|
|
16209
16219
|
enabled: true
|
|
16210
16220
|
};
|
|
16211
16221
|
}
|
|
16212
|
-
var
|
|
16222
|
+
var log4, SafetyDataAccessor;
|
|
16213
16223
|
var init_safety_data_accessor = __esm({
|
|
16214
16224
|
"packages/core/src/store/safety-data-accessor.ts"() {
|
|
16215
16225
|
"use strict";
|
|
16216
16226
|
init_logger();
|
|
16217
16227
|
init_data_safety_central();
|
|
16218
|
-
|
|
16228
|
+
log4 = getLogger("data-safety");
|
|
16219
16229
|
SafetyDataAccessor = class {
|
|
16220
16230
|
/** The underlying accessor being wrapped. */
|
|
16221
16231
|
inner;
|
|
@@ -16239,7 +16249,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16239
16249
|
...config2
|
|
16240
16250
|
};
|
|
16241
16251
|
if (this.config.verbose) {
|
|
16242
|
-
|
|
16252
|
+
log4.debug({ engine: inner.engine }, "SafetyDataAccessor initialized");
|
|
16243
16253
|
}
|
|
16244
16254
|
}
|
|
16245
16255
|
/** The storage engine backing this accessor. */
|
|
@@ -16251,7 +16261,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16251
16261
|
*/
|
|
16252
16262
|
logVerbose(message) {
|
|
16253
16263
|
if (this.config.verbose) {
|
|
16254
|
-
|
|
16264
|
+
log4.debug(message);
|
|
16255
16265
|
}
|
|
16256
16266
|
}
|
|
16257
16267
|
/**
|
|
@@ -20611,16 +20621,16 @@ async function queryAudit(options) {
|
|
|
20611
20621
|
error: row.errorMessage ?? void 0
|
|
20612
20622
|
}));
|
|
20613
20623
|
} catch (err) {
|
|
20614
|
-
|
|
20624
|
+
log5.warn({ err }, "Failed to query audit entries from SQLite");
|
|
20615
20625
|
return [];
|
|
20616
20626
|
}
|
|
20617
20627
|
}
|
|
20618
|
-
var
|
|
20628
|
+
var log5;
|
|
20619
20629
|
var init_audit = __esm({
|
|
20620
20630
|
"packages/core/src/audit.ts"() {
|
|
20621
20631
|
"use strict";
|
|
20622
20632
|
init_logger();
|
|
20623
|
-
|
|
20633
|
+
log5 = getLogger("audit");
|
|
20624
20634
|
}
|
|
20625
20635
|
});
|
|
20626
20636
|
|
|
@@ -42965,13 +42975,16 @@ async function runTierPromotion(projectRoot) {
|
|
|
42965
42975
|
try {
|
|
42966
42976
|
shortToMedium = typedAll(
|
|
42967
42977
|
nativeDb.prepare(`
|
|
42968
|
-
SELECT id, citation_count, quality_score
|
|
42978
|
+
SELECT id, citation_count, quality_score, verified
|
|
42969
42979
|
FROM ${table}
|
|
42970
42980
|
WHERE memory_tier = 'short'
|
|
42971
42981
|
AND invalid_at IS NULL
|
|
42972
42982
|
AND ${dateCol} < ?
|
|
42973
|
-
AND
|
|
42974
|
-
|
|
42983
|
+
AND (
|
|
42984
|
+
citation_count >= 3
|
|
42985
|
+
OR quality_score >= 0.7
|
|
42986
|
+
OR verified = 1
|
|
42987
|
+
)
|
|
42975
42988
|
`),
|
|
42976
42989
|
age24h
|
|
42977
42990
|
);
|
|
@@ -42981,13 +42994,15 @@ async function runTierPromotion(projectRoot) {
|
|
|
42981
42994
|
for (const row of shortToMedium) {
|
|
42982
42995
|
try {
|
|
42983
42996
|
nativeDb.prepare(`UPDATE ${table} SET memory_tier = 'medium', updated_at = ? WHERE id = ?`).run(now, row.id);
|
|
42984
|
-
|
|
42985
|
-
|
|
42986
|
-
|
|
42987
|
-
|
|
42988
|
-
|
|
42989
|
-
|
|
42990
|
-
|
|
42997
|
+
let reason;
|
|
42998
|
+
if (row.citation_count >= 3) {
|
|
42999
|
+
reason = `citationCount=${row.citation_count} >= 3, age > 24h`;
|
|
43000
|
+
} else if ((row.quality_score ?? 0) >= 0.7) {
|
|
43001
|
+
reason = `qualityScore=${row.quality_score?.toFixed(2)} >= 0.70, age > 24h`;
|
|
43002
|
+
} else {
|
|
43003
|
+
reason = `verified=true, age > 24h`;
|
|
43004
|
+
}
|
|
43005
|
+
promoted.push({ id: row.id, table, fromTier: "short", toTier: "medium", reason });
|
|
42991
43006
|
} catch {
|
|
42992
43007
|
}
|
|
42993
43008
|
}
|
|
@@ -42995,13 +43010,12 @@ async function runTierPromotion(projectRoot) {
|
|
|
42995
43010
|
try {
|
|
42996
43011
|
mediumToLong = typedAll(
|
|
42997
43012
|
nativeDb.prepare(`
|
|
42998
|
-
SELECT id, citation_count, quality_score
|
|
43013
|
+
SELECT id, citation_count, quality_score, verified
|
|
42999
43014
|
FROM ${table}
|
|
43000
43015
|
WHERE memory_tier = 'medium'
|
|
43001
43016
|
AND invalid_at IS NULL
|
|
43002
43017
|
AND ${dateCol} < ?
|
|
43003
|
-
AND verified = 1
|
|
43004
|
-
AND citation_count >= 5
|
|
43018
|
+
AND (citation_count >= 5 OR verified = 1)
|
|
43005
43019
|
`),
|
|
43006
43020
|
age7d
|
|
43007
43021
|
);
|
|
@@ -43011,13 +43025,8 @@ async function runTierPromotion(projectRoot) {
|
|
|
43011
43025
|
for (const row of mediumToLong) {
|
|
43012
43026
|
try {
|
|
43013
43027
|
nativeDb.prepare(`UPDATE ${table} SET memory_tier = 'long', updated_at = ? WHERE id = ?`).run(now, row.id);
|
|
43014
|
-
|
|
43015
|
-
|
|
43016
|
-
table,
|
|
43017
|
-
fromTier: "medium",
|
|
43018
|
-
toTier: "long",
|
|
43019
|
-
reason: `citationCount=${row.citation_count} >= 5, verified, age > 7d`
|
|
43020
|
-
});
|
|
43028
|
+
const reason = row.citation_count >= 5 ? `citationCount=${row.citation_count} >= 5, age > 7d` : `verified=true, age > 7d`;
|
|
43029
|
+
promoted.push({ id: row.id, table, fromTier: "medium", toTier: "long", reason });
|
|
43021
43030
|
} catch {
|
|
43022
43031
|
}
|
|
43023
43032
|
}
|
|
@@ -52550,9 +52559,7 @@ async function completeTask(options, cwd, accessor) {
|
|
|
52550
52559
|
const parent = await acc.loadSingleTask(task.parentId);
|
|
52551
52560
|
if (parent && parent.type === "epic" && !parent.noAutoComplete) {
|
|
52552
52561
|
const siblings = await acc.getChildren(parent.id);
|
|
52553
|
-
const allDone = siblings.every(
|
|
52554
|
-
(c) => c.id === task.id || c.status === "done" || c.status === "cancelled"
|
|
52555
|
-
);
|
|
52562
|
+
const allDone = siblings.length > 0 && siblings.every((c) => c.id === task.id || c.status === "done" || c.status === "cancelled");
|
|
52556
52563
|
if (allDone) {
|
|
52557
52564
|
parent.status = "done";
|
|
52558
52565
|
parent.completedAt = now;
|
|
@@ -59571,7 +59578,7 @@ init_logger();
|
|
|
59571
59578
|
init_paths();
|
|
59572
59579
|
init_tasks_schema();
|
|
59573
59580
|
import { basename as basename6, relative as relative2 } from "node:path";
|
|
59574
|
-
var
|
|
59581
|
+
var log6 = getLogger("lifecycle:evidence");
|
|
59575
59582
|
async function recordEvidence(epicId, stage, uri, type, options) {
|
|
59576
59583
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
59577
59584
|
const stageId = `stage-${epicId}-${stage}`;
|
|
@@ -59598,7 +59605,7 @@ async function recordEvidence(epicId, stage, uri, type, options) {
|
|
|
59598
59605
|
description: options?.description ?? null
|
|
59599
59606
|
}).run();
|
|
59600
59607
|
} catch (err) {
|
|
59601
|
-
|
|
59608
|
+
log6.warn({ err }, "Failed to write evidence to SQLite");
|
|
59602
59609
|
}
|
|
59603
59610
|
return record2;
|
|
59604
59611
|
}
|
|
@@ -65897,7 +65904,7 @@ init_sqlite2();
|
|
|
65897
65904
|
init_tasks_schema();
|
|
65898
65905
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
65899
65906
|
import { and as and8, eq as eq11, sql as sql11 } from "drizzle-orm";
|
|
65900
|
-
var
|
|
65907
|
+
var log7 = getLogger("link-store");
|
|
65901
65908
|
async function getLinksByProvider(providerId, cwd) {
|
|
65902
65909
|
const db = await getDb(cwd);
|
|
65903
65910
|
const rows = await db.select().from(externalTaskLinks).where(eq11(externalTaskLinks.providerId, providerId));
|
|
@@ -65952,7 +65959,7 @@ async function ensureExternalTaskLinksTable(cwd) {
|
|
|
65952
65959
|
)
|
|
65953
65960
|
);
|
|
65954
65961
|
} catch (err) {
|
|
65955
|
-
|
|
65962
|
+
log7.warn({ err }, "Failed to ensure external_task_links table exists");
|
|
65956
65963
|
throw err;
|
|
65957
65964
|
}
|
|
65958
65965
|
}
|
|
@@ -66026,7 +66033,7 @@ init_brain_accessor();
|
|
|
66026
66033
|
init_brain_sqlite();
|
|
66027
66034
|
init_data_accessor();
|
|
66028
66035
|
init_registry3();
|
|
66029
|
-
var
|
|
66036
|
+
var log8 = getLogger("nexus:transfer");
|
|
66030
66037
|
async function previewTransfer(params) {
|
|
66031
66038
|
return executeTransferInternal({ ...params, dryRun: true });
|
|
66032
66039
|
}
|
|
@@ -66167,7 +66174,7 @@ async function executeTransferInternal(params) {
|
|
|
66167
66174
|
}
|
|
66168
66175
|
}
|
|
66169
66176
|
} catch (err) {
|
|
66170
|
-
|
|
66177
|
+
log8.warn(
|
|
66171
66178
|
{ err, linksCreated },
|
|
66172
66179
|
"Failed to create external_task_links during transfer \u2014 tasks were transferred successfully but provenance links could not be written"
|
|
66173
66180
|
);
|
|
@@ -66195,7 +66202,7 @@ async function executeTransferInternal(params) {
|
|
|
66195
66202
|
})
|
|
66196
66203
|
});
|
|
66197
66204
|
} catch (err) {
|
|
66198
|
-
|
|
66205
|
+
log8.warn({ err }, "nexus transfer audit write failed");
|
|
66199
66206
|
}
|
|
66200
66207
|
if (mode === "move") {
|
|
66201
66208
|
let archived = 0;
|
|
@@ -66208,7 +66215,7 @@ async function executeTransferInternal(params) {
|
|
|
66208
66215
|
});
|
|
66209
66216
|
archived++;
|
|
66210
66217
|
} catch (err) {
|
|
66211
|
-
|
|
66218
|
+
log8.warn({ err, taskId: entry.sourceId }, "failed to archive source task after transfer");
|
|
66212
66219
|
}
|
|
66213
66220
|
}
|
|
66214
66221
|
}
|
|
@@ -66246,7 +66253,7 @@ async function executeTransferInternal(params) {
|
|
|
66246
66253
|
}
|
|
66247
66254
|
}
|
|
66248
66255
|
} catch (err) {
|
|
66249
|
-
|
|
66256
|
+
log8.warn({ err }, "brain observation transfer failed");
|
|
66250
66257
|
}
|
|
66251
66258
|
result.brainObservationsTransferred = brainTransferred;
|
|
66252
66259
|
result.manifest.brainObservationsTransferred = brainTransferred;
|
|
@@ -66294,8 +66301,8 @@ async function loadProjectACL(projectPath) {
|
|
|
66294
66301
|
async function logAclFailure(projectPath) {
|
|
66295
66302
|
try {
|
|
66296
66303
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
66297
|
-
const
|
|
66298
|
-
|
|
66304
|
+
const log11 = getLogger2("nexus.acl");
|
|
66305
|
+
log11.warn({ projectPath }, "Failed to load ACL configuration, defaulting to deny-all");
|
|
66299
66306
|
} catch {
|
|
66300
66307
|
}
|
|
66301
66308
|
}
|
|
@@ -66450,9 +66457,9 @@ async function executeOperation(operation, taskId, projectPath, accessor, direct
|
|
|
66450
66457
|
async function logRouteAudit(directive, projectName, taskId, operation, success2, error48) {
|
|
66451
66458
|
try {
|
|
66452
66459
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
66453
|
-
const
|
|
66460
|
+
const log11 = getLogger2("nexus.route");
|
|
66454
66461
|
const level = success2 ? "info" : "warn";
|
|
66455
|
-
|
|
66462
|
+
log11[level](
|
|
66456
66463
|
{
|
|
66457
66464
|
directive: directive.verb,
|
|
66458
66465
|
agentId: directive.agentId,
|
|
@@ -75028,7 +75035,7 @@ init_data_accessor();
|
|
|
75028
75035
|
|
|
75029
75036
|
// packages/core/src/stats/workflow-telemetry.ts
|
|
75030
75037
|
init_logger();
|
|
75031
|
-
var
|
|
75038
|
+
var log9 = getLogger("workflow-telemetry");
|
|
75032
75039
|
async function queryTasks(cwd, since) {
|
|
75033
75040
|
try {
|
|
75034
75041
|
const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
@@ -75050,7 +75057,7 @@ async function queryTasks(cwd, since) {
|
|
|
75050
75057
|
}).from(tasks2).where(conditions.length > 0 ? and10(...conditions) : void 0).all();
|
|
75051
75058
|
return rows;
|
|
75052
75059
|
} catch (err) {
|
|
75053
|
-
|
|
75060
|
+
log9.warn({ err }, "Failed to query tasks for workflow telemetry");
|
|
75054
75061
|
return [];
|
|
75055
75062
|
}
|
|
75056
75063
|
}
|
|
@@ -75084,7 +75091,7 @@ async function queryCompletionAuditRows(cwd, since) {
|
|
|
75084
75091
|
return isComplete;
|
|
75085
75092
|
});
|
|
75086
75093
|
} catch (err) {
|
|
75087
|
-
|
|
75094
|
+
log9.warn({ err }, "Failed to query audit log for workflow telemetry");
|
|
75088
75095
|
return [];
|
|
75089
75096
|
}
|
|
75090
75097
|
}
|
|
@@ -76540,11 +76547,11 @@ import { join as join87 } from "node:path";
|
|
|
76540
76547
|
import { Readable } from "node:stream";
|
|
76541
76548
|
import { pipeline } from "node:stream/promises";
|
|
76542
76549
|
import { createGzip } from "node:zlib";
|
|
76543
|
-
var
|
|
76550
|
+
var log10 = getLogger("prune");
|
|
76544
76551
|
async function pruneAuditLog(cleoDir, config2) {
|
|
76545
76552
|
try {
|
|
76546
76553
|
if (!config2.auditRetentionDays || config2.auditRetentionDays <= 0) {
|
|
76547
|
-
|
|
76554
|
+
log10.debug("auditRetentionDays is 0 or unset; skipping audit prune");
|
|
76548
76555
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
76549
76556
|
}
|
|
76550
76557
|
const cutoff = new Date(Date.now() - config2.auditRetentionDays * 864e5).toISOString();
|
|
@@ -76555,7 +76562,7 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
76555
76562
|
const db = await getDb3(projectRoot);
|
|
76556
76563
|
const oldRows = await db.select().from(auditLog2).where(lt3(auditLog2.timestamp, cutoff));
|
|
76557
76564
|
if (oldRows.length === 0) {
|
|
76558
|
-
|
|
76565
|
+
log10.debug("No audit_log rows older than cutoff; nothing to prune");
|
|
76559
76566
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
76560
76567
|
}
|
|
76561
76568
|
let archivePath;
|
|
@@ -76573,17 +76580,17 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
76573
76580
|
const inStream = Readable.from([jsonlContent]);
|
|
76574
76581
|
await pipeline(inStream, gzip, outStream);
|
|
76575
76582
|
rowsArchived = oldRows.length;
|
|
76576
|
-
|
|
76583
|
+
log10.info(
|
|
76577
76584
|
{ archivePath, rowsArchived },
|
|
76578
76585
|
`Archived ${rowsArchived} audit rows to ${archivePath}`
|
|
76579
76586
|
);
|
|
76580
76587
|
} catch (archiveErr) {
|
|
76581
|
-
|
|
76588
|
+
log10.warn({ err: archiveErr }, "Failed to archive audit rows; continuing with deletion");
|
|
76582
76589
|
archivePath = void 0;
|
|
76583
76590
|
}
|
|
76584
76591
|
}
|
|
76585
76592
|
await db.delete(auditLog2).where(lt3(auditLog2.timestamp, cutoff)).run();
|
|
76586
|
-
|
|
76593
|
+
log10.info(
|
|
76587
76594
|
{ rowsDeleted: oldRows.length, cutoff },
|
|
76588
76595
|
`Pruned ${oldRows.length} audit_log rows older than ${cutoff}`
|
|
76589
76596
|
);
|
|
@@ -76593,7 +76600,7 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
76593
76600
|
archivePath
|
|
76594
76601
|
};
|
|
76595
76602
|
} catch (err) {
|
|
76596
|
-
|
|
76603
|
+
log10.warn({ err }, "audit log pruning failed");
|
|
76597
76604
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
76598
76605
|
}
|
|
76599
76606
|
}
|