@claude-sync/cli 0.1.11 → 0.1.13
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 +136 -0
- package/dist/bin/claude-sync.js +42 -5
- package/dist/bin/claude-sync.js.map +1 -1
- package/dist/src/index.js +42 -5
- package/dist/src/index.js.map +1 -1
- package/package.json +10 -8
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://claude-sync.com">
|
|
3
|
+
<img src="https://claude-sync.com/opengraph-image" alt="Claude Sync" width="600" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">Claude Sync CLI</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>🔄 Never lose your Claude Code sessions again.</strong><br>
|
|
11
|
+
Seamlessly sync your AI conversations across all your machines.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://claude-sync.com">🌐 Website</a> •
|
|
16
|
+
<a href="https://claude-sync.com/docs">📚 Docs</a> •
|
|
17
|
+
<a href="https://claude-sync.com/dashboard">📊 Dashboard</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="https://img.shields.io/endpoint?url=https://api.claude-sync.com/api/stats/shields/developers&style=flat-square&color=6366f1" alt="Developers" />
|
|
22
|
+
<img src="https://img.shields.io/endpoint?url=https://api.claude-sync.com/api/stats/shields/devices&style=flat-square&color=22c55e" alt="Devices" />
|
|
23
|
+
<img src="https://img.shields.io/npm/v/@claude-sync/cli?style=flat-square&color=f97316" alt="npm version" />
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 😤 The Problem
|
|
29
|
+
|
|
30
|
+
You're deep in a Claude Code session on your laptop. Hours of context, perfect understanding of your codebase, brilliant solutions flowing. Then you need to switch to your desktop.
|
|
31
|
+
|
|
32
|
+
**Gone.** All that context. All that history. Start over.
|
|
33
|
+
|
|
34
|
+
## ✨ The Solution
|
|
35
|
+
|
|
36
|
+
**Claude Sync** keeps your Claude Code sessions synchronized across all your devices. Push from your laptop, pull from your desktop. Your AI remembers everything.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# On your laptop
|
|
40
|
+
claude-sync sync
|
|
41
|
+
|
|
42
|
+
# On your desktop
|
|
43
|
+
claude-sync sync
|
|
44
|
+
# → "Continue from another machine?" ✓
|
|
45
|
+
# → Select your laptop
|
|
46
|
+
# → All your sessions, right there 🎉
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 📦 Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g @claude-sync/cli
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 🚀 Quick Start
|
|
56
|
+
|
|
57
|
+
### 1️⃣ Create an account
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
claude-sync login
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Opens your browser to sign in with GitHub, Google, or email.
|
|
64
|
+
|
|
65
|
+
### 2️⃣ Register your device
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
claude-sync device add
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Give your machine a name (e.g., "MacBook Pro", "Home Desktop").
|
|
72
|
+
|
|
73
|
+
### 3️⃣ Sync your sessions
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cd /path/to/your/project
|
|
77
|
+
claude-sync sync
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
That's it! Your Claude Code sessions are now backed up and available everywhere. 🎊
|
|
81
|
+
|
|
82
|
+
## 📋 Commands
|
|
83
|
+
|
|
84
|
+
| Command | Description |
|
|
85
|
+
|---------|-------------|
|
|
86
|
+
| `claude-sync login` | 🔐 Sign in to your account |
|
|
87
|
+
| `claude-sync logout` | 👋 Sign out |
|
|
88
|
+
| `claude-sync device add` | 💻 Register this machine |
|
|
89
|
+
| `claude-sync device list` | 📱 List your devices |
|
|
90
|
+
| `claude-sync sync` | 🔄 Sync current project |
|
|
91
|
+
| `claude-sync status` | 📊 Check sync status |
|
|
92
|
+
| `claude-sync whoami` | 👤 Show current user |
|
|
93
|
+
|
|
94
|
+
## ⚙️ How It Works
|
|
95
|
+
|
|
96
|
+
1. **📤 Push** — Upload your local Claude Code sessions to the cloud
|
|
97
|
+
2. **📥 Pull** — Download sessions from your other devices
|
|
98
|
+
3. **🔀 Merge** — Smart conflict resolution keeps everything in sync
|
|
99
|
+
|
|
100
|
+
Your sessions are encrypted and stored securely. Only you can access them. 🔒
|
|
101
|
+
|
|
102
|
+
## 🌟 Features
|
|
103
|
+
|
|
104
|
+
- **🖥️ Cross-Platform** — Works on macOS, Linux, and Windows
|
|
105
|
+
- **🔐 Secure** — End-to-end encryption for your sessions
|
|
106
|
+
- **⚡ Fast** — Only syncs what's changed
|
|
107
|
+
- **🎯 Simple** — One command to sync everything
|
|
108
|
+
|
|
109
|
+
## 📋 Requirements
|
|
110
|
+
|
|
111
|
+
- Node.js 18+
|
|
112
|
+
- Claude Code installed
|
|
113
|
+
- A Claude Sync account (free tier available)
|
|
114
|
+
|
|
115
|
+
## 🔗 Links
|
|
116
|
+
|
|
117
|
+
| | |
|
|
118
|
+
|---|---|
|
|
119
|
+
| 🌐 Website | [claude-sync.com](https://claude-sync.com) |
|
|
120
|
+
| 📊 Dashboard | [claude-sync.com/dashboard](https://claude-sync.com/dashboard) |
|
|
121
|
+
| 📚 Documentation | [claude-sync.com/docs](https://claude-sync.com/docs) |
|
|
122
|
+
| 💡 Feature Requests | [claude-sync.com/requests](https://claude-sync.com/requests) |
|
|
123
|
+
|
|
124
|
+
## 💬 Support
|
|
125
|
+
|
|
126
|
+
Having issues? We're here to help!
|
|
127
|
+
|
|
128
|
+
- 📧 Email: [support@claude-sync.com](mailto:support@claude-sync.com)
|
|
129
|
+
- 💡 Feature Requests: [claude-sync.com/requests](https://claude-sync.com/requests)
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
<p align="center">
|
|
134
|
+
Made with ❤️ for developers who live in the terminal.<br>
|
|
135
|
+
<a href="https://claude-sync.com"><strong>claude-sync.com</strong></a>
|
|
136
|
+
</p>
|
package/dist/bin/claude-sync.js
CHANGED
|
@@ -5166,7 +5166,7 @@ __export(sync_exports, {
|
|
|
5166
5166
|
});
|
|
5167
5167
|
import { Command as Command4 } from "commander";
|
|
5168
5168
|
import { select as select2, isCancel as isCancel3 } from "@clack/prompts";
|
|
5169
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, lstat as lstat2, symlink, unlink } from "fs/promises";
|
|
5169
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, lstat as lstat2, symlink, unlink, rename } from "fs/promises";
|
|
5170
5170
|
import { join as join3, dirname as dirname2 } from "path";
|
|
5171
5171
|
import { homedir as homedir4 } from "os";
|
|
5172
5172
|
async function runSync(options) {
|
|
@@ -5330,6 +5330,10 @@ async function handleFirstRun(client, config, cwd, ctx, manifest, projectDir, pr
|
|
|
5330
5330
|
});
|
|
5331
5331
|
if (isCancel3(projectChoice)) return "cancelled";
|
|
5332
5332
|
const selectedProject = projects.find((p) => p.id === projectChoice);
|
|
5333
|
+
const existingCheck = await handleExistingSessionDir(projectsDir, ctx.encodedPath);
|
|
5334
|
+
if (existingCheck === "cancelled") {
|
|
5335
|
+
return "cancelled";
|
|
5336
|
+
}
|
|
5333
5337
|
const downloaded = await crossMachinePull(
|
|
5334
5338
|
client,
|
|
5335
5339
|
config.deviceId,
|
|
@@ -5356,6 +5360,43 @@ async function handleFirstRun(client, config, cwd, ctx, manifest, projectDir, pr
|
|
|
5356
5360
|
}
|
|
5357
5361
|
return "pulled";
|
|
5358
5362
|
}
|
|
5363
|
+
async function handleExistingSessionDir(projectsDir, localEncoded) {
|
|
5364
|
+
const symlinkPath = join3(projectsDir, localEncoded);
|
|
5365
|
+
try {
|
|
5366
|
+
const stats = await lstat2(symlinkPath);
|
|
5367
|
+
if (stats.isSymbolicLink()) {
|
|
5368
|
+
return "continue";
|
|
5369
|
+
}
|
|
5370
|
+
if (stats.isDirectory()) {
|
|
5371
|
+
printInfo(brand("Local session directory already exists"));
|
|
5372
|
+
printInfo(dim(symlinkPath));
|
|
5373
|
+
const choice = await select2({
|
|
5374
|
+
message: brand("What would you like to do?"),
|
|
5375
|
+
options: [
|
|
5376
|
+
{
|
|
5377
|
+
value: "backup",
|
|
5378
|
+
label: "Backup and continue",
|
|
5379
|
+
hint: dim("Move existing to .bak and sync from remote")
|
|
5380
|
+
},
|
|
5381
|
+
{
|
|
5382
|
+
value: "cancel",
|
|
5383
|
+
label: "Stop sync",
|
|
5384
|
+
hint: dim("Keep existing local sessions")
|
|
5385
|
+
}
|
|
5386
|
+
]
|
|
5387
|
+
});
|
|
5388
|
+
if (isCancel3(choice) || choice === "cancel") {
|
|
5389
|
+
return "cancelled";
|
|
5390
|
+
}
|
|
5391
|
+
const backupPath = `${symlinkPath}.bak.${Date.now()}`;
|
|
5392
|
+
await rename(symlinkPath, backupPath);
|
|
5393
|
+
printSuccess(`Backed up to: ${dim(backupPath)}`);
|
|
5394
|
+
return "continue";
|
|
5395
|
+
}
|
|
5396
|
+
} catch {
|
|
5397
|
+
}
|
|
5398
|
+
return "continue";
|
|
5399
|
+
}
|
|
5359
5400
|
async function createProjectSymlink(projectsDir, localEncoded, foreignEncoded) {
|
|
5360
5401
|
const symlinkPath = join3(projectsDir, localEncoded);
|
|
5361
5402
|
await mkdir2(projectsDir, { recursive: true });
|
|
@@ -5363,10 +5404,6 @@ async function createProjectSymlink(projectsDir, localEncoded, foreignEncoded) {
|
|
|
5363
5404
|
const stats = await lstat2(symlinkPath);
|
|
5364
5405
|
if (stats.isSymbolicLink()) {
|
|
5365
5406
|
await unlink(symlinkPath);
|
|
5366
|
-
} else if (stats.isDirectory()) {
|
|
5367
|
-
printError(`Local session directory already exists. Back it up first:
|
|
5368
|
-
mv "${symlinkPath}" "${symlinkPath}.bak"`);
|
|
5369
|
-
return;
|
|
5370
5407
|
}
|
|
5371
5408
|
} catch {
|
|
5372
5409
|
}
|