claude-code-backup 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Muhammad Afzal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,473 @@
1
+ # claude-code-backup
2
+
3
+ > Never lose your Claude Code memory, settings, or project instructions again.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/claude-code-backup.svg)](https://www.npmjs.com/package/claude-code-backup)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
8
+ [![Platform](https://img.shields.io/badge/platform-macOS-lightgrey)](https://www.apple.com/macos/)
9
+
10
+ `claude-code-backup` is a CLI tool that watches your Claude Code data directories and automatically syncs every change to a **private GitHub repository**. Set it up once — it runs silently in the background on every login, committing your memory files, settings, keybindings, custom commands, and project `CLAUDE.md` files to Git so you always have a versioned, restorable history.
11
+
12
+ ---
13
+
14
+ ## Why This Exists
15
+
16
+ Claude Code stores your entire working relationship with Claude on disk:
17
+
18
+ | Data | Location | What you lose without it |
19
+ |---|---|---|
20
+ | **Memory files** | `~/.claude/projects/*/memory/*.md` | Everything Claude knows about you and your projects — rebuilt from scratch |
21
+ | **Settings** | `~/.claude/settings.json` | All configuration, permissions, hooks |
22
+ | **Keybindings** | `~/.claude/keybindings.json` | Custom keyboard shortcuts |
23
+ | **Custom commands** | `~/.claude/commands/` | Every slash command and skill you've built |
24
+ | **CLAUDE.md files** | `<project>/CLAUDE.md` | Project-specific instructions Claude reads every session |
25
+
26
+ None of this is synced by Anthropic. A new machine, an accidental `rm -rf ~/.claude`, or a corrupted filesystem means starting over. `claude-code-backup` fixes that.
27
+
28
+ ---
29
+
30
+ ## Features
31
+
32
+ - **Real-time sync** — [chokidar](https://github.com/paulmillr/chokidar) file watcher detects changes within milliseconds and pushes to GitHub after a configurable debounce
33
+ - **Full version history** — every backup is a Git commit, so you can restore any point in time
34
+ - **Project CLAUDE.md support** — backs up per-project `CLAUDE.md` files without touching your source code
35
+ - **Safe restore** — always creates a local snapshot of your current state before overwriting anything
36
+ - **macOS auto-start** — installs as a launchd service so the watcher starts on every login with `KeepAlive`
37
+ - **Interactive setup** — guided wizard creates the GitHub repo for you if it doesn't exist
38
+ - **Configurable** — choose which dirs to watch, which files to exclude, debounce timing
39
+ - **Private by default** — your backup repo is always created as private
40
+
41
+ ---
42
+
43
+ ## Requirements
44
+
45
+ - **Node.js** 18 or later
46
+ - **macOS** (launchd service feature; file watching works on Linux/Windows too)
47
+ - **GitHub account** with a Personal Access Token
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ npm install -g claude-code-backup
55
+ ```
56
+
57
+ Installs the `claude-backup` command globally.
58
+
59
+ ---
60
+
61
+ ## Quick Start
62
+
63
+ ```bash
64
+ # 1. Run the setup wizard
65
+ claude-backup init
66
+
67
+ # 2. Do your first manual backup
68
+ claude-backup push
69
+
70
+ # 3. Install the background service (auto-syncs on every login)
71
+ claude-backup service install
72
+
73
+ # 4. Check everything is working
74
+ claude-backup status
75
+ ```
76
+
77
+ That's it. From this point the watcher runs silently in the background and pushes every change to your private GitHub repo.
78
+
79
+ ---
80
+
81
+ ## Setup Wizard (`init`)
82
+
83
+ ```
84
+ $ claude-backup init
85
+
86
+ Claude Backup — Setup Wizard
87
+
88
+ Step 1 of 4 — GitHub Personal Access Token
89
+
90
+ claude-backup needs a PAT with "repo" scope to create
91
+ and push to a private GitHub repository on your behalf.
92
+
93
+ Create your token here:
94
+ https://github.com/settings/tokens/new
95
+
96
+ Instructions:
97
+ 1. Note name → e.g. "claude-backup"
98
+ 2. Expiration → your preference (No expiration is fine)
99
+ 3. Scopes → tick repo (the top-level checkbox)
100
+ 4. Click "Generate token" and copy the value
101
+
102
+ ? Paste your GitHub PAT: ****
103
+
104
+ Step 2 of 4 — Repository & Branch
105
+ ? GitHub repo name (e.g. yourname/claude-backup): yourname/claude-backup
106
+ ? Branch name: main
107
+
108
+ Step 3 of 4 — Watched Directories & Filters
109
+ ? Directories to watch: /Users/you/.claude
110
+ ? Files to exclude: settings.local.json, *.log, .DS_Store
111
+ ? Debounce delay in ms: 2000
112
+
113
+ Step 4 of 4 — Project CLAUDE.md Files
114
+ ? Project root directories with CLAUDE.md (blank to skip): /Users/you/projects/my-app
115
+
116
+ ✔ Config saved
117
+ ✔ Created: github.com/yourname/claude-backup
118
+ ✔ Repo cloned
119
+ ✔ GitHub setup complete
120
+ ```
121
+
122
+ The wizard:
123
+ - Creates the GitHub repo as **private** if it doesn't exist
124
+ - Clones it locally to `~/.config/claude-backup/repo/`
125
+ - Writes a detailed `README.md` into your backup repo documenting the structure and restore process
126
+
127
+ ---
128
+
129
+ ## Command Reference
130
+
131
+ ### `claude-backup init`
132
+
133
+ Interactive setup wizard. Run once to configure, or again at any time to update settings.
134
+
135
+ ```bash
136
+ claude-backup init
137
+ ```
138
+
139
+ ---
140
+
141
+ ### `claude-backup push`
142
+
143
+ Manually push a backup to GitHub right now.
144
+
145
+ ```bash
146
+ claude-backup push # auto commit message: "backup: <ISO timestamp>"
147
+ claude-backup push -m "before OS upgrade" # custom commit message
148
+ ```
149
+
150
+ What it does:
151
+ 1. Walks all watched directories, applies exclude filters
152
+ 2. Copies every file into the local repo clone under a labelled directory
153
+ 3. Collects `CLAUDE.md` from each configured project root
154
+ 4. Writes `backup-manifest.json` (maps labels back to source paths for restore)
155
+ 5. Regenerates the backup repo `README.md`
156
+ 6. `git add -A` → `git commit` → `git push`
157
+ 7. Skips the push if nothing has changed
158
+
159
+ ---
160
+
161
+ ### `claude-backup pull`
162
+
163
+ Restore files from your GitHub backup.
164
+
165
+ ```bash
166
+ claude-backup pull # restore the latest backup
167
+ claude-backup pull --history # browse commits, pick a specific version
168
+ claude-backup pull --dry-run # preview what would change — no files written
169
+ ```
170
+
171
+ **Safety:** before touching any file, `pull` creates a timestamped snapshot of your current state at `~/.config/claude-backup/pre-restore-<timestamp>/`. You can always manually recover from there.
172
+
173
+ Restore works on:
174
+ - **Same machine** — recover from accidental deletion
175
+ - **New machine** — run `init` with the same repo, then `pull`
176
+ - **Historical version** — use `--history` to pick any commit
177
+
178
+ ---
179
+
180
+ ### `claude-backup watch`
181
+
182
+ Start the real-time file watcher. Normally this runs via the launchd service — use this command to run it manually in the foreground.
183
+
184
+ ```bash
185
+ claude-backup watch # file watcher (recommended)
186
+ claude-backup watch --interval 5 # poll every 5 minutes instead
187
+ ```
188
+
189
+ The watcher:
190
+ - Detects changes using [chokidar](https://github.com/paulmillr/chokidar)
191
+ - Waits for the debounce period (default 2 s) after the last change before pushing
192
+ - Ignores `.git` directories to avoid feedback loops
193
+ - Handles `SIGTERM`/`SIGINT` gracefully
194
+
195
+ ---
196
+
197
+ ### `claude-backup status`
198
+
199
+ Show the current state of your backup.
200
+
201
+ ```
202
+ $ claude-backup status
203
+
204
+ Claude Backup Status
205
+
206
+ Watched dirs:
207
+ /Users/you/.claude
208
+ Files tracked: 42
209
+
210
+ Project CLAUDE.md dirs:
211
+ /Users/you/projects/my-app
212
+ CLAUDE.md files: 1
213
+
214
+ GitHub: yourname/claude-backup [main]
215
+ Last backup: 2026-05-18 10:34:22
216
+ Commit: a3f9c1d backup: 2026-05-18T10:34:22.000Z
217
+ Sync status: Up to date
218
+
219
+ Auto-sync service: running (PID 4821)
220
+ ```
221
+
222
+ ---
223
+
224
+ ### `claude-backup service <action>`
225
+
226
+ Manage the macOS launchd background service.
227
+
228
+ ```bash
229
+ claude-backup service install # write plist, load service, start immediately
230
+ claude-backup service uninstall # stop service, remove plist
231
+ claude-backup service status # check if running, show PID
232
+ claude-backup service logs # tail the watcher log in real-time
233
+ ```
234
+
235
+ The service plist is installed at:
236
+
237
+ ```
238
+ ~/Library/LaunchAgents/com.claude-backup.watch.plist
239
+ ```
240
+
241
+ Key behaviour:
242
+ - `RunAtLoad: true` — starts immediately when installed, and on every login
243
+ - `KeepAlive: true` — launchd restarts the watcher automatically if it crashes
244
+ - `ThrottleInterval: 10` — prevents restart storms
245
+ - Logs go to `~/.config/claude-backup/watch.log`
246
+ - Errors go to `~/.config/claude-backup/watch.error.log`
247
+
248
+ ---
249
+
250
+ ### `claude-backup config <action>`
251
+
252
+ View or modify configuration without re-running `init`.
253
+
254
+ ```bash
255
+ claude-backup config show # print config (PAT masked)
256
+ claude-backup config set auto_sync.debounce_ms 3000 # change a value
257
+ claude-backup config add-dir <path> # fully mirror an extra directory
258
+ claude-backup config remove-dir <path>
259
+ claude-backup config add-project <path> # back up only CLAUDE.md from a project root
260
+ claude-backup config remove-project <path>
261
+ ```
262
+
263
+ ---
264
+
265
+ ## CLAUDE.md Backup
266
+
267
+ Claude Code lets you put a `CLAUDE.md` file at any project root. Claude reads it at the start of every session — it's where you define project-specific context, conventions, and rules.
268
+
269
+ `claude-code-backup` backs these up separately from your source code: only the `CLAUDE.md` file is collected, not the rest of the project directory.
270
+
271
+ ```bash
272
+ # Add a project during init (Step 4)
273
+ # Or add it later:
274
+ claude-backup config add-project /Users/you/projects/my-app
275
+ ```
276
+
277
+ In the backup repo, it appears as:
278
+
279
+ ```
280
+ claude_md_Users_you_projects_my-app/
281
+ CLAUDE.md
282
+ ```
283
+
284
+ On restore, it goes straight back to `/Users/you/projects/my-app/CLAUDE.md`.
285
+
286
+ ---
287
+
288
+ ## Backup Repo Structure
289
+
290
+ Your private GitHub backup repo looks like this:
291
+
292
+ ```
293
+ /
294
+ ├── README.md ← auto-generated usage guide
295
+ ├── backup-manifest.json ← label → source path mapping
296
+
297
+ ├── Users_<name>_.claude/ ← full mirror of ~/.claude/
298
+ │ ├── settings.json
299
+ │ ├── keybindings.json
300
+ │ ├── projects/
301
+ │ │ └── <hash>/
302
+ │ │ └── memory/
303
+ │ │ ├── MEMORY.md
304
+ │ │ └── *.md
305
+ │ └── commands/
306
+ │ └── *.md
307
+
308
+ └── claude_md_Users_<name>_projects_myapp/
309
+ └── CLAUDE.md
310
+ ```
311
+
312
+ Every push is a Git commit — you get full history, diffs, and can restore any point in time.
313
+
314
+ ---
315
+
316
+ ## Configuration Reference
317
+
318
+ Config file: `~/.config/claude-backup/config.json` (chmod 600)
319
+
320
+ | Key | Type | Default | Description |
321
+ |---|---|---|---|
322
+ | `github.repo` | string | — | GitHub repo in `owner/name` format |
323
+ | `github.branch` | string | `"main"` | Branch to push to |
324
+ | `github.pat` | string | — | Personal Access Token (never committed) |
325
+ | `watched_dirs` | string[] | `["~/.claude"]` | Directories to fully mirror |
326
+ | `claude_md_dirs` | string[] | `[]` | Project roots — only `CLAUDE.md` backed up |
327
+ | `exclude` | string[] | see below | Filenames/globs to skip |
328
+ | `auto_sync.debounce_ms` | number | `2000` | ms to wait after last change before pushing |
329
+
330
+ Default excludes: `settings.local.json`, `*.log`, `.DS_Store`
331
+
332
+ Local repo clone: `~/.config/claude-backup/repo/`
333
+
334
+ ---
335
+
336
+ ## Restore Guide
337
+
338
+ ### After accidental deletion (same machine)
339
+
340
+ ```bash
341
+ claude-backup pull
342
+ ```
343
+
344
+ ### Setting up a new machine
345
+
346
+ ```bash
347
+ npm install -g claude-code-backup
348
+ claude-backup init # use same repo name, generate a new PAT
349
+ claude-backup pull
350
+ claude-backup service install
351
+ ```
352
+
353
+ ### Restoring a specific historical version
354
+
355
+ ```bash
356
+ claude-backup pull --history
357
+ ```
358
+
359
+ Shows a list of all commits — pick the one you want by timestamp and message.
360
+
361
+ ### Undoing a restore
362
+
363
+ Every `pull` creates a safety snapshot first:
364
+
365
+ ```bash
366
+ ls ~/.config/claude-backup/pre-restore-*/
367
+ # Copy what you need back manually
368
+ ```
369
+
370
+ ---
371
+
372
+ ## Troubleshooting
373
+
374
+ **"Not configured. Run: claude-backup init"**
375
+ Config file is missing. Re-run `claude-backup init`.
376
+
377
+ **Push fails with 401 or authentication error**
378
+ Your PAT may have expired. Generate a new one and update:
379
+ ```bash
380
+ claude-backup config set github.pat <new-token>
381
+ claude-backup service install # restart the watcher with the new token
382
+ ```
383
+
384
+ **Service shows "loaded but not running"**
385
+ ```bash
386
+ claude-backup service logs
387
+ cat ~/.config/claude-backup/watch.error.log
388
+ claude-backup service install # reinstall to reset
389
+ ```
390
+
391
+ **Changes not being detected**
392
+ Confirm the directory is watched:
393
+ ```bash
394
+ claude-backup config show
395
+ claude-backup config add-dir /missing/path
396
+ ```
397
+
398
+ **Want to watch a project directory without backing up all source code**
399
+ Use `add-project` instead of `add-dir` — it only collects the `CLAUDE.md` file:
400
+ ```bash
401
+ claude-backup config add-project /path/to/project
402
+ ```
403
+
404
+ ---
405
+
406
+ ## How It Works
407
+
408
+ ```
409
+ ~/.claude/ (file changes)
410
+
411
+
412
+ chokidar watcher
413
+ │ debounce 2s
414
+
415
+ collectFiles()
416
+ ├─ walk watched_dirs recursively
417
+ └─ grab CLAUDE.md from claude_md_dirs
418
+
419
+
420
+ copy to ~/.config/claude-backup/repo/
421
+ write backup-manifest.json
422
+ write README.md
423
+
424
+
425
+ git add -A → git commit → git push
426
+
427
+
428
+ github.com/you/claude-backup (private)
429
+ ```
430
+
431
+ ---
432
+
433
+ ## Contributing
434
+
435
+ Contributions are welcome. Please open an issue first for any significant change.
436
+
437
+ ```bash
438
+ git clone https://github.com/mafzal9/claude-code-backup.git
439
+ cd claude-code-backup
440
+ npm install
441
+ node bin/claude-backup.js --help
442
+ ```
443
+
444
+ Ideas for future contributions:
445
+ - Google Drive backend
446
+ - Linux systemd service support
447
+ - Windows Task Scheduler support
448
+ - Encryption at rest before pushing
449
+ - Selective restore (pick individual files)
450
+ - Diff view before restore
451
+
452
+ ---
453
+
454
+ ## License
455
+
456
+ MIT — see [LICENSE](LICENSE)
457
+
458
+ Copyright © 2026 Muhammad Afzal
459
+
460
+ ---
461
+
462
+ ## Author
463
+
464
+ **Muhammad Afzal**
465
+
466
+ [![X / Twitter](https://img.shields.io/badge/X-%40AfzalBuilds-black?logo=x&logoColor=white)](https://x.com/AfzalBuilds)
467
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-mafzal9-0077B5?logo=linkedin&logoColor=white)](https://www.linkedin.com/in/mafzal9/)
468
+ [![YouTube](https://img.shields.io/badge/YouTube-%40AfzalBuilds-FF0000?logo=youtube&logoColor=white)](https://www.youtube.com/@AfzalBuilds)
469
+ [![GitHub](https://img.shields.io/badge/GitHub-mafzal9-181717?logo=github&logoColor=white)](https://github.com/mafzal9/)
470
+
471
+ ---
472
+
473
+ *Built for the Claude Code community. If this saved your memory files, give it a star ⭐*
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander';
4
+ import { runInit } from '../src/commands/init.js';
5
+ import { runPush } from '../src/commands/push.js';
6
+ import { runPull } from '../src/commands/pull.js';
7
+ import { runWatch } from '../src/commands/watch.js';
8
+ import { runStatus } from '../src/commands/status.js';
9
+ import { runService } from '../src/commands/service.js';
10
+ import { runConfig } from '../src/commands/config-cmd.js';
11
+
12
+ program
13
+ .name('claude-backup')
14
+ .description('Backup and auto-sync Claude Code memory and settings to GitHub')
15
+ .version('1.0.0');
16
+
17
+ program
18
+ .command('init')
19
+ .description('Interactive setup — configure GitHub repo and watched directories')
20
+ .action(runInit);
21
+
22
+ program
23
+ .command('push')
24
+ .description('Manually push a backup to GitHub right now')
25
+ .option('-m, --message <msg>', 'Custom commit message')
26
+ .action(runPush);
27
+
28
+ program
29
+ .command('pull')
30
+ .description('Restore files from a GitHub backup')
31
+ .option('--dry-run', 'Preview what would be restored without writing any files')
32
+ .option('--history', 'Browse commit history and pick a specific version to restore')
33
+ .action(runPull);
34
+
35
+ program
36
+ .command('watch')
37
+ .description('Start the file watcher — auto-syncs changes to GitHub')
38
+ .option('--interval <minutes>', 'Poll every N minutes instead of real-time file watching')
39
+ .action(runWatch);
40
+
41
+ program
42
+ .command('status')
43
+ .description('Show last backup time and any pending local changes')
44
+ .action(runStatus);
45
+
46
+ program
47
+ .command('service <action>')
48
+ .description('Manage the launchd background service: install | uninstall | status | logs')
49
+ .action(runService);
50
+
51
+ program
52
+ .command('config <action> [key] [value]')
53
+ .description('Manage config: show | set <key> <value> | add-dir <path> | remove-dir <path>')
54
+ .action(runConfig);
55
+
56
+ program.parseAsync();
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "claude-code-backup",
3
+ "version": "1.0.0",
4
+ "description": "Backup and auto-sync Claude Code memory, settings, and CLAUDE.md files to a private GitHub repo — with real-time file watching and macOS launchd auto-start",
5
+ "type": "module",
6
+ "bin": {
7
+ "claude-backup": "./bin/claude-backup.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "engines": {
16
+ "node": ">=18.0.0"
17
+ },
18
+ "keywords": [
19
+ "claude",
20
+ "claude-code",
21
+ "anthropic",
22
+ "backup",
23
+ "sync",
24
+ "github",
25
+ "memory",
26
+ "settings",
27
+ "cli",
28
+ "devtools",
29
+ "macos"
30
+ ],
31
+ "author": {
32
+ "name": "Muhammad Afzal",
33
+ "email": "digitalstorks00@gmail.com",
34
+ "url": "https://github.com/mafzal9"
35
+ },
36
+ "license": "MIT",
37
+ "homepage": "https://github.com/mafzal9/claude-code-backup#readme",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/mafzal9/claude-code-backup.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/mafzal9/claude-code-backup/issues"
44
+ },
45
+ "dependencies": {
46
+ "@octokit/rest": "^21.0.2",
47
+ "chalk": "^5.3.0",
48
+ "chokidar": "^3.6.0",
49
+ "commander": "^12.1.0",
50
+ "inquirer": "^9.3.7",
51
+ "ora": "^8.1.1",
52
+ "simple-git": "^3.27.0"
53
+ }
54
+ }