@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 +30 -12
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/cloud.d.ts +33 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +444 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/storage/resolve.d.ts +4 -0
- package/dist/storage/resolve.d.ts.map +1 -1
- package/dist/storage/resolve.js +11 -12
- package/dist/storage/resolve.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
161
|
+
## Storage
|
|
162
|
+
|
|
163
|
+
### Local Storage (Free)
|
|
162
164
|
|
|
163
165
|
```bash
|
|
164
|
-
#
|
|
166
|
+
# Default — snapshots stored in ~/.savestate/
|
|
165
167
|
savestate config --set storage.type=local
|
|
166
168
|
|
|
167
|
-
#
|
|
168
|
-
savestate config --set storage.
|
|
169
|
-
|
|
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
|
-
|
|
172
|
-
savestate config --set storage.type=r2
|
|
175
|
+
Cloud storage is managed through the SaveState API with server-side subscription verification:
|
|
173
176
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
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
|
-
|
|
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":";AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,qEAAqE,CAAC;KAClF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;KACnD,MAAM,CAAC,yBAAyB,EAAE,uCAAuC,CAAC;KAC1E,MAAM,CAAC,2BAA2B,EAAE,8CAA8C,CAAC;KACnF,MAAM,CAAC,QAAQ,EAAE,0CAA0C,CAAC;KAC5D,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,uBAAuB,CAAC;KAChC,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;KAC5D,MAAM,CAAC,WAAW,EAAE,oDAAoD,CAAC;KACzE,MAAM,CAAC,wBAAwB,EAAE,kEAAkE,CAAC;KACpG,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,aAAa,EAAE,qCAAqC,CAAC;KAC5D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACjD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,gEAAgE;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,eAAe,EAAE,iDAAiD,CAAC;KAC1E,MAAM,CAAC,aAAa,EAAE,iBAAiB,CAAC;KACxC,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;KAC9D,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,CAAC;KACjE,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,gEAAgE;AAEhE,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,gEAAgE;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,MAAM,CAAC,wBAAwB,EAAE,yCAAyC,CAAC;KAC3E,MAAM,CAAC,eAAe,EAAE,2BAA2B,CAAC;KACpD,MAAM,CAAC,cAAc,EAAE,sBAAsB,CAAC;KAC9C,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,gEAAgE;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,uBAAuB,EAAE,iCAAiC,CAAC;KAClE,MAAM,CAAC,qBAAqB,EAAE,+BAA+B,CAAC;KAC9D,MAAM,CAAC,qBAAqB,EAAE,mDAAmD,CAAC;KAClF,MAAM,CAAC,WAAW,EAAE,4CAA4C,CAAC;KACjE,MAAM,CAAC,YAAY,EAAE,iDAAiD,CAAC;KACvE,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,gEAAgE;AAEhE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO;KACJ,OAAO,CAAC,oBAAoB,CAAC;KAC7B,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,OAAO,EAAE,uBAAuB,CAAC;KACxC,MAAM,CAAC,aAAa,EAAE,0BAA0B,CAAC;KACjD,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,gEAAgE;AAEhE,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -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
|
|
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"}
|
package/dist/storage/resolve.js
CHANGED
|
@@ -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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
|
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
|
|
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"}
|