clawon 0.1.5 → 0.1.7
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 +154 -0
- package/dist/index.js +103 -48
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Clawon
|
|
2
|
+
|
|
3
|
+
Backup and restore your [OpenClaw](https://openclaw.ai) workspace. Move your memory, skills, and config between machines in one command.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# No install needed — runs with npx
|
|
9
|
+
npx clawon discover # Preview what will be backed up
|
|
10
|
+
npx clawon local backup # Save a local backup
|
|
11
|
+
npx clawon local restore # Restore from latest backup
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
|
|
16
|
+
### Local Backups (no account needed)
|
|
17
|
+
|
|
18
|
+
Local backups are stored in `~/.clawon/backups/` as standard `.tar.gz` archives. You can inspect them with `tar tzf` or extract manually with `tar xzf`.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Create a backup
|
|
22
|
+
npx clawon local backup
|
|
23
|
+
npx clawon local backup --tag "before migration"
|
|
24
|
+
|
|
25
|
+
# List all local backups
|
|
26
|
+
npx clawon local list
|
|
27
|
+
|
|
28
|
+
# Restore
|
|
29
|
+
npx clawon local restore # Latest backup
|
|
30
|
+
npx clawon local restore --pick 2 # Backup #2 from list
|
|
31
|
+
npx clawon local restore --file path.tar.gz # External file
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Cloud Backups (requires account)
|
|
35
|
+
|
|
36
|
+
Cloud backups sync your workspace to Clawon's servers for cross-machine access.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Authenticate
|
|
40
|
+
npx clawon login --api-key <your-key>
|
|
41
|
+
|
|
42
|
+
# Create a cloud backup
|
|
43
|
+
npx clawon backup
|
|
44
|
+
npx clawon backup --tag "stable config"
|
|
45
|
+
npx clawon backup --dry-run # Preview without uploading
|
|
46
|
+
|
|
47
|
+
# List cloud backups
|
|
48
|
+
npx clawon list
|
|
49
|
+
|
|
50
|
+
# Restore from cloud
|
|
51
|
+
npx clawon restore
|
|
52
|
+
npx clawon restore --snapshot <id> # Specific snapshot
|
|
53
|
+
npx clawon restore --dry-run # Preview without extracting
|
|
54
|
+
|
|
55
|
+
# Manage snapshots
|
|
56
|
+
npx clawon delete <id>
|
|
57
|
+
npx clawon delete --oldest
|
|
58
|
+
npx clawon files # List files in a cloud backup
|
|
59
|
+
npx clawon activity # Recent events
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Other Commands
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx clawon discover # Show exactly which files would be backed up
|
|
66
|
+
npx clawon status # Connection status and file count
|
|
67
|
+
npx clawon logout # Remove local credentials
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## What Gets Backed Up
|
|
71
|
+
|
|
72
|
+
Clawon uses an **allowlist** — only files matching these patterns are included:
|
|
73
|
+
|
|
74
|
+
| Pattern | What it captures |
|
|
75
|
+
|---------|-----------------|
|
|
76
|
+
| `workspace/*.md` | Workspace markdown (memory, notes, identity) |
|
|
77
|
+
| `workspace/memory/*.md` | Daily memory files |
|
|
78
|
+
| `workspace/memory/**/*.md` | Nested memory (projects, workflows, experiments) |
|
|
79
|
+
| `workspace/skills/**` | Custom skills |
|
|
80
|
+
| `workspace/canvas/**` | Canvas data |
|
|
81
|
+
| `skills/**` | Top-level skills |
|
|
82
|
+
| `agents/*/config.json` | Agent configurations |
|
|
83
|
+
|
|
84
|
+
Run `npx clawon discover` to see the exact file list for your instance.
|
|
85
|
+
|
|
86
|
+
## What's Excluded
|
|
87
|
+
|
|
88
|
+
These are **always excluded**, even if they match an include pattern:
|
|
89
|
+
|
|
90
|
+
| Pattern | Why |
|
|
91
|
+
|---------|-----|
|
|
92
|
+
| `credentials/**` | API keys, tokens, auth files |
|
|
93
|
+
| `openclaw.json` | May contain credentials |
|
|
94
|
+
| `agents/*/sessions/**` | Ephemeral session data |
|
|
95
|
+
| `memory/lancedb/**` | Vector database (binary, large) |
|
|
96
|
+
| `memory/*.sqlite` | SQLite databases |
|
|
97
|
+
| `*.lock`, `*.wal`, `*.shm` | Database lock files |
|
|
98
|
+
| `node_modules/**` | Dependencies |
|
|
99
|
+
|
|
100
|
+
**Credentials never leave your machine.** The entire `credentials/` directory and `openclaw.json` are excluded by default. You can verify this by running `npx clawon discover` before any backup.
|
|
101
|
+
|
|
102
|
+
## Archive Format
|
|
103
|
+
|
|
104
|
+
Local backups are standard gzip-compressed tar archives (`.tar.gz`). You can inspect and extract them with standard tools:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# List contents
|
|
108
|
+
tar tzf ~/.clawon/backups/backup-2026-03-05T1030.tar.gz
|
|
109
|
+
|
|
110
|
+
# Extract manually
|
|
111
|
+
tar xzf ~/.clawon/backups/backup-2026-03-05T1030.tar.gz -C /tmp/inspect
|
|
112
|
+
|
|
113
|
+
# View metadata
|
|
114
|
+
tar xzf backup.tar.gz _clawon_meta.json -O | cat
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Each archive contains:
|
|
118
|
+
- `_clawon_meta.json` — metadata (version, date, tag, file count)
|
|
119
|
+
- Your workspace files in their original directory structure
|
|
120
|
+
|
|
121
|
+
## Data Storage
|
|
122
|
+
|
|
123
|
+
| | Local | Cloud |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| **Location** | `~/.clawon/backups/` | Clawon servers (Supabase Storage) |
|
|
126
|
+
| **Format** | `.tar.gz` | Individual files with signed URLs |
|
|
127
|
+
| **Limit** | Unlimited | 2 snapshots (Starter), more on paid plans |
|
|
128
|
+
| **Account required** | No | Yes |
|
|
129
|
+
| **Cross-machine** | No (manual file transfer) | Yes |
|
|
130
|
+
|
|
131
|
+
## Configuration
|
|
132
|
+
|
|
133
|
+
Config is stored at `~/.clawon/config.json` after running `clawon login`. Contains your API key, profile ID, and API URL. Run `clawon logout` to remove it.
|
|
134
|
+
|
|
135
|
+
## Telemetry
|
|
136
|
+
|
|
137
|
+
Clawon collects anonymous usage events (e.g. "backup created", "restore completed") to understand which features are used. No file contents, filenames, or personal data are sent.
|
|
138
|
+
|
|
139
|
+
**To opt out**, set either environment variable:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Standard convention (https://consoledonottrack.com)
|
|
143
|
+
export DO_NOT_TRACK=1
|
|
144
|
+
|
|
145
|
+
# Or Clawon-specific
|
|
146
|
+
export CLAWON_NO_TELEMETRY=1
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Telemetry is powered by [PostHog](https://posthog.com). The public project key is visible in the source code.
|
|
150
|
+
|
|
151
|
+
## Requirements
|
|
152
|
+
|
|
153
|
+
- Node.js 18+
|
|
154
|
+
- An OpenClaw installation at `~/.openclaw/`
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import os from "os";
|
|
8
|
-
import
|
|
8
|
+
import * as tar from "tar";
|
|
9
9
|
var CONFIG_DIR = path.join(os.homedir(), ".clawon");
|
|
10
10
|
var CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
11
11
|
var OPENCLAW_DIR = path.join(os.homedir(), ".openclaw");
|
|
@@ -45,6 +45,7 @@ var INCLUDE_PATTERNS = [
|
|
|
45
45
|
];
|
|
46
46
|
var EXCLUDE_PATTERNS = [
|
|
47
47
|
"credentials/**",
|
|
48
|
+
"openclaw.json",
|
|
48
49
|
"agents/*/sessions/**",
|
|
49
50
|
"memory/lancedb/**",
|
|
50
51
|
"memory/*.sqlite",
|
|
@@ -93,27 +94,53 @@ function discoverFiles(baseDir) {
|
|
|
93
94
|
walk(baseDir);
|
|
94
95
|
return files;
|
|
95
96
|
}
|
|
96
|
-
function createLocalArchive(files, openclawDir) {
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
const content = fs.readFileSync(fullPath).toString("base64");
|
|
100
|
-
return { path: f.path, size: f.size, content };
|
|
101
|
-
});
|
|
102
|
-
const archive = {
|
|
103
|
-
version: 1,
|
|
97
|
+
async function createLocalArchive(files, openclawDir, outputPath, tag) {
|
|
98
|
+
const meta = {
|
|
99
|
+
version: 2,
|
|
104
100
|
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
105
|
-
|
|
101
|
+
...tag ? { tag } : {},
|
|
102
|
+
file_count: files.length
|
|
106
103
|
};
|
|
107
|
-
|
|
104
|
+
const metaPath = path.join(openclawDir, "_clawon_meta.json");
|
|
105
|
+
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
106
|
+
try {
|
|
107
|
+
await tar.create(
|
|
108
|
+
{ gzip: true, file: outputPath, cwd: openclawDir },
|
|
109
|
+
["_clawon_meta.json", ...files.map((f) => f.path)]
|
|
110
|
+
);
|
|
111
|
+
} finally {
|
|
112
|
+
fs.unlinkSync(metaPath);
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
async function readArchiveMeta(archivePath) {
|
|
116
|
+
let meta = null;
|
|
117
|
+
await tar.list({
|
|
118
|
+
file: archivePath,
|
|
119
|
+
onReadEntry: (entry) => {
|
|
120
|
+
if (entry.path === "_clawon_meta.json") {
|
|
121
|
+
const chunks = [];
|
|
122
|
+
entry.on("data", (c) => chunks.push(c));
|
|
123
|
+
entry.on("end", () => {
|
|
124
|
+
meta = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
if (!meta) throw new Error("Invalid archive: missing _clawon_meta.json");
|
|
130
|
+
return meta;
|
|
131
|
+
}
|
|
132
|
+
async function extractLocalArchive(archivePath, targetDir) {
|
|
133
|
+
const meta = await readArchiveMeta(archivePath);
|
|
134
|
+
ensureDir(targetDir);
|
|
135
|
+
await tar.extract({ file: archivePath, cwd: targetDir, filter: (p) => p !== "_clawon_meta.json" });
|
|
136
|
+
return meta;
|
|
114
137
|
}
|
|
115
138
|
var POSTHOG_KEY = "phc_LGJC4ZrED6EiK0sC1fusErOhR6gHlFCS5Qs7ou93SmV";
|
|
139
|
+
function telemetryDisabled() {
|
|
140
|
+
return process.env.DO_NOT_TRACK === "1" || process.env.CLAWON_NO_TELEMETRY === "1";
|
|
141
|
+
}
|
|
116
142
|
function trackCliEvent(distinctId, event, properties = {}) {
|
|
143
|
+
if (telemetryDisabled()) return;
|
|
117
144
|
fetch("https://us.i.posthog.com/capture/", {
|
|
118
145
|
method: "POST",
|
|
119
146
|
headers: { "content-type": "application/json" },
|
|
@@ -148,7 +175,7 @@ program.command("login").description("Connect to Clawon with your API key").requ
|
|
|
148
175
|
process.exit(1);
|
|
149
176
|
}
|
|
150
177
|
});
|
|
151
|
-
program.command("backup").description("Backup your OpenClaw workspace to the cloud").option("--dry-run", "Show what would be backed up without uploading").action(async (opts) => {
|
|
178
|
+
program.command("backup").description("Backup your OpenClaw workspace to the cloud").option("--dry-run", "Show what would be backed up without uploading").option("--tag <label>", "Add a label to this backup").action(async (opts) => {
|
|
152
179
|
const cfg = readConfig();
|
|
153
180
|
if (!cfg) {
|
|
154
181
|
console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
|
|
@@ -188,7 +215,8 @@ program.command("backup").description("Backup your OpenClaw workspace to the clo
|
|
|
188
215
|
cfg.apiKey,
|
|
189
216
|
{
|
|
190
217
|
profileId: cfg.profileId,
|
|
191
|
-
files: files.map((f) => ({ path: f.path, size: f.size }))
|
|
218
|
+
files: files.map((f) => ({ path: f.path, size: f.size })),
|
|
219
|
+
...opts.tag ? { tag: opts.tag } : {}
|
|
192
220
|
}
|
|
193
221
|
);
|
|
194
222
|
console.log(`Uploading ${files.length} files...`);
|
|
@@ -311,13 +339,14 @@ program.command("list").description("List your backups").option("--limit <n>", "
|
|
|
311
339
|
return;
|
|
312
340
|
}
|
|
313
341
|
console.log("Your backups:\n");
|
|
314
|
-
console.log("ID | Date | Files | Size");
|
|
315
|
-
console.log("\u2500".repeat(
|
|
342
|
+
console.log("ID | Date | Files | Size | Tag");
|
|
343
|
+
console.log("\u2500".repeat(100));
|
|
316
344
|
for (const s of snapshots) {
|
|
317
345
|
const date = new Date(s.created_at).toLocaleString();
|
|
318
346
|
const size = s.size_bytes ? `${(s.size_bytes / 1024).toFixed(1)} KB` : "N/A";
|
|
319
347
|
const files = s.changed_files_count || "N/A";
|
|
320
|
-
|
|
348
|
+
const tag = s.tag || "";
|
|
349
|
+
console.log(`${s.id} | ${date.padEnd(20)} | ${String(files).padEnd(5)} | ${String(size).padEnd(8)} | ${tag}`);
|
|
321
350
|
}
|
|
322
351
|
console.log(`
|
|
323
352
|
Total: ${snapshots.length} backup(s)`);
|
|
@@ -422,6 +451,36 @@ program.command("delete [id]").description("Delete a snapshot").option("--oldest
|
|
|
422
451
|
process.exit(1);
|
|
423
452
|
}
|
|
424
453
|
});
|
|
454
|
+
program.command("discover").description("Preview which files would be included in a backup").action(async () => {
|
|
455
|
+
if (!fs.existsSync(OPENCLAW_DIR)) {
|
|
456
|
+
console.error(`\u2717 OpenClaw directory not found: ${OPENCLAW_DIR}`);
|
|
457
|
+
process.exit(1);
|
|
458
|
+
}
|
|
459
|
+
const files = discoverFiles(OPENCLAW_DIR);
|
|
460
|
+
if (files.length === 0) {
|
|
461
|
+
console.log("No files matched the include patterns.");
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
465
|
+
const tree = {};
|
|
466
|
+
for (const f of files) {
|
|
467
|
+
const dir = path.dirname(f.path);
|
|
468
|
+
if (!tree[dir]) tree[dir] = [];
|
|
469
|
+
tree[dir].push(f);
|
|
470
|
+
}
|
|
471
|
+
console.log(`Files that would be backed up:
|
|
472
|
+
`);
|
|
473
|
+
for (const dir of Object.keys(tree).sort()) {
|
|
474
|
+
console.log(`\u{1F4C1} ${dir}/`);
|
|
475
|
+
for (const f of tree[dir]) {
|
|
476
|
+
const name = path.basename(f.path);
|
|
477
|
+
console.log(` \u{1F4C4} ${name} (${f.size} bytes)`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
console.log(`
|
|
481
|
+
Total: ${files.length} files (${(totalSize / 1024).toFixed(1)} KB)`);
|
|
482
|
+
console.log(`Source: ${OPENCLAW_DIR}`);
|
|
483
|
+
});
|
|
425
484
|
program.command("files").description("List files in a backup").option("--snapshot <id>", "Snapshot ID (default: latest)").action(async (opts) => {
|
|
426
485
|
const cfg = readConfig();
|
|
427
486
|
if (!cfg) {
|
|
@@ -463,7 +522,7 @@ Total: ${files.length} files`);
|
|
|
463
522
|
}
|
|
464
523
|
});
|
|
465
524
|
var local = program.command("local").description("Local backup and restore (no cloud required)");
|
|
466
|
-
local.command("backup").description("Save a local backup of your OpenClaw workspace").action(async () => {
|
|
525
|
+
local.command("backup").description("Save a local backup of your OpenClaw workspace").option("--tag <label>", "Add a label to this backup").action(async (opts) => {
|
|
467
526
|
if (!fs.existsSync(OPENCLAW_DIR)) {
|
|
468
527
|
console.error(`\u2717 OpenClaw directory not found: ${OPENCLAW_DIR}`);
|
|
469
528
|
process.exit(1);
|
|
@@ -476,18 +535,19 @@ local.command("backup").description("Save a local backup of your OpenClaw worksp
|
|
|
476
535
|
}
|
|
477
536
|
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
478
537
|
console.log(`Found ${files.length} files (${(totalSize / 1024).toFixed(1)} KB)`);
|
|
479
|
-
console.log("Creating archive...");
|
|
480
|
-
const archive = createLocalArchive(files, OPENCLAW_DIR);
|
|
481
538
|
ensureDir(BACKUPS_DIR);
|
|
482
539
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace("T", "T").slice(0, 15);
|
|
483
540
|
const filename = `backup-${timestamp}.tar.gz`;
|
|
484
541
|
const filePath = path.join(BACKUPS_DIR, filename);
|
|
485
|
-
|
|
542
|
+
console.log("Creating archive...");
|
|
543
|
+
await createLocalArchive(files, OPENCLAW_DIR, filePath, opts.tag);
|
|
544
|
+
const archiveSize = fs.statSync(filePath).size;
|
|
486
545
|
console.log(`
|
|
487
546
|
\u2713 Local backup saved!`);
|
|
488
547
|
console.log(` File: ${filePath}`);
|
|
489
548
|
console.log(` Files: ${files.length}`);
|
|
490
|
-
console.log(` Size: ${(
|
|
549
|
+
console.log(` Size: ${(archiveSize / 1024).toFixed(1)} KB (compressed)`);
|
|
550
|
+
if (opts.tag) console.log(` Tag: ${opts.tag}`);
|
|
491
551
|
const cfg = readConfig();
|
|
492
552
|
trackCliEvent(cfg?.profileId || "anonymous", "local_backup_created", {
|
|
493
553
|
file_count: files.length,
|
|
@@ -505,19 +565,21 @@ local.command("list").description("List local backups").action(async () => {
|
|
|
505
565
|
return;
|
|
506
566
|
}
|
|
507
567
|
console.log("Local backups:\n");
|
|
508
|
-
console.log("# | Date | Files | Size | Path");
|
|
509
|
-
console.log("\u2500".repeat(
|
|
568
|
+
console.log("# | Date | Files | Size | Tag | Path");
|
|
569
|
+
console.log("\u2500".repeat(120));
|
|
510
570
|
for (let i = 0; i < entries.length; i++) {
|
|
511
571
|
const filePath = path.join(BACKUPS_DIR, entries[i]);
|
|
512
572
|
try {
|
|
513
|
-
const
|
|
514
|
-
const
|
|
515
|
-
const
|
|
573
|
+
const meta = await readArchiveMeta(filePath);
|
|
574
|
+
const date = new Date(meta.created).toLocaleString();
|
|
575
|
+
const archiveSize = fs.statSync(filePath).size;
|
|
576
|
+
const sizeStr = `${(archiveSize / 1024).toFixed(1)} KB`;
|
|
577
|
+
const tagStr = (meta.tag || "").padEnd(20);
|
|
516
578
|
console.log(
|
|
517
|
-
`${String(i + 1).padStart(2)} | ${date.padEnd(25)} | ${String(
|
|
579
|
+
`${String(i + 1).padStart(2)} | ${date.padEnd(25)} | ${String(meta.file_count).padEnd(5)} | ${sizeStr.padEnd(10)} | ${tagStr} | ${filePath}`
|
|
518
580
|
);
|
|
519
581
|
} catch {
|
|
520
|
-
console.log(`${String(i + 1).padStart(2)} | ${entries[i].padEnd(25)} | ??? | ??? | ${filePath}`);
|
|
582
|
+
console.log(`${String(i + 1).padStart(2)} | ${entries[i].padEnd(25)} | ??? | ??? | | ${filePath}`);
|
|
521
583
|
}
|
|
522
584
|
}
|
|
523
585
|
console.log(`
|
|
@@ -559,26 +621,19 @@ local.command("restore").description("Restore from a local backup").option("--fi
|
|
|
559
621
|
}
|
|
560
622
|
console.log(`Restoring from: ${archivePath}`);
|
|
561
623
|
try {
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
console.log(`
|
|
565
|
-
console.log(`
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
const targetPath = path.join(OPENCLAW_DIR, file.path);
|
|
569
|
-
ensureDir(path.dirname(targetPath));
|
|
570
|
-
fs.writeFileSync(targetPath, Buffer.from(file.content, "base64"));
|
|
571
|
-
restored++;
|
|
572
|
-
process.stdout.write(`\r Restored: ${restored}/${files.length}`);
|
|
573
|
-
}
|
|
574
|
-
console.log("");
|
|
624
|
+
const meta = await readArchiveMeta(archivePath);
|
|
625
|
+
console.log(`Backup date: ${new Date(meta.created).toLocaleString()}`);
|
|
626
|
+
console.log(`Files: ${meta.file_count}`);
|
|
627
|
+
if (meta.tag) console.log(`Tag: ${meta.tag}`);
|
|
628
|
+
console.log("\nExtracting...");
|
|
629
|
+
await extractLocalArchive(archivePath, OPENCLAW_DIR);
|
|
575
630
|
console.log(`
|
|
576
631
|
\u2713 Restore complete!`);
|
|
577
632
|
console.log(` Restored to: ${OPENCLAW_DIR}`);
|
|
578
|
-
console.log(` Files: ${
|
|
633
|
+
console.log(` Files: ${meta.file_count}`);
|
|
579
634
|
const cfg = readConfig();
|
|
580
635
|
trackCliEvent(cfg?.profileId || "anonymous", "local_backup_restored", {
|
|
581
|
-
file_count:
|
|
636
|
+
file_count: meta.file_count,
|
|
582
637
|
source: opts.file ? "file" : "local"
|
|
583
638
|
});
|
|
584
639
|
} catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Backup and restore your OpenClaw workspace",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
],
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"commander": "^12.1.0"
|
|
27
|
+
"commander": "^12.1.0",
|
|
28
|
+
"tar": "^7.5.10"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"tsup": "^8.2.4",
|