@cleocode/core 2026.5.133 → 2026.5.134
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/store/exodus/index.d.ts +16 -0
- package/dist/store/exodus/index.d.ts.map +1 -0
- package/dist/store/exodus/index.js +16 -0
- package/dist/store/exodus/index.js.map +1 -0
- package/dist/store/exodus/migrate.d.ts +41 -0
- package/dist/store/exodus/migrate.d.ts.map +1 -0
- package/dist/store/exodus/migrate.js +416 -0
- package/dist/store/exodus/migrate.js.map +1 -0
- package/dist/store/exodus/plan.d.ts +44 -0
- package/dist/store/exodus/plan.d.ts.map +1 -0
- package/dist/store/exodus/plan.js +178 -0
- package/dist/store/exodus/plan.js.map +1 -0
- package/dist/store/exodus/status.d.ts +22 -0
- package/dist/store/exodus/status.d.ts.map +1 -0
- package/dist/store/exodus/status.js +88 -0
- package/dist/store/exodus/status.js.map +1 -0
- package/dist/store/exodus/types.d.ts +169 -0
- package/dist/store/exodus/types.d.ts.map +1 -0
- package/dist/store/exodus/types.js +21 -0
- package/dist/store/exodus/types.js.map +1 -0
- package/dist/store/exodus/verify.d.ts +34 -0
- package/dist/store/exodus/verify.d.ts.map +1 -0
- package/dist/store/exodus/verify.js +168 -0
- package/dist/store/exodus/verify.js.map +1 -0
- package/package.json +12 -12
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus pre-flight plan builder.
|
|
3
|
+
*
|
|
4
|
+
* `buildExodusPlan()` computes the full migration plan — source DB paths,
|
|
5
|
+
* combined size, free-disk availability, staging directory — BEFORE any
|
|
6
|
+
* writes occur. A `--dry-run` caller can print the plan and exit early.
|
|
7
|
+
*
|
|
8
|
+
* ## Disk pre-flight (AC8)
|
|
9
|
+
*
|
|
10
|
+
* `availableBytes >= 3 * totalSourceBytes` must hold before migration begins.
|
|
11
|
+
* The check uses `statvfs` via `node:fs.statfsSync()` (Node 18+).
|
|
12
|
+
*
|
|
13
|
+
* @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
|
|
14
|
+
* @saga T11242
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, readdirSync, statfsSync, statSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { getCleoHome, resolveCleoDir } from '../../paths.js';
|
|
19
|
+
import { resolveDualScopeDbPath } from '../dual-scope-db.js';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Legacy DB descriptors (AC2 — 6 per-machine source DBs mapped to 2 targets)
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Build the ordered list of legacy source DB descriptors for a given project.
|
|
25
|
+
*
|
|
26
|
+
* Project-scoped sources live under `<project>/.cleo/`.
|
|
27
|
+
* Global-scoped sources live under `getCleoHome()`.
|
|
28
|
+
*/
|
|
29
|
+
function buildSourceDescriptors(cwd) {
|
|
30
|
+
const cleoDir = resolveCleoDir(cwd);
|
|
31
|
+
const cleoHome = getCleoHome();
|
|
32
|
+
return [
|
|
33
|
+
// Project-tier — go into consolidated project-scope cleo.db
|
|
34
|
+
{
|
|
35
|
+
name: 'tasks',
|
|
36
|
+
path: join(cleoDir, 'tasks.db'),
|
|
37
|
+
targetScope: 'project',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'brain (project)',
|
|
41
|
+
path: join(cleoDir, 'brain.db'),
|
|
42
|
+
targetScope: 'project',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'conduit',
|
|
46
|
+
path: join(cleoDir, 'conduit.db'),
|
|
47
|
+
targetScope: 'project',
|
|
48
|
+
},
|
|
49
|
+
// Global-tier — go into consolidated global-scope cleo.db
|
|
50
|
+
{
|
|
51
|
+
name: 'nexus',
|
|
52
|
+
path: join(cleoHome, 'nexus.db'),
|
|
53
|
+
targetScope: 'global',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'signaldock',
|
|
57
|
+
path: join(cleoHome, 'signaldock.db'),
|
|
58
|
+
targetScope: 'global',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'skills',
|
|
62
|
+
path: join(cleoHome, 'skills.db'),
|
|
63
|
+
targetScope: 'global',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Safely stat a file and return its size in bytes, or 0 if it does not exist.
|
|
69
|
+
*/
|
|
70
|
+
function safeFileBytes(filePath) {
|
|
71
|
+
try {
|
|
72
|
+
return statSync(filePath).size;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Return available bytes on the filesystem that contains `dir`.
|
|
80
|
+
*
|
|
81
|
+
* Uses `statfsSync` (Node 18+). Falls back to 0 if unavailable.
|
|
82
|
+
*/
|
|
83
|
+
function getAvailableBytes(dir) {
|
|
84
|
+
try {
|
|
85
|
+
const result = statfsSync(dir);
|
|
86
|
+
// `bfree` = blocks free for privileged processes; `bavail` = unprivileged.
|
|
87
|
+
return (result.bavail ?? result.bfree ?? 0) * (result.bsize ?? 4096);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Derive the staging directory name from the current ISO-8601 timestamp.
|
|
95
|
+
*
|
|
96
|
+
* Pattern: `.cleo/exodus-staging-<YYYYMMDDTHHMMSSZ>`.
|
|
97
|
+
* Colons are replaced with empty string (NTFS + shell-safe).
|
|
98
|
+
*/
|
|
99
|
+
export function deriveStagingDirName() {
|
|
100
|
+
const iso = new Date()
|
|
101
|
+
.toISOString()
|
|
102
|
+
.replace(/[:]/g, '')
|
|
103
|
+
.replace(/\..+Z$/, 'Z');
|
|
104
|
+
return `exodus-staging-${iso}`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Scan for an existing staging directory from a previous (possibly crashed)
|
|
108
|
+
* run inside the given `.cleo/` directory.
|
|
109
|
+
*
|
|
110
|
+
* Returns the absolute path to the most-recent staging dir, or `null` if none
|
|
111
|
+
* exists.
|
|
112
|
+
*/
|
|
113
|
+
function findExistingStaging(cleoDir) {
|
|
114
|
+
try {
|
|
115
|
+
const entries = readdirSync(cleoDir, { withFileTypes: true });
|
|
116
|
+
const stagingDirs = entries
|
|
117
|
+
.filter((e) => e.isDirectory() && e.name.startsWith('exodus-staging-'))
|
|
118
|
+
.map((e) => e.name)
|
|
119
|
+
.sort()
|
|
120
|
+
.reverse(); // most recent first
|
|
121
|
+
if (stagingDirs.length > 0) {
|
|
122
|
+
return join(cleoDir, stagingDirs[0]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// .cleo/ may not exist yet
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Build the complete exodus plan.
|
|
132
|
+
*
|
|
133
|
+
* This is a pure read operation — no files are created or modified.
|
|
134
|
+
* Pass the result to `runExodusMigrate()` to execute the migration.
|
|
135
|
+
*
|
|
136
|
+
* @param cwd - Working directory used to resolve the project root. Defaults to
|
|
137
|
+
* `process.cwd()`.
|
|
138
|
+
* @returns {@link ExodusPlan} describing sources, disk availability, and paths.
|
|
139
|
+
*
|
|
140
|
+
* @task T11248 (AC8 — 3× disk pre-flight)
|
|
141
|
+
*/
|
|
142
|
+
export function buildExodusPlan(cwd) {
|
|
143
|
+
const cleoDir = resolveCleoDir(cwd);
|
|
144
|
+
const sources = buildSourceDescriptors(cwd);
|
|
145
|
+
// Compute total source size (only existing files count toward the check)
|
|
146
|
+
const totalSourceBytes = sources.reduce((sum, s) => sum + safeFileBytes(s.path), 0);
|
|
147
|
+
// Disk pre-flight: check against the directory that will hold the staging data
|
|
148
|
+
// (the .cleo/ dir, which is where both the backup and staging live).
|
|
149
|
+
const availableBytes = getAvailableBytes(cleoDir);
|
|
150
|
+
const diskPreflight = totalSourceBytes === 0 || availableBytes >= 3 * totalSourceBytes;
|
|
151
|
+
// Staging directory — resume if a previous one exists
|
|
152
|
+
const existingStaging = findExistingStaging(cleoDir);
|
|
153
|
+
const stagingDir = existingStaging ?? join(cleoDir, deriveStagingDirName());
|
|
154
|
+
const resumeFromStaging = existingStaging !== null;
|
|
155
|
+
// Target paths (consolidated cleo.db)
|
|
156
|
+
const projectDbPath = resolveDualScopeDbPath('project', cwd);
|
|
157
|
+
const globalDbPath = resolveDualScopeDbPath('global');
|
|
158
|
+
return {
|
|
159
|
+
sources,
|
|
160
|
+
totalSourceBytes,
|
|
161
|
+
availableBytes,
|
|
162
|
+
diskPreflight,
|
|
163
|
+
stagingDir,
|
|
164
|
+
resumeFromStaging,
|
|
165
|
+
projectDbPath,
|
|
166
|
+
globalDbPath,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check whether all required source DBs exist.
|
|
171
|
+
*
|
|
172
|
+
* Returns `true` if at least one source file is present (partial sets are
|
|
173
|
+
* acceptable — empty tables simply copy zero rows).
|
|
174
|
+
*/
|
|
175
|
+
export function sourcesPresent(sources) {
|
|
176
|
+
return sources.some((s) => existsSync(s.path));
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/store/exodus/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus status reporter.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusStatus()` returns a structured view of the current exodus state
|
|
5
|
+
* without performing any reads or writes beyond stat() calls.
|
|
6
|
+
*
|
|
7
|
+
* @task T11248 (E5 · AC3 · SG-DB-SUBSTRATE-V2)
|
|
8
|
+
* @saga T11242
|
|
9
|
+
*/
|
|
10
|
+
import type { ExodusStatusResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Return a structured status report for the exodus subsystem.
|
|
13
|
+
*
|
|
14
|
+
* This is a read-only operation — no mutations occur.
|
|
15
|
+
*
|
|
16
|
+
* @param cwd - Working directory used to resolve the project root.
|
|
17
|
+
* @returns {@link ExodusStatusResult}
|
|
18
|
+
*
|
|
19
|
+
* @task T11248 (AC3)
|
|
20
|
+
*/
|
|
21
|
+
export declare function runExodusStatus(cwd?: string): ExodusStatusResult;
|
|
22
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA0CpE;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA4BhE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus status reporter.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusStatus()` returns a structured view of the current exodus state
|
|
5
|
+
* without performing any reads or writes beyond stat() calls.
|
|
6
|
+
*
|
|
7
|
+
* @task T11248 (E5 · AC3 · SG-DB-SUBSTRATE-V2)
|
|
8
|
+
* @saga T11242
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { resolveCleoDir } from '../../paths.js';
|
|
13
|
+
import { resolveDualScopeDbPath } from '../dual-scope-db.js';
|
|
14
|
+
import { buildExodusPlan } from './plan.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Journal reader (mirrors logic in migrate.ts — kept local for zero coupling)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const JOURNAL_FILENAME = 'exodus-journal.json';
|
|
19
|
+
function readJournal(stagingDir) {
|
|
20
|
+
const p = join(stagingDir, JOURNAL_FILENAME);
|
|
21
|
+
if (!existsSync(p))
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function findStagingDirs(cleoDir) {
|
|
31
|
+
try {
|
|
32
|
+
return readdirSync(cleoDir, { withFileTypes: true })
|
|
33
|
+
.filter((e) => e.isDirectory() && e.name.startsWith('exodus-staging-'))
|
|
34
|
+
.map((e) => join(cleoDir, e.name))
|
|
35
|
+
.sort()
|
|
36
|
+
.reverse(); // most-recent first
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function safeBytes(p) {
|
|
43
|
+
try {
|
|
44
|
+
return statSync(p).size;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Main status runner
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Return a structured status report for the exodus subsystem.
|
|
55
|
+
*
|
|
56
|
+
* This is a read-only operation — no mutations occur.
|
|
57
|
+
*
|
|
58
|
+
* @param cwd - Working directory used to resolve the project root.
|
|
59
|
+
* @returns {@link ExodusStatusResult}
|
|
60
|
+
*
|
|
61
|
+
* @task T11248 (AC3)
|
|
62
|
+
*/
|
|
63
|
+
export function runExodusStatus(cwd) {
|
|
64
|
+
const plan = buildExodusPlan(cwd);
|
|
65
|
+
const cleoDir = resolveCleoDir(cwd);
|
|
66
|
+
// Find staging directories
|
|
67
|
+
const stagingDirs = findStagingDirs(cleoDir);
|
|
68
|
+
const latestStaging = stagingDirs[0] ?? null;
|
|
69
|
+
const journal = latestStaging ? readJournal(latestStaging) : null;
|
|
70
|
+
const projectDbPath = resolveDualScopeDbPath('project', cwd);
|
|
71
|
+
const globalDbPath = resolveDualScopeDbPath('global');
|
|
72
|
+
const sourcesInfo = plan.sources.map((s) => ({
|
|
73
|
+
name: s.name,
|
|
74
|
+
path: s.path,
|
|
75
|
+
exists: existsSync(s.path),
|
|
76
|
+
bytes: safeBytes(s.path),
|
|
77
|
+
}));
|
|
78
|
+
return {
|
|
79
|
+
hasStaging: latestStaging !== null,
|
|
80
|
+
stagingDir: latestStaging,
|
|
81
|
+
journal,
|
|
82
|
+
projectDbExists: existsSync(projectDbPath),
|
|
83
|
+
globalDbExists: existsSync(globalDbPath),
|
|
84
|
+
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
85
|
+
sources: sourcesInfo,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/store/exodus/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `cleo exodus` migration subsystem.
|
|
3
|
+
*
|
|
4
|
+
* The exodus subsystem migrates data from the legacy multi-DB fleet
|
|
5
|
+
* (tasks.db · brain.db · conduit.db · nexus.db · signaldock.db · skills.db)
|
|
6
|
+
* into the consolidated dual-scope `cleo.db` (project + global).
|
|
7
|
+
*
|
|
8
|
+
* @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
|
|
9
|
+
* @saga T11242
|
|
10
|
+
* @adr ADR-068, ADR-069
|
|
11
|
+
*/
|
|
12
|
+
/** The two consolidated target scopes. */
|
|
13
|
+
export type ExodusScope = 'project' | 'global';
|
|
14
|
+
/**
|
|
15
|
+
* Descriptor for one legacy source database.
|
|
16
|
+
*
|
|
17
|
+
* Each legacy DB maps to a scope (project or global) and a set of tables
|
|
18
|
+
* that will be copied into the consolidated `cleo.db` for that scope.
|
|
19
|
+
*/
|
|
20
|
+
export interface LegacyDbDescriptor {
|
|
21
|
+
/** Logical name for display / logging. */
|
|
22
|
+
readonly name: string;
|
|
23
|
+
/** Absolute path to the legacy `.db` file. */
|
|
24
|
+
readonly path: string;
|
|
25
|
+
/** Consolidated target scope that will receive this DB's tables. */
|
|
26
|
+
readonly targetScope: ExodusScope;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Per-table migration status tracked inside the staging journal
|
|
30
|
+
* (`exodus-journal.json`).
|
|
31
|
+
*/
|
|
32
|
+
export type TableMigrationStatus = 'pending' | 'done' | 'skipped';
|
|
33
|
+
/** Journal entry for one source table. */
|
|
34
|
+
export interface JournalTableEntry {
|
|
35
|
+
readonly sourceDb: string;
|
|
36
|
+
readonly tableName: string;
|
|
37
|
+
status: TableMigrationStatus;
|
|
38
|
+
rowsCopied: number;
|
|
39
|
+
/** ISO-8601 timestamp of last update. */
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
/** Error message if status ended in a non-retryable skip. */
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Contents of `.cleo/exodus-staging-<iso>/exodus-journal.json`.
|
|
46
|
+
*
|
|
47
|
+
* Written before the migration begins and updated atomically after each table
|
|
48
|
+
* copy so that a crash can be resumed from the last completed table.
|
|
49
|
+
*/
|
|
50
|
+
export interface ExodusJournal {
|
|
51
|
+
/** Exodus format version — bump when the schema changes. */
|
|
52
|
+
readonly version: 1;
|
|
53
|
+
/** cleo package version at the time the migration was started. */
|
|
54
|
+
readonly cleoVersion: string;
|
|
55
|
+
/** Drizzle v1.0.0-rc.3 schema hash (constant — used for cross-version guard). */
|
|
56
|
+
readonly targetSchemaVersion: string;
|
|
57
|
+
/** Node.js version at migration time. */
|
|
58
|
+
readonly nodeVersion: string;
|
|
59
|
+
/** SQLite version at migration time. */
|
|
60
|
+
readonly sqliteVersion: string;
|
|
61
|
+
/** ISO-8601 timestamp when the journal was first created. */
|
|
62
|
+
readonly startedAt: string;
|
|
63
|
+
/** ISO-8601 timestamp of last update. */
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
/** Per-table progress entries. Ordered by (sourceDb, tableName). */
|
|
66
|
+
tables: JournalTableEntry[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Result of a single `ExodusTable` copy operation.
|
|
70
|
+
*
|
|
71
|
+
* Returned by `copyTable` and collected into the migration report.
|
|
72
|
+
*/
|
|
73
|
+
export interface TableCopyResult {
|
|
74
|
+
readonly sourceDb: string;
|
|
75
|
+
readonly tableName: string;
|
|
76
|
+
readonly rowsCopied: number;
|
|
77
|
+
readonly skipped: boolean;
|
|
78
|
+
readonly reason?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Top-level exodus plan — computed by `buildExodusPlan()` before any writes.
|
|
82
|
+
*
|
|
83
|
+
* Carries all pre-flight information including disk-space check results so
|
|
84
|
+
* that `--dry-run` can print a rich preview.
|
|
85
|
+
*/
|
|
86
|
+
export interface ExodusPlan {
|
|
87
|
+
/** The legacy source descriptors that will participate in the migration. */
|
|
88
|
+
readonly sources: LegacyDbDescriptor[];
|
|
89
|
+
/** Combined size of all source DB files in bytes. */
|
|
90
|
+
readonly totalSourceBytes: number;
|
|
91
|
+
/** Available disk bytes on the target filesystem. */
|
|
92
|
+
readonly availableBytes: number;
|
|
93
|
+
/** Whether the 3× free-disk pre-flight passes. */
|
|
94
|
+
readonly diskPreflight: boolean;
|
|
95
|
+
/** Absolute path to the staging directory. */
|
|
96
|
+
readonly stagingDir: string;
|
|
97
|
+
/** Whether a staging directory from a previous run was found (resume mode). */
|
|
98
|
+
readonly resumeFromStaging: boolean;
|
|
99
|
+
/** Absolute path to the target project cleo.db. */
|
|
100
|
+
readonly projectDbPath: string;
|
|
101
|
+
/** Absolute path to the target global cleo.db. */
|
|
102
|
+
readonly globalDbPath: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Result returned by `runExodusMigrate()`.
|
|
106
|
+
*/
|
|
107
|
+
export interface ExodusMigrateResult {
|
|
108
|
+
readonly ok: boolean;
|
|
109
|
+
readonly tables: TableCopyResult[];
|
|
110
|
+
readonly stagingDir: string;
|
|
111
|
+
readonly backupPaths: string[];
|
|
112
|
+
/** Error message if `ok === false`. */
|
|
113
|
+
readonly error?: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Per-table verification entry produced by `runExodusVerify()`.
|
|
117
|
+
*/
|
|
118
|
+
export interface VerifyTableResult {
|
|
119
|
+
readonly tableName: string;
|
|
120
|
+
readonly scope: ExodusScope;
|
|
121
|
+
/** Row count in the source legacy DB. */
|
|
122
|
+
readonly sourceCount: number;
|
|
123
|
+
/** Row count in the consolidated cleo.db. */
|
|
124
|
+
readonly targetCount: number;
|
|
125
|
+
/** xxhash3-based ordered canonical-JSON digest (hex). */
|
|
126
|
+
readonly sourceHash: string;
|
|
127
|
+
readonly targetHash: string;
|
|
128
|
+
readonly hashMatch: boolean;
|
|
129
|
+
readonly countMatch: boolean;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Result returned by `runExodusVerify()`.
|
|
133
|
+
*/
|
|
134
|
+
export interface ExodusVerifyResult {
|
|
135
|
+
readonly ok: boolean;
|
|
136
|
+
readonly tables: VerifyTableResult[];
|
|
137
|
+
readonly error?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Status returned by `runExodusStatus()`.
|
|
141
|
+
*/
|
|
142
|
+
export interface ExodusStatusResult {
|
|
143
|
+
/** Whether a staging journal exists from a previous (possibly incomplete) run. */
|
|
144
|
+
readonly hasStaging: boolean;
|
|
145
|
+
readonly stagingDir: string | null;
|
|
146
|
+
readonly journal: ExodusJournal | null;
|
|
147
|
+
/** Whether the consolidated project-scope cleo.db already exists. */
|
|
148
|
+
readonly projectDbExists: boolean;
|
|
149
|
+
/** Whether the consolidated global-scope cleo.db already exists. */
|
|
150
|
+
readonly globalDbExists: boolean;
|
|
151
|
+
/** Whether all source legacy DBs exist. */
|
|
152
|
+
readonly sourcesPresent: boolean;
|
|
153
|
+
readonly sources: Array<{
|
|
154
|
+
name: string;
|
|
155
|
+
path: string;
|
|
156
|
+
exists: boolean;
|
|
157
|
+
bytes: number;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Canonical schema version tag embedded in the exodus journal.
|
|
162
|
+
*
|
|
163
|
+
* This constant represents the Drizzle v1.0.0-rc.3 target schema "epoch"
|
|
164
|
+
* for the dual-scope consolidation (T11245 · E2 · SG-DB-SUBSTRATE-V2).
|
|
165
|
+
* The exact value is a stable marker — not a live hash — so that import
|
|
166
|
+
* refuses cross-version migration unless `--force-cross-version` is passed.
|
|
167
|
+
*/
|
|
168
|
+
export declare const EXODUS_TARGET_SCHEMA_VERSION: "drizzle-v1.0.0-rc.3/dual-scope/2026-05";
|
|
169
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `cleo exodus` migration subsystem.
|
|
3
|
+
*
|
|
4
|
+
* The exodus subsystem migrates data from the legacy multi-DB fleet
|
|
5
|
+
* (tasks.db · brain.db · conduit.db · nexus.db · signaldock.db · skills.db)
|
|
6
|
+
* into the consolidated dual-scope `cleo.db` (project + global).
|
|
7
|
+
*
|
|
8
|
+
* @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
|
|
9
|
+
* @saga T11242
|
|
10
|
+
* @adr ADR-068, ADR-069
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Canonical schema version tag embedded in the exodus journal.
|
|
14
|
+
*
|
|
15
|
+
* This constant represents the Drizzle v1.0.0-rc.3 target schema "epoch"
|
|
16
|
+
* for the dual-scope consolidation (T11245 · E2 · SG-DB-SUBSTRATE-V2).
|
|
17
|
+
* The exact value is a stable marker — not a live hash — so that import
|
|
18
|
+
* refuses cross-version migration unless `--force-cross-version` is passed.
|
|
19
|
+
*/
|
|
20
|
+
export const EXODUS_TARGET_SCHEMA_VERSION = 'drizzle-v1.0.0-rc.3/dual-scope/2026-05';
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/store/exodus/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4JH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,wCAAiD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus verification engine.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusVerify()` checks equivalence between source legacy DBs and the
|
|
5
|
+
* consolidated dual-scope `cleo.db` after a migration.
|
|
6
|
+
*
|
|
7
|
+
* ## Equivalence checks (AC7)
|
|
8
|
+
*
|
|
9
|
+
* Per-table:
|
|
10
|
+
* 1. `COUNT(*)` parity — source and target row counts must match.
|
|
11
|
+
* 2. Ordered canonical-JSON digest — SELECT all rows ORDER BY rowid, JSON-
|
|
12
|
+
* stringify each row, SHA-256 the concatenation (truncated to 32 hex).
|
|
13
|
+
*
|
|
14
|
+
* @task T11248 (E5 · AC7 · SG-DB-SUBSTRATE-V2)
|
|
15
|
+
* @saga T11242
|
|
16
|
+
*/
|
|
17
|
+
import type { ExodusVerifyResult, LegacyDbDescriptor } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Run equivalence verification after an exodus migration.
|
|
20
|
+
*
|
|
21
|
+
* Opens source DBs read-only and the consolidated target DBs read-only, then
|
|
22
|
+
* compares row counts and canonical-JSON digests per table.
|
|
23
|
+
*
|
|
24
|
+
* @param sources - Legacy source descriptors (from `buildExodusPlan()`).
|
|
25
|
+
* @param projectDbPath - Absolute path to the consolidated project `cleo.db`.
|
|
26
|
+
* @param globalDbPath - Absolute path to the consolidated global `cleo.db`.
|
|
27
|
+
* @param onProgress - Optional progress callback.
|
|
28
|
+
*
|
|
29
|
+
* @returns {@link ExodusVerifyResult}
|
|
30
|
+
*
|
|
31
|
+
* @task T11248 (AC7)
|
|
32
|
+
*/
|
|
33
|
+
export declare function runExodusVerify(sources: LegacyDbDescriptor[], projectDbPath: string, globalDbPath: string, onProgress?: (msg: string) => void): ExodusVerifyResult;
|
|
34
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAkDpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GACjC,kBAAkB,CA4GpB"}
|