clawon 0.1.1 → 0.1.2
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/dist/index.js +110 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -183,8 +183,16 @@ program.command("backup").description("Backup your OpenClaw workspace to the clo
|
|
|
183
183
|
console.log(` Files: ${files.length}`);
|
|
184
184
|
console.log(` Size: ${(totalSize / 1024).toFixed(1)} KB`);
|
|
185
185
|
} catch (e) {
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
const msg = e.message;
|
|
187
|
+
if (msg.includes("Snapshot limit")) {
|
|
188
|
+
console.error("\n\u2717 Snapshot limit reached (5/5).");
|
|
189
|
+
console.error(" Delete one first: clawon delete <id>");
|
|
190
|
+
console.error(" Delete oldest: clawon delete --oldest");
|
|
191
|
+
console.error(" List snapshots: clawon list");
|
|
192
|
+
} else {
|
|
193
|
+
console.error(`
|
|
194
|
+
\u2717 Backup failed: ${msg}`);
|
|
195
|
+
}
|
|
188
196
|
process.exit(1);
|
|
189
197
|
}
|
|
190
198
|
});
|
|
@@ -230,6 +238,10 @@ program.command("restore").description("Restore your OpenClaw workspace from the
|
|
|
230
238
|
process.stdout.write(`\r Downloaded: ${downloaded}/${files.length}`);
|
|
231
239
|
}
|
|
232
240
|
console.log("");
|
|
241
|
+
await api(cfg.apiBaseUrl, "/api/v1/snapshots/restore", "POST", cfg.apiKey, {
|
|
242
|
+
profileId: cfg.profileId,
|
|
243
|
+
snapshotId: snapshot.id
|
|
244
|
+
});
|
|
233
245
|
console.log("\n\u2713 Restore complete!");
|
|
234
246
|
console.log(` Restored to: ${OPENCLAW_DIR}`);
|
|
235
247
|
console.log(` Files: ${files.length}`);
|
|
@@ -272,6 +284,102 @@ Total: ${snapshots.length} backup(s)`);
|
|
|
272
284
|
process.exit(1);
|
|
273
285
|
}
|
|
274
286
|
});
|
|
287
|
+
var ACTIVITY_LABELS = {
|
|
288
|
+
BACKUP_CREATED: "Backup created",
|
|
289
|
+
SNAPSHOT_CREATED: "Snapshot created",
|
|
290
|
+
SNAPSHOT_DELETED: "Snapshot deleted",
|
|
291
|
+
SNAPSHOT_RESTORED: "Snapshot restored",
|
|
292
|
+
BACKUP_DOWNLOADED: "Backup downloaded",
|
|
293
|
+
CONNECTED: "Connected",
|
|
294
|
+
DISCONNECTED: "Disconnected"
|
|
295
|
+
};
|
|
296
|
+
function formatEventLabel(type) {
|
|
297
|
+
return ACTIVITY_LABELS[type] || type.replace(/_/g, " ").toLowerCase().replace(/^\w/, (c) => c.toUpperCase());
|
|
298
|
+
}
|
|
299
|
+
function formatEventDetails(payload) {
|
|
300
|
+
if (!payload || typeof payload !== "object") return "";
|
|
301
|
+
const parts = [];
|
|
302
|
+
if (payload.fileCount != null || payload.changedFilesCount != null) {
|
|
303
|
+
parts.push(`${payload.fileCount ?? payload.changedFilesCount} files`);
|
|
304
|
+
}
|
|
305
|
+
if (payload.snapshotId) {
|
|
306
|
+
parts.push(payload.snapshotId);
|
|
307
|
+
}
|
|
308
|
+
if (payload.instanceName) {
|
|
309
|
+
parts.push(payload.instanceName);
|
|
310
|
+
}
|
|
311
|
+
return parts.join(" \xB7 ");
|
|
312
|
+
}
|
|
313
|
+
program.command("activity").description("Show recent activity").option("--limit <n>", "Number of events to show", "10").action(async (opts) => {
|
|
314
|
+
const cfg = readConfig();
|
|
315
|
+
if (!cfg) {
|
|
316
|
+
console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
const { events } = await api(
|
|
321
|
+
cfg.apiBaseUrl,
|
|
322
|
+
`/api/v1/events/list?profileId=${cfg.profileId}&limit=${opts.limit}`,
|
|
323
|
+
"GET",
|
|
324
|
+
cfg.apiKey
|
|
325
|
+
);
|
|
326
|
+
if (!events?.length) {
|
|
327
|
+
console.log("No activity yet. Run: clawon backup");
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
console.log("Recent activity:\n");
|
|
331
|
+
console.log("Date | Event | Details");
|
|
332
|
+
console.log("\u2500".repeat(80));
|
|
333
|
+
for (const ev of events) {
|
|
334
|
+
const date = new Date(ev.created_at).toLocaleString();
|
|
335
|
+
const label = formatEventLabel(ev.type);
|
|
336
|
+
const details = formatEventDetails(ev.payload);
|
|
337
|
+
console.log(`${date.padEnd(20)} | ${label.padEnd(18)} | ${details}`);
|
|
338
|
+
}
|
|
339
|
+
} catch (e) {
|
|
340
|
+
console.error(`\u2717 Failed to load activity: ${e.message}`);
|
|
341
|
+
process.exit(1);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
program.command("delete [id]").description("Delete a snapshot").option("--oldest", "Delete the oldest ready snapshot").action(async (id, opts) => {
|
|
345
|
+
const cfg = readConfig();
|
|
346
|
+
if (!cfg) {
|
|
347
|
+
console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
if (!id && !opts.oldest) {
|
|
351
|
+
console.error("\u2717 Provide a snapshot ID or use --oldest");
|
|
352
|
+
console.error(" Usage: clawon delete <id>");
|
|
353
|
+
console.error(" clawon delete --oldest");
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
let snapshotId = id;
|
|
358
|
+
if (opts.oldest) {
|
|
359
|
+
const { snapshots } = await api(
|
|
360
|
+
cfg.apiBaseUrl,
|
|
361
|
+
`/api/v1/snapshots/list?profileId=${cfg.profileId}&limit=50`,
|
|
362
|
+
"GET",
|
|
363
|
+
cfg.apiKey
|
|
364
|
+
);
|
|
365
|
+
const readySnapshots = (snapshots || []).filter((s) => s.status === "ready");
|
|
366
|
+
if (readySnapshots.length === 0) {
|
|
367
|
+
console.error("\u2717 No ready snapshots to delete");
|
|
368
|
+
process.exit(1);
|
|
369
|
+
}
|
|
370
|
+
snapshotId = readySnapshots[readySnapshots.length - 1].id;
|
|
371
|
+
console.log(`Oldest ready snapshot: ${snapshotId}`);
|
|
372
|
+
}
|
|
373
|
+
await api(cfg.apiBaseUrl, "/api/v1/snapshots/delete", "POST", cfg.apiKey, {
|
|
374
|
+
profileId: cfg.profileId,
|
|
375
|
+
snapshotId
|
|
376
|
+
});
|
|
377
|
+
console.log(`\u2713 Deleted snapshot ${snapshotId}`);
|
|
378
|
+
} catch (e) {
|
|
379
|
+
console.error(`\u2717 Delete failed: ${e.message}`);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
275
383
|
program.command("files").description("List files in a backup").option("--snapshot <id>", "Snapshot ID (default: latest)").action(async (opts) => {
|
|
276
384
|
const cfg = readConfig();
|
|
277
385
|
if (!cfg) {
|