@cleocode/core 2026.6.8 → 2026.6.10
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/docs/display-alias.d.ts +97 -0
- package/dist/docs/display-alias.d.ts.map +1 -0
- package/dist/docs/display-alias.js +136 -0
- package/dist/docs/display-alias.js.map +1 -0
- package/dist/docs/docs-read-model.d.ts +7 -0
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +11 -2
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/export-document.js +259 -131
- package/dist/docs/export-document.js.map +2 -2
- package/dist/docs/index.d.ts +2 -0
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +1 -0
- package/dist/docs/index.js.map +1 -1
- package/dist/docs/numbering.d.ts +29 -0
- package/dist/docs/numbering.d.ts.map +1 -1
- package/dist/docs/numbering.js +41 -0
- package/dist/docs/numbering.js.map +1 -1
- package/dist/internal.d.ts +3 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -1
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +372 -243
- package/dist/llm/plugin-facade.js.map +2 -2
- package/dist/store/attachment-store.d.ts +5 -0
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +7 -1
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +15 -0
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/migration-manager.d.ts +99 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +323 -23
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/schema/attachments.d.ts +16 -0
- package/dist/store/schema/attachments.d.ts.map +1 -1
- package/dist/store/schema/attachments.js +30 -0
- package/dist/store/schema/attachments.js.map +1 -1
- package/migrations/drizzle-tasks/20260606000001_t11875-attachments-display-alias/migration.sql +46 -0
- package/package.json +12 -12
|
@@ -14656,7 +14656,7 @@ var init_sql = __esm({
|
|
|
14656
14656
|
return new SQL([new StringChunk(str)]);
|
|
14657
14657
|
}
|
|
14658
14658
|
_sql.raw = raw;
|
|
14659
|
-
function
|
|
14659
|
+
function join28(chunks, separator) {
|
|
14660
14660
|
const result = [];
|
|
14661
14661
|
for (const [i, chunk] of chunks.entries()) {
|
|
14662
14662
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -14664,7 +14664,7 @@ var init_sql = __esm({
|
|
|
14664
14664
|
}
|
|
14665
14665
|
return new SQL(result);
|
|
14666
14666
|
}
|
|
14667
|
-
_sql.join =
|
|
14667
|
+
_sql.join = join28;
|
|
14668
14668
|
function identifier(value) {
|
|
14669
14669
|
return new Name(value);
|
|
14670
14670
|
}
|
|
@@ -17051,7 +17051,7 @@ var init_select2 = __esm({
|
|
|
17051
17051
|
const baseTableName = this.tableName;
|
|
17052
17052
|
const tableName = getTableLikeName(table);
|
|
17053
17053
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
17054
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
17054
|
+
if (typeof tableName === "string" && this.config.joins?.some((join28) => join28.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
17055
17055
|
if (!this.isPartialSelect) {
|
|
17056
17056
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
17057
17057
|
if (typeof tableName === "string" && !is(table, SQL)) {
|
|
@@ -20861,7 +20861,7 @@ var init_dialect = __esm({
|
|
|
20861
20861
|
if (!joins2) return;
|
|
20862
20862
|
const withEntries = Object.entries(joins2).filter(([_, v]) => v);
|
|
20863
20863
|
if (!withEntries.length) return;
|
|
20864
|
-
return sql.join(withEntries.map(([k,
|
|
20864
|
+
return sql.join(withEntries.map(([k, join28]) => {
|
|
20865
20865
|
const relation = tableConfig.relations[k];
|
|
20866
20866
|
const isSingle2 = is(relation, One);
|
|
20867
20867
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -20872,7 +20872,7 @@ var init_dialect = __esm({
|
|
|
20872
20872
|
table: targetTable,
|
|
20873
20873
|
mode: isSingle2 ? "first" : "many",
|
|
20874
20874
|
schema,
|
|
20875
|
-
queryConfig:
|
|
20875
|
+
queryConfig: join28,
|
|
20876
20876
|
tableConfig: schema[relation.targetTableName],
|
|
20877
20877
|
relationWhere: filter2,
|
|
20878
20878
|
isNested: true,
|
|
@@ -20886,7 +20886,7 @@ var init_dialect = __esm({
|
|
|
20886
20886
|
key: k,
|
|
20887
20887
|
selection: innerQuery.selection,
|
|
20888
20888
|
isArray: !isSingle2,
|
|
20889
|
-
isOptional: (relation.optional ?? false) ||
|
|
20889
|
+
isOptional: (relation.optional ?? false) || join28 !== true && !!join28.where
|
|
20890
20890
|
});
|
|
20891
20891
|
const jsonColumns = sql.join(innerQuery.selection.map((s) => {
|
|
20892
20892
|
return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb3}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
|
|
@@ -21707,7 +21707,7 @@ var init_update = __esm({
|
|
|
21707
21707
|
createJoin(joinType) {
|
|
21708
21708
|
return ((table, on) => {
|
|
21709
21709
|
const tableName = getTableLikeName(table);
|
|
21710
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
21710
|
+
if (typeof tableName === "string" && this.config.joins.some((join28) => join28.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
21711
21711
|
if (typeof on === "function") {
|
|
21712
21712
|
const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
|
|
21713
21713
|
on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -22651,6 +22651,67 @@ var init_with_retry = __esm({
|
|
|
22651
22651
|
});
|
|
22652
22652
|
|
|
22653
22653
|
// packages/core/src/store/migration-manager.ts
|
|
22654
|
+
import { copyFileSync, existsSync as existsSync2 } from "node:fs";
|
|
22655
|
+
import { dirname, join as join3 } from "node:path";
|
|
22656
|
+
function stripSqlComments(sql32) {
|
|
22657
|
+
return sql32.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
22658
|
+
}
|
|
22659
|
+
function computeEliminatedTables(migrations) {
|
|
22660
|
+
const createTableRegex = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"]?(\w+)[`"]?/i;
|
|
22661
|
+
const dropTableRegex = /DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?[`"]?(\w+)[`"]?/i;
|
|
22662
|
+
const renameRegex = /ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+RENAME\s+TO\s+[`"]?(\w+)[`"]?/i;
|
|
22663
|
+
const disposition = /* @__PURE__ */ new Map();
|
|
22664
|
+
const ordered = [...migrations].sort((a, b) => a.folderMillis - b.folderMillis);
|
|
22665
|
+
for (const migration of ordered) {
|
|
22666
|
+
const statements = Array.isArray(migration.sql) ? migration.sql : [migration.sql ?? ""];
|
|
22667
|
+
for (const rawStatement of statements) {
|
|
22668
|
+
const stripped = stripSqlComments(rawStatement);
|
|
22669
|
+
for (const clause of stripped.split(";")) {
|
|
22670
|
+
const create = createTableRegex.exec(clause);
|
|
22671
|
+
if (create) {
|
|
22672
|
+
disposition.set(create[1], true);
|
|
22673
|
+
continue;
|
|
22674
|
+
}
|
|
22675
|
+
const rename2 = renameRegex.exec(clause);
|
|
22676
|
+
if (rename2) {
|
|
22677
|
+
disposition.set(rename2[2], true);
|
|
22678
|
+
continue;
|
|
22679
|
+
}
|
|
22680
|
+
const drop = dropTableRegex.exec(clause);
|
|
22681
|
+
if (drop) {
|
|
22682
|
+
disposition.set(drop[1], false);
|
|
22683
|
+
}
|
|
22684
|
+
}
|
|
22685
|
+
}
|
|
22686
|
+
}
|
|
22687
|
+
const eliminated = /* @__PURE__ */ new Set();
|
|
22688
|
+
for (const [table, present] of disposition) {
|
|
22689
|
+
if (!present) eliminated.add(table);
|
|
22690
|
+
}
|
|
22691
|
+
return eliminated;
|
|
22692
|
+
}
|
|
22693
|
+
function resolveConsolidationCutoverPrefix(migrationsFolder) {
|
|
22694
|
+
const parent = dirname(migrationsFolder);
|
|
22695
|
+
for (const setName of ["drizzle-cleo-project", "drizzle-cleo-global"]) {
|
|
22696
|
+
const folder = join3(parent, setName);
|
|
22697
|
+
if (!existsSync2(folder)) continue;
|
|
22698
|
+
try {
|
|
22699
|
+
const consolidation = readMigrationFiles({ migrationsFolder: folder }).find(
|
|
22700
|
+
(m) => /-consolidation-cleo-/.test(m.name ?? "")
|
|
22701
|
+
);
|
|
22702
|
+
if (consolidation?.name) {
|
|
22703
|
+
return consolidation.name.slice(0, MIGRATION_TIMESTAMP_PREFIX_LEN);
|
|
22704
|
+
}
|
|
22705
|
+
} catch {
|
|
22706
|
+
}
|
|
22707
|
+
}
|
|
22708
|
+
return CONSOLIDATION_CUTOVER_PREFIX;
|
|
22709
|
+
}
|
|
22710
|
+
function isAtOrBeforeCutover(migrationName, cutoverPrefix) {
|
|
22711
|
+
const prefix = (migrationName ?? "").slice(0, MIGRATION_TIMESTAMP_PREFIX_LEN);
|
|
22712
|
+
if (prefix.length < MIGRATION_TIMESTAMP_PREFIX_LEN) return true;
|
|
22713
|
+
return prefix <= cutoverPrefix;
|
|
22714
|
+
}
|
|
22654
22715
|
function tableExists(nativeDb, tableName) {
|
|
22655
22716
|
const result = nativeDb.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(tableName);
|
|
22656
22717
|
return !!result;
|
|
@@ -22668,9 +22729,9 @@ function insertJournalEntry(nativeDb, hash2, createdAt, name15) {
|
|
|
22668
22729
|
`INSERT OR IGNORE INTO "__drizzle_migrations" ("hash", "created_at", "name") VALUES ('${hash2}', ${createdAt}, '${name15}')`
|
|
22669
22730
|
);
|
|
22670
22731
|
}
|
|
22671
|
-
function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
22732
|
+
function probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables = /* @__PURE__ */ new Set(), consolidationCutoverPrefix = CONSOLIDATION_CUTOVER_PREFIX) {
|
|
22672
22733
|
const sqlStatements = Array.isArray(migration.sql) ? migration.sql : [migration.sql ?? ""];
|
|
22673
|
-
const fullSql = sqlStatements.join("\n");
|
|
22734
|
+
const fullSql = stripSqlComments(sqlStatements.join("\n"));
|
|
22674
22735
|
const alterColumnRegex = /ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+COLUMN\s+[`"]?(\w+)[`"]?/gi;
|
|
22675
22736
|
const createTableRegex = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"]?(\w+)[`"]?/gi;
|
|
22676
22737
|
const createIndexRegex = /CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"]?(\w+)[`"]?/gi;
|
|
@@ -22697,10 +22758,17 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
|
22697
22758
|
}
|
|
22698
22759
|
const isRebuildOnlyMigration = allCreatedTablesAreRenamed && tableTargets.length > 0 && alterTargets.length === 0;
|
|
22699
22760
|
const performsTableRebuild = renameMap.size > 0;
|
|
22761
|
+
const createIndexWithTableRegex = /CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"]?(\w+)[`"]?\s+ON\s+[`"]?(\w+)[`"]?/gi;
|
|
22762
|
+
const indexOnTable = /* @__PURE__ */ new Map();
|
|
22763
|
+
for (const m of fullSql.matchAll(createIndexWithTableRegex)) {
|
|
22764
|
+
indexOnTable.set(m[1], m[2]);
|
|
22765
|
+
}
|
|
22700
22766
|
const indexTargets = [];
|
|
22701
22767
|
if (!isRebuildOnlyMigration && !performsTableRebuild) {
|
|
22702
22768
|
for (const m of fullSql.matchAll(createIndexRegex)) {
|
|
22703
|
-
|
|
22769
|
+
const idx = m[1];
|
|
22770
|
+
if (eliminatedTables.has(indexOnTable.get(idx) ?? "")) continue;
|
|
22771
|
+
indexTargets.push(idx);
|
|
22704
22772
|
}
|
|
22705
22773
|
}
|
|
22706
22774
|
const triggerTargets = [];
|
|
@@ -22709,6 +22777,14 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
|
22709
22777
|
}
|
|
22710
22778
|
const totalTargets = alterTargets.length + tableTargets.length + indexTargets.length + triggerTargets.length;
|
|
22711
22779
|
if (totalTargets === 0) {
|
|
22780
|
+
if (isAtOrBeforeCutover(migration.name, consolidationCutoverPrefix)) {
|
|
22781
|
+
insertJournalEntry(nativeDb, migration.hash, migration.folderMillis, migration.name ?? "");
|
|
22782
|
+
getLogger(logSubsystem).debug(
|
|
22783
|
+
{ migration: migration.name },
|
|
22784
|
+
`Zero-DDL pre-consolidation migration ${migration.name} stamped applied (subsumed; not re-run).`
|
|
22785
|
+
);
|
|
22786
|
+
return true;
|
|
22787
|
+
}
|
|
22712
22788
|
return false;
|
|
22713
22789
|
}
|
|
22714
22790
|
const allAltersPresent = alterTargets.every(({ table, column }) => {
|
|
@@ -22716,7 +22792,9 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
|
22716
22792
|
const cols = nativeDb.prepare(`PRAGMA table_info(${table})`).all();
|
|
22717
22793
|
return cols.some((c) => c.name === column);
|
|
22718
22794
|
});
|
|
22719
|
-
const allTablesPresent = tableTargets.every(
|
|
22795
|
+
const allTablesPresent = tableTargets.every(
|
|
22796
|
+
(t) => tableExists(nativeDb, t) || eliminatedTables.has(t)
|
|
22797
|
+
);
|
|
22720
22798
|
const allIndexesPresent = indexTargets.every((idx) => {
|
|
22721
22799
|
const rows = nativeDb.prepare(`SELECT name FROM sqlite_master WHERE type='index' AND name=?`).all(idx);
|
|
22722
22800
|
return rows.length > 0;
|
|
@@ -22743,6 +22821,8 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
|
22743
22821
|
return false;
|
|
22744
22822
|
}
|
|
22745
22823
|
function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsystem) {
|
|
22824
|
+
const eliminatedTables = computeEliminatedTables(readMigrationFiles({ migrationsFolder }));
|
|
22825
|
+
const cutoverPrefix = resolveConsolidationCutoverPrefix(migrationsFolder);
|
|
22746
22826
|
if (tableExists(nativeDb, existenceTable2) && !tableExists(nativeDb, "__drizzle_migrations")) {
|
|
22747
22827
|
const migrations = readMigrationFiles({ migrationsFolder });
|
|
22748
22828
|
const baseline = migrations[0];
|
|
@@ -22786,7 +22866,7 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22786
22866
|
);
|
|
22787
22867
|
for (const m of localMigrations) {
|
|
22788
22868
|
if (journaledHashesAfter.has(m.hash)) continue;
|
|
22789
|
-
probeAndMarkApplied(nativeDb, m, logSubsystem);
|
|
22869
|
+
probeAndMarkApplied(nativeDb, m, logSubsystem, eliminatedTables, cutoverPrefix);
|
|
22790
22870
|
}
|
|
22791
22871
|
}
|
|
22792
22872
|
}
|
|
@@ -22809,7 +22889,7 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22809
22889
|
});
|
|
22810
22890
|
}
|
|
22811
22891
|
if (alterMatches.length === 0) {
|
|
22812
|
-
const stripped = fullSql
|
|
22892
|
+
const stripped = stripSqlComments(fullSql).trim();
|
|
22813
22893
|
if (stripped === "") {
|
|
22814
22894
|
const log7 = getLogger(logSubsystem);
|
|
22815
22895
|
log7.debug(
|
|
@@ -22828,9 +22908,11 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22828
22908
|
const createTableRe = /CREATE\s+TABLE/i;
|
|
22829
22909
|
const createTriggerRe = /CREATE\s+TRIGGER/i;
|
|
22830
22910
|
if (renameRe.test(fullSql) && createTableRe.test(fullSql)) {
|
|
22831
|
-
probeAndMarkApplied(nativeDb, migration, logSubsystem);
|
|
22911
|
+
probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables, cutoverPrefix);
|
|
22832
22912
|
} else if (createTableRe.test(fullSql) || createTriggerRe.test(fullSql)) {
|
|
22833
|
-
probeAndMarkApplied(nativeDb, migration, logSubsystem);
|
|
22913
|
+
probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables, cutoverPrefix);
|
|
22914
|
+
} else {
|
|
22915
|
+
probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables, cutoverPrefix);
|
|
22834
22916
|
}
|
|
22835
22917
|
continue;
|
|
22836
22918
|
}
|
|
@@ -22907,13 +22989,22 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22907
22989
|
}
|
|
22908
22990
|
}
|
|
22909
22991
|
}
|
|
22992
|
+
function collectErrorMessages(err) {
|
|
22993
|
+
const messages = [];
|
|
22994
|
+
let current = err;
|
|
22995
|
+
for (let depth = 0; current instanceof Error && depth < 16; depth++) {
|
|
22996
|
+
messages.push(current.message);
|
|
22997
|
+
current = current.cause;
|
|
22998
|
+
}
|
|
22999
|
+
return messages.join("\n");
|
|
23000
|
+
}
|
|
22910
23001
|
function isDuplicateColumnError(err) {
|
|
22911
23002
|
if (!(err instanceof Error)) return false;
|
|
22912
|
-
return /duplicate column name/i.test(err
|
|
23003
|
+
return /duplicate column name/i.test(collectErrorMessages(err));
|
|
22913
23004
|
}
|
|
22914
23005
|
function isTableAlreadyExistsError(err) {
|
|
22915
23006
|
if (!(err instanceof Error)) return false;
|
|
22916
|
-
return /table .+ already exists/i.test(err
|
|
23007
|
+
return /table .+ already exists/i.test(collectErrorMessages(err));
|
|
22917
23008
|
}
|
|
22918
23009
|
function isExecutableStatement(stmt) {
|
|
22919
23010
|
if (stmt.trim() === "") return false;
|
|
@@ -22984,7 +23075,7 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem, conte
|
|
|
22984
23075
|
}
|
|
22985
23076
|
}
|
|
22986
23077
|
}
|
|
22987
|
-
var MAX_MIGRATION_RETRIES, MIGRATION_RETRY_BASE_DELAY_MS, MIGRATION_RETRY_MAX_DELAY_MS;
|
|
23078
|
+
var MAX_MIGRATION_RETRIES, MIGRATION_RETRY_BASE_DELAY_MS, MIGRATION_RETRY_MAX_DELAY_MS, CONSOLIDATION_CUTOVER_PREFIX, MIGRATION_TIMESTAMP_PREFIX_LEN;
|
|
22988
23079
|
var init_migration_manager = __esm({
|
|
22989
23080
|
"packages/core/src/store/migration-manager.ts"() {
|
|
22990
23081
|
"use strict";
|
|
@@ -22994,27 +23085,29 @@ var init_migration_manager = __esm({
|
|
|
22994
23085
|
MAX_MIGRATION_RETRIES = 5;
|
|
22995
23086
|
MIGRATION_RETRY_BASE_DELAY_MS = 100;
|
|
22996
23087
|
MIGRATION_RETRY_MAX_DELAY_MS = 2e3;
|
|
23088
|
+
CONSOLIDATION_CUTOVER_PREFIX = "20260531000001";
|
|
23089
|
+
MIGRATION_TIMESTAMP_PREFIX_LEN = 14;
|
|
22997
23090
|
}
|
|
22998
23091
|
});
|
|
22999
23092
|
|
|
23000
23093
|
// packages/core/src/store/resolve-migrations-folder.ts
|
|
23001
23094
|
import { createRequire } from "node:module";
|
|
23002
|
-
import { dirname, join as
|
|
23095
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
23003
23096
|
import { fileURLToPath } from "node:url";
|
|
23004
23097
|
function coreRootFromEntry(entryPath) {
|
|
23005
|
-
return
|
|
23098
|
+
return dirname2(dirname2(entryPath));
|
|
23006
23099
|
}
|
|
23007
23100
|
function resolveCorePackageMigrationsFolder(setName) {
|
|
23008
23101
|
try {
|
|
23009
23102
|
const resolved = import.meta.resolve("@cleocode/core", import.meta.url);
|
|
23010
23103
|
const entryPath = fileURLToPath(resolved);
|
|
23011
|
-
return
|
|
23104
|
+
return join4(coreRootFromEntry(entryPath), "migrations", setName);
|
|
23012
23105
|
} catch {
|
|
23013
23106
|
}
|
|
23014
23107
|
const _require3 = createRequire(import.meta.url);
|
|
23015
23108
|
try {
|
|
23016
23109
|
const entryPath = _require3.resolve("@cleocode/core");
|
|
23017
|
-
return
|
|
23110
|
+
return join4(coreRootFromEntry(entryPath), "migrations", setName);
|
|
23018
23111
|
} catch (err) {
|
|
23019
23112
|
throw new Error(
|
|
23020
23113
|
`resolveCorePackageMigrationsFolder("${setName}"): cannot locate @cleocode/core from "${import.meta.url}". Ensure @cleocode/core is installed (workspace or npm). Original error: ${err.message}`
|
|
@@ -27326,12 +27419,42 @@ var init_attachments = __esm({
|
|
|
27326
27419
|
*
|
|
27327
27420
|
* @task T11181 (Epic T10518 / Saga T10516)
|
|
27328
27421
|
*/
|
|
27329
|
-
docVersion: integer("doc_version").notNull().default(1)
|
|
27422
|
+
docVersion: integer("doc_version").notNull().default(1),
|
|
27423
|
+
/**
|
|
27424
|
+
* Optional explicit display-alias NUMBER for the doc, DECOUPLED from the
|
|
27425
|
+
* slug string.
|
|
27426
|
+
*
|
|
27427
|
+
* Background (T11875 · ADR reconcile T11676): under the ratified
|
|
27428
|
+
* slug-primary model the kebab `slug` is the canonical handle and the
|
|
27429
|
+
* displayed number (e.g. ADR "051") is a DISPLAY ALIAS only. Previously
|
|
27430
|
+
* that number was DERIVED by parsing the digits out of the slug
|
|
27431
|
+
* (`adr-051-*` → 051), so three distinct ADRs that all slug as `adr-051-*`
|
|
27432
|
+
* collided on the rendered number with no way to disambiguate.
|
|
27433
|
+
*
|
|
27434
|
+
* When non-null, this column is the authoritative display number and is
|
|
27435
|
+
* PREFERRED over the slug-derived number by
|
|
27436
|
+
* {@link import('../../docs/numbering.js').resolveDisplayNumber}. When null,
|
|
27437
|
+
* rendering falls back to the slug-derived number unchanged — so docs that
|
|
27438
|
+
* never had an alias assigned keep their historical behaviour.
|
|
27439
|
+
*
|
|
27440
|
+
* Uniqueness among `type='adr'` docs is enforced at the dispatch layer (not
|
|
27441
|
+
* via a SQL UNIQUE constraint) by
|
|
27442
|
+
* {@link import('../../docs/display-alias.js').setDisplayAlias}, mirroring
|
|
27443
|
+
* the dispatch-validated discipline used for `lifecycle_status` /
|
|
27444
|
+
* `relation` so future taxonomy changes never require a schema migration.
|
|
27445
|
+
*
|
|
27446
|
+
* @task T11875 (Epic T11781 / Saga T11778)
|
|
27447
|
+
*/
|
|
27448
|
+
displayAlias: integer("display_alias")
|
|
27330
27449
|
},
|
|
27331
27450
|
(table) => [
|
|
27332
27451
|
index("idx_attachments_sha256").on(table.sha256),
|
|
27333
27452
|
index("idx_attachments_lifecycle_status").on(table.lifecycleStatus),
|
|
27334
|
-
index("idx_attachments_supersedes").on(table.supersedes)
|
|
27453
|
+
index("idx_attachments_supersedes").on(table.supersedes),
|
|
27454
|
+
// Speeds the per-type uniqueness scan in `setDisplayAlias` (T11875). Not a
|
|
27455
|
+
// UNIQUE index — uniqueness is scoped to `type='adr'` and enforced at the
|
|
27456
|
+
// dispatch layer so non-adr kinds may reuse numbers freely.
|
|
27457
|
+
index("idx_attachments_display_alias").on(table.displayAlias)
|
|
27335
27458
|
]
|
|
27336
27459
|
);
|
|
27337
27460
|
attachmentRefs = sqliteTable(
|
|
@@ -31064,11 +31187,11 @@ var init_lock = __esm({
|
|
|
31064
31187
|
|
|
31065
31188
|
// packages/core/src/store/atomic.ts
|
|
31066
31189
|
import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
|
|
31067
|
-
import { dirname as
|
|
31190
|
+
import { dirname as dirname3 } from "node:path";
|
|
31068
31191
|
import writeFileAtomic from "write-file-atomic";
|
|
31069
31192
|
async function atomicWrite(filePath, data, options) {
|
|
31070
31193
|
try {
|
|
31071
|
-
await mkdir(
|
|
31194
|
+
await mkdir(dirname3(filePath), { recursive: true });
|
|
31072
31195
|
await writeFileAtomic(filePath, data, {
|
|
31073
31196
|
encoding: options?.encoding ?? "utf8",
|
|
31074
31197
|
mode: options?.mode
|
|
@@ -31101,7 +31224,7 @@ var init_atomic = __esm({
|
|
|
31101
31224
|
|
|
31102
31225
|
// packages/core/src/store/backup.ts
|
|
31103
31226
|
import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat, unlink as unlink2 } from "node:fs/promises";
|
|
31104
|
-
import { basename, join as
|
|
31227
|
+
import { basename, join as join5 } from "node:path";
|
|
31105
31228
|
async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
|
|
31106
31229
|
try {
|
|
31107
31230
|
await mkdir2(backupDir, { recursive: true });
|
|
@@ -31112,14 +31235,14 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
31112
31235
|
throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
|
|
31113
31236
|
}
|
|
31114
31237
|
for (let i = maxBackups; i >= 1; i--) {
|
|
31115
|
-
const current =
|
|
31238
|
+
const current = join5(backupDir, `${fileName}.${i}`);
|
|
31116
31239
|
if (i === maxBackups) {
|
|
31117
31240
|
try {
|
|
31118
31241
|
await unlink2(current);
|
|
31119
31242
|
} catch {
|
|
31120
31243
|
}
|
|
31121
31244
|
} else {
|
|
31122
|
-
const next =
|
|
31245
|
+
const next = join5(backupDir, `${fileName}.${i + 1}`);
|
|
31123
31246
|
try {
|
|
31124
31247
|
await stat(current);
|
|
31125
31248
|
await fsRename(current, next);
|
|
@@ -31127,7 +31250,7 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
|
|
|
31127
31250
|
}
|
|
31128
31251
|
}
|
|
31129
31252
|
}
|
|
31130
|
-
const backupPath =
|
|
31253
|
+
const backupPath = join5(backupDir, `${fileName}.1`);
|
|
31131
31254
|
await copyFile(filePath, backupPath);
|
|
31132
31255
|
return backupPath;
|
|
31133
31256
|
} catch (err) {
|
|
@@ -31406,16 +31529,16 @@ var init_json2 = __esm({
|
|
|
31406
31529
|
});
|
|
31407
31530
|
|
|
31408
31531
|
// packages/core/src/scaffold/ensure-config.ts
|
|
31409
|
-
import { existsSync as
|
|
31410
|
-
import { basename as basename2, dirname as
|
|
31532
|
+
import { existsSync as existsSync3, readFileSync } from "node:fs";
|
|
31533
|
+
import { basename as basename2, dirname as dirname4, join as join6, resolve as resolve2 } from "node:path";
|
|
31411
31534
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
31412
31535
|
function getPackageRoot() {
|
|
31413
31536
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
31414
|
-
return resolve2(
|
|
31537
|
+
return resolve2(dirname4(thisFile), "..", "..");
|
|
31415
31538
|
}
|
|
31416
31539
|
function getCleoVersion() {
|
|
31417
31540
|
try {
|
|
31418
|
-
const pkgPath =
|
|
31541
|
+
const pkgPath = join6(getPackageRoot(), "package.json");
|
|
31419
31542
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
31420
31543
|
return pkg.version ?? "0.0.0";
|
|
31421
31544
|
} catch {
|
|
@@ -31433,26 +31556,26 @@ var init_ensure_config = __esm({
|
|
|
31433
31556
|
|
|
31434
31557
|
// packages/core/src/store/exodus/archive.ts
|
|
31435
31558
|
import {
|
|
31436
|
-
copyFileSync,
|
|
31437
|
-
existsSync as
|
|
31559
|
+
copyFileSync as copyFileSync2,
|
|
31560
|
+
existsSync as existsSync4,
|
|
31438
31561
|
mkdirSync,
|
|
31439
31562
|
renameSync,
|
|
31440
31563
|
unlinkSync,
|
|
31441
31564
|
writeFileSync
|
|
31442
31565
|
} from "node:fs";
|
|
31443
|
-
import { basename as basename3, join as
|
|
31566
|
+
import { basename as basename3, join as join7 } from "node:path";
|
|
31444
31567
|
function scopeBaseDir(scope, cwd) {
|
|
31445
31568
|
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
31446
31569
|
}
|
|
31447
31570
|
function exodusArchiveDir(scope, cwd) {
|
|
31448
|
-
return
|
|
31571
|
+
return join7(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
|
|
31449
31572
|
}
|
|
31450
31573
|
function exodusMarkerPath(scope, cwd) {
|
|
31451
|
-
return
|
|
31574
|
+
return join7(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
|
|
31452
31575
|
}
|
|
31453
31576
|
function hasExodusCompleteMarker(scope, cwd) {
|
|
31454
31577
|
try {
|
|
31455
|
-
return
|
|
31578
|
+
return existsSync4(exodusMarkerPath(scope, cwd));
|
|
31456
31579
|
} catch {
|
|
31457
31580
|
return false;
|
|
31458
31581
|
}
|
|
@@ -31476,28 +31599,28 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd) {
|
|
|
31476
31599
|
}
|
|
31477
31600
|
function moveFileInto(srcPath, destDir) {
|
|
31478
31601
|
mkdirSync(destDir, { recursive: true });
|
|
31479
|
-
let dest =
|
|
31480
|
-
if (
|
|
31602
|
+
let dest = join7(destDir, basename3(srcPath));
|
|
31603
|
+
if (existsSync4(dest)) {
|
|
31481
31604
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
31482
|
-
dest =
|
|
31605
|
+
dest = join7(destDir, `${basename3(srcPath)}.${stamp}`);
|
|
31483
31606
|
}
|
|
31484
31607
|
try {
|
|
31485
31608
|
renameSync(srcPath, dest);
|
|
31486
31609
|
} catch {
|
|
31487
|
-
|
|
31610
|
+
copyFileSync2(srcPath, dest);
|
|
31488
31611
|
unlinkSync(srcPath);
|
|
31489
31612
|
}
|
|
31490
31613
|
return dest;
|
|
31491
31614
|
}
|
|
31492
31615
|
function archiveSourceDb(source, cwd) {
|
|
31493
|
-
if (!
|
|
31616
|
+
if (!existsSync4(source.path)) {
|
|
31494
31617
|
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
31495
31618
|
}
|
|
31496
31619
|
const destDir = exodusArchiveDir(source.targetScope, cwd);
|
|
31497
31620
|
const archivedTo = moveFileInto(source.path, destDir);
|
|
31498
31621
|
for (const suffix of SIDECAR_SUFFIXES) {
|
|
31499
31622
|
const sidecar = `${source.path}${suffix}`;
|
|
31500
|
-
if (
|
|
31623
|
+
if (existsSync4(sidecar)) {
|
|
31501
31624
|
try {
|
|
31502
31625
|
moveFileInto(sidecar, destDir);
|
|
31503
31626
|
} catch (err) {
|
|
@@ -31543,7 +31666,7 @@ function detectStrandedResidue(sources, cwd) {
|
|
|
31543
31666
|
const stranded = [];
|
|
31544
31667
|
for (const source of sources) {
|
|
31545
31668
|
if (!markedScopes.has(source.targetScope)) continue;
|
|
31546
|
-
if (
|
|
31669
|
+
if (existsSync4(source.path)) {
|
|
31547
31670
|
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
31548
31671
|
}
|
|
31549
31672
|
}
|
|
@@ -31960,7 +32083,7 @@ var init_table_name_map = __esm({
|
|
|
31960
32083
|
});
|
|
31961
32084
|
|
|
31962
32085
|
// packages/core/src/store/exodus/count-parity.ts
|
|
31963
|
-
import { existsSync as
|
|
32086
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
31964
32087
|
function listTables(db) {
|
|
31965
32088
|
return db.prepare(
|
|
31966
32089
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
@@ -31981,14 +32104,14 @@ function rowCount(db, tableName) {
|
|
|
31981
32104
|
function computeCountParity(sources, projectDbPath, globalDbPath) {
|
|
31982
32105
|
const entries = [];
|
|
31983
32106
|
let skipped = 0;
|
|
31984
|
-
if (!
|
|
32107
|
+
if (!existsSync5(projectDbPath) || !existsSync5(globalDbPath)) {
|
|
31985
32108
|
return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
31986
32109
|
}
|
|
31987
32110
|
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
31988
32111
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
31989
32112
|
try {
|
|
31990
32113
|
for (const src of sources) {
|
|
31991
|
-
if (!
|
|
32114
|
+
if (!existsSync5(src.path)) continue;
|
|
31992
32115
|
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
31993
32116
|
try {
|
|
31994
32117
|
for (const legacyTable of listTables(srcSnap.db)) {
|
|
@@ -32046,8 +32169,8 @@ var init_count_parity = __esm({
|
|
|
32046
32169
|
});
|
|
32047
32170
|
|
|
32048
32171
|
// packages/core/src/store/exodus/plan.ts
|
|
32049
|
-
import { existsSync as
|
|
32050
|
-
import { join as
|
|
32172
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, statfsSync, statSync } from "node:fs";
|
|
32173
|
+
import { join as join8 } from "node:path";
|
|
32051
32174
|
function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
|
|
32052
32175
|
return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
|
|
32053
32176
|
}
|
|
@@ -32058,33 +32181,33 @@ function buildSourceDescriptors(cwd) {
|
|
|
32058
32181
|
// Project-tier — go into consolidated project-scope cleo.db
|
|
32059
32182
|
{
|
|
32060
32183
|
name: "tasks",
|
|
32061
|
-
path:
|
|
32184
|
+
path: join8(cleoDir, "tasks.db"),
|
|
32062
32185
|
targetScope: "project"
|
|
32063
32186
|
},
|
|
32064
32187
|
{
|
|
32065
32188
|
name: "brain (project)",
|
|
32066
|
-
path:
|
|
32189
|
+
path: join8(cleoDir, "brain.db"),
|
|
32067
32190
|
targetScope: "project"
|
|
32068
32191
|
},
|
|
32069
32192
|
{
|
|
32070
32193
|
name: "conduit",
|
|
32071
|
-
path:
|
|
32194
|
+
path: join8(cleoDir, "conduit.db"),
|
|
32072
32195
|
targetScope: "project"
|
|
32073
32196
|
},
|
|
32074
32197
|
// Global-tier — go into consolidated global-scope cleo.db
|
|
32075
32198
|
{
|
|
32076
32199
|
name: "nexus",
|
|
32077
|
-
path:
|
|
32200
|
+
path: join8(cleoHome, "nexus.db"),
|
|
32078
32201
|
targetScope: "global"
|
|
32079
32202
|
},
|
|
32080
32203
|
{
|
|
32081
32204
|
name: "signaldock",
|
|
32082
|
-
path:
|
|
32205
|
+
path: join8(cleoHome, "signaldock.db"),
|
|
32083
32206
|
targetScope: "global"
|
|
32084
32207
|
},
|
|
32085
32208
|
{
|
|
32086
32209
|
name: "skills",
|
|
32087
|
-
path:
|
|
32210
|
+
path: join8(cleoHome, "skills.db"),
|
|
32088
32211
|
targetScope: "global"
|
|
32089
32212
|
}
|
|
32090
32213
|
];
|
|
@@ -32113,7 +32236,7 @@ function findExistingStaging(cleoDir) {
|
|
|
32113
32236
|
const entries = readdirSync2(cleoDir, { withFileTypes: true });
|
|
32114
32237
|
const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
|
|
32115
32238
|
if (stagingDirs.length > 0) {
|
|
32116
|
-
return
|
|
32239
|
+
return join8(cleoDir, stagingDirs[0]);
|
|
32117
32240
|
}
|
|
32118
32241
|
} catch {
|
|
32119
32242
|
}
|
|
@@ -32129,7 +32252,7 @@ function buildExodusPlan(cwd) {
|
|
|
32129
32252
|
const availableBytes = getAvailableBytes(cleoDir);
|
|
32130
32253
|
const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
|
|
32131
32254
|
const existingStaging = findExistingStaging(cleoDir);
|
|
32132
|
-
const stagingDir = existingStaging ??
|
|
32255
|
+
const stagingDir = existingStaging ?? join8(cleoDir, deriveStagingDirName());
|
|
32133
32256
|
const resumeFromStaging = existingStaging !== null;
|
|
32134
32257
|
const projectDbPath = resolveDualScopeDbPath("project", cwd);
|
|
32135
32258
|
const globalDbPath = resolveDualScopeDbPath("global");
|
|
@@ -32148,7 +32271,7 @@ function buildExodusPlan(cwd) {
|
|
|
32148
32271
|
};
|
|
32149
32272
|
}
|
|
32150
32273
|
function sourcesPresent(sources) {
|
|
32151
|
-
return sources.some((s) =>
|
|
32274
|
+
return sources.some((s) => existsSync6(s.path));
|
|
32152
32275
|
}
|
|
32153
32276
|
var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
|
|
32154
32277
|
var init_plan2 = __esm({
|
|
@@ -32162,18 +32285,18 @@ var init_plan2 = __esm({
|
|
|
32162
32285
|
});
|
|
32163
32286
|
|
|
32164
32287
|
// packages/core/src/store/exodus/health.ts
|
|
32165
|
-
import { existsSync as
|
|
32288
|
+
import { existsSync as existsSync7, statSync as statSync2 } from "node:fs";
|
|
32166
32289
|
function buildExodusHealth(cwd) {
|
|
32167
32290
|
const plan = buildExodusPlan(cwd);
|
|
32168
|
-
const anyLegacyPresent = plan.sources.some((s) =>
|
|
32291
|
+
const anyLegacyPresent = plan.sources.some((s) => existsSync7(s.path));
|
|
32169
32292
|
const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
|
|
32170
32293
|
const consolidatedExistsByScope = {
|
|
32171
|
-
project:
|
|
32172
|
-
global:
|
|
32294
|
+
project: existsSync7(plan.projectDbPath),
|
|
32295
|
+
global: existsSync7(plan.globalDbPath)
|
|
32173
32296
|
};
|
|
32174
32297
|
const buildScope = (scope) => {
|
|
32175
32298
|
const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
|
|
32176
|
-
const present =
|
|
32299
|
+
const present = existsSync7(s.path);
|
|
32177
32300
|
let bytes = 0;
|
|
32178
32301
|
if (present) {
|
|
32179
32302
|
try {
|
|
@@ -32439,8 +32562,8 @@ var init_types = __esm({
|
|
|
32439
32562
|
|
|
32440
32563
|
// packages/core/src/store/exodus/migrate.ts
|
|
32441
32564
|
import {
|
|
32442
|
-
copyFileSync as
|
|
32443
|
-
existsSync as
|
|
32565
|
+
copyFileSync as copyFileSync3,
|
|
32566
|
+
existsSync as existsSync8,
|
|
32444
32567
|
mkdirSync as mkdirSync2,
|
|
32445
32568
|
readFileSync as readFileSync2,
|
|
32446
32569
|
renameSync as renameSync2,
|
|
@@ -32448,7 +32571,7 @@ import {
|
|
|
32448
32571
|
unlinkSync as unlinkSync2,
|
|
32449
32572
|
writeFileSync as writeFileSync2
|
|
32450
32573
|
} from "node:fs";
|
|
32451
|
-
import { join as
|
|
32574
|
+
import { join as join9 } from "node:path";
|
|
32452
32575
|
function getSqliteVersion(db) {
|
|
32453
32576
|
try {
|
|
32454
32577
|
const row = db.prepare("SELECT sqlite_version() AS v").get();
|
|
@@ -32464,14 +32587,14 @@ function listTables2(db) {
|
|
|
32464
32587
|
return rows.map((r) => r.name);
|
|
32465
32588
|
}
|
|
32466
32589
|
function writeJournal(stagingDir, journal) {
|
|
32467
|
-
const journalPath =
|
|
32590
|
+
const journalPath = join9(stagingDir, JOURNAL_FILENAME);
|
|
32468
32591
|
const tmpPath = `${journalPath}.tmp`;
|
|
32469
32592
|
writeFileSync2(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
|
|
32470
32593
|
renameSync2(tmpPath, journalPath);
|
|
32471
32594
|
}
|
|
32472
32595
|
function readJournal(stagingDir) {
|
|
32473
|
-
const journalPath =
|
|
32474
|
-
if (!
|
|
32596
|
+
const journalPath = join9(stagingDir, JOURNAL_FILENAME);
|
|
32597
|
+
if (!existsSync8(journalPath)) return null;
|
|
32475
32598
|
try {
|
|
32476
32599
|
return JSON.parse(readFileSync2(journalPath, "utf8"));
|
|
32477
32600
|
} catch {
|
|
@@ -32479,9 +32602,9 @@ function readJournal(stagingDir) {
|
|
|
32479
32602
|
}
|
|
32480
32603
|
}
|
|
32481
32604
|
function clearExodusJournal(stagingDir) {
|
|
32482
|
-
const journalPath =
|
|
32605
|
+
const journalPath = join9(stagingDir, JOURNAL_FILENAME);
|
|
32483
32606
|
try {
|
|
32484
|
-
if (!
|
|
32607
|
+
if (!existsSync8(journalPath)) return false;
|
|
32485
32608
|
unlinkSync2(journalPath);
|
|
32486
32609
|
log3.info(
|
|
32487
32610
|
{ stagingDir },
|
|
@@ -32746,7 +32869,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
32746
32869
|
mkdirSync2(stagingDir, { recursive: true });
|
|
32747
32870
|
let sqliteVersion = "unknown";
|
|
32748
32871
|
for (const src of sources) {
|
|
32749
|
-
if (
|
|
32872
|
+
if (existsSync8(src.path)) {
|
|
32750
32873
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
32751
32874
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
32752
32875
|
snap.close();
|
|
@@ -32787,17 +32910,17 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
32787
32910
|
};
|
|
32788
32911
|
var extractNativeDb = extractNativeDb2;
|
|
32789
32912
|
for (const src of sources) {
|
|
32790
|
-
if (!
|
|
32791
|
-
const backupDest =
|
|
32913
|
+
if (!existsSync8(src.path)) continue;
|
|
32914
|
+
const backupDest = join9(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
32792
32915
|
const srcBytes = safeStatBytes(src.path);
|
|
32793
32916
|
const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
|
|
32794
32917
|
if (skipStagingCopy) {
|
|
32795
32918
|
onProgress?.(
|
|
32796
32919
|
`Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
|
|
32797
32920
|
);
|
|
32798
|
-
} else if (!
|
|
32921
|
+
} else if (!existsSync8(backupDest)) {
|
|
32799
32922
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
32800
|
-
|
|
32923
|
+
copyFileSync3(src.path, backupDest);
|
|
32801
32924
|
backupPaths.push(backupDest);
|
|
32802
32925
|
}
|
|
32803
32926
|
acquireAdvisoryLock(src.path);
|
|
@@ -32813,8 +32936,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
32813
32936
|
});
|
|
32814
32937
|
const projectNative = extractNativeDb2(projectHandle);
|
|
32815
32938
|
const globalNative = extractNativeDb2(globalHandle);
|
|
32816
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
32817
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
32939
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync8(s.path));
|
|
32940
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync8(s.path));
|
|
32818
32941
|
await migrateScope(
|
|
32819
32942
|
"project",
|
|
32820
32943
|
projectSources,
|
|
@@ -33089,11 +33212,11 @@ var init_seal = __esm({
|
|
|
33089
33212
|
});
|
|
33090
33213
|
|
|
33091
33214
|
// packages/core/src/store/exodus/status.ts
|
|
33092
|
-
import { existsSync as
|
|
33093
|
-
import { join as
|
|
33215
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync4 } from "node:fs";
|
|
33216
|
+
import { join as join10 } from "node:path";
|
|
33094
33217
|
function readJournal2(stagingDir) {
|
|
33095
|
-
const p =
|
|
33096
|
-
if (!
|
|
33218
|
+
const p = join10(stagingDir, JOURNAL_FILENAME2);
|
|
33219
|
+
if (!existsSync9(p)) return null;
|
|
33097
33220
|
try {
|
|
33098
33221
|
return JSON.parse(readFileSync3(p, "utf8"));
|
|
33099
33222
|
} catch {
|
|
@@ -33102,7 +33225,7 @@ function readJournal2(stagingDir) {
|
|
|
33102
33225
|
}
|
|
33103
33226
|
function findStagingDirs(cleoDir) {
|
|
33104
33227
|
try {
|
|
33105
|
-
return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) =>
|
|
33228
|
+
return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join10(cleoDir, e.name)).sort().reverse();
|
|
33106
33229
|
} catch {
|
|
33107
33230
|
return [];
|
|
33108
33231
|
}
|
|
@@ -33125,15 +33248,15 @@ function runExodusStatus(cwd) {
|
|
|
33125
33248
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
33126
33249
|
name: s.name,
|
|
33127
33250
|
path: s.path,
|
|
33128
|
-
exists:
|
|
33251
|
+
exists: existsSync9(s.path),
|
|
33129
33252
|
bytes: safeBytes(s.path)
|
|
33130
33253
|
}));
|
|
33131
33254
|
return {
|
|
33132
33255
|
hasStaging: latestStaging !== null,
|
|
33133
33256
|
stagingDir: latestStaging,
|
|
33134
33257
|
journal,
|
|
33135
|
-
projectDbExists:
|
|
33136
|
-
globalDbExists:
|
|
33258
|
+
projectDbExists: existsSync9(projectDbPath),
|
|
33259
|
+
globalDbExists: existsSync9(globalDbPath),
|
|
33137
33260
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
33138
33261
|
sources: sourcesInfo
|
|
33139
33262
|
};
|
|
@@ -33150,7 +33273,7 @@ var init_status = __esm({
|
|
|
33150
33273
|
});
|
|
33151
33274
|
|
|
33152
33275
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
33153
|
-
import { existsSync as
|
|
33276
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
33154
33277
|
import { createRequire as createRequire3 } from "node:module";
|
|
33155
33278
|
function orderByClause(db, tableName) {
|
|
33156
33279
|
try {
|
|
@@ -33398,7 +33521,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
33398
33521
|
const preExistingForeignKeyViolations = [];
|
|
33399
33522
|
const failureLines = [];
|
|
33400
33523
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
33401
|
-
if (!
|
|
33524
|
+
if (!existsSync10(projectDbPath)) {
|
|
33402
33525
|
return {
|
|
33403
33526
|
ok: false,
|
|
33404
33527
|
tables: [],
|
|
@@ -33409,7 +33532,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
33409
33532
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
33410
33533
|
};
|
|
33411
33534
|
}
|
|
33412
|
-
if (!
|
|
33535
|
+
if (!existsSync10(globalDbPath)) {
|
|
33413
33536
|
return {
|
|
33414
33537
|
ok: false,
|
|
33415
33538
|
tables: [],
|
|
@@ -33424,7 +33547,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
33424
33547
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
33425
33548
|
try {
|
|
33426
33549
|
for (const src of sources) {
|
|
33427
|
-
if (!
|
|
33550
|
+
if (!existsSync10(src.path)) {
|
|
33428
33551
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
33429
33552
|
continue;
|
|
33430
33553
|
}
|
|
@@ -33707,7 +33830,7 @@ __export(on_open_exports, {
|
|
|
33707
33830
|
isDataContinuityOk: () => isDataContinuityOk,
|
|
33708
33831
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen
|
|
33709
33832
|
});
|
|
33710
|
-
import { existsSync as
|
|
33833
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
33711
33834
|
function isDisabledByEnv() {
|
|
33712
33835
|
const v = process.env.CLEO_DISABLE_EXODUS_ON_OPEN;
|
|
33713
33836
|
return v === "1" || v === "true";
|
|
@@ -33822,7 +33945,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33822
33945
|
const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
33823
33946
|
const plan = buildExodusPlan2(cwd);
|
|
33824
33947
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
33825
|
-
if (!scopeSources.some((s) =>
|
|
33948
|
+
if (!scopeSources.some((s) => existsSync11(s.path))) {
|
|
33826
33949
|
return {
|
|
33827
33950
|
outcome: "skipped",
|
|
33828
33951
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -33839,7 +33962,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33839
33962
|
{
|
|
33840
33963
|
scope,
|
|
33841
33964
|
dbPath,
|
|
33842
|
-
sources: plan.sources.filter((s) =>
|
|
33965
|
+
sources: plan.sources.filter((s) => existsSync11(s.path)).map((s) => s.name)
|
|
33843
33966
|
},
|
|
33844
33967
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
33845
33968
|
);
|
|
@@ -33895,7 +34018,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33895
34018
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
33896
34019
|
);
|
|
33897
34020
|
try {
|
|
33898
|
-
const consumed = plan.sources.filter((s) =>
|
|
34021
|
+
const consumed = plan.sources.filter((s) => existsSync11(s.path));
|
|
33899
34022
|
const archiveResult = archiveMigratedSources(consumed, cwd);
|
|
33900
34023
|
log6.info(
|
|
33901
34024
|
{
|
|
@@ -33952,9 +34075,9 @@ __export(dual_scope_db_exports, {
|
|
|
33952
34075
|
resolveDualScopeDbPath: () => resolveDualScopeDbPath,
|
|
33953
34076
|
upsertIdempotent: () => upsertIdempotent
|
|
33954
34077
|
});
|
|
33955
|
-
import { existsSync as
|
|
34078
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync3 } from "node:fs";
|
|
33956
34079
|
import { createRequire as createRequire4 } from "node:module";
|
|
33957
|
-
import { dirname as
|
|
34080
|
+
import { dirname as dirname5, join as join11 } from "node:path";
|
|
33958
34081
|
function assertWriteDurable(handle) {
|
|
33959
34082
|
if (handle.exodusAbort) {
|
|
33960
34083
|
throw new ExodusAbortWriteUnsafeError(handle.exodusAbort);
|
|
@@ -33971,9 +34094,9 @@ function cacheKey(scope, dbPath) {
|
|
|
33971
34094
|
}
|
|
33972
34095
|
function resolveDualScopeDbPath(scope, cwd) {
|
|
33973
34096
|
if (scope === "project") {
|
|
33974
|
-
return
|
|
34097
|
+
return join11(resolveCleoDir(cwd), "cleo.db");
|
|
33975
34098
|
}
|
|
33976
|
-
return
|
|
34099
|
+
return join11(getCleoHome(), "cleo.db");
|
|
33977
34100
|
}
|
|
33978
34101
|
function migrationsSetName(scope) {
|
|
33979
34102
|
return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
|
|
@@ -34013,8 +34136,8 @@ async function openDualScopeDb(scope, cwd) {
|
|
|
34013
34136
|
}
|
|
34014
34137
|
async function openDedicatedDualScopeDb(scope, dbPath, log7) {
|
|
34015
34138
|
log7.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
34016
|
-
const dir =
|
|
34017
|
-
if (!
|
|
34139
|
+
const dir = dirname5(dbPath);
|
|
34140
|
+
if (!existsSync12(dir)) {
|
|
34018
34141
|
mkdirSync3(dir, { recursive: true });
|
|
34019
34142
|
}
|
|
34020
34143
|
const DatabaseSyncCtor = getDatabaseSyncCtor();
|
|
@@ -34063,8 +34186,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
34063
34186
|
}
|
|
34064
34187
|
const initPromise = (async () => {
|
|
34065
34188
|
log7.debug({ scope, dbPath }, "opening dual-scope cleo.db");
|
|
34066
|
-
const dir =
|
|
34067
|
-
if (!
|
|
34189
|
+
const dir = dirname5(dbPath);
|
|
34190
|
+
if (!existsSync12(dir)) {
|
|
34068
34191
|
mkdirSync3(dir, { recursive: true });
|
|
34069
34192
|
}
|
|
34070
34193
|
const DatabaseSyncCtor = getDatabaseSyncCtor();
|
|
@@ -34142,6 +34265,12 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
|
34142
34265
|
nativeDb: null,
|
|
34143
34266
|
initPromise
|
|
34144
34267
|
});
|
|
34268
|
+
initPromise.catch(() => {
|
|
34269
|
+
const entry = _cache.get(key);
|
|
34270
|
+
if (entry && entry.initPromise === initPromise) {
|
|
34271
|
+
_cache.delete(key);
|
|
34272
|
+
}
|
|
34273
|
+
});
|
|
34145
34274
|
return initPromise;
|
|
34146
34275
|
}
|
|
34147
34276
|
function _resetDualScopeDbCache(scope) {
|
|
@@ -34732,8 +34861,8 @@ __export(nexus_sqlite_exports, {
|
|
|
34732
34861
|
resetNexusDbState: () => resetNexusDbState,
|
|
34733
34862
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
34734
34863
|
});
|
|
34735
|
-
import { copyFileSync as
|
|
34736
|
-
import { join as
|
|
34864
|
+
import { copyFileSync as copyFileSync4, existsSync as existsSync13 } from "node:fs";
|
|
34865
|
+
import { join as join12 } from "node:path";
|
|
34737
34866
|
function getNexusDbPath(cwd) {
|
|
34738
34867
|
return resolveDualScopeDbPath("project", cwd);
|
|
34739
34868
|
}
|
|
@@ -34765,7 +34894,7 @@ function resolveNexusMigrationsFolder() {
|
|
|
34765
34894
|
return resolveCorePackageMigrationsFolder("drizzle-nexus");
|
|
34766
34895
|
}
|
|
34767
34896
|
function getNestedNexusSentinelPath() {
|
|
34768
|
-
return
|
|
34897
|
+
return join12(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
|
|
34769
34898
|
}
|
|
34770
34899
|
function detectAndWarnOnNestedNexus() {
|
|
34771
34900
|
let nestedPath;
|
|
@@ -34774,7 +34903,7 @@ function detectAndWarnOnNestedNexus() {
|
|
|
34774
34903
|
} catch {
|
|
34775
34904
|
return false;
|
|
34776
34905
|
}
|
|
34777
|
-
if (!
|
|
34906
|
+
if (!existsSync13(nestedPath)) return false;
|
|
34778
34907
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
34779
34908
|
_warnedNestedPaths.add(nestedPath);
|
|
34780
34909
|
const canonicalPath = getNexusDbPath();
|
|
@@ -34933,9 +35062,9 @@ function runNexusMigrations(nativeDb, db) {
|
|
|
34933
35062
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
34934
35063
|
if (tableExists4(nativeDb, "nexus_nodes") && _nexusDbPath) {
|
|
34935
35064
|
const backupPath = _nexusDbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
34936
|
-
if (!
|
|
35065
|
+
if (!existsSync13(backupPath)) {
|
|
34937
35066
|
try {
|
|
34938
|
-
|
|
35067
|
+
copyFileSync4(_nexusDbPath, backupPath);
|
|
34939
35068
|
} catch {
|
|
34940
35069
|
}
|
|
34941
35070
|
}
|
|
@@ -35065,10 +35194,10 @@ var init_nexus_sqlite = __esm({
|
|
|
35065
35194
|
|
|
35066
35195
|
// packages/core/src/paths.ts
|
|
35067
35196
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
35068
|
-
import { existsSync as
|
|
35197
|
+
import { existsSync as existsSync14, readFileSync as readFileSync4, statSync as statSync5 } from "node:fs";
|
|
35069
35198
|
import { createRequire as createRequire5 } from "node:module";
|
|
35070
35199
|
import { homedir } from "node:os";
|
|
35071
|
-
import { basename as basename4, dirname as
|
|
35200
|
+
import { basename as basename4, dirname as dirname6, join as join13, resolve as resolve3 } from "node:path";
|
|
35072
35201
|
import {
|
|
35073
35202
|
computeCanonicalProjectId as _computeCanonicalProjectId,
|
|
35074
35203
|
getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
|
|
@@ -35158,8 +35287,8 @@ function getCleoDirAbsolute(cwd, opts) {
|
|
|
35158
35287
|
function _resolveProjectByCwdFromNexus(cwd) {
|
|
35159
35288
|
try {
|
|
35160
35289
|
const cleoHome = getCleoHome();
|
|
35161
|
-
const globalDbPath =
|
|
35162
|
-
if (!
|
|
35290
|
+
const globalDbPath = join13(cleoHome, "cleo.db");
|
|
35291
|
+
if (!existsSync14(globalDbPath)) return null;
|
|
35163
35292
|
const start = resolve3(cwd ?? process.cwd());
|
|
35164
35293
|
let current = start;
|
|
35165
35294
|
const DatabaseSync2 = _getDatabaseSyncCtor();
|
|
@@ -35173,7 +35302,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
|
|
|
35173
35302
|
if (row && typeof row.project_id === "string" && row.project_id.length > 0) {
|
|
35174
35303
|
return row.project_id;
|
|
35175
35304
|
}
|
|
35176
|
-
const parent =
|
|
35305
|
+
const parent = dirname6(current);
|
|
35177
35306
|
if (parent === current) break;
|
|
35178
35307
|
current = parent;
|
|
35179
35308
|
}
|
|
@@ -35198,13 +35327,13 @@ function _findCleoDirRoot(cwd) {
|
|
|
35198
35327
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
35199
35328
|
if (!isDangerousRoot) {
|
|
35200
35329
|
try {
|
|
35201
|
-
if (statSync5(
|
|
35330
|
+
if (statSync5(join13(current, ".cleo")).isDirectory()) {
|
|
35202
35331
|
return current;
|
|
35203
35332
|
}
|
|
35204
35333
|
} catch {
|
|
35205
35334
|
}
|
|
35206
35335
|
}
|
|
35207
|
-
const parent =
|
|
35336
|
+
const parent = dirname6(current);
|
|
35208
35337
|
if (parent === current) break;
|
|
35209
35338
|
current = parent;
|
|
35210
35339
|
}
|
|
@@ -35213,7 +35342,7 @@ function _findCleoDirRoot(cwd) {
|
|
|
35213
35342
|
function resolveCleoDir(cwd) {
|
|
35214
35343
|
const scope = worktreeScope.getStore();
|
|
35215
35344
|
if (scope !== void 0) {
|
|
35216
|
-
return
|
|
35345
|
+
return join13(scope.worktreeRoot, ".cleo");
|
|
35217
35346
|
}
|
|
35218
35347
|
const override = _cleoDirEnvOverride();
|
|
35219
35348
|
if (override !== null) {
|
|
@@ -35221,16 +35350,16 @@ function resolveCleoDir(cwd) {
|
|
|
35221
35350
|
}
|
|
35222
35351
|
const root = _findCleoDirRoot(cwd);
|
|
35223
35352
|
if (root !== null) {
|
|
35224
|
-
return
|
|
35353
|
+
return join13(root, ".cleo");
|
|
35225
35354
|
}
|
|
35226
35355
|
const start = resolve3(cwd ?? process.cwd());
|
|
35227
35356
|
let current = start;
|
|
35228
35357
|
while (true) {
|
|
35229
35358
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
35230
35359
|
if (mainRepo !== null) {
|
|
35231
|
-
return
|
|
35360
|
+
return join13(mainRepo, ".cleo");
|
|
35232
35361
|
}
|
|
35233
|
-
const parent =
|
|
35362
|
+
const parent = dirname6(current);
|
|
35234
35363
|
if (parent === current) {
|
|
35235
35364
|
break;
|
|
35236
35365
|
}
|
|
@@ -35270,30 +35399,30 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
35270
35399
|
const start = resolve3(cwd ?? process.cwd());
|
|
35271
35400
|
let current = start;
|
|
35272
35401
|
while (true) {
|
|
35273
|
-
const gitMarker =
|
|
35402
|
+
const gitMarker = join13(current, ".git");
|
|
35274
35403
|
try {
|
|
35275
|
-
if (
|
|
35404
|
+
if (existsSync14(gitMarker)) {
|
|
35276
35405
|
return true;
|
|
35277
35406
|
}
|
|
35278
35407
|
} catch {
|
|
35279
35408
|
}
|
|
35280
|
-
const parent =
|
|
35409
|
+
const parent = dirname6(current);
|
|
35281
35410
|
if (parent === current) return false;
|
|
35282
35411
|
current = parent;
|
|
35283
35412
|
}
|
|
35284
35413
|
}
|
|
35285
35414
|
function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
35286
35415
|
try {
|
|
35287
|
-
const gitLinkPath =
|
|
35288
|
-
if (!
|
|
35416
|
+
const gitLinkPath = join13(gitlinkDir, ".git");
|
|
35417
|
+
if (!existsSync14(gitLinkPath)) return null;
|
|
35289
35418
|
const stat2 = statSync5(gitLinkPath);
|
|
35290
35419
|
if (!stat2.isFile()) return null;
|
|
35291
35420
|
const gitLinkContent = readFileSync4(gitLinkPath, "utf-8").trim();
|
|
35292
35421
|
const match = gitLinkContent.match(/^gitdir:\s*(.+)$/m);
|
|
35293
35422
|
if (!match) return null;
|
|
35294
35423
|
const gitdir = match[1].trim();
|
|
35295
|
-
const mainRepo =
|
|
35296
|
-
if (
|
|
35424
|
+
const mainRepo = dirname6(dirname6(dirname6(gitdir)));
|
|
35425
|
+
if (existsSync14(join13(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
|
|
35297
35426
|
return mainRepo;
|
|
35298
35427
|
}
|
|
35299
35428
|
} catch {
|
|
@@ -35301,18 +35430,18 @@ function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
|
35301
35430
|
return null;
|
|
35302
35431
|
}
|
|
35303
35432
|
function validateProjectRoot(candidate) {
|
|
35304
|
-
const cleoDir =
|
|
35305
|
-
if (!
|
|
35433
|
+
const cleoDir = join13(candidate, ".cleo");
|
|
35434
|
+
if (!existsSync14(cleoDir)) {
|
|
35306
35435
|
return false;
|
|
35307
35436
|
}
|
|
35308
|
-
const projectInfoPath =
|
|
35309
|
-
if (
|
|
35437
|
+
const projectInfoPath = join13(cleoDir, "project-info.json");
|
|
35438
|
+
if (existsSync14(projectInfoPath)) {
|
|
35310
35439
|
try {
|
|
35311
35440
|
const raw = readFileSync4(projectInfoPath, "utf-8");
|
|
35312
35441
|
const parsed = JSON.parse(raw);
|
|
35313
35442
|
if (typeof parsed === "object" && parsed !== null && "projectId" in parsed && typeof parsed["projectId"] === "string" && parsed["projectId"] !== "") {
|
|
35314
|
-
const gitMarker =
|
|
35315
|
-
if (
|
|
35443
|
+
const gitMarker = join13(candidate, ".git");
|
|
35444
|
+
if (existsSync14(gitMarker)) {
|
|
35316
35445
|
try {
|
|
35317
35446
|
if (!statSync5(gitMarker).isDirectory()) {
|
|
35318
35447
|
return false;
|
|
@@ -35326,8 +35455,8 @@ function validateProjectRoot(candidate) {
|
|
|
35326
35455
|
} catch {
|
|
35327
35456
|
}
|
|
35328
35457
|
}
|
|
35329
|
-
const gitDir =
|
|
35330
|
-
if (
|
|
35458
|
+
const gitDir = join13(candidate, ".git");
|
|
35459
|
+
if (existsSync14(gitDir)) {
|
|
35331
35460
|
let isRealGitDir = false;
|
|
35332
35461
|
try {
|
|
35333
35462
|
const stat2 = statSync5(gitDir);
|
|
@@ -35363,7 +35492,7 @@ function getProjectRoot(cwd) {
|
|
|
35363
35492
|
const cleoDirEnv = process.env["CLEO_DIR"];
|
|
35364
35493
|
if (cleoDirEnv && isAbsolutePath(cleoDirEnv)) {
|
|
35365
35494
|
if (cleoDirEnv.endsWith("/.cleo") || cleoDirEnv.endsWith("\\.cleo")) {
|
|
35366
|
-
return
|
|
35495
|
+
return dirname6(cleoDirEnv);
|
|
35367
35496
|
}
|
|
35368
35497
|
return cleoDirEnv;
|
|
35369
35498
|
}
|
|
@@ -35374,16 +35503,16 @@ function getProjectRoot(cwd) {
|
|
|
35374
35503
|
const homeRoot = homedir();
|
|
35375
35504
|
const skippedCleoDirs = [];
|
|
35376
35505
|
while (true) {
|
|
35377
|
-
const cleoDir =
|
|
35378
|
-
const gitDir =
|
|
35506
|
+
const cleoDir = join13(current, ".cleo");
|
|
35507
|
+
const gitDir = join13(current, ".git");
|
|
35379
35508
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
35380
|
-
if (
|
|
35509
|
+
if (existsSync14(cleoDir) && !isDangerousRoot) {
|
|
35381
35510
|
if (validateProjectRoot(current)) {
|
|
35382
35511
|
return current;
|
|
35383
35512
|
}
|
|
35384
35513
|
skippedCleoDirs.push(current);
|
|
35385
35514
|
}
|
|
35386
|
-
if (
|
|
35515
|
+
if (existsSync14(gitDir) && !isDangerousRoot) {
|
|
35387
35516
|
let isRealGitDir = false;
|
|
35388
35517
|
try {
|
|
35389
35518
|
isRealGitDir = statSync5(gitDir).isDirectory();
|
|
@@ -35398,7 +35527,7 @@ function getProjectRoot(cwd) {
|
|
|
35398
35527
|
const mainRepoFromWalk = _resolveMainRepoFromGitlink(current);
|
|
35399
35528
|
if (mainRepoFromWalk !== null) return mainRepoFromWalk;
|
|
35400
35529
|
}
|
|
35401
|
-
const parent =
|
|
35530
|
+
const parent = dirname6(current);
|
|
35402
35531
|
if (parent === current) {
|
|
35403
35532
|
break;
|
|
35404
35533
|
}
|
|
@@ -35428,18 +35557,18 @@ function resolveOrCwd(maybeRoot) {
|
|
|
35428
35557
|
return getProjectRoot();
|
|
35429
35558
|
}
|
|
35430
35559
|
function getConfigPath(cwd) {
|
|
35431
|
-
return
|
|
35560
|
+
return join13(_resolveCleoDir(cwd), "config.json");
|
|
35432
35561
|
}
|
|
35433
35562
|
function getGlobalConfigPath() {
|
|
35434
|
-
return
|
|
35563
|
+
return join13(getCleoHome(), "config.json");
|
|
35435
35564
|
}
|
|
35436
35565
|
function isAbsolutePath(path) {
|
|
35437
35566
|
return _isAbsolutePath(path);
|
|
35438
35567
|
}
|
|
35439
35568
|
function _readProjectNameFromInfo(projectRoot) {
|
|
35440
35569
|
try {
|
|
35441
|
-
const infoPath =
|
|
35442
|
-
if (!
|
|
35570
|
+
const infoPath = join13(projectRoot, ".cleo", "project-info.json");
|
|
35571
|
+
if (!existsSync14(infoPath)) return void 0;
|
|
35443
35572
|
const raw = readFileSync4(infoPath, "utf-8");
|
|
35444
35573
|
const data = JSON.parse(raw);
|
|
35445
35574
|
return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
|
|
@@ -35465,8 +35594,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
|
|
|
35465
35594
|
if (existingRows.length > 0) {
|
|
35466
35595
|
const existingPath = existingRows[0].projectPath;
|
|
35467
35596
|
if (existingPath !== resolvedPath) {
|
|
35468
|
-
const newBrainDbPath =
|
|
35469
|
-
const newTasksDbPath =
|
|
35597
|
+
const newBrainDbPath = join13(resolvedPath, ".cleo", "brain.db");
|
|
35598
|
+
const newTasksDbPath = join13(resolvedPath, ".cleo", "tasks.db");
|
|
35470
35599
|
await db.update(projectRegistry2).set({
|
|
35471
35600
|
projectPath: resolvedPath,
|
|
35472
35601
|
projectHash: generateProjectHash2(resolvedPath),
|
|
@@ -35497,8 +35626,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
|
|
|
35497
35626
|
lastSync: now,
|
|
35498
35627
|
taskCount: 0,
|
|
35499
35628
|
labelsJson: "[]",
|
|
35500
|
-
brainDbPath:
|
|
35501
|
-
tasksDbPath:
|
|
35629
|
+
brainDbPath: join13(resolvedPath, ".cleo", "brain.db"),
|
|
35630
|
+
tasksDbPath: join13(resolvedPath, ".cleo", "tasks.db"),
|
|
35502
35631
|
statsJson: "{}"
|
|
35503
35632
|
}).onConflictDoNothing();
|
|
35504
35633
|
const aliases = canonicalResult.legacyAliases ?? [];
|
|
@@ -35531,7 +35660,7 @@ var init_paths = __esm({
|
|
|
35531
35660
|
// packages/core/src/store/file-utils.ts
|
|
35532
35661
|
import { randomBytes } from "node:crypto";
|
|
35533
35662
|
import {
|
|
35534
|
-
existsSync as
|
|
35663
|
+
existsSync as existsSync15,
|
|
35535
35664
|
mkdirSync as mkdirSync4,
|
|
35536
35665
|
readdirSync as readdirSync4,
|
|
35537
35666
|
readFileSync as readFileSync5,
|
|
@@ -35539,34 +35668,34 @@ import {
|
|
|
35539
35668
|
unlinkSync as unlinkSync3,
|
|
35540
35669
|
writeFileSync as writeFileSync3
|
|
35541
35670
|
} from "node:fs";
|
|
35542
|
-
import { basename as basename5, dirname as
|
|
35671
|
+
import { basename as basename5, dirname as dirname7, join as join14 } from "node:path";
|
|
35543
35672
|
import * as lockfile2 from "proper-lockfile";
|
|
35544
35673
|
function rotateBackup(filePath, mode) {
|
|
35545
|
-
const dir =
|
|
35674
|
+
const dir = dirname7(filePath);
|
|
35546
35675
|
const name15 = basename5(filePath);
|
|
35547
|
-
const backupDir =
|
|
35676
|
+
const backupDir = join14(dir, ".backups");
|
|
35548
35677
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
35549
|
-
if (!
|
|
35678
|
+
if (!existsSync15(backupDir)) {
|
|
35550
35679
|
mkdirSync4(backupDir, { recursive: true, mode: dirMode });
|
|
35551
35680
|
}
|
|
35552
35681
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
35553
|
-
const current =
|
|
35682
|
+
const current = join14(backupDir, `${name15}.${i}`);
|
|
35554
35683
|
if (i === MAX_BACKUPS) {
|
|
35555
35684
|
try {
|
|
35556
35685
|
unlinkSync3(current);
|
|
35557
35686
|
} catch {
|
|
35558
35687
|
}
|
|
35559
35688
|
} else {
|
|
35560
|
-
const next =
|
|
35689
|
+
const next = join14(backupDir, `${name15}.${i + 1}`);
|
|
35561
35690
|
try {
|
|
35562
|
-
if (
|
|
35691
|
+
if (existsSync15(current)) renameSync3(current, next);
|
|
35563
35692
|
} catch {
|
|
35564
35693
|
}
|
|
35565
35694
|
}
|
|
35566
35695
|
}
|
|
35567
35696
|
try {
|
|
35568
35697
|
const content = readFileSync5(filePath, "utf-8");
|
|
35569
|
-
const backupPath =
|
|
35698
|
+
const backupPath = join14(backupDir, `${name15}.1`);
|
|
35570
35699
|
if (typeof mode === "number") {
|
|
35571
35700
|
writeFileSync3(backupPath, content, { encoding: "utf-8", mode });
|
|
35572
35701
|
} else {
|
|
@@ -35586,8 +35715,8 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
35586
35715
|
const opts = typeof optsOrIndent === "number" ? { indent: optsOrIndent } : optsOrIndent;
|
|
35587
35716
|
const indent = opts.indent ?? 2;
|
|
35588
35717
|
const mode = opts.mode;
|
|
35589
|
-
const dir =
|
|
35590
|
-
const tempPath =
|
|
35718
|
+
const dir = dirname7(filePath);
|
|
35719
|
+
const tempPath = join14(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
35591
35720
|
const content = JSON.stringify(data, null, indent) + "\n";
|
|
35592
35721
|
if (typeof mode === "number") {
|
|
35593
35722
|
writeFileSync3(tempPath, content, { encoding: "utf-8", mode });
|
|
@@ -35595,7 +35724,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
35595
35724
|
writeFileSync3(tempPath, content, "utf-8");
|
|
35596
35725
|
}
|
|
35597
35726
|
try {
|
|
35598
|
-
if (
|
|
35727
|
+
if (existsSync15(filePath)) {
|
|
35599
35728
|
rotateBackup(filePath, mode);
|
|
35600
35729
|
}
|
|
35601
35730
|
renameSync3(tempPath, filePath);
|
|
@@ -35619,12 +35748,12 @@ function readJsonFile(filePath) {
|
|
|
35619
35748
|
}
|
|
35620
35749
|
}
|
|
35621
35750
|
async function withLock2(filePath, transform2, opts = {}) {
|
|
35622
|
-
const dir =
|
|
35751
|
+
const dir = dirname7(filePath);
|
|
35623
35752
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
35624
|
-
if (!
|
|
35753
|
+
if (!existsSync15(dir)) {
|
|
35625
35754
|
mkdirSync4(dir, { recursive: true, mode: dirMode });
|
|
35626
35755
|
}
|
|
35627
|
-
if (!
|
|
35756
|
+
if (!existsSync15(filePath)) {
|
|
35628
35757
|
if (typeof opts.mode === "number") {
|
|
35629
35758
|
writeFileSync3(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
35630
35759
|
} else {
|
|
@@ -35645,11 +35774,11 @@ async function withLock2(filePath, transform2, opts = {}) {
|
|
|
35645
35774
|
}
|
|
35646
35775
|
}
|
|
35647
35776
|
async function withFileLock(filePath, operation) {
|
|
35648
|
-
const dir =
|
|
35649
|
-
if (!
|
|
35777
|
+
const dir = dirname7(filePath);
|
|
35778
|
+
if (!existsSync15(dir)) {
|
|
35650
35779
|
mkdirSync4(dir, { recursive: true });
|
|
35651
35780
|
}
|
|
35652
|
-
if (!
|
|
35781
|
+
if (!existsSync15(filePath)) {
|
|
35653
35782
|
writeFileSync3(filePath, "", "utf-8");
|
|
35654
35783
|
}
|
|
35655
35784
|
let release;
|
|
@@ -35683,10 +35812,10 @@ var init_file_utils = __esm({
|
|
|
35683
35812
|
|
|
35684
35813
|
// packages/core/src/llm/credential-removal.ts
|
|
35685
35814
|
import { unlinkSync as unlinkSync4 } from "node:fs";
|
|
35686
|
-
import { join as
|
|
35815
|
+
import { join as join15 } from "node:path";
|
|
35687
35816
|
import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
|
|
35688
35817
|
function suppressionStatePath() {
|
|
35689
|
-
return
|
|
35818
|
+
return join15(getCleoHome2(), SUPPRESSION_FILENAME);
|
|
35690
35819
|
}
|
|
35691
35820
|
function readSuppressionFile() {
|
|
35692
35821
|
const data = readJsonFile(suppressionStatePath());
|
|
@@ -35790,7 +35919,7 @@ var init_credential_removal = __esm({
|
|
|
35790
35919
|
sourceId: "cleo-pkce",
|
|
35791
35920
|
description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
|
|
35792
35921
|
async remove() {
|
|
35793
|
-
const path =
|
|
35922
|
+
const path = join15(getCleoHome2(), "anthropic-oauth.json");
|
|
35794
35923
|
const cleaned = [];
|
|
35795
35924
|
try {
|
|
35796
35925
|
unlinkSync4(path);
|
|
@@ -35869,9 +35998,9 @@ __export(config_exports, {
|
|
|
35869
35998
|
parseConfigValue: () => parseConfigValue,
|
|
35870
35999
|
setConfigValue: () => setConfigValue
|
|
35871
36000
|
});
|
|
35872
|
-
import { existsSync as
|
|
36001
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
35873
36002
|
import { mkdir as mkdir3, writeFile } from "node:fs/promises";
|
|
35874
|
-
import { dirname as
|
|
36003
|
+
import { dirname as dirname8 } from "node:path";
|
|
35875
36004
|
function getNestedValue(obj, path) {
|
|
35876
36005
|
const parts = path.split(".");
|
|
35877
36006
|
let current = obj;
|
|
@@ -35993,8 +36122,8 @@ function parseConfigValue(value) {
|
|
|
35993
36122
|
}
|
|
35994
36123
|
async function setConfigValue(key, value, cwd, opts) {
|
|
35995
36124
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
35996
|
-
if (!
|
|
35997
|
-
const dir =
|
|
36125
|
+
if (!existsSync16(configPath)) {
|
|
36126
|
+
const dir = dirname8(configPath);
|
|
35998
36127
|
await mkdir3(dir, { recursive: true });
|
|
35999
36128
|
await writeFile(configPath, "{}", "utf-8");
|
|
36000
36129
|
}
|
|
@@ -36007,8 +36136,8 @@ async function setConfigValue(key, value, cwd, opts) {
|
|
|
36007
36136
|
async function applyStrictnessPreset(preset, cwd, opts) {
|
|
36008
36137
|
const definition = STRICTNESS_PRESETS[preset];
|
|
36009
36138
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
36010
|
-
if (!
|
|
36011
|
-
const dir =
|
|
36139
|
+
if (!existsSync16(configPath)) {
|
|
36140
|
+
const dir = dirname8(configPath);
|
|
36012
36141
|
await mkdir3(dir, { recursive: true });
|
|
36013
36142
|
await writeFile(configPath, "{}", "utf-8");
|
|
36014
36143
|
}
|
|
@@ -36209,10 +36338,10 @@ var init_config = __esm({
|
|
|
36209
36338
|
// packages/core/src/llm/credential-seeders/claude-code-seeder.ts
|
|
36210
36339
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
36211
36340
|
import { homedir as homedir2 } from "node:os";
|
|
36212
|
-
import { join as
|
|
36341
|
+
import { join as join16 } from "node:path";
|
|
36213
36342
|
function defaultReadCredentialFile() {
|
|
36214
36343
|
try {
|
|
36215
|
-
return readFileSync6(
|
|
36344
|
+
return readFileSync6(join16(homedir2(), ".claude", ".credentials.json"), "utf-8");
|
|
36216
36345
|
} catch {
|
|
36217
36346
|
return null;
|
|
36218
36347
|
}
|
|
@@ -36307,9 +36436,9 @@ var init_claude_code_seeder = __esm({
|
|
|
36307
36436
|
|
|
36308
36437
|
// packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
|
|
36309
36438
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
36310
|
-
import { join as
|
|
36439
|
+
import { join as join17 } from "node:path";
|
|
36311
36440
|
function defaultCleoPkcePath() {
|
|
36312
|
-
return
|
|
36441
|
+
return join17(getCleoHome(), "anthropic-oauth.json");
|
|
36313
36442
|
}
|
|
36314
36443
|
function defaultReadCredentialFile2() {
|
|
36315
36444
|
try {
|
|
@@ -36380,13 +36509,13 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
36380
36509
|
});
|
|
36381
36510
|
|
|
36382
36511
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
36383
|
-
import { existsSync as
|
|
36512
|
+
import { existsSync as existsSync17, readFileSync as readFileSync8 } from "node:fs";
|
|
36384
36513
|
import { homedir as homedir3 } from "node:os";
|
|
36385
|
-
import { join as
|
|
36514
|
+
import { join as join18 } from "node:path";
|
|
36386
36515
|
function getCodexAuthPath() {
|
|
36387
36516
|
const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
|
|
36388
|
-
const root = codexHome ||
|
|
36389
|
-
return
|
|
36517
|
+
const root = codexHome || join18(homedir3(), ".codex");
|
|
36518
|
+
return join18(root, "auth.json");
|
|
36390
36519
|
}
|
|
36391
36520
|
var CodexCliSeeder, codexCliSeeder;
|
|
36392
36521
|
var init_codex_cli_seeder = __esm({
|
|
@@ -36405,7 +36534,7 @@ var init_codex_cli_seeder = __esm({
|
|
|
36405
36534
|
*/
|
|
36406
36535
|
async seed() {
|
|
36407
36536
|
const authPath = getCodexAuthPath();
|
|
36408
|
-
if (!
|
|
36537
|
+
if (!existsSync17(authPath)) {
|
|
36409
36538
|
return { entries: [] };
|
|
36410
36539
|
}
|
|
36411
36540
|
let raw;
|
|
@@ -36535,11 +36664,11 @@ var init_google_pkce = __esm({
|
|
|
36535
36664
|
});
|
|
36536
36665
|
|
|
36537
36666
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
36538
|
-
import { existsSync as
|
|
36539
|
-
import { join as
|
|
36667
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9 } from "node:fs";
|
|
36668
|
+
import { join as join19 } from "node:path";
|
|
36540
36669
|
import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
|
|
36541
36670
|
function getGoogleOauthPath() {
|
|
36542
|
-
return
|
|
36671
|
+
return join19(getCleoHome3(), "google_oauth.json");
|
|
36543
36672
|
}
|
|
36544
36673
|
function parseGoogleOauthFile(raw) {
|
|
36545
36674
|
let json3;
|
|
@@ -36584,7 +36713,7 @@ var init_gemini_cli_seeder = __esm({
|
|
|
36584
36713
|
*/
|
|
36585
36714
|
async seed() {
|
|
36586
36715
|
const path = getGoogleOauthPath();
|
|
36587
|
-
if (!
|
|
36716
|
+
if (!existsSync18(path)) {
|
|
36588
36717
|
return { entries: [] };
|
|
36589
36718
|
}
|
|
36590
36719
|
let raw;
|
|
@@ -36809,23 +36938,23 @@ var init_credential_seeders = __esm({
|
|
|
36809
36938
|
|
|
36810
36939
|
// packages/core/src/llm/global-config-migration.ts
|
|
36811
36940
|
import {
|
|
36812
|
-
existsSync as
|
|
36941
|
+
existsSync as existsSync19,
|
|
36813
36942
|
mkdirSync as mkdirSync5,
|
|
36814
36943
|
readFileSync as readFileSync10,
|
|
36815
36944
|
renameSync as renameSync4,
|
|
36816
36945
|
unlinkSync as unlinkSync5,
|
|
36817
36946
|
writeFileSync as writeFileSync4
|
|
36818
36947
|
} from "node:fs";
|
|
36819
|
-
import { join as
|
|
36948
|
+
import { join as join20 } from "node:path";
|
|
36820
36949
|
import { getCleoHome as getCleoHome4, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
|
|
36821
36950
|
function configDirGlobalConfigPath() {
|
|
36822
|
-
return
|
|
36951
|
+
return join20(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
|
|
36823
36952
|
}
|
|
36824
36953
|
function legacyGlobalConfigPath() {
|
|
36825
|
-
return
|
|
36954
|
+
return join20(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
|
|
36826
36955
|
}
|
|
36827
36956
|
function migrationMarkerPath() {
|
|
36828
|
-
return
|
|
36957
|
+
return join20(getCleoHome4(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
|
|
36829
36958
|
}
|
|
36830
36959
|
function tempTargetPath() {
|
|
36831
36960
|
return `${configDirGlobalConfigPath()}.tmp`;
|
|
@@ -36835,12 +36964,12 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
36835
36964
|
const source = legacyGlobalConfigPath();
|
|
36836
36965
|
const target = configDirGlobalConfigPath();
|
|
36837
36966
|
const marker16 = migrationMarkerPath();
|
|
36838
|
-
if (
|
|
36839
|
-
if (!
|
|
36967
|
+
if (existsSync19(marker16)) return false;
|
|
36968
|
+
if (!existsSync19(source)) {
|
|
36840
36969
|
stampMarker(marker16);
|
|
36841
36970
|
return false;
|
|
36842
36971
|
}
|
|
36843
|
-
if (
|
|
36972
|
+
if (existsSync19(target)) {
|
|
36844
36973
|
backupSourceQuiet(source);
|
|
36845
36974
|
stampMarker(marker16);
|
|
36846
36975
|
return false;
|
|
@@ -36873,7 +37002,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
36873
37002
|
} catch (err) {
|
|
36874
37003
|
try {
|
|
36875
37004
|
const temp = tempTargetPath();
|
|
36876
|
-
if (
|
|
37005
|
+
if (existsSync19(temp)) unlinkSync5(temp);
|
|
36877
37006
|
} catch {
|
|
36878
37007
|
}
|
|
36879
37008
|
console.error(
|
|
@@ -36884,7 +37013,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
36884
37013
|
}
|
|
36885
37014
|
function stampMarker(markerPath) {
|
|
36886
37015
|
try {
|
|
36887
|
-
mkdirSync5(
|
|
37016
|
+
mkdirSync5(join20(getCleoHome4(), MIGRATIONS_SUBDIR), { recursive: true });
|
|
36888
37017
|
writeFileSync4(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
36889
37018
|
`, { mode: 420 });
|
|
36890
37019
|
} catch {
|
|
@@ -36893,7 +37022,7 @@ function stampMarker(markerPath) {
|
|
|
36893
37022
|
function backupSourceQuiet(source) {
|
|
36894
37023
|
try {
|
|
36895
37024
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
36896
|
-
if (
|
|
37025
|
+
if (existsSync19(backup)) return;
|
|
36897
37026
|
renameSync4(source, backup);
|
|
36898
37027
|
} catch {
|
|
36899
37028
|
}
|
|
@@ -36916,15 +37045,15 @@ var init_global_config_migration = __esm({
|
|
|
36916
37045
|
});
|
|
36917
37046
|
|
|
36918
37047
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
36919
|
-
import { existsSync as
|
|
36920
|
-
import { join as
|
|
37048
|
+
import { existsSync as existsSync20, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
37049
|
+
import { join as join21 } from "node:path";
|
|
36921
37050
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
36922
37051
|
function migrationPaths() {
|
|
36923
37052
|
const home = getCleoHome5();
|
|
36924
37053
|
return {
|
|
36925
|
-
flatPath:
|
|
36926
|
-
bakPath:
|
|
36927
|
-
markerPath:
|
|
37054
|
+
flatPath: join21(home, "anthropic-key"),
|
|
37055
|
+
bakPath: join21(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
|
|
37056
|
+
markerPath: join21(home, LEGACY_FLAT_KEY_MARKER)
|
|
36928
37057
|
};
|
|
36929
37058
|
}
|
|
36930
37059
|
function writeMarker(markerPath) {
|
|
@@ -36945,7 +37074,7 @@ function writeMarker(markerPath) {
|
|
|
36945
37074
|
}
|
|
36946
37075
|
function readFlatKey(flatPath) {
|
|
36947
37076
|
try {
|
|
36948
|
-
if (!
|
|
37077
|
+
if (!existsSync20(flatPath)) return null;
|
|
36949
37078
|
const raw = readFileSync11(flatPath, "utf-8").trim();
|
|
36950
37079
|
return raw || null;
|
|
36951
37080
|
} catch (err) {
|
|
@@ -36958,7 +37087,7 @@ function readFlatKey(flatPath) {
|
|
|
36958
37087
|
}
|
|
36959
37088
|
async function importLegacyFlatAnthropicKey() {
|
|
36960
37089
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
36961
|
-
if (
|
|
37090
|
+
if (existsSync20(markerPath)) {
|
|
36962
37091
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
36963
37092
|
}
|
|
36964
37093
|
let existing = null;
|
|
@@ -36975,7 +37104,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
36975
37104
|
writeMarker(markerPath);
|
|
36976
37105
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
36977
37106
|
}
|
|
36978
|
-
if (!
|
|
37107
|
+
if (!existsSync20(flatPath)) {
|
|
36979
37108
|
writeMarker(markerPath);
|
|
36980
37109
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
36981
37110
|
}
|
|
@@ -37051,15 +37180,15 @@ __export(credentials_exports, {
|
|
|
37051
37180
|
resolveProviderStatus: () => resolveProviderStatus,
|
|
37052
37181
|
storeAnthropicApiKey: () => storeAnthropicApiKey
|
|
37053
37182
|
});
|
|
37054
|
-
import { existsSync as
|
|
37055
|
-
import { join as
|
|
37183
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
|
|
37184
|
+
import { join as join22 } from "node:path";
|
|
37056
37185
|
import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
|
|
37057
37186
|
function globalConfigPath() {
|
|
37058
37187
|
return configDirGlobalConfigPath();
|
|
37059
37188
|
}
|
|
37060
37189
|
function projectConfigPath(projectRoot) {
|
|
37061
37190
|
const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
|
|
37062
|
-
return
|
|
37191
|
+
return join22(projectRoot, cleoDir, "config.json");
|
|
37063
37192
|
}
|
|
37064
37193
|
function readGlobalProviderKey(provider) {
|
|
37065
37194
|
ensureGlobalConfigMigrated();
|
|
@@ -37069,8 +37198,8 @@ function readGlobalProviderKey(provider) {
|
|
|
37069
37198
|
}
|
|
37070
37199
|
function readFlatAnthropicKey() {
|
|
37071
37200
|
try {
|
|
37072
|
-
const keyFile =
|
|
37073
|
-
if (!
|
|
37201
|
+
const keyFile = join22(getCleoHome6(), "anthropic-key");
|
|
37202
|
+
if (!existsSync21(keyFile)) return null;
|
|
37074
37203
|
const stored = readFileSync12(keyFile, "utf-8").trim();
|
|
37075
37204
|
return stored || null;
|
|
37076
37205
|
} catch {
|
|
@@ -37079,7 +37208,7 @@ function readFlatAnthropicKey() {
|
|
|
37079
37208
|
}
|
|
37080
37209
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
37081
37210
|
try {
|
|
37082
|
-
if (!
|
|
37211
|
+
if (!existsSync21(configFile)) return null;
|
|
37083
37212
|
const raw = readFileSync12(configFile, "utf-8");
|
|
37084
37213
|
const config2 = JSON.parse(raw);
|
|
37085
37214
|
const llm = config2["llm"];
|
|
@@ -37242,10 +37371,10 @@ function resolveProviderStatus(provider) {
|
|
|
37242
37371
|
}
|
|
37243
37372
|
function storeAnthropicApiKey(apiKey) {
|
|
37244
37373
|
const dir = getCleoHome6();
|
|
37245
|
-
if (!
|
|
37374
|
+
if (!existsSync21(dir)) {
|
|
37246
37375
|
mkdirSync6(dir, { recursive: true });
|
|
37247
37376
|
}
|
|
37248
|
-
const keyFile =
|
|
37377
|
+
const keyFile = join22(dir, "anthropic-key");
|
|
37249
37378
|
writeFileSync6(keyFile, apiKey.trim(), { mode: 384 });
|
|
37250
37379
|
}
|
|
37251
37380
|
function clearAnthropicKeyCache() {
|
|
@@ -37297,16 +37426,16 @@ var init_credentials2 = __esm({
|
|
|
37297
37426
|
});
|
|
37298
37427
|
|
|
37299
37428
|
// packages/core/src/llm/credentials-store.ts
|
|
37300
|
-
import { chmodSync, existsSync as
|
|
37301
|
-
import { dirname as
|
|
37429
|
+
import { chmodSync, existsSync as existsSync22, mkdirSync as mkdirSync7, readFileSync as readFileSync13, statSync as statSync6, writeFileSync as writeFileSync7 } from "node:fs";
|
|
37430
|
+
import { dirname as dirname9, join as join23 } from "node:path";
|
|
37302
37431
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
37303
37432
|
function credentialsStorePath() {
|
|
37304
|
-
return
|
|
37433
|
+
return join23(getCleoHome7(), "llm-credentials.json");
|
|
37305
37434
|
}
|
|
37306
37435
|
function ensureFileInitialized(path) {
|
|
37307
|
-
if (
|
|
37308
|
-
const dir =
|
|
37309
|
-
if (!
|
|
37436
|
+
if (existsSync22(path)) return;
|
|
37437
|
+
const dir = dirname9(path);
|
|
37438
|
+
if (!existsSync22(dir)) {
|
|
37310
37439
|
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
37311
37440
|
} else {
|
|
37312
37441
|
try {
|
|
@@ -37683,13 +37812,13 @@ var init_gemini = __esm({
|
|
|
37683
37812
|
|
|
37684
37813
|
// packages/core/src/llm/stable-device-id.ts
|
|
37685
37814
|
import { randomUUID } from "node:crypto";
|
|
37686
|
-
import { existsSync as
|
|
37687
|
-
import { dirname as
|
|
37815
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync14, renameSync as renameSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
37816
|
+
import { dirname as dirname10, join as join24 } from "node:path";
|
|
37688
37817
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
37689
37818
|
function getStableDeviceId() {
|
|
37690
37819
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
37691
|
-
const path =
|
|
37692
|
-
if (
|
|
37820
|
+
const path = join24(getCleoHome8(), DEVICE_ID_FILE);
|
|
37821
|
+
if (existsSync23(path)) {
|
|
37693
37822
|
try {
|
|
37694
37823
|
const raw = readFileSync14(path, "utf-8").trim();
|
|
37695
37824
|
if (raw.length > 0) {
|
|
@@ -37701,8 +37830,8 @@ function getStableDeviceId() {
|
|
|
37701
37830
|
}
|
|
37702
37831
|
const fresh = randomUUID();
|
|
37703
37832
|
try {
|
|
37704
|
-
const dir =
|
|
37705
|
-
if (!
|
|
37833
|
+
const dir = dirname10(path);
|
|
37834
|
+
if (!existsSync23(dir)) {
|
|
37706
37835
|
mkdirSync8(dir, { recursive: true });
|
|
37707
37836
|
}
|
|
37708
37837
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
@@ -38005,13 +38134,13 @@ var init_xai = __esm({
|
|
|
38005
38134
|
|
|
38006
38135
|
// packages/core/src/llm/provider-registry/loader.ts
|
|
38007
38136
|
import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
|
|
38008
|
-
import { join as
|
|
38137
|
+
import { join as join25 } from "node:path";
|
|
38009
38138
|
import { pathToFileURL } from "node:url";
|
|
38010
38139
|
function isPluginFile(filename) {
|
|
38011
38140
|
return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
|
|
38012
38141
|
}
|
|
38013
38142
|
function getPluginDir() {
|
|
38014
|
-
return
|
|
38143
|
+
return join25(getCleoHome(), "plugins", "model-providers");
|
|
38015
38144
|
}
|
|
38016
38145
|
async function loadOnePlugin(absPath, api) {
|
|
38017
38146
|
let mod;
|
|
@@ -38059,13 +38188,13 @@ async function scanAndLoadPlugins(pluginDir, api) {
|
|
|
38059
38188
|
}
|
|
38060
38189
|
const pluginFiles = entries.filter((name15) => !name15.startsWith(".") && isPluginFile(name15)).filter((name15) => {
|
|
38061
38190
|
try {
|
|
38062
|
-
return statSync7(
|
|
38191
|
+
return statSync7(join25(pluginDir, name15)).isFile();
|
|
38063
38192
|
} catch {
|
|
38064
38193
|
return false;
|
|
38065
38194
|
}
|
|
38066
38195
|
}).sort();
|
|
38067
38196
|
for (const filename of pluginFiles) {
|
|
38068
|
-
await loadOnePlugin(
|
|
38197
|
+
await loadOnePlugin(join25(pluginDir, filename), api);
|
|
38069
38198
|
}
|
|
38070
38199
|
}
|
|
38071
38200
|
async function runDiscovery(registerProvider2, builtins) {
|
|
@@ -38146,15 +38275,15 @@ var init_provider_registry = __esm({
|
|
|
38146
38275
|
});
|
|
38147
38276
|
|
|
38148
38277
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
38149
|
-
import { existsSync as
|
|
38150
|
-
import { join as
|
|
38278
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync9, unlinkSync as unlinkSync6 } from "node:fs";
|
|
38279
|
+
import { join as join26 } from "node:path";
|
|
38151
38280
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
38152
38281
|
function sanitize(value) {
|
|
38153
38282
|
return value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
38154
38283
|
}
|
|
38155
38284
|
function rateLimitStatePath(provider, label) {
|
|
38156
|
-
const dir =
|
|
38157
|
-
return
|
|
38285
|
+
const dir = join26(getCleoHome9(), "rate-limit-state");
|
|
38286
|
+
return join26(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
|
|
38158
38287
|
}
|
|
38159
38288
|
function parseResetFromHeaders(headers) {
|
|
38160
38289
|
const get = (k) => {
|
|
@@ -38201,8 +38330,8 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
38201
38330
|
source = "default";
|
|
38202
38331
|
}
|
|
38203
38332
|
const filePath = rateLimitStatePath(provider, label);
|
|
38204
|
-
const dir =
|
|
38205
|
-
if (!
|
|
38333
|
+
const dir = join26(getCleoHome9(), "rate-limit-state");
|
|
38334
|
+
if (!existsSync24(dir)) {
|
|
38206
38335
|
mkdirSync9(dir, { recursive: true });
|
|
38207
38336
|
}
|
|
38208
38337
|
const state = { resetAt, recordedAt: now, source };
|
|
@@ -39045,14 +39174,14 @@ var init_catalog_cache = __esm({
|
|
|
39045
39174
|
|
|
39046
39175
|
// packages/core/src/llm/model-metadata.ts
|
|
39047
39176
|
import { readFileSync as readFileSync15 } from "node:fs";
|
|
39048
|
-
import { dirname as
|
|
39177
|
+
import { dirname as dirname11, join as join27 } from "node:path";
|
|
39049
39178
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
39050
39179
|
function getCuratedTable() {
|
|
39051
39180
|
if (_curated !== void 0) {
|
|
39052
39181
|
return _curated;
|
|
39053
39182
|
}
|
|
39054
|
-
const thisDir =
|
|
39055
|
-
const jsonPath =
|
|
39183
|
+
const thisDir = dirname11(fileURLToPath3(import.meta.url));
|
|
39184
|
+
const jsonPath = join27(thisDir, "curated-models.json");
|
|
39056
39185
|
const raw = JSON.parse(readFileSync15(jsonPath, "utf-8"));
|
|
39057
39186
|
_curated = raw.models;
|
|
39058
39187
|
return _curated;
|