@cleocode/core 2026.4.12 → 2026.4.13
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/package.json +9 -7
- package/src/internal.ts +48 -1
- package/src/store/__tests__/backup-crypto.test.ts +101 -0
- package/src/store/__tests__/backup-pack.test.ts +491 -0
- package/src/store/__tests__/backup-unpack.test.ts +298 -0
- package/src/store/__tests__/regenerators.test.ts +234 -0
- package/src/store/__tests__/restore-conflict-report.test.ts +274 -0
- package/src/store/__tests__/restore-json-merge.test.ts +521 -0
- package/src/store/__tests__/t310-readiness.test.ts +111 -0
- package/src/store/__tests__/t311-integration.test.ts +661 -0
- package/src/store/backup-crypto.ts +209 -0
- package/src/store/backup-pack.ts +739 -0
- package/src/store/backup-unpack.ts +583 -0
- package/src/store/regenerators.ts +243 -0
- package/src/store/restore-conflict-report.ts +317 -0
- package/src/store/restore-json-merge.ts +653 -0
- package/src/store/t310-readiness.ts +119 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T310-readiness gate: detect conduit.db vs legacy signaldock.db at project tier.
|
|
3
|
+
*
|
|
4
|
+
* T311 backup/restore code paths reference `.cleo/conduit.db` (project tier) and
|
|
5
|
+
* `$XDG_DATA_HOME/cleo/signaldock.db` (global tier) per ADR-037. A project that
|
|
6
|
+
* has not yet been migrated (still has `.cleo/signaldock.db` without a
|
|
7
|
+
* `.cleo/conduit.db`) will confuse T311 export/import commands. This gate runs
|
|
8
|
+
* as a precondition on every T311 CLI verb.
|
|
9
|
+
*
|
|
10
|
+
* @task T342
|
|
11
|
+
* @epic T311
|
|
12
|
+
* @why T311 export/import references .cleo/conduit.db (project tier) and
|
|
13
|
+
* $XDG_DATA_HOME/cleo/signaldock.db (global tier) per ADR-037.
|
|
14
|
+
* If the current project is still on the pre-T310 topology, T311
|
|
15
|
+
* commands must surface a clear error telling the user to run a
|
|
16
|
+
* cleo command first to trigger migration.
|
|
17
|
+
* @what Throws T310MigrationRequiredError with instructions if legacy
|
|
18
|
+
* signaldock.db exists AND conduit.db does not.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { existsSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { getProjectRoot } from '../paths.js';
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Error class
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Thrown by `assertT310Ready` when the current project is still on the
|
|
31
|
+
* pre-T310 topology: `.cleo/signaldock.db` is present but `.cleo/conduit.db`
|
|
32
|
+
* is absent. T311 commands cannot proceed until migration has run.
|
|
33
|
+
*
|
|
34
|
+
* @task T342
|
|
35
|
+
* @epic T311
|
|
36
|
+
*/
|
|
37
|
+
export class T310MigrationRequiredError extends Error {
|
|
38
|
+
/**
|
|
39
|
+
* @param projectRoot - Absolute path to the project root that needs migration.
|
|
40
|
+
*/
|
|
41
|
+
constructor(public readonly projectRoot: string) {
|
|
42
|
+
super(
|
|
43
|
+
`T310 migration required: .cleo/signaldock.db still exists at ${projectRoot} ` +
|
|
44
|
+
`without a .cleo/conduit.db. Run any cleo command from within the project ` +
|
|
45
|
+
`(e.g. \`cleo version\`) to trigger the automatic T310 migration, then retry.`,
|
|
46
|
+
);
|
|
47
|
+
this.name = 'T310MigrationRequiredError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Public API
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Asserts the current project is on the post-T310 topology. Does nothing
|
|
57
|
+
* if conduit.db exists (migration already ran) OR if no legacy signaldock.db
|
|
58
|
+
* exists (fresh install — no migration needed).
|
|
59
|
+
*
|
|
60
|
+
* Throws when legacy signaldock.db is present AND conduit.db is absent,
|
|
61
|
+
* which indicates the project has not yet been migrated to the T310 topology
|
|
62
|
+
* expected by T311 backup/restore commands.
|
|
63
|
+
*
|
|
64
|
+
* @param projectRoot - Absolute path to the project root. Defaults to
|
|
65
|
+
* `getProjectRoot()` (walks ancestors for `.cleo/` sentinel).
|
|
66
|
+
* @throws {T310MigrationRequiredError} if legacy signaldock.db exists
|
|
67
|
+
* without conduit.db at the project tier.
|
|
68
|
+
*
|
|
69
|
+
* @task T342
|
|
70
|
+
* @epic T311
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* // Precondition guard at the top of every T311 CLI verb handler:
|
|
75
|
+
* assertT310Ready();
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export function assertT310Ready(projectRoot?: string): void {
|
|
79
|
+
const root = projectRoot ?? getProjectRoot();
|
|
80
|
+
const legacyPath = join(root, '.cleo', 'signaldock.db');
|
|
81
|
+
const conduitPath = join(root, '.cleo', 'conduit.db');
|
|
82
|
+
|
|
83
|
+
if (existsSync(legacyPath) && !existsSync(conduitPath)) {
|
|
84
|
+
throw new T310MigrationRequiredError(root);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns true if T311 commands can safely run on the current project.
|
|
90
|
+
*
|
|
91
|
+
* This is the non-throwing companion to `assertT310Ready`. Returns false
|
|
92
|
+
* only when the pre-T310 topology is detected (legacy signaldock.db exists
|
|
93
|
+
* without conduit.db). All other states — fresh installs, fully-migrated
|
|
94
|
+
* projects — return true.
|
|
95
|
+
*
|
|
96
|
+
* @param projectRoot - Absolute path to the project root. Defaults to
|
|
97
|
+
* `getProjectRoot()` (walks ancestors for `.cleo/` sentinel).
|
|
98
|
+
* @returns `true` if the project is on the post-T310 topology or is a fresh
|
|
99
|
+
* install; `false` if migration is required.
|
|
100
|
+
*
|
|
101
|
+
* @task T342
|
|
102
|
+
* @epic T311
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* if (!isT310Ready()) {
|
|
107
|
+
* console.error('Run `cleo version` to trigger T310 migration first.');
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function isT310Ready(projectRoot?: string): boolean {
|
|
112
|
+
try {
|
|
113
|
+
assertT310Ready(projectRoot);
|
|
114
|
+
return true;
|
|
115
|
+
} catch (err) {
|
|
116
|
+
if (err instanceof T310MigrationRequiredError) return false;
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|