@cleocode/core 2026.10.13 → 2026.10.14-rc.ci.683

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.
Files changed (204) hide show
  1. package/dist/build-provenance.json +2 -2
  2. package/dist/cloud/nexus-vault.d.ts +6 -2
  3. package/dist/cloud/nexus-vault.d.ts.map +1 -1
  4. package/dist/cloud/nexus-vault.js +53 -3
  5. package/dist/cloud/nexus-vault.js.map +1 -1
  6. package/dist/cloud/secret-seal.js +2 -2
  7. package/dist/cloud/secret-seal.js.map +1 -1
  8. package/dist/config/registry.d.ts +0 -21
  9. package/dist/config/registry.d.ts.map +1 -1
  10. package/dist/config/registry.js +0 -41
  11. package/dist/config/registry.js.map +1 -1
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +1 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/crypto/credentials.d.ts +13 -0
  16. package/dist/crypto/credentials.d.ts.map +1 -1
  17. package/dist/crypto/credentials.js +35 -6
  18. package/dist/crypto/credentials.js.map +1 -1
  19. package/dist/docs/docs-ops.d.ts +11 -1
  20. package/dist/docs/docs-ops.d.ts.map +1 -1
  21. package/dist/docs/docs-ops.js +38 -3
  22. package/dist/docs/docs-ops.js.map +1 -1
  23. package/dist/docs/docs-update.d.ts.map +1 -1
  24. package/dist/docs/docs-update.js +5 -1
  25. package/dist/docs/docs-update.js.map +1 -1
  26. package/dist/docs/supersede.d.ts.map +1 -1
  27. package/dist/docs/supersede.js +5 -1
  28. package/dist/docs/supersede.js.map +1 -1
  29. package/dist/docs/wikilinks.d.ts +3 -1
  30. package/dist/docs/wikilinks.d.ts.map +1 -1
  31. package/dist/docs/wikilinks.js +23 -12
  32. package/dist/docs/wikilinks.js.map +1 -1
  33. package/dist/gateway-client/generated/index.d.ts +2 -2
  34. package/dist/gateway-client/generated/index.d.ts.map +1 -1
  35. package/dist/gateway-client/generated/index.js +1 -1
  36. package/dist/gateway-client/generated/index.js.map +1 -1
  37. package/dist/gateway-client/generated/namespaces.gen.d.ts +33 -0
  38. package/dist/gateway-client/generated/namespaces.gen.d.ts.map +1 -1
  39. package/dist/gateway-client/generated/namespaces.gen.js +34 -1
  40. package/dist/gateway-client/generated/namespaces.gen.js.map +1 -1
  41. package/dist/gateway-client/generated/sdk.gen.d.ts +137 -5
  42. package/dist/gateway-client/generated/sdk.gen.d.ts.map +1 -1
  43. package/dist/gateway-client/generated/sdk.gen.js +355 -6
  44. package/dist/gateway-client/generated/sdk.gen.js.map +1 -1
  45. package/dist/gateway-client/generated/types.gen.d.ts +1811 -187
  46. package/dist/gateway-client/generated/types.gen.d.ts.map +1 -1
  47. package/dist/lib/error-message.d.ts +30 -0
  48. package/dist/lib/error-message.d.ts.map +1 -0
  49. package/dist/lib/error-message.js +65 -0
  50. package/dist/lib/error-message.js.map +1 -0
  51. package/dist/lib/index.d.ts +1 -0
  52. package/dist/lib/index.d.ts.map +1 -1
  53. package/dist/lib/index.js +1 -0
  54. package/dist/lib/index.js.map +1 -1
  55. package/dist/llm/credentials-store.d.ts +29 -16
  56. package/dist/llm/credentials-store.d.ts.map +1 -1
  57. package/dist/llm/credentials-store.js +158 -139
  58. package/dist/llm/credentials-store.js.map +1 -1
  59. package/dist/memory/brain-embedding.d.ts +4 -2
  60. package/dist/memory/brain-embedding.d.ts.map +1 -1
  61. package/dist/memory/brain-embedding.js +8 -2
  62. package/dist/memory/brain-embedding.js.map +1 -1
  63. package/dist/memory/embedding-local.d.ts +28 -5
  64. package/dist/memory/embedding-local.d.ts.map +1 -1
  65. package/dist/memory/embedding-local.js +47 -9
  66. package/dist/memory/embedding-local.js.map +1 -1
  67. package/dist/memory/engine-compat.d.ts +4 -0
  68. package/dist/memory/engine-compat.d.ts.map +1 -1
  69. package/dist/memory/engine-compat.js +76 -0
  70. package/dist/memory/engine-compat.js.map +1 -1
  71. package/dist/memory/global-brain.d.ts +93 -0
  72. package/dist/memory/global-brain.d.ts.map +1 -0
  73. package/dist/memory/global-brain.js +183 -0
  74. package/dist/memory/global-brain.js.map +1 -0
  75. package/dist/memory/patterns.d.ts +2 -2
  76. package/dist/memory/quality-feedback.d.ts.map +1 -1
  77. package/dist/memory/quality-feedback.js +0 -26
  78. package/dist/memory/quality-feedback.js.map +1 -1
  79. package/dist/memory/retrieval/observe.js +4 -4
  80. package/dist/memory/retrieval/observe.js.map +1 -1
  81. package/dist/memory/transcript-extractor.js +5 -2
  82. package/dist/memory/transcript-extractor.js.map +1 -1
  83. package/dist/orchestration/lean-change.d.ts.map +1 -1
  84. package/dist/orchestration/lean-change.js +2 -3
  85. package/dist/orchestration/lean-change.js.map +1 -1
  86. package/dist/orchestration/lean-debt.d.ts +48 -0
  87. package/dist/orchestration/lean-debt.d.ts.map +1 -0
  88. package/dist/orchestration/lean-debt.js +167 -0
  89. package/dist/orchestration/lean-debt.js.map +1 -0
  90. package/dist/sessions/briefing.d.ts.map +1 -1
  91. package/dist/sessions/briefing.js +10 -0
  92. package/dist/sessions/briefing.js.map +1 -1
  93. package/dist/store/attachment-store.d.ts.map +1 -1
  94. package/dist/store/attachment-store.js +5 -1
  95. package/dist/store/attachment-store.js.map +1 -1
  96. package/dist/store/backup-sidecar.d.ts +5 -2
  97. package/dist/store/backup-sidecar.d.ts.map +1 -1
  98. package/dist/store/backup-sidecar.js +31 -18
  99. package/dist/store/backup-sidecar.js.map +1 -1
  100. package/dist/store/credential-transfer.d.ts +13 -14
  101. package/dist/store/credential-transfer.d.ts.map +1 -1
  102. package/dist/store/credential-transfer.js +75 -23
  103. package/dist/store/credential-transfer.js.map +1 -1
  104. package/dist/store/docs-bytes-backup.d.ts +133 -0
  105. package/dist/store/docs-bytes-backup.d.ts.map +1 -0
  106. package/dist/store/docs-bytes-backup.js +450 -0
  107. package/dist/store/docs-bytes-backup.js.map +1 -0
  108. package/dist/store/llm-accounts-accessor.d.ts +107 -0
  109. package/dist/store/llm-accounts-accessor.d.ts.map +1 -0
  110. package/dist/store/llm-accounts-accessor.js +224 -0
  111. package/dist/store/llm-accounts-accessor.js.map +1 -0
  112. package/dist/store/memory-accessor.d.ts +44 -0
  113. package/dist/store/memory-accessor.d.ts.map +1 -1
  114. package/dist/store/memory-accessor.js +60 -0
  115. package/dist/store/memory-accessor.js.map +1 -1
  116. package/dist/store/memory-sqlite.d.ts +18 -0
  117. package/dist/store/memory-sqlite.d.ts.map +1 -1
  118. package/dist/store/memory-sqlite.js +40 -23
  119. package/dist/store/memory-sqlite.js.map +1 -1
  120. package/dist/store/migration-manager.d.ts.map +1 -1
  121. package/dist/store/migration-manager.js +7 -1
  122. package/dist/store/migration-manager.js.map +1 -1
  123. package/dist/store/restore-store.d.ts +12 -1
  124. package/dist/store/restore-store.d.ts.map +1 -1
  125. package/dist/store/restore-store.js +150 -11
  126. package/dist/store/restore-store.js.map +1 -1
  127. package/dist/store/row-identity-registry.d.ts +4 -4
  128. package/dist/store/row-identity-registry.d.ts.map +1 -1
  129. package/dist/store/row-identity-registry.js +35 -8
  130. package/dist/store/row-identity-registry.js.map +1 -1
  131. package/dist/store/schema/cleo-global/accounts.d.ts +6 -5
  132. package/dist/store/schema/cleo-global/accounts.d.ts.map +1 -1
  133. package/dist/store/schema/cleo-global/accounts.js +7 -6
  134. package/dist/store/schema/cleo-global/accounts.js.map +1 -1
  135. package/dist/store/schema/cleo-project/docs.d.ts +32 -0
  136. package/dist/store/schema/cleo-project/docs.d.ts.map +1 -1
  137. package/dist/store/schema/cleo-project/docs.js +9 -0
  138. package/dist/store/schema/cleo-project/docs.js.map +1 -1
  139. package/dist/store/sync/apply/applier.d.ts +3 -1
  140. package/dist/store/sync/apply/applier.d.ts.map +1 -1
  141. package/dist/store/sync/apply/applier.js +80 -19
  142. package/dist/store/sync/apply/applier.js.map +1 -1
  143. package/dist/store/sync/apply/parent-delete.d.ts.map +1 -1
  144. package/dist/store/sync/apply/parent-delete.js +4 -0
  145. package/dist/store/sync/apply/parent-delete.js.map +1 -1
  146. package/dist/store/sync/apply/write-api.d.ts +5 -1
  147. package/dist/store/sync/apply/write-api.d.ts.map +1 -1
  148. package/dist/store/sync/apply/write-api.js +22 -0
  149. package/dist/store/sync/apply/write-api.js.map +1 -1
  150. package/dist/store/sync/capture.d.ts +27 -0
  151. package/dist/store/sync/capture.d.ts.map +1 -1
  152. package/dist/store/sync/capture.js +32 -1
  153. package/dist/store/sync/capture.js.map +1 -1
  154. package/dist/store/sync/genesis.d.ts.map +1 -1
  155. package/dist/store/sync/genesis.js +3 -1
  156. package/dist/store/sync/genesis.js.map +1 -1
  157. package/dist/store/sync/inbox.d.ts +18 -2
  158. package/dist/store/sync/inbox.d.ts.map +1 -1
  159. package/dist/store/sync/inbox.js +23 -2
  160. package/dist/store/sync/inbox.js.map +1 -1
  161. package/dist/store/sync/pull.d.ts +1 -1
  162. package/dist/store/sync/pull.d.ts.map +1 -1
  163. package/dist/store/sync/pull.js +4 -1
  164. package/dist/store/sync/pull.js.map +1 -1
  165. package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
  166. package/dist/store/sync/timestamp-canon.js +3 -0
  167. package/dist/store/sync/timestamp-canon.js.map +1 -1
  168. package/dist/store/table-classification.d.ts.map +1 -1
  169. package/dist/store/table-classification.js +29 -3
  170. package/dist/store/table-classification.js.map +1 -1
  171. package/dist/system/backup.d.ts +5 -2
  172. package/dist/system/backup.d.ts.map +1 -1
  173. package/dist/system/backup.js +39 -3
  174. package/dist/system/backup.js.map +1 -1
  175. package/dist/tasks/affected-scope.d.ts +44 -5
  176. package/dist/tasks/affected-scope.d.ts.map +1 -1
  177. package/dist/tasks/affected-scope.js +159 -20
  178. package/dist/tasks/affected-scope.js.map +1 -1
  179. package/dist/tasks/complete-ci.d.ts.map +1 -1
  180. package/dist/tasks/complete-ci.js +11 -9
  181. package/dist/tasks/complete-ci.js.map +1 -1
  182. package/dist/tasks/done-plan.d.ts.map +1 -1
  183. package/dist/tasks/done-plan.js +4 -6
  184. package/dist/tasks/done-plan.js.map +1 -1
  185. package/dist/tasks/gate-preview.d.ts.map +1 -1
  186. package/dist/tasks/gate-preview.js +13 -5
  187. package/dist/tasks/gate-preview.js.map +1 -1
  188. package/dist/tasks/gate-result-cache.d.ts +30 -1
  189. package/dist/tasks/gate-result-cache.d.ts.map +1 -1
  190. package/dist/tasks/gate-result-cache.js +81 -2
  191. package/dist/tasks/gate-result-cache.js.map +1 -1
  192. package/dist/tasks/gate-runner.d.ts +27 -2
  193. package/dist/tasks/gate-runner.d.ts.map +1 -1
  194. package/dist/tasks/gate-runner.js +67 -14
  195. package/dist/tasks/gate-runner.js.map +1 -1
  196. package/dist/tasks/qa-run-binding.d.ts +15 -0
  197. package/dist/tasks/qa-run-binding.d.ts.map +1 -1
  198. package/dist/tasks/qa-run-binding.js +24 -3
  199. package/dist/tasks/qa-run-binding.js.map +1 -1
  200. package/migrations/drizzle-brain/20261014180000_t13719-prune-candidate-column/migration.sql +16 -0
  201. package/migrations/drizzle-cleo-project/20261014100000_t12919-docs-row-uids/migration.sql +27 -0
  202. package/package.json +13 -13
  203. package/templates/CLEO-REFERENCE.md +1 -1
  204. package/templates/global-config.template.json +2 -1
