@cleocode/cleo 2026.3.26 → 2026.3.27
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/.claude-plugin/README.md +315 -0
- package/.claude-plugin/hooks/hooks.json +56 -0
- package/.claude-plugin/hooks/scripts/brain-context.sh +35 -0
- package/.claude-plugin/hooks/scripts/brain-hook.sh +17 -0
- package/.claude-plugin/hooks/scripts/brain-start.sh +6 -0
- package/.claude-plugin/hooks/scripts/brain-worker.cjs +338 -0
- package/.claude-plugin/hooks/scripts/observe.sh +41 -0
- package/.claude-plugin/hooks/scripts/session-start.sh +48 -0
- package/.claude-plugin/hooks/scripts/stop.sh +23 -0
- package/.claude-plugin/plugin.json +24 -0
- package/dist/cli/index.js +270 -176
- package/dist/cli/index.js.map +4 -4
- package/package.json +3 -2
- package/server.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -10904,10 +10904,10 @@ async function readProjectMeta(projectPath) {
|
|
|
10904
10904
|
}
|
|
10905
10905
|
async function readProjectId(projectPath) {
|
|
10906
10906
|
try {
|
|
10907
|
-
const { readFileSync:
|
|
10907
|
+
const { readFileSync: readFileSync58, existsSync: existsSync75 } = await import("node:fs");
|
|
10908
10908
|
const infoPath = join32(projectPath, ".cleo", "project-info.json");
|
|
10909
|
-
if (!
|
|
10910
|
-
const data = JSON.parse(
|
|
10909
|
+
if (!existsSync75(infoPath)) return "";
|
|
10910
|
+
const data = JSON.parse(readFileSync58(infoPath, "utf-8"));
|
|
10911
10911
|
return typeof data.projectId === "string" ? data.projectId : "";
|
|
10912
10912
|
} catch {
|
|
10913
10913
|
return "";
|
|
@@ -19068,6 +19068,90 @@ var init_session_store = __esm({
|
|
|
19068
19068
|
}
|
|
19069
19069
|
});
|
|
19070
19070
|
|
|
19071
|
+
// src/core/install/claude-plugin.ts
|
|
19072
|
+
var claude_plugin_exports = {};
|
|
19073
|
+
__export(claude_plugin_exports, {
|
|
19074
|
+
installClaudePlugin: () => installClaudePlugin
|
|
19075
|
+
});
|
|
19076
|
+
import { cpSync, existsSync as existsSync67, mkdirSync as mkdirSync17, readFileSync as readFileSync50, writeFileSync as writeFileSync11 } from "node:fs";
|
|
19077
|
+
import { homedir as homedir4 } from "node:os";
|
|
19078
|
+
import { dirname as dirname18, join as join68, resolve as resolve9 } from "node:path";
|
|
19079
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
19080
|
+
async function installClaudePlugin(opts) {
|
|
19081
|
+
const { dryRun = false } = opts;
|
|
19082
|
+
const created = [];
|
|
19083
|
+
const warnings = [];
|
|
19084
|
+
const home = homedir4();
|
|
19085
|
+
const claudeHome = join68(home, ".claude");
|
|
19086
|
+
const settingsPath = join68(claudeHome, "settings.json");
|
|
19087
|
+
const thisFile = fileURLToPath6(import.meta.url);
|
|
19088
|
+
const packageRoot = resolve9(dirname18(thisFile), "..", "..", "..");
|
|
19089
|
+
const pluginSrc = join68(packageRoot, ".claude-plugin");
|
|
19090
|
+
if (!existsSync67(pluginSrc)) {
|
|
19091
|
+
warnings.push("CLEO Claude plugin source not found \u2014 skipping plugin install");
|
|
19092
|
+
return { created, warnings };
|
|
19093
|
+
}
|
|
19094
|
+
let pluginVersion = "0.0.0";
|
|
19095
|
+
try {
|
|
19096
|
+
const pluginJson = JSON.parse(readFileSync50(join68(pluginSrc, "plugin.json"), "utf-8"));
|
|
19097
|
+
pluginVersion = pluginJson.version ?? "0.0.0";
|
|
19098
|
+
} catch {
|
|
19099
|
+
}
|
|
19100
|
+
const cacheDir = join68(claudeHome, "plugins", "cache", PLUGIN_CACHE_NAME, PLUGIN_PACKAGE_NAME, pluginVersion);
|
|
19101
|
+
const cacheDirDisplay = cacheDir.replace(home, "~");
|
|
19102
|
+
if (!dryRun) {
|
|
19103
|
+
try {
|
|
19104
|
+
mkdirSync17(cacheDir, { recursive: true });
|
|
19105
|
+
cpSync(pluginSrc, cacheDir, { recursive: true });
|
|
19106
|
+
created.push(`${cacheDirDisplay} (CLEO Claude plugin installed)`);
|
|
19107
|
+
} catch (err) {
|
|
19108
|
+
warnings.push(`Plugin cache copy failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
19109
|
+
return { created, warnings };
|
|
19110
|
+
}
|
|
19111
|
+
} else {
|
|
19112
|
+
created.push(`${cacheDirDisplay} (would install CLEO Claude plugin)`);
|
|
19113
|
+
}
|
|
19114
|
+
if (!dryRun) {
|
|
19115
|
+
try {
|
|
19116
|
+
let settings = {};
|
|
19117
|
+
if (existsSync67(settingsPath)) {
|
|
19118
|
+
try {
|
|
19119
|
+
settings = JSON.parse(readFileSync50(settingsPath, "utf-8"));
|
|
19120
|
+
} catch {
|
|
19121
|
+
}
|
|
19122
|
+
}
|
|
19123
|
+
const enabledPlugins = settings["enabledPlugins"] ?? {};
|
|
19124
|
+
if (enabledPlugins["claude-mem@thedotmack"] === true) {
|
|
19125
|
+
enabledPlugins["claude-mem@thedotmack"] = false;
|
|
19126
|
+
created.push("~/.claude/settings.json (disabled claude-mem@thedotmack)");
|
|
19127
|
+
}
|
|
19128
|
+
const pluginKey = `${PLUGIN_PACKAGE_NAME}@${PLUGIN_CACHE_NAME}`;
|
|
19129
|
+
if (!enabledPlugins[pluginKey]) {
|
|
19130
|
+
enabledPlugins[pluginKey] = true;
|
|
19131
|
+
created.push(`~/.claude/settings.json (enabled ${pluginKey})`);
|
|
19132
|
+
}
|
|
19133
|
+
settings["enabledPlugins"] = enabledPlugins;
|
|
19134
|
+
mkdirSync17(claudeHome, { recursive: true });
|
|
19135
|
+
writeFileSync11(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
19136
|
+
} catch (err) {
|
|
19137
|
+
warnings.push(
|
|
19138
|
+
`settings.json update failed: ${err instanceof Error ? err.message : String(err)}`
|
|
19139
|
+
);
|
|
19140
|
+
}
|
|
19141
|
+
} else {
|
|
19142
|
+
created.push(`~/.claude/settings.json (would enable ${PLUGIN_PACKAGE_NAME}@${PLUGIN_CACHE_NAME})`);
|
|
19143
|
+
}
|
|
19144
|
+
return { created, warnings };
|
|
19145
|
+
}
|
|
19146
|
+
var PLUGIN_CACHE_NAME, PLUGIN_PACKAGE_NAME;
|
|
19147
|
+
var init_claude_plugin = __esm({
|
|
19148
|
+
"src/core/install/claude-plugin.ts"() {
|
|
19149
|
+
"use strict";
|
|
19150
|
+
PLUGIN_CACHE_NAME = "cleocode";
|
|
19151
|
+
PLUGIN_PACKAGE_NAME = "cleo";
|
|
19152
|
+
}
|
|
19153
|
+
});
|
|
19154
|
+
|
|
19071
19155
|
// src/store/provider.ts
|
|
19072
19156
|
var init_provider = __esm({
|
|
19073
19157
|
"src/store/provider.ts"() {
|
|
@@ -19089,19 +19173,19 @@ import {
|
|
|
19089
19173
|
accessSync as accessSync2,
|
|
19090
19174
|
appendFileSync as appendFileSync5,
|
|
19091
19175
|
constants as constants2,
|
|
19092
|
-
existsSync as
|
|
19093
|
-
mkdirSync as
|
|
19176
|
+
existsSync as existsSync71,
|
|
19177
|
+
mkdirSync as mkdirSync18,
|
|
19094
19178
|
readdirSync as readdirSync19,
|
|
19095
|
-
readFileSync as
|
|
19179
|
+
readFileSync as readFileSync53,
|
|
19096
19180
|
statSync as statSync10,
|
|
19097
19181
|
unlinkSync as unlinkSync5
|
|
19098
19182
|
} from "node:fs";
|
|
19099
|
-
import { dirname as
|
|
19183
|
+
import { dirname as dirname20, join as join71, relative as relative6 } from "node:path";
|
|
19100
19184
|
function createMigrationLogger(cleoDir, config) {
|
|
19101
19185
|
return new MigrationLogger(cleoDir, config);
|
|
19102
19186
|
}
|
|
19103
19187
|
function readMigrationLog(logPath) {
|
|
19104
|
-
const content =
|
|
19188
|
+
const content = readFileSync53(logPath, "utf-8");
|
|
19105
19189
|
return content.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
19106
19190
|
}
|
|
19107
19191
|
function logFileExists(logPath) {
|
|
@@ -19114,14 +19198,14 @@ function logFileExists(logPath) {
|
|
|
19114
19198
|
}
|
|
19115
19199
|
function getLatestMigrationLog(cleoDir) {
|
|
19116
19200
|
try {
|
|
19117
|
-
const logsDir =
|
|
19118
|
-
if (!
|
|
19201
|
+
const logsDir = join71(cleoDir, "logs");
|
|
19202
|
+
if (!existsSync71(logsDir)) {
|
|
19119
19203
|
return null;
|
|
19120
19204
|
}
|
|
19121
19205
|
const files = readdirSync19(logsDir).filter((f) => f.startsWith("migration-") && f.endsWith(".jsonl")).map((f) => ({
|
|
19122
19206
|
name: f,
|
|
19123
|
-
path:
|
|
19124
|
-
mtime: statSync10(
|
|
19207
|
+
path: join71(logsDir, f),
|
|
19208
|
+
mtime: statSync10(join71(logsDir, f)).mtime.getTime()
|
|
19125
19209
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
19126
19210
|
return files.length > 0 ? files[0].path : null;
|
|
19127
19211
|
} catch {
|
|
@@ -19151,10 +19235,10 @@ var init_logger2 = __esm({
|
|
|
19151
19235
|
consoleOutput: config.consoleOutput ?? false
|
|
19152
19236
|
};
|
|
19153
19237
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
19154
|
-
this.logPath =
|
|
19155
|
-
const logsDir =
|
|
19156
|
-
if (!
|
|
19157
|
-
|
|
19238
|
+
this.logPath = join71(cleoDir, "logs", `migration-${timestamp}.jsonl`);
|
|
19239
|
+
const logsDir = dirname20(this.logPath);
|
|
19240
|
+
if (!existsSync71(logsDir)) {
|
|
19241
|
+
mkdirSync18(logsDir, { recursive: true });
|
|
19158
19242
|
}
|
|
19159
19243
|
this.startTime = Date.now();
|
|
19160
19244
|
this.cleanupOldLogs();
|
|
@@ -19242,7 +19326,7 @@ var init_logger2 = __esm({
|
|
|
19242
19326
|
sourcePath: relative6(this.cleoDir, sourcePath),
|
|
19243
19327
|
...additionalData
|
|
19244
19328
|
};
|
|
19245
|
-
if (
|
|
19329
|
+
if (existsSync71(sourcePath)) {
|
|
19246
19330
|
try {
|
|
19247
19331
|
const stats2 = statSync10(sourcePath);
|
|
19248
19332
|
data.sourceSize = stats2.size;
|
|
@@ -19252,7 +19336,7 @@ var init_logger2 = __esm({
|
|
|
19252
19336
|
}
|
|
19253
19337
|
if (targetPath) {
|
|
19254
19338
|
data.targetPath = relative6(this.cleoDir, targetPath);
|
|
19255
|
-
if (
|
|
19339
|
+
if (existsSync71(targetPath)) {
|
|
19256
19340
|
try {
|
|
19257
19341
|
const stats2 = statSync10(targetPath);
|
|
19258
19342
|
data.targetSize = stats2.size;
|
|
@@ -19321,14 +19405,14 @@ var init_logger2 = __esm({
|
|
|
19321
19405
|
*/
|
|
19322
19406
|
cleanupOldLogs() {
|
|
19323
19407
|
try {
|
|
19324
|
-
const logsDir =
|
|
19325
|
-
if (!
|
|
19408
|
+
const logsDir = join71(this.cleoDir, "logs");
|
|
19409
|
+
if (!existsSync71(logsDir)) {
|
|
19326
19410
|
return;
|
|
19327
19411
|
}
|
|
19328
19412
|
const files = readdirSync19(logsDir).filter((f) => f.startsWith("migration-") && f.endsWith(".jsonl")).map((f) => ({
|
|
19329
19413
|
name: f,
|
|
19330
|
-
path:
|
|
19331
|
-
mtime: statSync10(
|
|
19414
|
+
path: join71(logsDir, f),
|
|
19415
|
+
mtime: statSync10(join71(logsDir, f)).mtime.getTime()
|
|
19332
19416
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
19333
19417
|
const filesToRemove = files.slice(this.config.maxLogFiles);
|
|
19334
19418
|
for (const file of filesToRemove) {
|
|
@@ -19424,9 +19508,9 @@ __export(state_exports, {
|
|
|
19424
19508
|
verifySourceIntegrity: () => verifySourceIntegrity
|
|
19425
19509
|
});
|
|
19426
19510
|
import { createHash as createHash9 } from "node:crypto";
|
|
19427
|
-
import { existsSync as
|
|
19511
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
19428
19512
|
import { readFile as readFile18, unlink as unlink5, writeFile as writeFile12 } from "node:fs/promises";
|
|
19429
|
-
import { join as
|
|
19513
|
+
import { join as join72 } from "node:path";
|
|
19430
19514
|
async function computeFileChecksum(filePath) {
|
|
19431
19515
|
try {
|
|
19432
19516
|
const content = await readFile18(filePath);
|
|
@@ -19447,8 +19531,8 @@ async function countRecords(filePath, key) {
|
|
|
19447
19531
|
async function createMigrationState(cleoDir, sourceFiles) {
|
|
19448
19532
|
const files = sourceFiles ?? {};
|
|
19449
19533
|
if (!files.todoJson) {
|
|
19450
|
-
const todoPath =
|
|
19451
|
-
if (
|
|
19534
|
+
const todoPath = join72(cleoDir, "todo.json");
|
|
19535
|
+
if (existsSync72(todoPath)) {
|
|
19452
19536
|
files.todoJson = {
|
|
19453
19537
|
path: todoPath,
|
|
19454
19538
|
checksum: await computeFileChecksum(todoPath),
|
|
@@ -19457,8 +19541,8 @@ async function createMigrationState(cleoDir, sourceFiles) {
|
|
|
19457
19541
|
}
|
|
19458
19542
|
}
|
|
19459
19543
|
if (!files.sessionsJson) {
|
|
19460
|
-
const sessionsPath =
|
|
19461
|
-
if (
|
|
19544
|
+
const sessionsPath = join72(cleoDir, "sessions.json");
|
|
19545
|
+
if (existsSync72(sessionsPath)) {
|
|
19462
19546
|
files.sessionsJson = {
|
|
19463
19547
|
path: sessionsPath,
|
|
19464
19548
|
checksum: await computeFileChecksum(sessionsPath),
|
|
@@ -19467,8 +19551,8 @@ async function createMigrationState(cleoDir, sourceFiles) {
|
|
|
19467
19551
|
}
|
|
19468
19552
|
}
|
|
19469
19553
|
if (!files.archiveJson) {
|
|
19470
|
-
const archivePath =
|
|
19471
|
-
if (
|
|
19554
|
+
const archivePath = join72(cleoDir, "todo-archive.json");
|
|
19555
|
+
if (existsSync72(archivePath)) {
|
|
19472
19556
|
files.archiveJson = {
|
|
19473
19557
|
path: archivePath,
|
|
19474
19558
|
checksum: await computeFileChecksum(archivePath),
|
|
@@ -19496,7 +19580,7 @@ async function createMigrationState(cleoDir, sourceFiles) {
|
|
|
19496
19580
|
return state;
|
|
19497
19581
|
}
|
|
19498
19582
|
async function writeMigrationState(cleoDir, state) {
|
|
19499
|
-
const statePath =
|
|
19583
|
+
const statePath = join72(cleoDir, STATE_FILENAME);
|
|
19500
19584
|
const tempPath = `${statePath}.tmp`;
|
|
19501
19585
|
await writeFile12(tempPath, JSON.stringify(state, null, 2));
|
|
19502
19586
|
await writeFile12(statePath, await readFile18(tempPath));
|
|
@@ -19571,7 +19655,7 @@ async function addMigrationWarning(cleoDir, warning) {
|
|
|
19571
19655
|
}
|
|
19572
19656
|
async function loadMigrationState(cleoDir) {
|
|
19573
19657
|
try {
|
|
19574
|
-
const statePath =
|
|
19658
|
+
const statePath = join72(cleoDir, STATE_FILENAME);
|
|
19575
19659
|
const content = await readFile18(statePath, "utf-8");
|
|
19576
19660
|
return JSON.parse(content);
|
|
19577
19661
|
} catch {
|
|
@@ -19613,7 +19697,7 @@ async function failMigration(cleoDir, error) {
|
|
|
19613
19697
|
}
|
|
19614
19698
|
async function clearMigrationState(cleoDir) {
|
|
19615
19699
|
try {
|
|
19616
|
-
const statePath =
|
|
19700
|
+
const statePath = join72(cleoDir, STATE_FILENAME);
|
|
19617
19701
|
await unlink5(statePath);
|
|
19618
19702
|
} catch {
|
|
19619
19703
|
}
|
|
@@ -19657,7 +19741,7 @@ async function verifySourceIntegrity(cleoDir) {
|
|
|
19657
19741
|
const missing = [];
|
|
19658
19742
|
for (const [key, fileInfo] of Object.entries(state.sourceFiles)) {
|
|
19659
19743
|
if (!fileInfo) continue;
|
|
19660
|
-
if (!
|
|
19744
|
+
if (!existsSync72(fileInfo.path)) {
|
|
19661
19745
|
missing.push(key);
|
|
19662
19746
|
continue;
|
|
19663
19747
|
}
|
|
@@ -19688,8 +19772,8 @@ __export(migration_sqlite_exports, {
|
|
|
19688
19772
|
migrateJsonToSqlite: () => migrateJsonToSqlite2,
|
|
19689
19773
|
migrateJsonToSqliteAtomic: () => migrateJsonToSqliteAtomic
|
|
19690
19774
|
});
|
|
19691
|
-
import { existsSync as
|
|
19692
|
-
import { dirname as
|
|
19775
|
+
import { existsSync as existsSync73, mkdirSync as mkdirSync19, readFileSync as readFileSync54 } from "node:fs";
|
|
19776
|
+
import { dirname as dirname21, join as join73 } from "node:path";
|
|
19693
19777
|
import { drizzle as drizzle4 } from "drizzle-orm/sqlite-proxy";
|
|
19694
19778
|
import { migrate as migrate4 } from "drizzle-orm/sqlite-proxy/migrator";
|
|
19695
19779
|
function topoSortTasks(tasks2) {
|
|
@@ -19726,26 +19810,26 @@ function countJsonRecords(cleoDir) {
|
|
|
19726
19810
|
let tasks2 = 0;
|
|
19727
19811
|
let archived = 0;
|
|
19728
19812
|
let sessions2 = 0;
|
|
19729
|
-
const todoPath =
|
|
19730
|
-
if (
|
|
19813
|
+
const todoPath = join73(cleoDir, "todo.json");
|
|
19814
|
+
if (existsSync73(todoPath)) {
|
|
19731
19815
|
try {
|
|
19732
|
-
const data = JSON.parse(
|
|
19816
|
+
const data = JSON.parse(readFileSync54(todoPath, "utf-8"));
|
|
19733
19817
|
tasks2 = (data.tasks ?? []).length;
|
|
19734
19818
|
} catch {
|
|
19735
19819
|
}
|
|
19736
19820
|
}
|
|
19737
|
-
const archivePath =
|
|
19738
|
-
if (
|
|
19821
|
+
const archivePath = join73(cleoDir, "todo-archive.json");
|
|
19822
|
+
if (existsSync73(archivePath)) {
|
|
19739
19823
|
try {
|
|
19740
|
-
const data = JSON.parse(
|
|
19824
|
+
const data = JSON.parse(readFileSync54(archivePath, "utf-8"));
|
|
19741
19825
|
archived = (data.tasks ?? data.archivedTasks ?? []).length;
|
|
19742
19826
|
} catch {
|
|
19743
19827
|
}
|
|
19744
19828
|
}
|
|
19745
|
-
const sessionsPath =
|
|
19746
|
-
if (
|
|
19829
|
+
const sessionsPath = join73(cleoDir, "sessions.json");
|
|
19830
|
+
if (existsSync73(sessionsPath)) {
|
|
19747
19831
|
try {
|
|
19748
|
-
const data = JSON.parse(
|
|
19832
|
+
const data = JSON.parse(readFileSync54(sessionsPath, "utf-8"));
|
|
19749
19833
|
sessions2 = (data.sessions ?? []).length;
|
|
19750
19834
|
} catch {
|
|
19751
19835
|
}
|
|
@@ -19769,7 +19853,7 @@ async function migrateJsonToSqliteAtomic(cwd, tempDbPath, logger) {
|
|
|
19769
19853
|
closeDb2();
|
|
19770
19854
|
try {
|
|
19771
19855
|
logger?.info("import", "init", "Initializing node:sqlite for migration");
|
|
19772
|
-
|
|
19856
|
+
mkdirSync19(dirname21(tempDbPath), { recursive: true });
|
|
19773
19857
|
const nativeDb = openNativeDatabase(tempDbPath, { enableWal: true });
|
|
19774
19858
|
const drizzleCallback = createDrizzleCallback(nativeDb);
|
|
19775
19859
|
const batchCallback = createBatchCallback(nativeDb);
|
|
@@ -19826,13 +19910,13 @@ async function migrateJsonToSqliteAtomic(cwd, tempDbPath, logger) {
|
|
|
19826
19910
|
}
|
|
19827
19911
|
}
|
|
19828
19912
|
async function runMigrationDataImport(db, cleoDir, result, logger) {
|
|
19829
|
-
const todoPath =
|
|
19830
|
-
if (
|
|
19913
|
+
const todoPath = join73(cleoDir, "todo.json");
|
|
19914
|
+
if (existsSync73(todoPath)) {
|
|
19831
19915
|
try {
|
|
19832
19916
|
logger?.info("import", "read-todo", "Reading todo.json", {
|
|
19833
19917
|
path: todoPath.replace(cleoDir, ".")
|
|
19834
19918
|
});
|
|
19835
|
-
const todoData = JSON.parse(
|
|
19919
|
+
const todoData = JSON.parse(readFileSync54(todoPath, "utf-8"));
|
|
19836
19920
|
const tasks2 = topoSortTasks(todoData.tasks ?? []);
|
|
19837
19921
|
const totalTasks = tasks2.length;
|
|
19838
19922
|
logger?.info("import", "tasks-start", `Starting import of ${totalTasks} tasks`, {
|
|
@@ -19906,13 +19990,13 @@ async function runMigrationDataImport(db, cleoDir, result, logger) {
|
|
|
19906
19990
|
result.warnings.push("todo.json not found, skipping task import");
|
|
19907
19991
|
logger?.warn("import", "todo-missing", "todo.json not found, skipping task import");
|
|
19908
19992
|
}
|
|
19909
|
-
const archivePath =
|
|
19910
|
-
if (
|
|
19993
|
+
const archivePath = join73(cleoDir, "todo-archive.json");
|
|
19994
|
+
if (existsSync73(archivePath)) {
|
|
19911
19995
|
try {
|
|
19912
19996
|
logger?.info("import", "read-archive", "Reading todo-archive.json", {
|
|
19913
19997
|
path: archivePath.replace(cleoDir, ".")
|
|
19914
19998
|
});
|
|
19915
|
-
const archiveData = JSON.parse(
|
|
19999
|
+
const archiveData = JSON.parse(readFileSync54(archivePath, "utf-8"));
|
|
19916
20000
|
const archivedTasks = topoSortTasks(archiveData.tasks ?? archiveData.archivedTasks ?? []);
|
|
19917
20001
|
const totalArchived = archivedTasks.length;
|
|
19918
20002
|
logger?.info(
|
|
@@ -19975,13 +20059,13 @@ async function runMigrationDataImport(db, cleoDir, result, logger) {
|
|
|
19975
20059
|
logger?.error("import", "parse-archive", errorMsg);
|
|
19976
20060
|
}
|
|
19977
20061
|
}
|
|
19978
|
-
const sessionsPath =
|
|
19979
|
-
if (
|
|
20062
|
+
const sessionsPath = join73(cleoDir, "sessions.json");
|
|
20063
|
+
if (existsSync73(sessionsPath)) {
|
|
19980
20064
|
try {
|
|
19981
20065
|
logger?.info("import", "read-sessions", "Reading sessions.json", {
|
|
19982
20066
|
path: sessionsPath.replace(cleoDir, ".")
|
|
19983
20067
|
});
|
|
19984
|
-
const sessionsData = JSON.parse(
|
|
20068
|
+
const sessionsData = JSON.parse(readFileSync54(sessionsPath, "utf-8"));
|
|
19985
20069
|
const sessions2 = sessionsData.sessions ?? [];
|
|
19986
20070
|
const totalSessions = sessions2.length;
|
|
19987
20071
|
logger?.info("import", "sessions-start", `Starting import of ${totalSessions} sessions`, {
|
|
@@ -20108,10 +20192,10 @@ async function migrateJsonToSqlite2(cwd, options) {
|
|
|
20108
20192
|
return result;
|
|
20109
20193
|
}
|
|
20110
20194
|
const db = await getDb(cwd);
|
|
20111
|
-
const todoPath =
|
|
20112
|
-
if (
|
|
20195
|
+
const todoPath = join73(cleoDir, "todo.json");
|
|
20196
|
+
if (existsSync73(todoPath)) {
|
|
20113
20197
|
try {
|
|
20114
|
-
const todoData = JSON.parse(
|
|
20198
|
+
const todoData = JSON.parse(readFileSync54(todoPath, "utf-8"));
|
|
20115
20199
|
const tasks2 = topoSortTasks(todoData.tasks ?? []);
|
|
20116
20200
|
for (const task of tasks2) {
|
|
20117
20201
|
try {
|
|
@@ -20160,10 +20244,10 @@ async function migrateJsonToSqlite2(cwd, options) {
|
|
|
20160
20244
|
} else {
|
|
20161
20245
|
result.warnings.push("todo.json not found, skipping task import");
|
|
20162
20246
|
}
|
|
20163
|
-
const archivePath =
|
|
20164
|
-
if (
|
|
20247
|
+
const archivePath = join73(cleoDir, "todo-archive.json");
|
|
20248
|
+
if (existsSync73(archivePath)) {
|
|
20165
20249
|
try {
|
|
20166
|
-
const archiveData = JSON.parse(
|
|
20250
|
+
const archiveData = JSON.parse(readFileSync54(archivePath, "utf-8"));
|
|
20167
20251
|
const archivedTasks = topoSortTasks(archiveData.tasks ?? archiveData.archivedTasks ?? []);
|
|
20168
20252
|
for (const task of archivedTasks) {
|
|
20169
20253
|
try {
|
|
@@ -20198,10 +20282,10 @@ async function migrateJsonToSqlite2(cwd, options) {
|
|
|
20198
20282
|
result.errors.push(`Failed to parse todo-archive.json: ${String(err)}`);
|
|
20199
20283
|
}
|
|
20200
20284
|
}
|
|
20201
|
-
const sessionsPath =
|
|
20202
|
-
if (
|
|
20285
|
+
const sessionsPath = join73(cleoDir, "sessions.json");
|
|
20286
|
+
if (existsSync73(sessionsPath)) {
|
|
20203
20287
|
try {
|
|
20204
|
-
const sessionsData = JSON.parse(
|
|
20288
|
+
const sessionsData = JSON.parse(readFileSync54(sessionsPath, "utf-8"));
|
|
20205
20289
|
const sessions2 = sessionsData.sessions ?? [];
|
|
20206
20290
|
for (const session of sessions2) {
|
|
20207
20291
|
try {
|
|
@@ -20269,8 +20353,8 @@ init_config();
|
|
|
20269
20353
|
init_platform();
|
|
20270
20354
|
init_storage_preflight();
|
|
20271
20355
|
import { Command, Help } from "commander";
|
|
20272
|
-
import { readFileSync as
|
|
20273
|
-
import { join as
|
|
20356
|
+
import { readFileSync as readFileSync57 } from "node:fs";
|
|
20357
|
+
import { join as join78 } from "node:path";
|
|
20274
20358
|
|
|
20275
20359
|
// src/dispatch/adapters/cli.ts
|
|
20276
20360
|
init_renderers();
|
|
@@ -31775,10 +31859,10 @@ async function systemLog(projectRoot, filters) {
|
|
|
31775
31859
|
}
|
|
31776
31860
|
async function queryAuditLogSqlite(projectRoot, filters) {
|
|
31777
31861
|
try {
|
|
31778
|
-
const { join:
|
|
31779
|
-
const { existsSync:
|
|
31780
|
-
const dbPath =
|
|
31781
|
-
if (!
|
|
31862
|
+
const { join: join79 } = await import("node:path");
|
|
31863
|
+
const { existsSync: existsSync75 } = await import("node:fs");
|
|
31864
|
+
const dbPath = join79(projectRoot, ".cleo", "tasks.db");
|
|
31865
|
+
if (!existsSync75(dbPath)) {
|
|
31782
31866
|
const offset = filters?.offset ?? 0;
|
|
31783
31867
|
const limit = filters?.limit ?? 20;
|
|
31784
31868
|
return {
|
|
@@ -44545,11 +44629,11 @@ function registerInjectCommand(program2) {
|
|
|
44545
44629
|
// src/cli/commands/install-global.ts
|
|
44546
44630
|
init_paths();
|
|
44547
44631
|
init_renderers();
|
|
44548
|
-
import { existsSync as
|
|
44632
|
+
import { existsSync as existsSync68, readFileSync as readFileSync51 } from "node:fs";
|
|
44549
44633
|
import { mkdir as mkdir12, readFile as readFile17, writeFile as writeFile11 } from "node:fs/promises";
|
|
44550
|
-
import { homedir as
|
|
44551
|
-
import { dirname as
|
|
44552
|
-
import { fileURLToPath as
|
|
44634
|
+
import { homedir as homedir5 } from "node:os";
|
|
44635
|
+
import { dirname as dirname19, join as join69, resolve as resolve10 } from "node:path";
|
|
44636
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
44553
44637
|
function registerInstallGlobalCommand(program2) {
|
|
44554
44638
|
program2.command("install-global").description("Refresh global CLEO setup: provider files, MCP configs, templates").option("--dry-run", "Preview changes without applying").action(async (opts) => {
|
|
44555
44639
|
const isDryRun = !!opts["dryRun"];
|
|
@@ -44557,17 +44641,17 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44557
44641
|
const warnings = [];
|
|
44558
44642
|
try {
|
|
44559
44643
|
const cleoHome = getCleoHome();
|
|
44560
|
-
const globalTemplatesDir =
|
|
44644
|
+
const globalTemplatesDir = join69(cleoHome, "templates");
|
|
44561
44645
|
if (!isDryRun) {
|
|
44562
44646
|
await mkdir12(globalTemplatesDir, { recursive: true });
|
|
44563
44647
|
}
|
|
44564
44648
|
try {
|
|
44565
|
-
const thisFile =
|
|
44566
|
-
const packageRoot =
|
|
44567
|
-
const templatePath =
|
|
44568
|
-
if (
|
|
44569
|
-
const content =
|
|
44570
|
-
const globalPath =
|
|
44649
|
+
const thisFile = fileURLToPath7(import.meta.url);
|
|
44650
|
+
const packageRoot = resolve10(dirname19(thisFile), "..", "..", "..");
|
|
44651
|
+
const templatePath = join69(packageRoot, "templates", "CLEO-INJECTION.md");
|
|
44652
|
+
if (existsSync68(templatePath)) {
|
|
44653
|
+
const content = readFileSync51(templatePath, "utf-8");
|
|
44654
|
+
const globalPath = join69(globalTemplatesDir, "CLEO-INJECTION.md");
|
|
44571
44655
|
if (!isDryRun) {
|
|
44572
44656
|
await writeFile11(globalPath, content);
|
|
44573
44657
|
}
|
|
@@ -44579,12 +44663,12 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44579
44663
|
warnings.push("Could not refresh CLEO-INJECTION.md template");
|
|
44580
44664
|
}
|
|
44581
44665
|
const globalAgentsDir = getAgentsHome();
|
|
44582
|
-
const globalAgentsMd =
|
|
44666
|
+
const globalAgentsMd = join69(globalAgentsDir, "AGENTS.md");
|
|
44583
44667
|
try {
|
|
44584
44668
|
const { inject, getInstalledProviders: getInstalledProviders3, injectAll: injectAll2, buildInjectionContent: buildInjectionContent2 } = await import("@cleocode/caamp");
|
|
44585
44669
|
if (!isDryRun) {
|
|
44586
44670
|
await mkdir12(globalAgentsDir, { recursive: true });
|
|
44587
|
-
if (
|
|
44671
|
+
if (existsSync68(globalAgentsMd)) {
|
|
44588
44672
|
const content = await readFile17(globalAgentsMd, "utf8");
|
|
44589
44673
|
const stripped = content.replace(
|
|
44590
44674
|
/\n?<!-- CLEO:START -->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
@@ -44608,8 +44692,8 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44608
44692
|
});
|
|
44609
44693
|
if (!isDryRun) {
|
|
44610
44694
|
for (const provider of providers) {
|
|
44611
|
-
const instructFilePath =
|
|
44612
|
-
if (
|
|
44695
|
+
const instructFilePath = join69(provider.pathGlobal, provider.instructFile);
|
|
44696
|
+
if (existsSync68(instructFilePath)) {
|
|
44613
44697
|
const fileContent = await readFile17(instructFilePath, "utf8");
|
|
44614
44698
|
const stripped = fileContent.replace(
|
|
44615
44699
|
/\n?<!-- CLEO:START -->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
@@ -44620,14 +44704,14 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44620
44704
|
}
|
|
44621
44705
|
}
|
|
44622
44706
|
}
|
|
44623
|
-
const results = await injectAll2(providers,
|
|
44707
|
+
const results = await injectAll2(providers, homedir5(), "global", injectionContent);
|
|
44624
44708
|
for (const [filePath, action] of results) {
|
|
44625
|
-
const displayPath = filePath.replace(
|
|
44709
|
+
const displayPath = filePath.replace(homedir5(), "~");
|
|
44626
44710
|
created.push(`${displayPath} (${action})`);
|
|
44627
44711
|
}
|
|
44628
44712
|
} else {
|
|
44629
44713
|
for (const p of providers) {
|
|
44630
|
-
const displayPath =
|
|
44714
|
+
const displayPath = join69(p.pathGlobal, p.instructFile).replace(homedir5(), "~");
|
|
44631
44715
|
created.push(`${displayPath} (would update CAAMP block)`);
|
|
44632
44716
|
}
|
|
44633
44717
|
}
|
|
@@ -44649,7 +44733,7 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44649
44733
|
serverName,
|
|
44650
44734
|
serverEntry,
|
|
44651
44735
|
"global",
|
|
44652
|
-
|
|
44736
|
+
homedir5()
|
|
44653
44737
|
);
|
|
44654
44738
|
const successes = results.filter((r) => r.success);
|
|
44655
44739
|
if (successes.length > 0) {
|
|
@@ -44674,6 +44758,16 @@ function registerInstallGlobalCommand(program2) {
|
|
|
44674
44758
|
`Core skills installation failed: ${err instanceof Error ? err.message : String(err)}`
|
|
44675
44759
|
);
|
|
44676
44760
|
}
|
|
44761
|
+
try {
|
|
44762
|
+
const { installClaudePlugin: installClaudePlugin2 } = await Promise.resolve().then(() => (init_claude_plugin(), claude_plugin_exports));
|
|
44763
|
+
const pluginResult = await installClaudePlugin2({ dryRun: isDryRun });
|
|
44764
|
+
created.push(...pluginResult.created);
|
|
44765
|
+
warnings.push(...pluginResult.warnings);
|
|
44766
|
+
} catch (err) {
|
|
44767
|
+
warnings.push(
|
|
44768
|
+
`Claude plugin install skipped: ${err instanceof Error ? err.message : String(err)}`
|
|
44769
|
+
);
|
|
44770
|
+
}
|
|
44677
44771
|
cliOutput(
|
|
44678
44772
|
{
|
|
44679
44773
|
success: true,
|
|
@@ -44699,7 +44793,7 @@ import { execFileSync as execFileSync12 } from "node:child_process";
|
|
|
44699
44793
|
// src/config/build-config.ts
|
|
44700
44794
|
var BUILD_CONFIG = {
|
|
44701
44795
|
"name": "@cleocode/cleo",
|
|
44702
|
-
"version": "2026.3.
|
|
44796
|
+
"version": "2026.3.27",
|
|
44703
44797
|
"description": "CLEO V2 - TypeScript task management CLI for AI coding agents",
|
|
44704
44798
|
"repository": {
|
|
44705
44799
|
"owner": "kryptobaseddev",
|
|
@@ -44708,7 +44802,7 @@ var BUILD_CONFIG = {
|
|
|
44708
44802
|
"url": "https://github.com/kryptobaseddev/cleo.git",
|
|
44709
44803
|
"issuesUrl": "https://github.com/kryptobaseddev/cleo/issues"
|
|
44710
44804
|
},
|
|
44711
|
-
"buildDate": "2026-03-09T06:
|
|
44805
|
+
"buildDate": "2026-03-09T06:31:53.689Z",
|
|
44712
44806
|
"templates": {
|
|
44713
44807
|
"issueTemplatesDir": "templates/issue-templates"
|
|
44714
44808
|
}
|
|
@@ -45167,7 +45261,7 @@ function registerMemoryBrainCommand(program2) {
|
|
|
45167
45261
|
init_brain_sqlite();
|
|
45168
45262
|
init_paths();
|
|
45169
45263
|
init_brain_search();
|
|
45170
|
-
import { existsSync as
|
|
45264
|
+
import { existsSync as existsSync69 } from "node:fs";
|
|
45171
45265
|
import { createRequire as createRequire5 } from "node:module";
|
|
45172
45266
|
var _require5 = createRequire5(import.meta.url);
|
|
45173
45267
|
var { DatabaseSync: DatabaseSync3 } = _require5("node:sqlite");
|
|
@@ -45211,7 +45305,7 @@ async function migrateClaudeMem(projectRoot, options = {}) {
|
|
|
45211
45305
|
errors: [],
|
|
45212
45306
|
dryRun
|
|
45213
45307
|
};
|
|
45214
|
-
if (!
|
|
45308
|
+
if (!existsSync69(sourcePath)) {
|
|
45215
45309
|
throw new Error(
|
|
45216
45310
|
`claude-mem database not found at: ${sourcePath}
|
|
45217
45311
|
Expected location: ~/.claude-mem/claude-mem.db
|
|
@@ -45649,22 +45743,22 @@ function registerOrchestrateCommand(program2) {
|
|
|
45649
45743
|
init_errors();
|
|
45650
45744
|
|
|
45651
45745
|
// src/core/otel/index.ts
|
|
45652
|
-
import { copyFileSync as copyFileSync4, existsSync as
|
|
45653
|
-
import { join as
|
|
45746
|
+
import { copyFileSync as copyFileSync4, existsSync as existsSync70, readFileSync as readFileSync52, writeFileSync as writeFileSync12 } from "node:fs";
|
|
45747
|
+
import { join as join70 } from "node:path";
|
|
45654
45748
|
function getProjectRoot2() {
|
|
45655
45749
|
let dir = process.cwd();
|
|
45656
45750
|
while (dir !== "/") {
|
|
45657
|
-
if (
|
|
45658
|
-
dir =
|
|
45751
|
+
if (existsSync70(join70(dir, ".cleo", "config.json"))) return dir;
|
|
45752
|
+
dir = join70(dir, "..");
|
|
45659
45753
|
}
|
|
45660
45754
|
return process.cwd();
|
|
45661
45755
|
}
|
|
45662
45756
|
function getTokenFilePath() {
|
|
45663
|
-
return
|
|
45757
|
+
return join70(getProjectRoot2(), ".cleo", "metrics", "TOKEN_USAGE.jsonl");
|
|
45664
45758
|
}
|
|
45665
45759
|
function readJsonlFile(filePath) {
|
|
45666
|
-
if (!
|
|
45667
|
-
const content =
|
|
45760
|
+
if (!existsSync70(filePath)) return [];
|
|
45761
|
+
const content = readFileSync52(filePath, "utf-8").trim();
|
|
45668
45762
|
if (!content) return [];
|
|
45669
45763
|
return content.split("\n").map((line) => JSON.parse(line));
|
|
45670
45764
|
}
|
|
@@ -45746,10 +45840,10 @@ async function getRealTokenUsage(_opts) {
|
|
|
45746
45840
|
}
|
|
45747
45841
|
async function clearOtelData() {
|
|
45748
45842
|
const tokenFile = getTokenFilePath();
|
|
45749
|
-
if (
|
|
45843
|
+
if (existsSync70(tokenFile)) {
|
|
45750
45844
|
const backup = `${tokenFile}.backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
45751
45845
|
copyFileSync4(tokenFile, backup);
|
|
45752
|
-
|
|
45846
|
+
writeFileSync12(tokenFile, "");
|
|
45753
45847
|
return { message: "Token tracking cleared", backup };
|
|
45754
45848
|
}
|
|
45755
45849
|
return { message: "No token file to clear" };
|
|
@@ -46056,11 +46150,11 @@ init_output();
|
|
|
46056
46150
|
init_git_checkpoint();
|
|
46057
46151
|
init_paths();
|
|
46058
46152
|
import { execFile as execFile6 } from "node:child_process";
|
|
46059
|
-
import { resolve as
|
|
46153
|
+
import { resolve as resolve11 } from "node:path";
|
|
46060
46154
|
import { promisify as promisify8 } from "node:util";
|
|
46061
46155
|
var execFileAsync4 = promisify8(execFile6);
|
|
46062
46156
|
async function cleoGitExec(args, cleoDir) {
|
|
46063
|
-
const abs =
|
|
46157
|
+
const abs = resolve11(cleoDir);
|
|
46064
46158
|
const result = await execFileAsync4("git", args, {
|
|
46065
46159
|
cwd: abs,
|
|
46066
46160
|
env: makeCleoGitEnv(cleoDir),
|
|
@@ -46825,7 +46919,7 @@ function registerSafestopCommand(program2) {
|
|
|
46825
46919
|
// src/cli/commands/self-update.ts
|
|
46826
46920
|
import { execFile as execFile7 } from "node:child_process";
|
|
46827
46921
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
46828
|
-
import { join as
|
|
46922
|
+
import { join as join75 } from "node:path";
|
|
46829
46923
|
import * as readline from "node:readline";
|
|
46830
46924
|
import { promisify as promisify9 } from "node:util";
|
|
46831
46925
|
init_errors();
|
|
@@ -46836,13 +46930,13 @@ init_storage_preflight();
|
|
|
46836
46930
|
// src/core/upgrade.ts
|
|
46837
46931
|
import {
|
|
46838
46932
|
copyFileSync as copyFileSync5,
|
|
46839
|
-
existsSync as
|
|
46840
|
-
mkdirSync as
|
|
46933
|
+
existsSync as existsSync74,
|
|
46934
|
+
mkdirSync as mkdirSync20,
|
|
46841
46935
|
readdirSync as readdirSync20,
|
|
46842
|
-
readFileSync as
|
|
46843
|
-
writeFileSync as
|
|
46936
|
+
readFileSync as readFileSync55,
|
|
46937
|
+
writeFileSync as writeFileSync13
|
|
46844
46938
|
} from "node:fs";
|
|
46845
|
-
import { join as
|
|
46939
|
+
import { join as join74 } from "node:path";
|
|
46846
46940
|
|
|
46847
46941
|
// src/store/index.ts
|
|
46848
46942
|
init_atomic();
|
|
@@ -46888,8 +46982,8 @@ async function runUpgrade(options = {}) {
|
|
|
46888
46982
|
};
|
|
46889
46983
|
}
|
|
46890
46984
|
const cleoDir = getCleoDirAbsolute(options.cwd);
|
|
46891
|
-
const dbPath =
|
|
46892
|
-
const dbExists2 =
|
|
46985
|
+
const dbPath = join74(cleoDir, "tasks.db");
|
|
46986
|
+
const dbExists2 = existsSync74(dbPath);
|
|
46893
46987
|
const legacyRecordCount = preflight.details.todoJsonTaskCount + preflight.details.archiveJsonTaskCount + preflight.details.sessionsJsonCount;
|
|
46894
46988
|
const needsMigration = !dbExists2 && legacyRecordCount > 0;
|
|
46895
46989
|
const needsCleanup = dbExists2 && preflight.migrationNeeded;
|
|
@@ -46905,7 +46999,7 @@ async function runUpgrade(options = {}) {
|
|
|
46905
46999
|
let migrationLock = null;
|
|
46906
47000
|
try {
|
|
46907
47001
|
const cleoDir2 = getCleoDirAbsolute(options.cwd);
|
|
46908
|
-
const dbPath2 =
|
|
47002
|
+
const dbPath2 = join74(cleoDir2, "tasks.db");
|
|
46909
47003
|
try {
|
|
46910
47004
|
migrationLock = await acquireLock(dbPath2, { stale: 3e4, retries: 0 });
|
|
46911
47005
|
} catch {
|
|
@@ -46930,28 +47024,28 @@ async function runUpgrade(options = {}) {
|
|
|
46930
47024
|
} = await Promise.resolve().then(() => (init_state(), state_exports));
|
|
46931
47025
|
const logger = new MigrationLogger2(cleoDir2);
|
|
46932
47026
|
await createMigrationState2(cleoDir2, {
|
|
46933
|
-
todoJson: { path:
|
|
46934
|
-
sessionsJson: { path:
|
|
46935
|
-
archiveJson: { path:
|
|
47027
|
+
todoJson: { path: join74(cleoDir2, "todo.json"), checksum: "" },
|
|
47028
|
+
sessionsJson: { path: join74(cleoDir2, "sessions.json"), checksum: "" },
|
|
47029
|
+
archiveJson: { path: join74(cleoDir2, "todo-archive.json"), checksum: "" }
|
|
46936
47030
|
});
|
|
46937
47031
|
await updateMigrationPhase2(cleoDir2, "backup");
|
|
46938
47032
|
logger.info("init", "start", "Migration state initialized");
|
|
46939
|
-
const dbBackupPath =
|
|
47033
|
+
const dbBackupPath = join74(
|
|
46940
47034
|
cleoDir2,
|
|
46941
47035
|
"backups",
|
|
46942
47036
|
"safety",
|
|
46943
47037
|
`tasks.db.pre-migration.${Date.now()}`
|
|
46944
47038
|
);
|
|
46945
|
-
const dbTempPath =
|
|
46946
|
-
if (
|
|
46947
|
-
const backupDir =
|
|
46948
|
-
if (!
|
|
46949
|
-
|
|
47039
|
+
const dbTempPath = join74(cleoDir2, "tasks.db.migrating");
|
|
47040
|
+
if (existsSync74(dbPath2)) {
|
|
47041
|
+
const backupDir = join74(cleoDir2, "backups", "safety");
|
|
47042
|
+
if (!existsSync74(backupDir)) {
|
|
47043
|
+
mkdirSync20(backupDir, { recursive: true });
|
|
46950
47044
|
}
|
|
46951
47045
|
copyFileSync5(dbPath2, dbBackupPath);
|
|
46952
47046
|
const { createHash: createHash10 } = await import("node:crypto");
|
|
46953
|
-
const origChecksum = createHash10("sha256").update(
|
|
46954
|
-
const backupChecksum = createHash10("sha256").update(
|
|
47047
|
+
const origChecksum = createHash10("sha256").update(readFileSync55(dbPath2)).digest("hex");
|
|
47048
|
+
const backupChecksum = createHash10("sha256").update(readFileSync55(dbBackupPath)).digest("hex");
|
|
46955
47049
|
if (origChecksum !== backupChecksum) {
|
|
46956
47050
|
throw new Error(
|
|
46957
47051
|
`Backup verification failed: checksum mismatch. Aborting migration to prevent data loss.`
|
|
@@ -46968,14 +47062,14 @@ async function runUpgrade(options = {}) {
|
|
|
46968
47062
|
checksum: origChecksum
|
|
46969
47063
|
});
|
|
46970
47064
|
}
|
|
46971
|
-
if (
|
|
47065
|
+
if (existsSync74(dbTempPath)) {
|
|
46972
47066
|
const { unlinkSync: unlinkSync6 } = await import("node:fs");
|
|
46973
47067
|
unlinkSync6(dbTempPath);
|
|
46974
47068
|
}
|
|
46975
|
-
const configPath =
|
|
47069
|
+
const configPath = join74(cleoDir2, "config.json");
|
|
46976
47070
|
let configBackup = null;
|
|
46977
|
-
if (
|
|
46978
|
-
configBackup =
|
|
47071
|
+
if (existsSync74(configPath)) {
|
|
47072
|
+
configBackup = readFileSync55(configPath, "utf-8");
|
|
46979
47073
|
}
|
|
46980
47074
|
const { resetDbState: resetDbState2 } = await Promise.resolve().then(() => (init_sqlite(), sqlite_exports));
|
|
46981
47075
|
resetDbState2();
|
|
@@ -47003,10 +47097,10 @@ async function runUpgrade(options = {}) {
|
|
|
47003
47097
|
resetDbState2();
|
|
47004
47098
|
if (result.success) {
|
|
47005
47099
|
const totalImported = result.tasksImported + result.archivedImported;
|
|
47006
|
-
if (totalImported === 0 &&
|
|
47100
|
+
if (totalImported === 0 && existsSync74(dbBackupPath)) {
|
|
47007
47101
|
copyFileSync5(dbBackupPath, dbPath2);
|
|
47008
47102
|
if (configBackup) {
|
|
47009
|
-
|
|
47103
|
+
writeFileSync13(configPath, configBackup);
|
|
47010
47104
|
}
|
|
47011
47105
|
actions.push({
|
|
47012
47106
|
action: "storage_migration",
|
|
@@ -47017,9 +47111,9 @@ async function runUpgrade(options = {}) {
|
|
|
47017
47111
|
errors.push("Migration imported 0 tasks \u2014 restored from backup to prevent data loss");
|
|
47018
47112
|
} else {
|
|
47019
47113
|
let config = {};
|
|
47020
|
-
if (
|
|
47114
|
+
if (existsSync74(configPath)) {
|
|
47021
47115
|
try {
|
|
47022
|
-
config = JSON.parse(
|
|
47116
|
+
config = JSON.parse(readFileSync55(configPath, "utf-8"));
|
|
47023
47117
|
} catch {
|
|
47024
47118
|
}
|
|
47025
47119
|
}
|
|
@@ -47027,7 +47121,7 @@ async function runUpgrade(options = {}) {
|
|
|
47027
47121
|
config.storage = {};
|
|
47028
47122
|
}
|
|
47029
47123
|
config.storage.engine = "sqlite";
|
|
47030
|
-
|
|
47124
|
+
writeFileSync13(configPath, JSON.stringify(config, null, 2));
|
|
47031
47125
|
actions.push({
|
|
47032
47126
|
action: "storage_migration",
|
|
47033
47127
|
status: "applied",
|
|
@@ -47045,11 +47139,11 @@ async function runUpgrade(options = {}) {
|
|
|
47045
47139
|
logger.info("complete", "finish", "Migration completed successfully");
|
|
47046
47140
|
}
|
|
47047
47141
|
} else {
|
|
47048
|
-
if (
|
|
47142
|
+
if (existsSync74(dbBackupPath)) {
|
|
47049
47143
|
copyFileSync5(dbBackupPath, dbPath2);
|
|
47050
47144
|
}
|
|
47051
47145
|
if (configBackup) {
|
|
47052
|
-
|
|
47146
|
+
writeFileSync13(configPath, configBackup);
|
|
47053
47147
|
}
|
|
47054
47148
|
await updateMigrationPhase2(cleoDir2, "failed");
|
|
47055
47149
|
for (const error of result.errors) {
|
|
@@ -47068,12 +47162,12 @@ async function runUpgrade(options = {}) {
|
|
|
47068
47162
|
} catch (err) {
|
|
47069
47163
|
try {
|
|
47070
47164
|
const cleoDir2 = getCleoDirAbsolute(options.cwd);
|
|
47071
|
-
const dbPath2 =
|
|
47072
|
-
const safetyDir =
|
|
47073
|
-
if (
|
|
47165
|
+
const dbPath2 = join74(cleoDir2, "tasks.db");
|
|
47166
|
+
const safetyDir = join74(cleoDir2, "backups", "safety");
|
|
47167
|
+
if (existsSync74(safetyDir)) {
|
|
47074
47168
|
const backups = readdirSync20(safetyDir).filter((f) => f.startsWith("tasks.db.pre-migration.")).sort().reverse();
|
|
47075
|
-
if (backups.length > 0 && !
|
|
47076
|
-
copyFileSync5(
|
|
47169
|
+
if (backups.length > 0 && !existsSync74(dbPath2)) {
|
|
47170
|
+
copyFileSync5(join74(safetyDir, backups[0]), dbPath2);
|
|
47077
47171
|
}
|
|
47078
47172
|
}
|
|
47079
47173
|
} catch {
|
|
@@ -47108,7 +47202,7 @@ async function runUpgrade(options = {}) {
|
|
|
47108
47202
|
details: preflight.summary
|
|
47109
47203
|
});
|
|
47110
47204
|
}
|
|
47111
|
-
if (
|
|
47205
|
+
if (existsSync74(dbPath)) {
|
|
47112
47206
|
try {
|
|
47113
47207
|
const { runAllRepairs: runAllRepairs2 } = await Promise.resolve().then(() => (init_repair(), repair_exports));
|
|
47114
47208
|
const repairActions = await runAllRepairs2(options.cwd, isDryRun);
|
|
@@ -47118,9 +47212,9 @@ async function runUpgrade(options = {}) {
|
|
|
47118
47212
|
} catch {
|
|
47119
47213
|
}
|
|
47120
47214
|
}
|
|
47121
|
-
if (
|
|
47215
|
+
if (existsSync74(dbPath)) {
|
|
47122
47216
|
const legacySequenceFiles = [".sequence", ".sequence.json"].filter(
|
|
47123
|
-
(f) =>
|
|
47217
|
+
(f) => existsSync74(join74(cleoDir, f))
|
|
47124
47218
|
);
|
|
47125
47219
|
if (legacySequenceFiles.length > 0) {
|
|
47126
47220
|
if (isDryRun) {
|
|
@@ -47156,7 +47250,7 @@ async function runUpgrade(options = {}) {
|
|
|
47156
47250
|
".sequence",
|
|
47157
47251
|
".sequence.json"
|
|
47158
47252
|
];
|
|
47159
|
-
const foundStale = staleJsonFiles.filter((f) =>
|
|
47253
|
+
const foundStale = staleJsonFiles.filter((f) => existsSync74(join74(cleoDir, f)));
|
|
47160
47254
|
if (foundStale.length > 0) {
|
|
47161
47255
|
if (isDryRun) {
|
|
47162
47256
|
actions.push({
|
|
@@ -47166,15 +47260,15 @@ async function runUpgrade(options = {}) {
|
|
|
47166
47260
|
});
|
|
47167
47261
|
} else {
|
|
47168
47262
|
try {
|
|
47169
|
-
const backupDir =
|
|
47170
|
-
|
|
47263
|
+
const backupDir = join74(cleoDir, ".backups", `legacy-json-${Date.now()}`);
|
|
47264
|
+
mkdirSync20(backupDir, { recursive: true });
|
|
47171
47265
|
for (const f of foundStale) {
|
|
47172
|
-
const src =
|
|
47173
|
-
copyFileSync5(src,
|
|
47266
|
+
const src = join74(cleoDir, f);
|
|
47267
|
+
copyFileSync5(src, join74(backupDir, f));
|
|
47174
47268
|
}
|
|
47175
47269
|
const { unlinkSync: unlinkSync6 } = await import("node:fs");
|
|
47176
47270
|
for (const f of foundStale) {
|
|
47177
|
-
unlinkSync6(
|
|
47271
|
+
unlinkSync6(join74(cleoDir, f));
|
|
47178
47272
|
}
|
|
47179
47273
|
actions.push({
|
|
47180
47274
|
action: "stale_json_cleanup",
|
|
@@ -47194,7 +47288,7 @@ async function runUpgrade(options = {}) {
|
|
|
47194
47288
|
if (options.includeGlobal) {
|
|
47195
47289
|
try {
|
|
47196
47290
|
const globalDir = getCleoHome();
|
|
47197
|
-
const globalPreflight = checkStorageMigration(
|
|
47291
|
+
const globalPreflight = checkStorageMigration(join74(globalDir, ".."));
|
|
47198
47292
|
if (globalPreflight.migrationNeeded) {
|
|
47199
47293
|
actions.push({
|
|
47200
47294
|
action: "global_storage_check",
|
|
@@ -47215,8 +47309,8 @@ async function runUpgrade(options = {}) {
|
|
|
47215
47309
|
try {
|
|
47216
47310
|
const projectRoot = getProjectRoot(options.cwd);
|
|
47217
47311
|
if (isDryRun) {
|
|
47218
|
-
const gitignorePath =
|
|
47219
|
-
if (!
|
|
47312
|
+
const gitignorePath = join74(cleoDir, ".gitignore");
|
|
47313
|
+
if (!existsSync74(gitignorePath)) {
|
|
47220
47314
|
actions.push({
|
|
47221
47315
|
action: "gitignore_integrity",
|
|
47222
47316
|
status: "preview",
|
|
@@ -47267,8 +47361,8 @@ async function runUpgrade(options = {}) {
|
|
|
47267
47361
|
try {
|
|
47268
47362
|
const projectRootForContext = getProjectRoot(options.cwd);
|
|
47269
47363
|
if (isDryRun) {
|
|
47270
|
-
const contextPath =
|
|
47271
|
-
if (!
|
|
47364
|
+
const contextPath = join74(cleoDir, "project-context.json");
|
|
47365
|
+
if (!existsSync74(contextPath)) {
|
|
47272
47366
|
actions.push({
|
|
47273
47367
|
action: "project_context_detection",
|
|
47274
47368
|
status: "preview",
|
|
@@ -47276,7 +47370,7 @@ async function runUpgrade(options = {}) {
|
|
|
47276
47370
|
});
|
|
47277
47371
|
} else {
|
|
47278
47372
|
try {
|
|
47279
|
-
const context = JSON.parse(
|
|
47373
|
+
const context = JSON.parse(readFileSync55(contextPath, "utf-8"));
|
|
47280
47374
|
if (context.detectedAt) {
|
|
47281
47375
|
const daysSince = (Date.now() - new Date(context.detectedAt).getTime()) / (1e3 * 60 * 60 * 24);
|
|
47282
47376
|
if (daysSince > 30) {
|
|
@@ -47505,7 +47599,7 @@ var GITHUB_REPO = BUILD_CONFIG.repository.fullName;
|
|
|
47505
47599
|
async function getCurrentVersion() {
|
|
47506
47600
|
const cleoHome = getCleoHome();
|
|
47507
47601
|
try {
|
|
47508
|
-
const content = await readFile19(
|
|
47602
|
+
const content = await readFile19(join75(cleoHome, "VERSION"), "utf-8");
|
|
47509
47603
|
return (content.split("\n")[0] ?? "unknown").trim();
|
|
47510
47604
|
} catch {
|
|
47511
47605
|
return "unknown";
|
|
@@ -47559,7 +47653,7 @@ async function writeRuntimeVersionMetadata(mode, source, version) {
|
|
|
47559
47653
|
];
|
|
47560
47654
|
await import("node:fs/promises").then(
|
|
47561
47655
|
({ writeFile: writeFile14, mkdir: mkdir14 }) => mkdir14(cleoHome, { recursive: true }).then(
|
|
47562
|
-
() => writeFile14(
|
|
47656
|
+
() => writeFile14(join75(cleoHome, "VERSION"), `${lines.join("\n")}
|
|
47563
47657
|
`, "utf-8")
|
|
47564
47658
|
)
|
|
47565
47659
|
);
|
|
@@ -47752,11 +47846,11 @@ async function runPostUpdateDiagnostics(opts) {
|
|
|
47752
47846
|
input: process.stdin,
|
|
47753
47847
|
output: process.stdout
|
|
47754
47848
|
});
|
|
47755
|
-
shouldMigrate = await new Promise((
|
|
47849
|
+
shouldMigrate = await new Promise((resolve12) => {
|
|
47756
47850
|
rl.question(" Do you want to run the upgrade now? [Y/n] ", (answer) => {
|
|
47757
47851
|
rl.close();
|
|
47758
47852
|
const clean = answer.trim().toLowerCase();
|
|
47759
|
-
|
|
47853
|
+
resolve12(clean === "" || clean === "y" || clean === "yes");
|
|
47760
47854
|
});
|
|
47761
47855
|
});
|
|
47762
47856
|
}
|
|
@@ -48507,12 +48601,12 @@ function registerTestingCommand(program2) {
|
|
|
48507
48601
|
}
|
|
48508
48602
|
|
|
48509
48603
|
// src/cli/commands/token.ts
|
|
48510
|
-
import { readFileSync as
|
|
48604
|
+
import { readFileSync as readFileSync56 } from "node:fs";
|
|
48511
48605
|
init_renderers();
|
|
48512
48606
|
function readPayload(opts, textKey, fileKey) {
|
|
48513
48607
|
const text5 = opts[textKey];
|
|
48514
48608
|
const file = opts[fileKey];
|
|
48515
|
-
if (file) return
|
|
48609
|
+
if (file) return readFileSync56(file, "utf-8");
|
|
48516
48610
|
return text5;
|
|
48517
48611
|
}
|
|
48518
48612
|
function registerTokenCommand(program2) {
|
|
@@ -48745,15 +48839,15 @@ init_exit_codes();
|
|
|
48745
48839
|
init_renderers();
|
|
48746
48840
|
import { execFileSync as execFileSync13, spawn as spawn2 } from "node:child_process";
|
|
48747
48841
|
import { mkdir as mkdir13, readFile as readFile20, rm as rm4, stat as stat4, writeFile as writeFile13 } from "node:fs/promises";
|
|
48748
|
-
import { join as
|
|
48842
|
+
import { join as join76 } from "node:path";
|
|
48749
48843
|
var DEFAULT_PORT = 3456;
|
|
48750
48844
|
var DEFAULT_HOST = "127.0.0.1";
|
|
48751
48845
|
function getWebPaths() {
|
|
48752
48846
|
const cleoHome = getCleoHome();
|
|
48753
48847
|
return {
|
|
48754
|
-
pidFile:
|
|
48755
|
-
configFile:
|
|
48756
|
-
logFile:
|
|
48848
|
+
pidFile: join76(cleoHome, "web-server.pid"),
|
|
48849
|
+
configFile: join76(cleoHome, "web-server.json"),
|
|
48850
|
+
logFile: join76(cleoHome, "logs", "web-server.log")
|
|
48757
48851
|
};
|
|
48758
48852
|
}
|
|
48759
48853
|
function isProcessRunning(pid) {
|
|
@@ -48800,8 +48894,8 @@ function registerWebCommand(program2) {
|
|
|
48800
48894
|
);
|
|
48801
48895
|
}
|
|
48802
48896
|
const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
|
|
48803
|
-
const distMcpDir =
|
|
48804
|
-
await mkdir13(
|
|
48897
|
+
const distMcpDir = join76(projectRoot, "dist", "mcp");
|
|
48898
|
+
await mkdir13(join76(getCleoHome(), "logs"), { recursive: true });
|
|
48805
48899
|
await writeFile13(
|
|
48806
48900
|
configFile,
|
|
48807
48901
|
JSON.stringify({
|
|
@@ -48810,7 +48904,7 @@ function registerWebCommand(program2) {
|
|
|
48810
48904
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
48811
48905
|
})
|
|
48812
48906
|
);
|
|
48813
|
-
const webIndexPath =
|
|
48907
|
+
const webIndexPath = join76(distMcpDir, "index.js");
|
|
48814
48908
|
try {
|
|
48815
48909
|
await stat4(webIndexPath);
|
|
48816
48910
|
} catch {
|
|
@@ -48843,7 +48937,7 @@ function registerWebCommand(program2) {
|
|
|
48843
48937
|
}
|
|
48844
48938
|
} catch {
|
|
48845
48939
|
}
|
|
48846
|
-
await new Promise((
|
|
48940
|
+
await new Promise((resolve12) => setTimeout(resolve12, 500));
|
|
48847
48941
|
}
|
|
48848
48942
|
if (!started) {
|
|
48849
48943
|
try {
|
|
@@ -48885,7 +48979,7 @@ function registerWebCommand(program2) {
|
|
|
48885
48979
|
}
|
|
48886
48980
|
for (let i = 0; i < 10; i++) {
|
|
48887
48981
|
if (!isProcessRunning(status.pid)) break;
|
|
48888
|
-
await new Promise((
|
|
48982
|
+
await new Promise((resolve12) => setTimeout(resolve12, 500));
|
|
48889
48983
|
}
|
|
48890
48984
|
if (isProcessRunning(status.pid)) {
|
|
48891
48985
|
try {
|
|
@@ -48952,10 +49046,10 @@ init_format_context();
|
|
|
48952
49046
|
// src/cli/logger-bootstrap.ts
|
|
48953
49047
|
init_logger();
|
|
48954
49048
|
init_project_info();
|
|
48955
|
-
import { join as
|
|
49049
|
+
import { join as join77 } from "node:path";
|
|
48956
49050
|
function initCliLogger(cwd, loggingConfig) {
|
|
48957
49051
|
const projectInfo = getProjectInfoSync(cwd);
|
|
48958
|
-
initLogger(
|
|
49052
|
+
initLogger(join77(cwd, ".cleo"), loggingConfig, projectInfo?.projectHash);
|
|
48959
49053
|
}
|
|
48960
49054
|
|
|
48961
49055
|
// src/cli/middleware/output-format.ts
|
|
@@ -49166,8 +49260,8 @@ Upgrade options:
|
|
|
49166
49260
|
}
|
|
49167
49261
|
function getPackageVersion() {
|
|
49168
49262
|
try {
|
|
49169
|
-
const moduleRoot =
|
|
49170
|
-
const pkg = JSON.parse(
|
|
49263
|
+
const moduleRoot = join78(import.meta.dirname ?? "", "..", "..");
|
|
49264
|
+
const pkg = JSON.parse(readFileSync57(join78(moduleRoot, "package.json"), "utf-8"));
|
|
49171
49265
|
return pkg.version ?? "0.0.0";
|
|
49172
49266
|
} catch {
|
|
49173
49267
|
return "0.0.0";
|
|
@@ -49279,7 +49373,7 @@ program.hook("preAction", async () => {
|
|
|
49279
49373
|
const config = await loadConfig();
|
|
49280
49374
|
initCliLogger(process.cwd(), config.logging);
|
|
49281
49375
|
const { pruneAuditLog: pruneAuditLog2 } = await Promise.resolve().then(() => (init_audit_prune(), audit_prune_exports));
|
|
49282
|
-
pruneAuditLog2(
|
|
49376
|
+
pruneAuditLog2(join78(process.cwd(), ".cleo"), config.logging).catch(() => {
|
|
49283
49377
|
});
|
|
49284
49378
|
} catch {
|
|
49285
49379
|
}
|
|
@@ -49319,7 +49413,7 @@ program.hook("preAction", (thisCommand) => {
|
|
|
49319
49413
|
}
|
|
49320
49414
|
});
|
|
49321
49415
|
if (process.argv[2] === "mcp") {
|
|
49322
|
-
const mcpPath =
|
|
49416
|
+
const mcpPath = join78(import.meta.dirname ?? "", "..", "mcp", "index.js");
|
|
49323
49417
|
const { spawn: spawn3 } = await import("node:child_process");
|
|
49324
49418
|
const child = spawn3(process.execPath, ["--disable-warning=ExperimentalWarning", mcpPath], {
|
|
49325
49419
|
stdio: "inherit"
|