@savestate/cli 0.3.1 → 0.4.1

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/README.md CHANGED
@@ -32,7 +32,7 @@ npx savestate diff v3 v5 # What changed between snapshots
32
32
  - 📦 **Open archive format** — The SaveState Archive Format (SAF) is an open spec. No vendor lock-in.
33
33
  - 🔌 **Platform adapters** — Works with ChatGPT, Claude, Gemini, Clawdbot, OpenAI Assistants, and more.
34
34
  - 📊 **Incremental** — Like git — only captures what changed. Full history, tiny storage.
35
- - 💾 **Flexible storage** — Local filesystem, S3, R2, Backblaze, Dropbox, iCloud — you choose.
35
+ - 💾 **Flexible storage** — Local filesystem (free) or SaveState Cloud (Pro/Team).
36
36
  - ⏰ **Scheduled backups** — Set it and forget it. Auto-snapshot on your schedule.
37
37
  - 🖥️ **CLI-first** — Built for developers. Also has a web dashboard (coming soon).
38
38
 
@@ -158,25 +158,43 @@ savestate migrate Migration wizard between platforms
158
158
  --dry-run Preview migration plan
159
159
  ```
160
160
 
161
- ## Storage Backends
161
+ ## Storage
162
+
163
+ ### Local Storage (Free)
162
164
 
163
165
  ```bash
164
- # Local filesystem (default)
166
+ # Default snapshots stored in ~/.savestate/
165
167
  savestate config --set storage.type=local
166
168
 