@@ -0,0 +1,450 @@
1
+ /**
2
+ * Back up and restore the docs byte surfaces (T13704): the content a project
3
+ * store backup alone cannot serve `docs fetch` from.
4
+ *
5
+ * - `.cleo/blobs/manifest.db` (blob-store metadata) and
6
+ * `.cleo/blobs/blobs/<sha256>` (the bytes);
7
+ * - `.cleo/attachments/index.db` and the legacy byte tree under
8
+ * `.cleo/attachments/` (`sha256/<2>/<62><ext>`, `keep/...`).
9
+ *
10
+ * The two databases are snapshotted per backup with `VACUUM INTO`, checked
11
+ * with `PRAGMA integrity_check`, and stored as flat `<label>.<backupId>`
12
+ * payloads beside the store snapshot. The byte files go into ONE shared
13
+ * content-addressed pool, `.cleo/backups/blobs/<sha256>`, written once and
14
+ * shared by every backup (T13710: a real store holds ~10k files, so per-backup
15
+ * copies made rotation delete the backups themselves). Each backup lists what
16
+ * it references in a `docs-bytes.json.<backupId>` sidecar; rotation removes a
17
+ * whole backup, sidecar included, and {@link sweepDocsBytePool} then unlinks
18
+ * only pool files no surviving sidecar references.
19
+ *
20
+ * Restore verifies every byte before placing it: each pool file must hash to
21
+ * its recorded sha256, each database snapshot must match its recorded sha256
22
+ * and pass `integrity_check` on the staged copy that is then renamed into
23
+ * place. Anything that fails is listed; a restore with failures is partial,
24
+ * never clean (T13709).
25
+ *
26
+ * Synchronous on purpose: callers hold no async lock across it, and the pool
27
+ * lock is a {@link withLockSync} lock whose stale age covers a full pass.
28
+ *
29
+ * @module store/docs-bytes-backup
30
+ * @task T13704
31
+ * @task T13708
32
+ * @task T13709
33
+ * @task T13710
34
+ */
35
+ import { createHash } from 'node:crypto';
36
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, unlinkSync, writeFileSync, } from 'node:fs';
37
+ import { dirname, isAbsolute, join } from 'node:path';
38
+ import { z } from 'zod';
39
+ import { getLogger } from '../logger.js';
40
+ import { withLockSync } from './lock.js';
41
+ import { integrityCheck, vacuumSnapshot } from './portable-bundle-scan.js';
42
+ import { storeOpenElsewhere } from './writer-lease.js';
43
+ /** Label of the per-backup sidecar listing the docs bytes it references (`<label>.<backupId>`). */
44
+ export const DOCS_BYTES_SIDECAR_LABEL = 'docs-bytes.json';
45
+ /** The docs databases, snapshotted per backup as `<label>.<backupId>`. Paths relative to `.cleo/`. */
46
+ const DOCS_DBS = [
47
+ { label: 'blobs.manifest.db', path: 'blobs/manifest.db' },
48
+ { label: 'attachments.index.db', path: 'attachments/index.db' },
49
+ ];
50
+ /** The byte trees pooled by content address. Paths relative to `.cleo/`. */
51
+ const DOCS_BYTE_TREES = ['blobs/blobs', 'attachments'];
52
+ /** SQLite sidecars of a live database: never copied as bytes. */
53
+ const DB_SIDECARS = ['-wal', '-shm', '-journal'];
54
+ /** A full pass over ~10k files blocks for seconds; the pool lock is never taken as stale before this. */
55
+ const POOL_LOCK_STALE_MS = 10 * 60_000;
56
+ const sha256Hex = /^[0-9a-f]{64}$/;
57
+ const sidecarSchema = z.object({
58
+ version: z.literal(1),
59
+ dbs: z.array(z.object({ label: z.string(), path: z.string(), sha256: z.string().regex(sha256Hex) })),
60
+ files: z.array(z.object({ path: z.string(), sha256: z.string().regex(sha256Hex) })),
61
+ });
62
+ /** The shared byte pool of a backup directory (`.cleo/backups/sqlite` -> `.cleo/backups/blobs`). */
63
+ export function docsBytePoolDir(backupDir) {
64
+ return join(dirname(backupDir), 'blobs');
65
+ }
66
+ function sha256OfFile(path) {
67
+ return createHash('sha256').update(readFileSync(path)).digest('hex');
68
+ }
69
+ /**
70
+ * The sha256 a byte file's path claims, or `null` when the path is not
71
+ * content-addressed: `blobs/blobs/<sha>`, or `attachments/{sha256,keep}/<2>/<62>[.ext]`.
72
+ */
73
+ function contentAddress(rel) {
74
+ const parts = rel.split('/');
75
+ if (parts[0] === 'blobs' && parts.length === 3) {
76
+ return sha256Hex.test(parts[2] ?? '') ? (parts[2] ?? null) : null;
77
+ }
78
+ if (parts[0] !== 'attachments' || parts.length !== 4)
79
+ return null;
80
+ if (parts[1] !== 'sha256' && parts[1] !== 'keep')
81
+ return null;
82
+ const name = parts[3] ?? '';
83
+ const stem = name.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;
84
+ const sha = `${parts[2]}${stem}`;
85
+ return sha256Hex.test(sha) ? sha : null;
86
+ }
87
+ /** Every regular file under `dir`, as paths relative to `cleoDir` with `/` separators. */
88
+ function walkFiles(cleoDir, dir, out) {
89
+ if (!existsSync(dir))
90
+ return;
91
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
92
+ const abs = join(dir, entry.name);
93
+ if (entry.isDirectory())
94
+ walkFiles(cleoDir, abs, out);
95
+ else if (entry.isFile())
96
+ out.push(abs
97
+ .slice(cleoDir.length + 1)
98
+ .split('\\')
99
+ .join('/'));
100
+ }
101
+ }
102
+ /** Whether `rel` is one of the docs databases or a sidecar of one (snapshotted, never copied raw). */
103
+ function isDocsDbFile(rel) {
104
+ return DOCS_DBS.some((db) => rel === db.path || DB_SIDECARS.some((suffix) => rel === `${db.path}${suffix}`));
105
+ }
106
+ /** Copy `from` to a private name beside `to`, then rename it into place. */
107
+ function copyAtomic(from, to) {
108
+ mkdirSync(dirname(to), { recursive: true });
109
+ const tmp = `${to}.tmp-${process.pid}-${Date.now()}`;
110
+ try {
111
+ copyFileSync(from, tmp);
112
+ renameSync(tmp, to);
113
+ }
114
+ finally {
115
+ rmSync(tmp, { force: true });
116
+ }
117
+ }
118
+ function withPoolLock(backupDir, fn) {
119
+ const pool = docsBytePoolDir(backupDir);
120
+ mkdirSync(pool, { recursive: true });
121
+ return withLockSync(pool, fn, {
122
+ waitMs: 60_000,
123
+ stale: POOL_LOCK_STALE_MS,
124
+ label: 'the backup blob pool',
125
+ });
126
+ }
127
+ /**
128
+ * Snapshot the docs byte surfaces of `cleoDir` into backup `backupId` (T13704):
129
+ * VACUUM INTO + integrity_check for each docs database, every byte file into
130
+ * the shared pool (written once), and the `docs-bytes.json.<backupId>`
131
+ * sidecar listing what the backup references. Best effort per file: what
132
+ * fails is reported in `skipped`, never silently dropped.
133
+ *
134
+ * @param cleoDir - The project's `.cleo/` directory.
135
+ * @param backupDir - `.cleo/backups/sqlite`.
136
+ * @param backupId - The backup the snapshot belongs to.
137
+ * @returns What was captured, or `null` when there are no docs byte surfaces.
138
+ */
139
+ export function backupDocsBytes(cleoDir, backupDir, backupId) {
140
+ if (!existsSync(join(cleoDir, 'blobs')) && !existsSync(join(cleoDir, 'attachments')))
141
+ return null;
142
+ return withPoolLock(backupDir, () => {
143
+ const pool = docsBytePoolDir(backupDir);
144
+ const skipped = [];
145
+ const sidecar = { version: 1, dbs: [], files: [] };
146
+ for (const db of DOCS_DBS) {
147
+ const src = join(cleoDir, db.path);
148
+ if (!existsSync(src))
149
+ continue;
150
+ const dest = join(backupDir, `${db.label}.${backupId}`);
151
+ const tmp = `${dest}.tmp`;
152
+ try {
153
+ rmSync(tmp, { force: true });
154
+ vacuumSnapshot(src, tmp);
155
+ const integrity = integrityCheck(tmp);
156
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
157
+ if (integrity !== 'ok')
158
+ throw new Error(`integrity_check: ${integrity}`);
159
+ const sha256 = sha256OfFile(tmp);
160
+ renameSync(tmp, dest);
161
+ sidecar.dbs.push({ label: db.label, path: db.path, sha256 });
162
+ }
163
+ catch (err) {
164
+ rmSync(tmp, { force: true });
165
+ skipped.push(`${db.path}: ${err instanceof Error ? err.message : String(err)}`);
166
+ }
167
+ }
168
+ const files = [];
169
+ for (const tree of DOCS_BYTE_TREES)
170
+ walkFiles(cleoDir, join(cleoDir, tree), files);
171
+ let pooled = 0;
172
+ for (const rel of files) {
173
+ if (isDocsDbFile(rel))
174
+ continue;
175
+ try {
176
+ // A content-addressed name already in the pool was verified when it
177
+ // was written: reference it without reading the live file again.
178
+ const claimed = contentAddress(rel);
179
+ if (claimed !== null && existsSync(join(pool, claimed))) {
180
+ sidecar.files.push({ path: rel, sha256: claimed });
181
+ continue;
182
+ }
183
+ const abs = join(cleoDir, rel);
184
+ const sha256 = sha256OfFile(abs);
185
+ if (!existsSync(join(pool, sha256))) {
186
+ copyAtomic(abs, join(pool, sha256));
187
+ pooled++;
188
+ }
189
+ sidecar.files.push({ path: rel, sha256 });
190
+ }
191
+ catch (err) {
192
+ skipped.push(`${rel}: ${err instanceof Error ? err.message : String(err)}`);
193
+ }
194
+ }
195
+ if (sidecar.dbs.length === 0 && sidecar.files.length === 0 && skipped.length === 0)
196
+ return null;
197
+ const dest = join(backupDir, `${DOCS_BYTES_SIDECAR_LABEL}.${backupId}`);
198
+ const tmp = `${dest}.tmp`;
199
+ writeFileSync(tmp, JSON.stringify(sidecar));
200
+ renameSync(tmp, dest);
201
+ if (skipped.length > 0) {
202
+ getLogger('backup').warn({ backupId, skipped }, 'docs byte surfaces partly captured');
203
+ }
204
+ return {
205
+ dbs: sidecar.dbs.map((d) => d.label),
206
+ files: sidecar.files.length,
207
+ pooled,
208
+ skipped,
209
+ };
210
+ });
211
+ }
212
+ /**
213
+ * Unlink every pool file that no `docs-bytes.json.<backupId>` sidecar left in
214
+ * `backupDir` references (T13710); run after rotation. When any sidecar
215
+ * cannot be read, what it references is unknown, so nothing is removed.
216
+ *
217
+ * @param backupDir - `.cleo/backups/sqlite`.
218
+ * @returns The pool files removed.
219
+ */
220
+ export function sweepDocsBytePool(backupDir) {
221
+ const pool = docsBytePoolDir(backupDir);
222
+ if (!existsSync(pool))
223
+ return [];
224
+ return withPoolLock(backupDir, () => {
225
+ const referenced = new Set();
226
+ for (const name of readdirSync(backupDir)) {
227
+ if (!name.startsWith(`${DOCS_BYTES_SIDECAR_LABEL}.`) || name.endsWith('.tmp'))
228
+ continue;
229
+ const sidecar = readSidecarFile(join(backupDir, name));
230
+ if (sidecar === null) {
231
+ getLogger('backup').warn({ sidecar: name }, 'unreadable docs-bytes sidecar: pool kept');
232
+ return [];
233
+ }
234
+ for (const f of sidecar.files)
235
+ referenced.add(f.sha256);
236
+ }
237
+ const removed = [];
238
+ for (const name of readdirSync(pool)) {
239
+ if (referenced.has(name) || !sha256Hex.test(name))
240
+ continue;
241
+ try {
242
+ unlinkSync(join(pool, name));
243
+ removed.push(name);
244
+ }
245
+ catch {
246
+ // non-fatal: an unreferenced pool file only costs space
247
+ }
248
+ }
249
+ return removed;
250
+ });
251
+ }
252
+ function readSidecarFile(path) {
253
+ try {
254
+ const parsed = sidecarSchema.safeParse(JSON.parse(readFileSync(path, 'utf-8')));
255
+ return parsed.success ? parsed.data : null;
256
+ }
257
+ catch {
258
+ return null;
259
+ }
260
+ }
261
+ /**
262
+ * Whether backup `backupId` carries docs byte surfaces (a `docs-bytes.json` sidecar).
263
+ *
264
+ * @param backupDir - `.cleo/backups/sqlite`.
265
+ * @param backupId - The backup.
266
+ */
267
+ export function hasDocsBytes(backupDir, backupId) {
268
+ return existsSync(join(backupDir, `${DOCS_BYTES_SIDECAR_LABEL}.${backupId}`));
269
+ }
270
+ /**
271
+ * The live docs databases another connection holds open (a restore over
272
+ * them would be lost to that connection's writes).
273
+ *
274
+ * @param cleoDir - The project's `.cleo/` directory.
275
+ * @returns Absolute paths of the busy databases.
276
+ */
277
+ export function docsDbsOpenElsewhere(cleoDir) {
278
+ return DOCS_DBS.map((db) => join(cleoDir, db.path)).filter((p) => storeOpenElsewhere(p));
279
+ }
280
+ /**
281
+ * Restore the docs byte surfaces of backup `backupId` into `cleoDir`, placing
282
+ * only verified bytes (T13708, T13709). Each database snapshot must match its
283
+ * recorded sha256 and pass `integrity_check` on the staged copy, and its live
284
+ * file must not be open elsewhere; each pool file must hash to its recorded
285
+ * sha256. Failures are listed in `failed`, and `complete` is `false` when
286
+ * there are any.
287
+ *
288
+ * @param cleoDir - The project's `.cleo/` directory.
289
+ * @param backupDir - `.cleo/backups/sqlite`.
290
+ * @param backupId - The backup to restore from.
291
+ * @returns What was placed and what failed, or `null` when the backup holds no docs bytes.
292
+ */
293
+ export function restoreDocsBytes(cleoDir, backupDir, backupId) {
294
+ const sidecarPath = join(backupDir, `${DOCS_BYTES_SIDECAR_LABEL}.${backupId}`);
295
+ if (!existsSync(sidecarPath))
296
+ return null;
297
+ const sidecar = readSidecarFile(sidecarPath);
298
+ if (sidecar === null) {
299
+ return {
300
+ complete: false,
301
+ dbsRestored: [],
302
+ filesRestored: 0,
303
+ failed: [`${DOCS_BYTES_SIDECAR_LABEL}.${backupId}: unreadable sidecar`],
304
+ };
305
+ }
306
+ const dbsRestored = [];
307
+ const failed = [];
308
+ for (const db of sidecar.dbs) {
309
+ // The sidecar is data read from disk: a db entry must name a known docs
310
+ // database exactly, or it could replace cleo.db or escape `.cleo/`.
311
+ if (!DOCS_DBS.some((known) => known.label === db.label && known.path === db.path)) {
312
+ failed.push(`${db.path}: not a docs database (${db.label})`);
313
+ continue;
314
+ }
315
+ const dest = join(cleoDir, db.path);
316
+ const staged = `${dest}.restore-${process.pid}-${Date.now()}`;
317
+ try {
318
+ const from = join(backupDir, `${db.label}.${backupId}`);
319
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
320
+ if (!existsSync(from))
321
+ throw new Error('snapshot missing from the backup');
322
+ mkdirSync(dirname(dest), { recursive: true });
323
+ copyFileSync(from, staged);
324
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
325
+ if (sha256OfFile(staged) !== db.sha256)
326
+ throw new Error('sha256 mismatch');
327
+ const integrity = integrityCheck(staged);
328
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
329
+ if (integrity !== 'ok')
330
+ throw new Error(`integrity_check: ${integrity}`);
331
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
332
+ if (storeOpenElsewhere(dest))
333
+ throw new Error('open in another process');
334
+ for (const suffix of DB_SIDECARS)
335
+ rmSync(`${dest}${suffix}`, { force: true });
336
+ renameSync(staged, dest);
337
+ dbsRestored.push(db.path);
338
+ }
339
+ catch (err) {
340
+ failed.push(`${db.path}: ${err instanceof Error ? err.message : String(err)}`);
341
+ }
342
+ finally {
343
+ for (const p of [staged, ...DB_SIDECARS.map((s) => `${staged}${s}`)]) {
344
+ rmSync(p, { force: true });
345
+ }
346
+ }
347
+ }
348
+ const pool = docsBytePoolDir(backupDir);
349
+ let filesRestored = 0;
350
+ for (const file of sidecar.files) {
351
+ // The sidecar is data read from disk: place bytes only inside the two trees.
352
+ const inTree = (file.path.startsWith('blobs/blobs/') || file.path.startsWith('attachments/')) &&
353
+ !file.path.includes('\\') &&
354
+ !isAbsolute(file.path) &&
355
+ !file.path.split('/').includes('..') &&
356
+ !isDocsDbFile(file.path);
357
+ if (!inTree) {
358
+ failed.push(`${file.path}: not a docs byte path`);
359
+ continue;
360
+ }
361
+ const dest = join(cleoDir, file.path);
362
+ const staged = `${dest}.restore-${process.pid}-${Date.now()}`;
363
+ try {
364
+ const from = join(pool, file.sha256);
365
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
366
+ if (!existsSync(from))
367
+ throw new Error('missing from the backup pool');
368
+ mkdirSync(dirname(dest), { recursive: true });
369
+ copyFileSync(from, staged);
370
+ // @sync-invariant none:local-only caught below and listed; a local backup/restore file, no synced row
371
+ if (sha256OfFile(staged) !== file.sha256)
372
+ throw new Error('sha256 mismatch');
373
+ renameSync(staged, dest);
374
+ filesRestored++;
375
+ }
376
+ catch (err) {
377
+ failed.push(`${file.path}: ${err instanceof Error ? err.message : String(err)}`);
378
+ }
379
+ finally {
380
+ rmSync(staged, { force: true });
381
+ }
382
+ }
383
+ return { complete: failed.length === 0, dbsRestored, filesRestored, failed };
384
+ }
385
+ /**
386
+ * Labels of the docs databases that exist live under `cleoDir`: a safety
387
+ * copy of them must hold each of these before anything replaces them.
388
+ *
389
+ * @param cleoDir - The project's `.cleo/` directory.
390
+ * @returns The live database labels (`blobs.manifest.db`, `attachments.index.db`).
391
+ */
392
+ export function liveDocsDbLabels(cleoDir) {
393
+ return DOCS_DBS.filter((db) => existsSync(join(cleoDir, db.path))).map((db) => db.label);
394
+ }
395
+ const metaSchema = z.object({
396
+ docsBytes: z
397
+ .object({
398
+ dbs: z.array(z.string()).optional(),
399
+ files: z.number().optional(),
400
+ skipped: z.array(z.string()).optional(),
401
+ error: z.string().optional(),
402
+ })
403
+ .optional(),
404
+ });
405
+ /**
406
+ * Where backup `backupId` falls short of the docs capture its
407
+ * `<backupId>.meta.json` records (T13709): a capture that failed or skipped
408
+ * files, or a `docs-bytes.json` sidecar that is missing or lists fewer
409
+ * databases or files than recorded. A backup whose meta records no docs
410
+ * capture (older builds) yields nothing.
411
+ *
412
+ * @param backupDir - `.cleo/backups/sqlite`.
413
+ * @param backupId - The backup.
414
+ * @returns One warning per shortfall.
415
+ */
416
+ export function docsBytesMetaWarnings(backupDir, backupId) {
417
+ let meta;
418
+ try {
419
+ const parsed = metaSchema.safeParse(JSON.parse(readFileSync(join(backupDir, `${backupId}.meta.json`), 'utf-8')));
420
+ meta = parsed.success ? parsed.data.docsBytes : undefined;
421
+ }
422
+ catch {
423
+ return [];
424
+ }
425
+ if (meta === undefined)
426
+ return [];
427
+ const warnings = [];
428
+ if (meta.error !== undefined)
429
+ warnings.push(`docs bytes were not captured: ${meta.error}`);
430
+ for (const s of meta.skipped ?? [])
431
+ warnings.push(`docs bytes were not captured: ${s}`);
432
+ const recorded = (meta.dbs?.length ?? 0) + (meta.files ?? 0);
433
+ if (recorded === 0)
434
+ return warnings;
435
+ const sidecarPath = join(backupDir, `${DOCS_BYTES_SIDECAR_LABEL}.${backupId}`);
436
+ if (!existsSync(sidecarPath)) {
437
+ warnings.push(`${DOCS_BYTES_SIDECAR_LABEL}.${backupId} is missing (the backup recorded docs bytes)`);
438
+ return warnings;
439
+ }
440
+ const sidecar = readSidecarFile(sidecarPath);
441
+ // An unreadable sidecar is reported by restoreDocsBytes.
442
+ if (sidecar === null)
443
+ return warnings;
444
+ const missingDbs = (meta.dbs ?? []).filter((l) => !sidecar.dbs.some((d) => d.label === l));
445
+ if (missingDbs.length > 0 || sidecar.files.length < (meta.files ?? 0)) {
446
+ warnings.push(`${DOCS_BYTES_SIDECAR_LABEL}.${backupId} is incomplete: ${sidecar.files.length}/${meta.files ?? 0} files${missingDbs.length > 0 ? `, missing ${missingDbs.join(', ')}` : ''}`);
447
+ }
448
+ return warnings;
449
+ }
450
+ //# sourceMappingURL=docs-bytes-backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-bytes-backup.js","sourceRoot":"","sources":["../../src/store/docs-bytes-backup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * LLM credential pool accessor — the encrypting writer and reader of the
3
+ * global `accounts` table (T13715 · T13528).
4
+ *
5
+ * `cleo llm add` and every other pool writer store credentials here, so the
6
+ * pool syncs on the home stream: the secret columns hold {@link encryptGlobal}
7
+ * ciphertext under `account:<provider>:<label>` ({@link llmAccountSecretId}),
8
+ * the id the sync sealer (`cloud/secret-seal.ts`) decrypts, seals and
9
+ * re-encrypts under the receiving machine's key. No plaintext secret is ever
10
+ * written to the store, the same way `service-connections-accessor.ts`
11
+ * stores service credentials.
12
+ *
13
+ * Writes go through {@link openDualScopeDb}`('global')` (migrated, captured).
14
+ * Reads are synchronous — the LLM resolver (`resolveCredentials`) cannot
15
+ * await — so they open the global `cleo.db` read-only and decrypt with
16
+ * {@link decryptGlobalSync}. A missing store or table reads as empty.
17
+ *
18
+ * The non-secret fields of a {@link StoredCredential} without a column of
19
+ * their own (`baseUrl`, `extraHeaders`, `metadata`, `disabled`, `lastStatus`)
20
+ * live in the row's `metadata` JSON.
21
+ *
22
+ * @module store/llm-accounts-accessor
23
+ * @task T13715
24
+ * @task T13528
25
+ */
26
+ import { type StoredCredential } from '../llm/credentials-store.js';
27
+ /**
28
+ * Where the pool lives. Both fields default to the ambient global store.
29
+ *
30
+ * @task T13715
31
+ */
32
+ export interface LlmAccountsOptions {
33
+ /** CLEO home whose machine key encrypts the secrets. */
34
+ readonly cleoHome?: string;
35
+ /** Global `cleo.db` to use instead of `<cleoHome>/cleo.db` (a restore target or a test store). */
36
+ readonly dbPath?: string;
37
+ }
38
+ /**
39
+ * One `accounts` row as stored: secrets still encrypted.
40
+ *
41
+ * @task T13715
42
+ */
43
+ export type LlmAccountRow = {
44
+ readonly provider: string;
45
+ readonly label: string;
46
+ readonly auth_type: string;
47
+ readonly secret_enc: string | null;
48
+ readonly refresh_enc: string | null;
49
+ readonly expires_at: string | null;
50
+ readonly priority: number;
51
+ readonly source: string | null;
52
+ readonly last_error_code: string | null;
53
+ readonly cooldown_reset_at: string | null;
54
+ readonly request_count: number;
55
+ readonly metadata: string;
56
+ };
57
+ /**
58
+ * The {@link encryptGlobal} id of a pool credential's secret columns. The sync
59
+ * sealer derives the same id from the row's natural key.
60
+ *
61
+ * @param provider - The credential's provider.
62
+ * @param label - Its label.
63
+ * @returns `account:<provider>:<label>`.
64
+ * @task T13715
65
+ */
66
+ export declare function llmAccountSecretId(provider: string, label: string): string;
67
+ /**
68
+ * List the pool's rows, still encrypted, ordered by provider and label. A
69
+ * missing store, or one not yet migrated to carry `accounts`, holds none.
70
+ *
71
+ * @param opts - Which store.
72
+ * @returns The rows.
73
+ * @task T13715
74
+ */
75
+ export declare function listLlmAccountRowsSync(opts?: LlmAccountsOptions): LlmAccountRow[];
76
+ /**
77
+ * Decrypt one row into a {@link StoredCredential}.
78
+ *
79
+ * @param row - The row.
80
+ * @param opts - Whose machine key decrypts it.
81
+ * @returns The credential, or `null` for a row without a secret (redacted by an
82
+ * unencrypted backup) or with an unknown provider or auth type.
83
+ * @throws When this machine's key cannot decrypt the secret.
84
+ * @task T13715
85
+ */
86
+ export declare function llmAccountToCredentialSync(row: LlmAccountRow, opts?: LlmAccountsOptions): StoredCredential | null;
87
+ /**
88
+ * Upsert a credential into the pool, encrypting its secrets under this
89
+ * machine's key. The `(provider, label)` pair is the key.
90
+ *
91
+ * @param credential - The credential.
92
+ * @param opts - Which store and machine key.
93
+ * @task T13715
94
+ * @sync-invariant none:input-shape reads only its own row, by the (provider, label) natural key, to keep an unchanged ciphertext; no other row is read or written
95
+ */
96
+ export declare function upsertLlmAccount(credential: StoredCredential, opts?: LlmAccountsOptions): Promise<void>;
97
+ /**
98
+ * Delete a credential from the pool.
99
+ *
100
+ * @param provider - Its provider.
101
+ * @param label - Its label.
102
+ * @param opts - Which store.
103
+ * @returns Whether a row was deleted.
104
+ * @task T13715
105
+ */
106
+ export declare function deleteLlmAccount(provider: string, label: string, opts?: LlmAccountsOptions): Promise<boolean>;
107
+ //# sourceMappingURL=llm-accounts-accessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-accounts-accessor.d.ts","sourceRoot":"","sources":["../../src/store/llm-accounts-accessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,6BAA6B,CAAC;AAMrC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAWF;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1E;AAOD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,kBAAuB,GAAG,aAAa,EAAE,CAwBrF;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,kBAAuB,GAC5B,gBAAgB,GAAG,IAAI,CA2BzB;AA8BD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,gBAAgB,EAC5B,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,OAAO,CAAC,CASlB"}