crewly 1.11.4 → 1.11.6

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 (75) hide show
  1. package/dist/backend/backend/src/constants.d.ts +22 -1
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +22 -1
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts +90 -0
  6. package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts.map +1 -0
  7. package/dist/backend/backend/src/services/backup/backup-archive.service.js +309 -0
  8. package/dist/backend/backend/src/services/backup/backup-archive.service.js.map +1 -0
  9. package/dist/backend/backend/src/services/backup/backup-cloud.client.d.ts +75 -0
  10. package/dist/backend/backend/src/services/backup/backup-cloud.client.d.ts.map +1 -0
  11. package/dist/backend/backend/src/services/backup/backup-cloud.client.js +134 -0
  12. package/dist/backend/backend/src/services/backup/backup-cloud.client.js.map +1 -0
  13. package/dist/backend/backend/src/services/backup/backup-restore.service.d.ts +78 -0
  14. package/dist/backend/backend/src/services/backup/backup-restore.service.d.ts.map +1 -0
  15. package/dist/backend/backend/src/services/backup/backup-restore.service.js +358 -0
  16. package/dist/backend/backend/src/services/backup/backup-restore.service.js.map +1 -0
  17. package/dist/backend/backend/src/services/backup/backup.types.d.ts +163 -0
  18. package/dist/backend/backend/src/services/backup/backup.types.d.ts.map +1 -0
  19. package/dist/backend/backend/src/services/backup/backup.types.js +13 -0
  20. package/dist/backend/backend/src/services/backup/backup.types.js.map +1 -0
  21. package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts +29 -2
  22. package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
  23. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +97 -13
  24. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
  25. package/dist/cli/backend/src/constants.d.ts +22 -1
  26. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  27. package/dist/cli/backend/src/constants.js +22 -1
  28. package/dist/cli/backend/src/constants.js.map +1 -1
  29. package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts +70 -0
  30. package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts.map +1 -0
  31. package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.js +427 -0
  32. package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.js.map +1 -0
  33. package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts +90 -0
  34. package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts.map +1 -0
  35. package/dist/cli/backend/src/services/backup/backup-archive.service.js +309 -0
  36. package/dist/cli/backend/src/services/backup/backup-archive.service.js.map +1 -0
  37. package/dist/cli/backend/src/services/backup/backup-cloud.client.d.ts +75 -0
  38. package/dist/cli/backend/src/services/backup/backup-cloud.client.d.ts.map +1 -0
  39. package/dist/cli/backend/src/services/backup/backup-cloud.client.js +134 -0
  40. package/dist/cli/backend/src/services/backup/backup-cloud.client.js.map +1 -0
  41. package/dist/cli/backend/src/services/backup/backup-restore.service.d.ts +78 -0
  42. package/dist/cli/backend/src/services/backup/backup-restore.service.d.ts.map +1 -0
  43. package/dist/cli/backend/src/services/backup/backup-restore.service.js +358 -0
  44. package/dist/cli/backend/src/services/backup/backup-restore.service.js.map +1 -0
  45. package/dist/cli/backend/src/services/backup/backup.types.d.ts +163 -0
  46. package/dist/cli/backend/src/services/backup/backup.types.d.ts.map +1 -0
  47. package/dist/cli/backend/src/services/backup/backup.types.js +13 -0
  48. package/dist/cli/backend/src/services/backup/backup.types.js.map +1 -0
  49. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +410 -0
  50. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -0
  51. package/dist/cli/backend/src/services/cloud/cloud-client.service.js +863 -0
  52. package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -0
  53. package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts +292 -0
  54. package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -0
  55. package/dist/cli/backend/src/services/cloud/cloud-sync.service.js +1093 -0
  56. package/dist/cli/backend/src/services/cloud/cloud-sync.service.js.map +1 -0
  57. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +328 -0
  58. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -0
  59. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +171 -0
  60. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -0
  61. package/dist/cli/backend/src/services/cloud/device-identity.service.d.ts +89 -0
  62. package/dist/cli/backend/src/services/cloud/device-identity.service.d.ts.map +1 -0
  63. package/dist/cli/backend/src/services/cloud/device-identity.service.js +148 -0
  64. package/dist/cli/backend/src/services/cloud/device-identity.service.js.map +1 -0
  65. package/dist/cli/backend/src/services/user/user-identity.service.d.ts +86 -0
  66. package/dist/cli/backend/src/services/user/user-identity.service.d.ts.map +1 -0
  67. package/dist/cli/backend/src/services/user/user-identity.service.js +190 -0
  68. package/dist/cli/backend/src/services/user/user-identity.service.js.map +1 -0
  69. package/dist/cli/cli/src/commands/backup.d.ts +31 -0
  70. package/dist/cli/cli/src/commands/backup.d.ts.map +1 -0
  71. package/dist/cli/cli/src/commands/backup.js +280 -0
  72. package/dist/cli/cli/src/commands/backup.js.map +1 -0
  73. package/dist/cli/cli/src/index.js +10 -0
  74. package/dist/cli/cli/src/index.js.map +1 -1
  75. package/package.json +1 -1
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Backup Restore Service (P1)
3
+ *
4
+ * Restores a workspace archive (produced by BackupArchiveService) onto this
5
+ * machine to resume work after a machine dies / is replaced.
6
+ *
7
+ * Safety model:
8
+ * - `preview()` is non-destructive (dry-run) — reports the plan + conflicts.
9
+ * - `restore()` snapshots the CURRENT CREWLY_HOME first (rollback), refuses
10
+ * on overlapping ids unless mode='overwrite', then applies and — on any
11
+ * failure — rolls back from the snapshot.
12
+ * - device.json is NEVER in the archive, so the target keeps its own identity.
13
+ * - cron `nextRunAt` is reset to null so the scheduler recomputes from
14
+ * `cronExpression` (no stale fires); runtime/session state is wiped so
15
+ * agents start clean.
16
+ *
17
+ * See specs/2026-06-07-workspace-backup.md.
18
+ *
19
+ * @module services/backup/backup-restore.service
20
+ */
21
+ import { createHash } from 'node:crypto';
22
+ import { createReadStream } from 'node:fs';
23
+ import * as fs from 'node:fs/promises';
24
+ import * as os from 'node:os';
25
+ import * as path from 'node:path';
26
+ import { extract as tarExtract } from 'tar';
27
+ import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
28
+ import { LoggerService } from '../core/logger.service.js';
29
+ import { BACKUP_SCHEMA_VERSION, } from './backup.types.js';
30
+ /** Runtime/session state wiped on restore so agents start clean (relative to home). */
31
+ const RUNTIME_WIPE = ['runtime.json', '.orchestrator-state', 'session-state.json'];
32
+ /** Cron files whose `nextRunAt` is reset so the scheduler recomputes. */
33
+ const CRON_FILES = ['recurring-checks.json', 'one-time-checks.json'];
34
+ /** Thrown by restore() when mode='abort' and the target has overlapping data. */
35
+ export class RestoreConflictError extends Error {
36
+ plan;
37
+ constructor(message, plan) {
38
+ super(message);
39
+ this.plan = plan;
40
+ this.name = 'RestoreConflictError';
41
+ }
42
+ }
43
+ /**
44
+ * Service that restores workspace backup archives.
45
+ */
46
+ export class BackupRestoreService {
47
+ logger;
48
+ constructor(logger) {
49
+ this.logger = logger ?? LoggerService.getInstance().createComponentLogger('BackupRestore');
50
+ }
51
+ /**
52
+ * Non-destructive restore plan (dry-run): what would be created/overwritten,
53
+ * id conflicts, resolved project paths, and what's regenerated/discarded.
54
+ *
55
+ * @param options - Restore options (mode/pathMap affect conflict + path resolution)
56
+ * @returns The plan; never writes to disk
57
+ */
58
+ async preview(options) {
59
+ const home = options.homePath ?? getCrewlyHomePath();
60
+ const temp = await this.extract(options.archivePath);
61
+ try {
62
+ const manifest = await this.readManifest(temp);
63
+ return await this.buildPlan(manifest, home, options);
64
+ }
65
+ finally {
66
+ await fs.rm(temp, { recursive: true, force: true }).catch(() => undefined);
67
+ }
68
+ }
69
+ /**
70
+ * Restore the archive onto this machine.
71
+ *
72
+ * @param options - Restore options
73
+ * @returns Summary of what was restored
74
+ * @throws RestoreConflictError when mode='abort' and ids overlap
75
+ * @throws Error on integrity failure or unsupported schema (no changes applied)
76
+ */
77
+ async restore(options) {
78
+ const home = options.homePath ?? getCrewlyHomePath();
79
+ const mode = options.mode ?? 'abort';
80
+ const temp = await this.extract(options.archivePath);
81
+ try {
82
+ const manifest = await this.readManifest(temp);
83
+ if (manifest.schemaVersion > BACKUP_SCHEMA_VERSION) {
84
+ throw new Error(`Backup schemaVersion ${manifest.schemaVersion} is newer than supported ${BACKUP_SCHEMA_VERSION}; upgrade Crewly to restore it`);
85
+ }
86
+ await this.verifyChecksums(temp, manifest);
87
+ const plan = await this.buildPlan(manifest, home, options);
88
+ if (mode === 'abort' && (plan.conflicts.teams.length > 0 || plan.conflicts.projects.length > 0)) {
89
+ throw new RestoreConflictError(`Restore aborted: target already has ${plan.conflicts.teams.length} team(s) and ${plan.conflicts.projects.length} project(s) from this backup. Re-run with mode='overwrite' to replace them.`, plan);
90
+ }
91
+ // 1) Snapshot current home for rollback (best-effort full copy, sans backups/).
92
+ const rollbackSnapshotPath = path.join(home, 'backups', `pre-restore-${options.now.replace(/[:.]/g, '-')}`);
93
+ await fs.mkdir(home, { recursive: true });
94
+ await this.copyTree(home, rollbackSnapshotPath, new Set(['backups']));
95
+ try {
96
+ // 2) Apply
97
+ const restoredGlobalFiles = await this.applyGlobals(temp, home);
98
+ const restoredProjects = await this.applyProjects(temp, manifest, plan);
99
+ const chatDbRestored = await this.applyChatDb(temp, home, manifest);
100
+ await this.rewriteProjectsJson(home, plan);
101
+ await this.resetCron(home);
102
+ await this.wipeRuntime(home);
103
+ this.logger.info('Workspace restore applied', {
104
+ restoredGlobalFiles,
105
+ restoredProjects,
106
+ chatDbRestored,
107
+ rollbackSnapshotPath,
108
+ });
109
+ return { restoredGlobalFiles, restoredProjects, chatDbRestored, rollbackSnapshotPath, warnings: plan.warnings };
110
+ }
111
+ catch (applyErr) {
112
+ // 3) Rollback from the pre-restore snapshot.
113
+ this.logger.error('Restore failed mid-apply — rolling back', {
114
+ error: applyErr instanceof Error ? applyErr.message : String(applyErr),
115
+ });
116
+ await this.copyTree(rollbackSnapshotPath, home, new Set(['backups'])).catch(() => undefined);
117
+ throw applyErr;
118
+ }
119
+ }
120
+ finally {
121
+ await fs.rm(temp, { recursive: true, force: true }).catch(() => undefined);
122
+ }
123
+ }
124
+ // -------------------------------------------------------------------------
125
+ // Internals
126
+ // -------------------------------------------------------------------------
127
+ /** Extract the archive to a fresh temp dir; returns its path. */
128
+ async extract(archivePath) {
129
+ if (!(await fs.stat(archivePath).catch(() => null))?.isFile()) {
130
+ throw new Error(`Backup archive not found: ${archivePath}`);
131
+ }
132
+ const temp = await fs.mkdtemp(path.join(os.tmpdir(), 'crewly-restore-'));
133
+ await tarExtract({ file: archivePath, cwd: temp });
134
+ return temp;
135
+ }
136
+ /** Read + minimally validate the manifest from an extracted archive. */
137
+ async readManifest(temp) {
138
+ const raw = await fs.readFile(path.join(temp, 'manifest.json'), 'utf8').catch(() => null);
139
+ if (!raw)
140
+ throw new Error('Invalid backup: manifest.json missing');
141
+ let manifest;
142
+ try {
143
+ manifest = JSON.parse(raw);
144
+ }
145
+ catch {
146
+ throw new Error('Invalid backup: manifest.json is not valid JSON');
147
+ }
148
+ if (typeof manifest.schemaVersion !== 'number' || !Array.isArray(manifest.global)) {
149
+ throw new Error('Invalid backup: manifest is missing required fields');
150
+ }
151
+ return manifest;
152
+ }
153
+ /** Verify every recorded file's sha256 against the extracted bytes. */
154
+ async verifyChecksums(temp, manifest) {
155
+ const entries = [
156
+ ...manifest.global,
157
+ ...manifest.projects.flatMap((p) => p.files),
158
+ ];
159
+ if (manifest.chatDb.included && manifest.chatDb.sha256) {
160
+ entries.push({ path: 'chat.db', sha256: manifest.chatDb.sha256 });
161
+ }
162
+ for (const e of entries) {
163
+ const abs = path.join(temp, ...e.path.split('/'));
164
+ const actual = await sha256File(abs).catch(() => null);
165
+ if (actual !== e.sha256) {
166
+ throw new Error(`Backup integrity check failed for ${e.path} (checksum mismatch or missing)`);
167
+ }
168
+ }
169
+ }
170
+ /** Build the dry-run plan (conflicts, resolved project paths, warnings). */
171
+ async buildPlan(manifest, home, options) {
172
+ const warnings = [];
173
+ // Teams present in the backup (ids parsed from home/teams/<id>/...).
174
+ const backupTeamIds = new Set();
175
+ for (const g of manifest.global) {
176
+ const m = g.path.match(/^home\/teams\/([^/]+)\//);
177
+ if (m && m[1] !== 'orchestrator')
178
+ backupTeamIds.add(m[1]);
179
+ }
180
+ const targetTeamIds = new Set((await fs.readdir(path.join(home, 'teams'), { withFileTypes: true }).catch(() => []))
181
+ .filter((d) => d.isDirectory() && d.name !== 'orchestrator')
182
+ .map((d) => d.name));
183
+ const conflictTeams = [...backupTeamIds].filter((id) => targetTeamIds.has(id));
184
+ const targetProjectIds = new Set((await this.readJson(path.join(home, 'projects.json'), [])).map((p) => p.id));
185
+ const conflictProjects = manifest.projects.map((p) => p.id).filter((id) => targetProjectIds.has(id));
186
+ const projects = [];
187
+ for (const p of manifest.projects) {
188
+ const mapped = options.pathMap?.[p.sourcePath];
189
+ let targetPath = null;
190
+ if (mapped)
191
+ targetPath = mapped;
192
+ else if (await this.pathExists(p.sourcePath))
193
+ targetPath = p.sourcePath;
194
+ const targetExists = targetPath ? await this.pathExists(targetPath) : false;
195
+ if (!targetPath) {
196
+ warnings.push(`Project "${p.name}" (${p.sourcePath}) has no target path on this machine — re-clone ${p.git.remote ?? 'the repo'} and pass --map ${p.sourcePath}=<new-path> to restore its .crewly data.`);
197
+ }
198
+ else if (!targetExists) {
199
+ warnings.push(`Project "${p.name}" target path ${targetPath} does not exist yet — its .crewly will be created there.`);
200
+ }
201
+ projects.push({ id: p.id, name: p.name, sourcePath: p.sourcePath, targetPath, git: p.git, targetExists });
202
+ }
203
+ return {
204
+ ok: !(options.mode !== 'overwrite' && (conflictTeams.length > 0 || conflictProjects.length > 0)),
205
+ manifestCreatedAt: manifest.createdAt,
206
+ sourceHomePath: manifest.sourceHomePath,
207
+ conflicts: { teams: conflictTeams, projects: conflictProjects },
208
+ globalFileCount: manifest.global.length,
209
+ projects,
210
+ chatDbIncluded: manifest.chatDb.included,
211
+ regenerated: ['device.json (kept this machine\'s identity — not in backup)'],
212
+ discarded: [...RUNTIME_WIPE, 'in-flight cron nextRunAt (recomputed)'],
213
+ warnings,
214
+ };
215
+ }
216
+ /** Copy every manifest global file from temp/home/* into CREWLY_HOME. */
217
+ async applyGlobals(temp, home) {
218
+ let n = 0;
219
+ for (const g of (await this.readManifest(temp)).global) {
220
+ // g.path = 'home/<rel>'
221
+ const rel = g.path.replace(/^home\//, '');
222
+ const src = path.join(temp, ...g.path.split('/'));
223
+ const dest = path.join(home, ...rel.split('/'));
224
+ await fs.mkdir(path.dirname(dest), { recursive: true });
225
+ await fs.copyFile(src, dest);
226
+ n += 1;
227
+ }
228
+ return n;
229
+ }
230
+ /** Copy each resolved project's `.crewly/` from the archive to its target path. */
231
+ async applyProjects(temp, manifest, plan) {
232
+ let n = 0;
233
+ const planById = new Map(plan.projects.map((p) => [p.id, p]));
234
+ for (const proj of manifest.projects) {
235
+ const target = planById.get(proj.id)?.targetPath;
236
+ if (!target)
237
+ continue; // unresolved — warned in the plan
238
+ for (const f of proj.files) {
239
+ // f.path = 'projects/<id>/.crewly/<rel>' → dest = <target>/.crewly/<rel>
240
+ const rel = f.path.replace(new RegExp(`^projects/${proj.id}/`), '');
241
+ const src = path.join(temp, ...f.path.split('/'));
242
+ const dest = path.join(target, ...rel.split('/'));
243
+ await fs.mkdir(path.dirname(dest), { recursive: true });
244
+ await fs.copyFile(src, dest);
245
+ }
246
+ n += 1;
247
+ }
248
+ return n;
249
+ }
250
+ /** Atomically swap chat.db into place (temp copy → rename). */
251
+ async applyChatDb(temp, home, manifest) {
252
+ if (!manifest.chatDb.included)
253
+ return false;
254
+ const src = path.join(temp, 'chat.db');
255
+ const finalDest = path.join(home, 'chat.db');
256
+ const tmpDest = path.join(home, `chat.db.restore-${Date.now()}.tmp`);
257
+ await fs.mkdir(home, { recursive: true });
258
+ await fs.copyFile(src, tmpDest);
259
+ await fs.rename(tmpDest, finalDest);
260
+ // Drop stale WAL/SHM sidecars so SQLite reopens cleanly from the restored db.
261
+ for (const sidecar of ['chat.db-wal', 'chat.db-shm']) {
262
+ await fs.rm(path.join(home, sidecar), { force: true }).catch(() => undefined);
263
+ }
264
+ return true;
265
+ }
266
+ /** Rewrite projects.json `path` entries using the resolved plan mapping. */
267
+ async rewriteProjectsJson(home, plan) {
268
+ const file = path.join(home, 'projects.json');
269
+ const projects = await this.readJson(file, []);
270
+ if (projects.length === 0)
271
+ return;
272
+ const targetById = new Map(plan.projects.map((p) => [p.id, p.targetPath]));
273
+ let changed = false;
274
+ for (const proj of projects) {
275
+ const target = targetById.get(proj.id);
276
+ if (target && target !== proj.path) {
277
+ proj.path = target;
278
+ changed = true;
279
+ }
280
+ }
281
+ if (changed)
282
+ await fs.writeFile(file, JSON.stringify(projects, null, 2), 'utf8');
283
+ }
284
+ /** Reset cron `nextRunAt` so the scheduler recomputes from cronExpression. */
285
+ async resetCron(home) {
286
+ for (const name of CRON_FILES) {
287
+ const file = path.join(home, name);
288
+ const items = await this.readJson(file, []);
289
+ if (!Array.isArray(items) || items.length === 0)
290
+ continue;
291
+ let changed = false;
292
+ for (const item of items) {
293
+ if ('nextRunAt' in item) {
294
+ item.nextRunAt = null;
295
+ changed = true;
296
+ }
297
+ }
298
+ if (changed)
299
+ await fs.writeFile(file, JSON.stringify(items, null, 2), 'utf8');
300
+ }
301
+ }
302
+ /** Remove runtime/session state so agents start clean on the restored machine. */
303
+ async wipeRuntime(home) {
304
+ for (const name of RUNTIME_WIPE) {
305
+ await fs.rm(path.join(home, name), { recursive: true, force: true }).catch(() => undefined);
306
+ }
307
+ }
308
+ // ---- small fs helpers ----
309
+ /** Recursively copy a directory tree, skipping top-level names in `skipTop`. */
310
+ async copyTree(srcDir, destDir, skipTop) {
311
+ const entries = await fs.readdir(srcDir, { withFileTypes: true }).catch(() => []);
312
+ await fs.mkdir(destDir, { recursive: true });
313
+ for (const e of entries) {
314
+ if (skipTop.has(e.name))
315
+ continue;
316
+ const s = path.join(srcDir, e.name);
317
+ const d = path.join(destDir, e.name);
318
+ if (e.isDirectory())
319
+ await this.copyTreeRec(s, d);
320
+ else if (e.isFile())
321
+ await fs.copyFile(s, d);
322
+ }
323
+ }
324
+ /** Recursive copy without the top-level skip filter. */
325
+ async copyTreeRec(srcDir, destDir) {
326
+ await fs.mkdir(destDir, { recursive: true });
327
+ for (const e of await fs.readdir(srcDir, { withFileTypes: true })) {
328
+ const s = path.join(srcDir, e.name);
329
+ const d = path.join(destDir, e.name);
330
+ if (e.isDirectory())
331
+ await this.copyTreeRec(s, d);
332
+ else if (e.isFile())
333
+ await fs.copyFile(s, d);
334
+ }
335
+ }
336
+ async pathExists(p) {
337
+ return !!(await fs.stat(p).catch(() => null));
338
+ }
339
+ async readJson(file, fallback) {
340
+ try {
341
+ return JSON.parse(await fs.readFile(file, 'utf8'));
342
+ }
343
+ catch {
344
+ return fallback;
345
+ }
346
+ }
347
+ }
348
+ /** Stream a file through SHA-256 → hex digest. */
349
+ async function sha256File(filePath) {
350
+ return new Promise((resolve, reject) => {
351
+ const hash = createHash('sha256');
352
+ const stream = createReadStream(filePath);
353
+ stream.on('data', (c) => hash.update(c));
354
+ stream.on('error', reject);
355
+ stream.on('end', () => resolve(hash.digest('hex')));
356
+ });
357
+ }
358
+ //# sourceMappingURL=backup-restore.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-restore.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/backup/backup-restore.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Types for the Workspace Backup feature.
3
+ *
4
+ * A backup is a single `.tar.gz` archive containing a top-level
5
+ * `manifest.json` plus the captured `CREWLY_HOME` globals, each project's
6
+ * `.crewly/` tree, and (optionally) `chat.db`. See
7
+ * specs/2026-06-07-workspace-backup.md.
8
+ *
9
+ * @module services/backup/backup.types
10
+ */
11
+ /** Manifest schema version — bump on any breaking layout/field change. */
12
+ export declare const BACKUP_SCHEMA_VERSION = 1;
13
+ /** A single captured file recorded in the manifest for integrity + listing. */
14
+ export interface BackupFileEntry {
15
+ /** Path inside the archive, relative to the archive root. */
16
+ path: string;
17
+ /** SHA-256 of the file content (hex). */
18
+ sha256: string;
19
+ /** Size in bytes. */
20
+ bytes: number;
21
+ }
22
+ /** Git provenance for a captured project so restore can re-clone the source tree. */
23
+ export interface BackupProjectGit {
24
+ /** `origin` remote URL, or null when not a git repo / no origin. */
25
+ remote: string | null;
26
+ /** HEAD commit sha, or null when unavailable. */
27
+ commit: string | null;
28
+ }
29
+ /** One project's captured `.crewly/` data + provenance. */
30
+ export interface BackupProjectEntry {
31
+ /** Stable project id (from projects.json). */
32
+ id: string;
33
+ /** Human-readable project name. */
34
+ name: string;
35
+ /** Absolute path on the SOURCE machine (used for restore path-rewriting). */
36
+ sourcePath: string;
37
+ /** Git provenance for re-clone on restore. */
38
+ git: BackupProjectGit;
39
+ /** Captured files under `projects/<id>/` in the archive. */
40
+ files: BackupFileEntry[];
41
+ }
42
+ /** chat.db capture record. */
43
+ export interface BackupChatDb {
44
+ /** Whether chat.db was included (false when excluded or the native module is absent). */
45
+ included: boolean;
46
+ /** SHA-256 of the captured db, when included. */
47
+ sha256?: string;
48
+ /** Size in bytes, when included. */
49
+ bytes?: number;
50
+ /** Reason it was skipped, when not included. */
51
+ skippedReason?: string;
52
+ }
53
+ /** Encryption envelope descriptor. v1 archives are unencrypted on disk; Cloud adds SSE. */
54
+ export interface BackupCrypto {
55
+ /** `none` for v1 local archives. `sse` once parked in the cloud. */
56
+ mode: 'none' | 'sse';
57
+ }
58
+ /** Top-level archive manifest. */
59
+ export interface BackupManifest {
60
+ schemaVersion: number;
61
+ crewlyVersion: string;
62
+ /** ISO timestamp — the logical point-in-time of the snapshot. */
63
+ createdAt: string;
64
+ /** Source device id (observability only; NEVER restored). */
65
+ sourceDeviceId: string | null;
66
+ sourceDeviceName: string | null;
67
+ /** Source `CREWLY_HOME` absolute path — restore uses it for path rewriting. */
68
+ sourceHomePath: string;
69
+ /** Owner account (JWT `sub`/googleId). Null for local-only archives; stamped by Cloud on upload. */
70
+ ownerSub: string | null;
71
+ /** Captured CREWLY_HOME global files (relative to `home/` in the archive). */
72
+ global: BackupFileEntry[];
73
+ /** Captured per-project `.crewly/` data. */
74
+ projects: BackupProjectEntry[];
75
+ chatDb: BackupChatDb;
76
+ crypto: BackupCrypto;
77
+ }
78
+ /** Options for building an archive. */
79
+ export interface CreateBackupOptions {
80
+ /** Output archive path. Defaults to `CREWLY_HOME/backups/workspace-<ts>.tar.gz`. */
81
+ outPath?: string;
82
+ /** Exclude chat.db (smaller archive, avoids SQLite capture). Default false. */
83
+ excludeChatDb?: boolean;
84
+ /** Override CREWLY_HOME (tests). Defaults to getCrewlyHomePath(). */
85
+ homePath?: string;
86
+ /** ISO timestamp for the snapshot point. Defaults to caller-supplied now (no Date in lib). */
87
+ createdAt: string;
88
+ /** Owner sub to stamp (usually null locally; Cloud stamps on upload). */
89
+ ownerSub?: string | null;
90
+ /** Source device id/name for the manifest (observability). */
91
+ sourceDeviceId?: string | null;
92
+ sourceDeviceName?: string | null;
93
+ }
94
+ /** Result of a successful archive build. */
95
+ export interface CreateBackupResult {
96
+ archivePath: string;
97
+ manifest: BackupManifest;
98
+ /** Total uncompressed bytes captured (for quota/UX). */
99
+ totalBytes: number;
100
+ }
101
+ /** How to handle a target that already has overlapping data. */
102
+ export type RestoreMode = 'abort' | 'overwrite';
103
+ /** Options for restoring an archive onto this machine. */
104
+ export interface RestoreOptions {
105
+ /** Archive (.tar.gz) to restore. */
106
+ archivePath: string;
107
+ /** Target CREWLY_HOME. Defaults to getCrewlyHomePath(). */
108
+ homePath?: string;
109
+ /** Conflict policy. Default 'abort'. */
110
+ mode?: RestoreMode;
111
+ /**
112
+ * Source→target absolute path remap for projects, e.g.
113
+ * `{ '/Users/alice/web': '/Users/bob/web' }`. When a source path isn't
114
+ * mapped, restore reuses it if it exists on the target, else records a
115
+ * warning and skips that project's `.crewly/` write.
116
+ */
117
+ pathMap?: Record<string, string>;
118
+ /** ISO timestamp used to name the pre-restore rollback snapshot. */
119
+ now: string;
120
+ }
121
+ /** One project's restore plan entry. */
122
+ export interface RestoreProjectPlan {
123
+ id: string;
124
+ name: string;
125
+ sourcePath: string;
126
+ /** Resolved target path (pathMap → existing sourcePath → null when unresolved). */
127
+ targetPath: string | null;
128
+ git: {
129
+ remote: string | null;
130
+ commit: string | null;
131
+ };
132
+ /** Whether the resolved target path currently exists on this machine. */
133
+ targetExists: boolean;
134
+ }
135
+ /** Non-destructive restore plan (dry-run). */
136
+ export interface RestorePlan {
137
+ /** False when mode='abort' and conflicts exist (apply would refuse). */
138
+ ok: boolean;
139
+ manifestCreatedAt: string;
140
+ sourceHomePath: string;
141
+ /** Stable ids present on BOTH the backup and this machine (would be overwritten). */
142
+ conflicts: {
143
+ teams: string[];
144
+ projects: string[];
145
+ };
146
+ globalFileCount: number;
147
+ projects: RestoreProjectPlan[];
148
+ chatDbIncluded: boolean;
149
+ /** Things to regenerate (device identity) / discard (runtime/session). */
150
+ regenerated: string[];
151
+ discarded: string[];
152
+ warnings: string[];
153
+ }
154
+ /** Result of an applied restore. */
155
+ export interface RestoreResult {
156
+ restoredGlobalFiles: number;
157
+ restoredProjects: number;
158
+ chatDbRestored: boolean;
159
+ /** Where the pre-restore snapshot of the current CREWLY_HOME was saved. */
160
+ rollbackSnapshotPath: string;
161
+ warnings: string[];
162
+ }
163
+ //# sourceMappingURL=backup.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.types.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/backup/backup.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Types for the Workspace Backup feature.
3
+ *
4
+ * A backup is a single `.tar.gz` archive containing a top-level
5
+ * `manifest.json` plus the captured `CREWLY_HOME` globals, each project's
6
+ * `.crewly/` tree, and (optionally) `chat.db`. See
7
+ * specs/2026-06-07-workspace-backup.md.
8
+ *
9
+ * @module services/backup/backup.types
10
+ */
11
+ /** Manifest schema version — bump on any breaking layout/field change. */
12
+ export const BACKUP_SCHEMA_VERSION = 1;
13
+ //# sourceMappingURL=backup.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.types.js","sourceRoot":"","sources":["../../../../../../backend/src/services/backup/backup.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC"}