167
- # Amazon S3
168
- savestate config --set storage.type=s3
169
- savestate config --set storage.options.bucket=my-savestate-backups
169
+ # Custom path (e.g., Dropbox, iCloud sync folder)
170
+ savestate config --set storage.options.path=~/Dropbox/savestate
171
+ ```
172
+
173
+ ### Cloud Storage (Pro/Team)
170
174
 
171
- # Cloudflare R2
172
- savestate config --set storage.type=r2
175
+ Cloud storage is managed through the SaveState API with server-side subscription verification:
173
176
 
174
- # Any sync folder (Dropbox, iCloud, etc.)
175
- savestate config --set storage.type=local
176
- savestate config --set storage.options.path=~/Dropbox/savestate
177
+ ```bash
178
+ # Authenticate first
179
+ savestate login
180
+
181
+ # Push local snapshots to cloud
182
+ savestate cloud push # Push latest snapshot
183
+ savestate cloud push --all # Push all snapshots
184
+
185
+ # Pull snapshots from cloud
186
+ savestate cloud pull # Pull latest
187
+ savestate cloud pull --id abc123 # Pull specific snapshot
188
+
189
+ # List cloud snapshots
190
+ savestate cloud list # Shows usage stats
177
191
  ```
178
192
 
179
- All backends receive **only encrypted data**. Zero-knowledge by design.
193
+ Cloud storage quotas:
194
+ - **Pro ($9/mo)**: 10 GB
195
+ - **Team ($29/mo)**: 100 GB
196
+
197
+ All data is **encrypted locally** before upload. Zero-knowledge by design.
180
198
 
181
199
  ## Contributing
182
200
 
package/dist/cli.js CHANGED
@@ -109,6 +109,15 @@ program
109
109
  .option('--dry-run', 'Show migration plan without making changes')
110
110
  .option('-l, --list', 'List available platforms and their capabilities')
111
111
  .action(migrateCommand);
112
+ // ─── savestate cloud ─────────────────────────────────────────
113
+ import { cloudCommand } from './commands/cloud.js';
114
+ program
115
+ .command('cloud <subcommand>')
116
+ .description('Cloud storage commands (Pro/Team)')
117
+ .option('--id <id>', 'Specific snapshot ID')
118
+ .option('--all', 'Process all snapshots')
119
+ .option('-f, --force', 'Overwrite existing files')
120
+ .action(cloudCommand);
112
121
  // ─── Parse & run ─────────────────────────────────────────────
113
122
  program.parse();
114
123
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * savestate cloud — Cloud storage commands (Pro/Team)
3
+ *
4
+ * Manages cloud backups through the SaveState API.
5
+ * Requires Pro or Team subscription.
6
+ */
7
+ interface CloudOptions {
8
+ id?: string;
9
+ all?: boolean;
10
+ force?: boolean;
11
+ }
12
+ /**
13
+ * Push local snapshots to cloud
14
+ */
15
+ export declare function cloudPushCommand(options: CloudOptions): Promise<void>;
16
+ /**
17
+ * Pull snapshots from cloud
18
+ */
19
+ export declare function cloudPullCommand(options: CloudOptions): Promise<void>;
20
+ /**
21
+ * List cloud snapshots
22
+ */
23
+ export declare function cloudListCommand(): Promise<void>;
24
+ /**
25
+ * Delete cloud snapshots
26
+ */
27
+ export declare function cloudDeleteCommand(options: CloudOptions): Promise<void>;
28
+ /**
29
+ * Main cloud command handler
30
+ */
31
+ export declare function cloudCommand(subcommand: string, options: CloudOptions): Promise<void>;
32
+ export {};
33
+ //# sourceMappingURL=cloud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/commands/cloud.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,UAAU,YAAY;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAoJD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqG3E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF3E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CtD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6E7E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB3F"}
@@ -0,0 +1,444 @@
1
+ /**
2
+ * savestate cloud — Cloud storage commands (Pro/Team)
3
+ *
4
+ * Manages cloud backups through the SaveState API.
5
+ * Requires Pro or Team subscription.
6
+ */
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import { existsSync, readFileSync, createWriteStream, statSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { isInitialized, loadConfig, localConfigDir } from '../config.js';
12
+ import { loadIndex } from '../index-file.js';
13
+ /** Get the snapshots directory */
14
+ function getSnapshotsDir() {
15
+ return join(localConfigDir(), 'snapshots');
16
+ }
17
+ const API_BASE = process.env.SAVESTATE_API_URL || 'https://savestate.dev/api';
18
+ /**
19
+ * Verify subscription is Pro or Team
20
+ */
21
+ async function verifySubscription() {
22
+ const config = await loadConfig();
23
+ const extConfig = config;
24
+ const apiKey = extConfig.apiKey;
25
+ if (!apiKey) {
26
+ return { valid: false, error: 'Not logged in. Run `savestate login` first.' };
27
+ }
28
+ try {
29
+ const res = await fetch(`${API_BASE}/account`, {
30
+ headers: { Authorization: `Bearer ${apiKey}` },
31
+ });
32
+ if (!res.ok) {
33
+ return { valid: false, error: 'Could not verify subscription.' };
34
+ }
35
+ const data = await res.json();
36
+ const tier = (data.tier || 'free').toLowerCase();
37
+ const storage = data.storage || {};
38
+ const cloudStorageUsed = storage.used || 0;
39
+ const cloudStorageLimit = storage.limit || 0;
40
+ if (tier === 'pro' || tier === 'team') {
41
+ return { valid: true, tier, cloudStorageUsed, cloudStorageLimit };
42
+ }
43
+ return {
44
+ valid: false,
45
+ tier,
46
+ error: 'Cloud storage requires a Pro or Team subscription.'
47
+ };
48
+ }
49
+ catch {
50
+ return { valid: false, error: 'Could not verify subscription. Check your internet connection.' };
51
+ }
52
+ }
53
+ /**
54
+ * Upload snapshot to cloud via proxy API
55
+ */
56
+ async function uploadToCloud(snapshotId, data) {
57
+ const config = await loadConfig();
58
+ const extConfig = config;
59
+ const apiKey = extConfig.apiKey;
60
+ try {
61
+ const key = `snapshots/${snapshotId}.saf.enc`;
62
+ const res = await fetch(`${API_BASE}/storage?key=${encodeURIComponent(key)}`, {
63
+ method: 'PUT',
64
+ headers: {
65
+ Authorization: `Bearer ${apiKey}`,
66
+ 'Content-Type': 'application/octet-stream',
67
+ },
68
+ body: data,
69
+ });
70
+ if (!res.ok) {
71
+ const body = await res.json().catch(() => ({}));
72
+ return { success: false, error: body.error || `HTTP ${res.status}` };
73
+ }
74
+ return { success: true };
75
+ }
76
+ catch (err) {
77
+ return { success: false, error: err instanceof Error ? err.message : 'Upload failed' };
78
+ }
79
+ }
80
+ /**
81
+ * Download snapshot from cloud via proxy API
82
+ */
83
+ async function downloadFromCloud(snapshotId) {
84
+ const config = await loadConfig();
85
+ const extConfig = config;
86
+ const apiKey = extConfig.apiKey;
87
+ try {
88
+ const key = `snapshots/${snapshotId}.saf.enc`;
89
+ const res = await fetch(`${API_BASE}/storage?key=${encodeURIComponent(key)}`, {
90
+ headers: { Authorization: `Bearer ${apiKey}` },
91
+ });
92
+ if (!res.ok)
93
+ return null;
94
+ return Buffer.from(await res.arrayBuffer());
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ /**
101
+ * Delete snapshot from cloud
102
+ */
103
+ async function deleteFromCloud(snapshotId) {
104
+ const config = await loadConfig();
105
+ const extConfig = config;
106
+ const apiKey = extConfig.apiKey;
107
+ try {
108
+ const key = `snapshots/${snapshotId}.saf.enc`;
109
+ const res = await fetch(`${API_BASE}/storage?key=${encodeURIComponent(key)}`, {
110
+ method: 'DELETE',
111
+ headers: { Authorization: `Bearer ${apiKey}` },
112
+ });
113
+ return res.ok;
114
+ }
115
+ catch {
116
+ return false;
117
+ }
118
+ }
119
+ /**
120
+ * List cloud snapshots from API
121
+ */
122
+ async function listCloudSnapshots() {
123
+ const config = await loadConfig();
124
+ const extConfig = config;
125
+ const apiKey = extConfig.apiKey;
126
+ try {
127
+ const res = await fetch(`${API_BASE}/storage?list=true`, {
128
+ headers: { Authorization: `Bearer ${apiKey}` },
129
+ });
130
+ if (!res.ok)
131
+ return [];
132
+ const data = await res.json();
133
+ // Transform API response to expected format
134
+ return (data.items || []).map(item => ({
135
+ id: item.key.replace('snapshots/', '').replace('.saf.enc', ''),
136
+ size: item.size,
137
+ createdAt: item.lastModified,
138
+ }));
139
+ }
140
+ catch {
141
+ return [];
142
+ }
143
+ }
144
+ /**
145
+ * Push local snapshots to cloud
146
+ */
147
+ export async function cloudPushCommand(options) {
148
+ console.log();
149
+ if (!isInitialized()) {
150
+ console.log(chalk.red('✗ SaveState not initialized. Run `savestate init` first.'));
151
+ process.exit(1);
152
+ }
153
+ // Verify subscription
154
+ const spinner = ora('Verifying subscription...').start();
155
+ const sub = await verifySubscription();
156
+ if (!sub.valid) {
157
+ spinner.fail('Subscription required');
158
+ console.log();
159
+ console.log(chalk.red(` ${sub.error}`));
160
+ if (sub.tier === 'free') {
161
+ console.log();
162
+ console.log(chalk.dim(' Upgrade at: https://savestate.dev/#pricing'));
163
+ }
164
+ process.exit(1);
165
+ }
166
+ spinner.succeed(`Subscription verified (${sub.tier})`);
167
+ // Show storage usage
168
+ if (sub.cloudStorageLimit) {
169
+ const usedMB = Math.round((sub.cloudStorageUsed || 0) / 1024 / 1024);
170
+ const limitMB = Math.round(sub.cloudStorageLimit / 1024 / 1024);
171
+ console.log(chalk.dim(` Cloud storage: ${usedMB} MB / ${limitMB} MB`));
172
+ }
173
+ console.log();
174
+ // Get local snapshots
175
+ const index = await loadIndex();
176
+ const entries = index.snapshots || [];
177
+ if (entries.length === 0) {
178
+ console.log(chalk.yellow('No local snapshots to push.'));
179
+ console.log(chalk.dim(' Run `savestate snapshot` to create one.'));
180
+ process.exit(0);
181
+ }
182
+ // Filter to specific snapshot or all
183
+ let toPush = entries;
184
+ if (options.id) {
185
+ toPush = entries.filter(e => e.id === options.id || e.id.startsWith(options.id));
186
+ if (toPush.length === 0) {
187
+ console.log(chalk.red(`Snapshot not found: ${options.id}`));
188
+ process.exit(1);
189
+ }
190
+ }
191
+ else if (!options.all) {
192
+ // Default: push latest only
193
+ toPush = [entries[entries.length - 1]];
194
+ }
195
+ console.log(chalk.blue(`Pushing ${toPush.length} snapshot(s) to cloud...`));
196
+ console.log();
197
+ const snapshotsDir = getSnapshotsDir();
198
+ let success = 0;
199
+ let failed = 0;
200
+ for (const entry of toPush) {
201
+ const filePath = join(snapshotsDir, `${entry.id}.saf.enc`);
202
+ if (!existsSync(filePath)) {
203
+ console.log(chalk.yellow(` ⚠ ${entry.id.slice(0, 8)} — file not found, skipping`));
204
+ failed++;
205
+ continue;
206
+ }
207
+ const stat = statSync(filePath);
208
+ const uploadSpinner = ora(` Uploading ${entry.id.slice(0, 8)}... (${Math.round(stat.size / 1024)} KB)`).start();
209
+ try {
210
+ // Read and upload the file through the proxy API
211
+ const fileBuffer = readFileSync(filePath);
212
+ const result = await uploadToCloud(entry.id, fileBuffer);
213
+ if (!result.success) {
214
+ uploadSpinner.fail(` ${entry.id.slice(0, 8)} — ${result.error || 'upload failed'}`);
215
+ failed++;
216
+ continue;
217
+ }
218
+ uploadSpinner.succeed(` ${entry.id.slice(0, 8)} — uploaded`);
219
+ success++;
220
+ }
221
+ catch (err) {
222
+ uploadSpinner.fail(` ${entry.id.slice(0, 8)} — ${err instanceof Error ? err.message : 'failed'}`);
223
+ failed++;
224
+ }
225
+ }
226
+ console.log();
227
+ if (success > 0) {
228
+ console.log(chalk.green(`✓ Pushed ${success} snapshot(s) to cloud`));
229
+ }
230
+ if (failed > 0) {
231
+ console.log(chalk.yellow(`⚠ ${failed} snapshot(s) failed`));
232
+ }
233
+ }
234
+ /**
235
+ * Pull snapshots from cloud
236
+ */
237
+ export async function cloudPullCommand(options) {
238
+ console.log();
239
+ if (!isInitialized()) {
240
+ console.log(chalk.red('✗ SaveState not initialized. Run `savestate init` first.'));
241
+ process.exit(1);
242
+ }
243
+ // Verify subscription
244
+ const spinner = ora('Verifying subscription...').start();
245
+ const sub = await verifySubscription();
246
+ if (!sub.valid) {
247
+ spinner.fail('Subscription required');
248
+ console.log();
249
+ console.log(chalk.red(` ${sub.error}`));
250
+ process.exit(1);
251
+ }
252
+ spinner.succeed(`Subscription verified (${sub.tier})`);
253
+ console.log();
254
+ // Get cloud snapshots
255
+ const listSpinner = ora('Fetching cloud snapshots...').start();
256
+ const cloudSnapshots = await listCloudSnapshots();
257
+ listSpinner.stop();
258
+ if (cloudSnapshots.length === 0) {
259
+ console.log(chalk.yellow('No snapshots in cloud storage.'));
260
+ console.log(chalk.dim(' Run `savestate cloud push` to upload snapshots.'));
261
+ process.exit(0);
262
+ }
263
+ // Filter
264
+ let toPull = cloudSnapshots;
265
+ if (options.id) {
266
+ toPull = cloudSnapshots.filter(s => s.id === options.id || s.id.startsWith(options.id));
267
+ if (toPull.length === 0) {
268
+ console.log(chalk.red(`Snapshot not found in cloud: ${options.id}`));
269
+ process.exit(1);
270
+ }
271
+ }
272
+ else if (!options.all) {
273
+ toPull = [cloudSnapshots[cloudSnapshots.length - 1]];
274
+ }
275
+ console.log(chalk.blue(`Pulling ${toPull.length} snapshot(s) from cloud...`));
276
+ console.log();
277
+ const snapshotsDir = getSnapshotsDir();
278
+ let success = 0;
279
+ for (const snap of toPull) {
280
+ const filePath = join(snapshotsDir, `${snap.id}.saf.enc`);
281
+ if (existsSync(filePath) && !options.force) {
282
+ console.log(chalk.dim(` ⏭ ${snap.id.slice(0, 8)} — already exists locally`));
283
+ continue;
284
+ }
285
+ const dlSpinner = ora(` Downloading ${snap.id.slice(0, 8)}...`).start();
286
+ try {
287
+ const data = await downloadFromCloud(snap.id);
288
+ if (!data) {
289
+ dlSpinner.fail(` ${snap.id.slice(0, 8)} — download failed`);
290
+ continue;
291
+ }
292
+ const fileStream = createWriteStream(filePath);
293
+ fileStream.write(data);
294
+ fileStream.end();
295
+ dlSpinner.succeed(` ${snap.id.slice(0, 8)} — downloaded`);
296
+ success++;
297
+ }
298
+ catch (err) {
299
+ dlSpinner.fail(` ${snap.id.slice(0, 8)} — ${err instanceof Error ? err.message : 'failed'}`);
300
+ }
301
+ }
302
+ console.log();
303
+ console.log(chalk.green(`✓ Pulled ${success} snapshot(s) from cloud`));
304
+ }
305
+ /**
306
+ * List cloud snapshots
307
+ */
308
+ export async function cloudListCommand() {
309
+ console.log();
310
+ // Verify subscription
311
+ const spinner = ora('Verifying subscription...').start();
312
+ const sub = await verifySubscription();
313
+ if (!sub.valid) {
314
+ spinner.fail('Subscription required');
315
+ console.log();
316
+ console.log(chalk.red(` ${sub.error}`));
317
+ process.exit(1);
318
+ }
319
+ spinner.text = 'Fetching cloud snapshots...';
320
+ const snapshots = await listCloudSnapshots();
321
+ spinner.stop();
322
+ console.log(chalk.blue(`Cloud Storage (${sub.tier})`));
323
+ if (sub.cloudStorageLimit) {
324
+ const usedMB = Math.round((sub.cloudStorageUsed || 0) / 1024 / 1024);
325
+ const limitMB = Math.round(sub.cloudStorageLimit / 1024 / 1024);
326
+ const pct = Math.round((sub.cloudStorageUsed || 0) / sub.cloudStorageLimit * 100);
327
+ console.log(chalk.dim(` Usage: ${usedMB} MB / ${limitMB} MB (${pct}%)`));
328
+ }
329
+ console.log();
330
+ if (snapshots.length === 0) {
331
+ console.log(chalk.yellow(' No snapshots in cloud.'));
332
+ console.log(chalk.dim(' Run `savestate cloud push` to upload.'));
333
+ return;
334
+ }
335
+ console.log(chalk.dim(' ID Size Date'));
336
+ console.log(chalk.dim(' ───────── ───────── ──────────────────'));
337
+ for (const snap of snapshots) {
338
+ const sizeKB = Math.round(snap.size / 1024);
339
+ const date = new Date(snap.createdAt).toLocaleDateString();
340
+ console.log(` ${snap.id.slice(0, 8)} ${String(sizeKB).padStart(6)} KB ${date}`);
341
+ }
342
+ console.log();
343
+ console.log(chalk.dim(` ${snapshots.length} snapshot(s) in cloud`));
344
+ }
345
+ /**
346
+ * Delete cloud snapshots
347
+ */
348
+ export async function cloudDeleteCommand(options) {
349
+ console.log();
350
+ if (!options.id && !options.all) {
351
+ console.log(chalk.red('✗ Specify --id <snapshot> or --all to delete'));
352
+ process.exit(1);
353
+ }
354
+ // Verify subscription
355
+ const spinner = ora('Verifying subscription...').start();
356
+ const sub = await verifySubscription();
357
+ if (!sub.valid) {
358
+ spinner.fail('Subscription required');
359
+ console.log();
360
+ console.log(chalk.red(` ${sub.error}`));
361
+ process.exit(1);
362
+ }
363
+ spinner.text = 'Fetching cloud snapshots...';
364
+ const cloudSnapshots = await listCloudSnapshots();
365
+ spinner.stop();
366
+ if (cloudSnapshots.length === 0) {
367
+ console.log(chalk.yellow('No snapshots in cloud storage.'));
368
+ process.exit(0);
369
+ }
370
+ // Filter
371
+ let toDelete = cloudSnapshots;
372
+ if (options.id) {
373
+ toDelete = cloudSnapshots.filter(s => s.id === options.id || s.id.startsWith(options.id));
374
+ if (toDelete.length === 0) {
375
+ console.log(chalk.red(`Snapshot not found in cloud: ${options.id}`));
376
+ process.exit(1);
377
+ }
378
+ }
379
+ // Confirm deletion
380
+ if (!options.force) {
381
+ const readline = await import('node:readline');
382
+ const rl = readline.createInterface({
383
+ input: process.stdin,
384
+ output: process.stdout,
385
+ });
386
+ const answer = await new Promise((resolve) => {
387
+ rl.question(chalk.yellow(` Delete ${toDelete.length} snapshot(s) from cloud? [y/N] `), (ans) => {
388
+ rl.close();
389
+ resolve(ans.trim().toLowerCase());
390
+ });
391
+ });
392
+ if (answer !== 'y' && answer !== 'yes') {
393
+ console.log(chalk.dim(' Cancelled.'));
394
+ process.exit(0);
395
+ }
396
+ }
397
+ console.log();
398
+ console.log(chalk.blue(`Deleting ${toDelete.length} snapshot(s)...`));
399
+ console.log();
400
+ let success = 0;
401
+ for (const snap of toDelete) {
402
+ const delSpinner = ora(` Deleting ${snap.id.slice(0, 8)}...`).start();
403
+ const ok = await deleteFromCloud(snap.id);
404
+ if (ok) {
405
+ delSpinner.succeed(` ${snap.id.slice(0, 8)} — deleted`);
406
+ success++;
407
+ }
408
+ else {
409
+ delSpinner.fail(` ${snap.id.slice(0, 8)} — failed`);
410
+ }
411
+ }
412
+ console.log();
413
+ console.log(chalk.green(`✓ Deleted ${success} snapshot(s) from cloud`));
414
+ }
415
+ /**
416
+ * Main cloud command handler
417
+ */
418
+ export async function cloudCommand(subcommand, options) {
419
+ switch (subcommand) {
420
+ case 'push':
421
+ await cloudPushCommand(options);
422
+ break;
423
+ case 'pull':
424
+ await cloudPullCommand(options);
425
+ break;
426
+ case 'list':
427
+ await cloudListCommand();
428
+ break;
429
+ case 'delete':
430
+ await cloudDeleteCommand(options);
431
+ break;
432
+ default:
433
+ console.log(chalk.red(`Unknown cloud command: ${subcommand}`));
434
+ console.log();
435
+ console.log('Usage:');
436
+ console.log(' savestate cloud push [--id <id>] [--all] Push snapshots to cloud');
437
+ console.log(' savestate cloud pull [--id <id>] [--all] Pull snapshots from cloud');
438
+ console.log(' savestate cloud list List cloud snapshots');
439
+ console.log(' savestate cloud delete --id <id> [--force] Delete cloud snapshot');
440
+ console.log(' savestate cloud delete --all [--force] Delete all cloud snapshots');
441
+ process.exit(1);
442
+ }
443
+ }
444
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","sourceRoot":"","sources":["../../src/commands/cloud.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,14 @@
2
2
  * Storage Backend Resolver
3
3
  *
4
4
  * Creates a storage backend instance from config.
5
+ * Cloud storage (S3/R2/B2) requires Pro or Team subscription.
5
6
  */
6
7
  import type { SaveStateConfig, StorageBackend } from '../types.js';
7
8
  /**
8
9
  * Create a storage backend from the config's storage section.
10
+ *
11
+ * Note: Direct cloud storage (s3/r2/b2) has been removed from the CLI.
12
+ * Use `savestate cloud push/pull` for cloud backups (requires Pro subscription).
9
13
  */
10
14
  export declare function resolveStorage(config: SaveStateConfig): StorageBackend;
11
15
  //# sourceMappingURL=resolve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKnE;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CA6BtE"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CA2BtE"}
@@ -2,11 +2,14 @@
2
2
  * Storage Backend Resolver
3
3
  *
4
4
  * Creates a storage backend instance from config.
5
+ * Cloud storage (S3/R2/B2) requires Pro or Team subscription.
5
6
  */
6
7
  import { LocalStorageBackend } from './local.js';
7
- import { S3Storage } from './s3.js';
8
8
  /**
9
9
  * Create a storage backend from the config's storage section.
10
+ *
11
+ * Note: Direct cloud storage (s3/r2/b2) has been removed from the CLI.
12
+ * Use `savestate cloud push/pull` for cloud backups (requires Pro subscription).
10
13
  */
11
14
  export function resolveStorage(config) {
12
15
  const { type, options } = config.storage;
@@ -18,19 +21,15 @@ export function resolveStorage(config) {
18
21
  case 's3':
19
22
  case 'r2':
20
23
  case 'b2':
21
- return new S3Storage({
22
- bucket: options.bucket,
23
- endpoint: options.endpoint,
24
- region: options.region,
25
- accessKeyId: options.accessKeyId,
26
- secretAccessKey: options.secretAccessKey,
27
- prefix: options.prefix,
28
- timeoutMs: options.timeoutMs,
29
- maxRetries: options.maxRetries,
30
- });
24
+ throw new Error(`Direct cloud storage (${type}) has been removed.\n\n` +
25
+ `Cloud backups are now managed through the SaveState API:\n` +
26
+ ` savestate cloud push Push local snapshots to cloud (Pro)\n` +
27
+ ` savestate cloud pull Pull snapshots from cloud (Pro)\n` +
28
+ ` savestate cloud list List cloud snapshots (Pro)\n\n` +
29
+ `Upgrade at: https://savestate.dev/#pricing`);
31
30
  default:
32
31
  throw new Error(`Unknown storage backend: ${type}. ` +
33
- `Supported: local, s3, r2, b2.`);
32
+ `Supported: local (use 'savestate cloud' for cloud storage).`);
34
33
  }
35
34
  }
36
35
  //# sourceMappingURL=resolve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAuB;IACpD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IAEzC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,IAAI,mBAAmB,CAAC;gBAC7B,IAAI,EAAE,OAAO,CAAC,IAA0B;aACzC,CAAC,CAAC;QAEL,KAAK,IAAI,CAAC;QACV,KAAK,IAAI,CAAC;QACV,KAAK,IAAI;YACP,OAAO,IAAI,SAAS,CAAC;gBACnB,MAAM,EAAE,OAAO,CAAC,MAAgB;gBAChC,QAAQ,EAAE,OAAO,CAAC,QAAkB;gBACpC,MAAM,EAAE,OAAO,CAAC,MAA4B;gBAC5C,WAAW,EAAE,OAAO,CAAC,WAAiC;gBACtD,eAAe,EAAE,OAAO,CAAC,eAAqC;gBAC9D,MAAM,EAAE,OAAO,CAAC,MAA4B;gBAC5C,SAAS,EAAE,OAAO,CAAC,SAA+B;gBAClD,UAAU,EAAE,OAAO,CAAC,UAAgC;aAC1B,CAAC,CAAC;QAEhC;YACE,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,IAAI;gBACpC,+BAA+B,CAChC,CAAC;IACN,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/storage/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAuB;IACpD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IAEzC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,IAAI,mBAAmB,CAAC;gBAC7B,IAAI,EAAE,OAAO,CAAC,IAA0B;aACzC,CAAC,CAAC;QAEL,KAAK,IAAI,CAAC;QACV,KAAK,IAAI,CAAC;QACV,KAAK,IAAI;YACP,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,yBAAyB;gBACtD,4DAA4D;gBAC5D,kEAAkE;gBAClE,8DAA8D;gBAC9D,2DAA2D;gBAC3D,4CAA4C,CAC7C,CAAC;QAEJ;YACE,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,IAAI;gBACpC,6DAA6D,CAC9D,CAAC;IACN,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savestate/cli",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Time Machine for AI. Backup, restore, and migrate your AI identity.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",