@tawandotorg/claude-sync 0.4.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/.githooks/pre-commit +31 -0
- package/.releaserc.json +23 -0
- package/CHANGELOG.md +62 -0
- package/README.md +291 -0
- package/bin/claude-sync.js +36 -0
- package/install.js +116 -0
- package/package.json +45 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
echo "Running pre-commit checks..."
|
|
6
|
+
|
|
7
|
+
# Run go fmt
|
|
8
|
+
echo "Checking formatting..."
|
|
9
|
+
UNFORMATTED=$(gofmt -l .)
|
|
10
|
+
if [ -n "$UNFORMATTED" ]; then
|
|
11
|
+
echo "Error: The following files are not formatted:"
|
|
12
|
+
echo "$UNFORMATTED"
|
|
13
|
+
echo "Run 'go fmt ./...' to fix."
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Run go vet
|
|
18
|
+
echo "Running go vet..."
|
|
19
|
+
go vet ./...
|
|
20
|
+
|
|
21
|
+
# Run tests
|
|
22
|
+
echo "Running tests..."
|
|
23
|
+
go test ./... -short
|
|
24
|
+
|
|
25
|
+
# Run golangci-lint if available
|
|
26
|
+
if command -v golangci-lint &> /dev/null; then
|
|
27
|
+
echo "Running golangci-lint..."
|
|
28
|
+
golangci-lint run
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
echo "All checks passed!"
|
package/.releaserc.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": ["main"],
|
|
3
|
+
"plugins": [
|
|
4
|
+
"@semantic-release/commit-analyzer",
|
|
5
|
+
"@semantic-release/release-notes-generator",
|
|
6
|
+
"@semantic-release/changelog",
|
|
7
|
+
["@semantic-release/exec", {
|
|
8
|
+
"prepareCmd": "VERSION=${nextRelease.version} make build-all"
|
|
9
|
+
}],
|
|
10
|
+
["@semantic-release/git", {
|
|
11
|
+
"assets": ["CHANGELOG.md"],
|
|
12
|
+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
|
13
|
+
}],
|
|
14
|
+
["@semantic-release/github", {
|
|
15
|
+
"assets": [
|
|
16
|
+
{"path": "bin/claude-sync-darwin-arm64", "label": "claude-sync-darwin-arm64"},
|
|
17
|
+
{"path": "bin/claude-sync-darwin-amd64", "label": "claude-sync-darwin-amd64"},
|
|
18
|
+
{"path": "bin/claude-sync-linux-amd64", "label": "claude-sync-linux-amd64"},
|
|
19
|
+
{"path": "bin/claude-sync-linux-arm64", "label": "claude-sync-linux-arm64"}
|
|
20
|
+
]
|
|
21
|
+
}]
|
|
22
|
+
]
|
|
23
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# [0.4.0](https://github.com/tawanorg/claude-sync/compare/v0.3.2...v0.4.0) (2026-02-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* remove unused promptInput function ([0cf28ee](https://github.com/tawanorg/claude-sync/commit/0cf28eeca5a340e85c0ece250fa26a3db75c3cea))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* add multi-provider storage support (R2, S3, GCS) ([ded6fe8](https://github.com/tawanorg/claude-sync/commit/ded6fe8937dce96c77cba4cac9d904728047b5c1))
|
|
12
|
+
* add npm package for easy installation ([2e3c62f](https://github.com/tawanorg/claude-sync/commit/2e3c62f08e32a8b8171a0a27d6e0cc7d9410156a))
|
|
13
|
+
|
|
14
|
+
## [0.3.2](https://github.com/tawanorg/claude-sync/compare/v0.3.1...v0.3.2) (2026-02-08)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* use git tags for version instead of hardcoded value ([972f0e8](https://github.com/tawanorg/claude-sync/commit/972f0e8da314d47eaff64368c38d80fe5b4a0eca))
|
|
20
|
+
|
|
21
|
+
## [0.3.1](https://github.com/tawanorg/claude-sync/compare/v0.3.0...v0.3.1) (2026-02-08)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* handle unchecked error returns for linter ([2390505](https://github.com/tawanorg/claude-sync/commit/23905053d96612b43314e4291df644f6bc7763af))
|
|
27
|
+
|
|
28
|
+
# [0.3.0](https://github.com/tawanorg/claude-sync/compare/v0.2.1...v0.3.0) (2026-02-08)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
* add update command for self-updating CLI ([4c91357](https://github.com/tawanorg/claude-sync/commit/4c9135767dcafdf4b9d78b86e0dd3b84078b22bf))
|
|
34
|
+
|
|
35
|
+
## [0.2.1](https://github.com/tawanorg/claude-sync/compare/v0.2.0...v0.2.1) (2026-02-08)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Bug Fixes
|
|
39
|
+
|
|
40
|
+
* resolve deprecated API warnings ([f1c9559](https://github.com/tawanorg/claude-sync/commit/f1c955937034fe66449bcc87b1542d9c71c58eb7))
|
|
41
|
+
|
|
42
|
+
# [0.2.0](https://github.com/tawanorg/claude-sync/compare/v0.1.1...v0.2.0) (2026-02-08)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Features
|
|
46
|
+
|
|
47
|
+
* add reset command for forgot passphrase recovery ([3cd1cdb](https://github.com/tawanorg/claude-sync/commit/3cd1cdbd1964e108d312e2739fd4938f7a43eaf5))
|
|
48
|
+
|
|
49
|
+
## [0.1.1](https://github.com/tawanorg/claude-sync/compare/v0.1.0...v0.1.1) (2026-02-08)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Bug Fixes
|
|
53
|
+
|
|
54
|
+
* correct Go version to 1.21 in go.mod ([28146ef](https://github.com/tawanorg/claude-sync/commit/28146efb234b699ad96a5e0b4ebcbec80299a21c))
|
|
55
|
+
* use Linux-compatible sed in semantic-release ([4a5fb37](https://github.com/tawanorg/claude-sync/commit/4a5fb37697deae23a73db14cfd3c4bca3b34cffc))
|
|
56
|
+
|
|
57
|
+
# Changelog
|
|
58
|
+
|
|
59
|
+
All notable changes to this project will be documented in this file.
|
|
60
|
+
|
|
61
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
62
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
package/README.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="assets/banner.svg" alt="Claude Sync" width="100%">
|
|
4
|
+
|
|
5
|
+
<br>
|
|
6
|
+
|
|
7
|
+
*Encrypted with [age](https://github.com/FiloSottile/age) • R2 / S3 / GCS supported*
|
|
8
|
+
|
|
9
|
+
[](https://github.com/tawanorg/claude-sync/releases)
|
|
10
|
+
[](https://go.dev)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
|
|
13
|
+
[Quick Start](#quick-start) • [Setup Guide](#setup-guide) • [Commands](#commands) • [Security](#security)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Cross-device sync**: Continue Claude Code conversations on any laptop
|
|
22
|
+
- **Multi-provider storage**: Cloudflare R2, AWS S3, or Google Cloud Storage
|
|
23
|
+
- **End-to-end encryption**: All files encrypted with age before upload
|
|
24
|
+
- **Passphrase-based keys**: Same passphrase = same key on any device (no file copying)
|
|
25
|
+
- **Interactive wizard**: Arrow-key driven setup with validation
|
|
26
|
+
- **Self-updating**: `claude-sync update` to get the latest version
|
|
27
|
+
- **Simple CLI**: `push`, `pull`, `status`, `diff`, `conflicts` commands
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### First Device
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Install (pick one)
|
|
35
|
+
npm install -g claude-sync
|
|
36
|
+
# or: go install github.com/tawanorg/claude-sync/cmd/claude-sync@latest
|
|
37
|
+
|
|
38
|
+
# Set up (interactive wizard)
|
|
39
|
+
claude-sync init
|
|
40
|
+
|
|
41
|
+
# Push your sessions
|
|
42
|
+
claude-sync push
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Second Device
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Install
|
|
49
|
+
npm install -g claude-sync
|
|
50
|
+
|
|
51
|
+
# Set up with SAME storage credentials and SAME passphrase
|
|
52
|
+
claude-sync init
|
|
53
|
+
|
|
54
|
+
# Pull sessions
|
|
55
|
+
claude-sync pull
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**That's it!** Same passphrase = same encryption key. No file copying needed.
|
|
59
|
+
|
|
60
|
+
## Setup Guide
|
|
61
|
+
|
|
62
|
+
### Step 1: Choose a Storage Provider
|
|
63
|
+
|
|
64
|
+
| Provider | Free Tier | Best For |
|
|
65
|
+
|----------|-----------|----------|
|
|
66
|
+
| **Cloudflare R2** | 10GB storage | Personal use (recommended) |
|
|
67
|
+
| **AWS S3** | 5GB (12 months) | AWS users |
|
|
68
|
+
| **Google Cloud Storage** | 5GB | GCP users |
|
|
69
|
+
|
|
70
|
+
### Step 2: Create a Bucket
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary><b>Cloudflare R2</b> (recommended)</summary>
|
|
74
|
+
|
|
75
|
+
1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) → R2 Object Storage
|
|
76
|
+
2. Click "Create bucket" → name it `claude-sync`
|
|
77
|
+
3. Go to "Manage R2 API Tokens" → "Create API Token"
|
|
78
|
+
4. Select **Object Read & Write** permission → Create
|
|
79
|
+
|
|
80
|
+
You'll need: Account ID, Access Key ID, Secret Access Key
|
|
81
|
+
</details>
|
|
82
|
+
|
|
83
|
+
<details>
|
|
84
|
+
<summary><b>AWS S3</b></summary>
|
|
85
|
+
|
|
86
|
+
1. Go to [S3 Console](https://s3.console.aws.amazon.com/s3/bucket/create) → Create bucket
|
|
87
|
+
2. Go to [IAM Security Credentials](https://console.aws.amazon.com/iam/home#/security_credentials)
|
|
88
|
+
3. Create Access Keys
|
|
89
|
+
|
|
90
|
+
You'll need: Access Key ID, Secret Access Key, Region
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details>
|
|
94
|
+
<summary><b>Google Cloud Storage</b></summary>
|
|
95
|
+
|
|
96
|
+
1. Go to [Cloud Storage](https://console.cloud.google.com/storage/create-bucket) → Create bucket
|
|
97
|
+
2. Go to [Service Accounts](https://console.cloud.google.com/iam-admin/serviceaccounts) → Create service account
|
|
98
|
+
3. Grant "Storage Object Admin" role → Create JSON key
|
|
99
|
+
|
|
100
|
+
You'll need: Project ID, Service Account JSON file (or use `gcloud auth application-default login`)
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
### Step 3: Run Init
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
claude-sync init
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The interactive wizard will guide you through:
|
|
110
|
+
|
|
111
|
+
1. **Select storage provider** (R2, S3, or GCS)
|
|
112
|
+
2. **Enter credentials** (provider-specific)
|
|
113
|
+
3. **Choose encryption method**:
|
|
114
|
+
- **Passphrase** (recommended) - same passphrase on all devices = same key
|
|
115
|
+
- **Random key** - must copy `~/.claude-sync/age-key.txt` to other devices
|
|
116
|
+
4. **Test the connection** to verify everything works
|
|
117
|
+
|
|
118
|
+
### Step 4: Push and Pull
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Upload local changes
|
|
122
|
+
claude-sync push
|
|
123
|
+
|
|
124
|
+
# Download remote changes
|
|
125
|
+
claude-sync pull
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## What Gets Synced
|
|
129
|
+
|
|
130
|
+
| Path | Content |
|
|
131
|
+
|------|---------|
|
|
132
|
+
| `~/.claude/projects/` | Session files, auto-memory |
|
|
133
|
+
| `~/.claude/history.jsonl` | Command history |
|
|
134
|
+
| `~/.claude/agents/` | Custom agents |
|
|
135
|
+
| `~/.claude/skills/` | Custom skills |
|
|
136
|
+
| `~/.claude/plugins/` | Plugins |
|
|
137
|
+
| `~/.claude/rules/` | Custom rules |
|
|
138
|
+
| `~/.claude/settings.json` | Settings |
|
|
139
|
+
| `~/.claude/CLAUDE.md` | Global instructions |
|
|
140
|
+
|
|
141
|
+
## Commands
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
claude-sync init # Set up configuration (interactive wizard)
|
|
145
|
+
claude-sync push # Upload local changes to cloud storage
|
|
146
|
+
claude-sync pull # Download remote changes from cloud storage
|
|
147
|
+
claude-sync status # Show pending local changes
|
|
148
|
+
claude-sync diff # Show differences between local and remote
|
|
149
|
+
claude-sync conflicts # List and resolve conflicts
|
|
150
|
+
claude-sync reset # Reset configuration (forgot passphrase)
|
|
151
|
+
claude-sync update # Update to latest version
|
|
152
|
+
claude-sync --help # Show all commands
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Quiet Mode
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
claude-sync push -q # No output (for scripts)
|
|
159
|
+
claude-sync pull -q
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Check for Updates
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
claude-sync update --check # Check without installing
|
|
166
|
+
claude-sync update # Download and install latest version
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Shell Integration
|
|
170
|
+
|
|
171
|
+
Add to `~/.zshrc` or `~/.bashrc`:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Auto-pull on shell start
|
|
175
|
+
if command -v claude-sync &> /dev/null; then
|
|
176
|
+
claude-sync pull -q &
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Auto-push on shell exit
|
|
180
|
+
trap 'claude-sync push -q' EXIT
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Conflict Resolution
|
|
184
|
+
|
|
185
|
+
When both local and remote files change, the remote version is saved as `.conflict`:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
claude-sync conflicts # Interactive resolution
|
|
189
|
+
claude-sync conflicts --list # Just list conflicts
|
|
190
|
+
claude-sync conflicts --keep local # Keep all local versions
|
|
191
|
+
claude-sync conflicts --keep remote # Keep all remote versions
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Interactive options:
|
|
195
|
+
- **[l]** Keep local (delete conflict file)
|
|
196
|
+
- **[r]** Keep remote (replace local)
|
|
197
|
+
- **[d]** Show diff
|
|
198
|
+
- **[s]** Skip
|
|
199
|
+
- **[q]** Quit
|
|
200
|
+
|
|
201
|
+
## Forgot Passphrase?
|
|
202
|
+
|
|
203
|
+
The passphrase is **never stored**. If you forget it:
|
|
204
|
+
|
|
205
|
+
1. Your encrypted files cannot be recovered
|
|
206
|
+
2. Reset and start fresh:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
claude-sync reset --remote # Delete remote files and local config
|
|
210
|
+
claude-sync init # Set up again with new passphrase
|
|
211
|
+
claude-sync push # Re-upload from this device
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Security
|
|
215
|
+
|
|
216
|
+
- Files encrypted with [age](https://github.com/FiloSottile/age) before upload
|
|
217
|
+
- Passphrase-derived keys use Argon2 (memory-hard KDF)
|
|
218
|
+
- Passphrase is never stored - only the derived key at `~/.claude-sync/age-key.txt`
|
|
219
|
+
- Cloud storage is private (API key/IAM auth)
|
|
220
|
+
- Config files stored with 0600 permissions
|
|
221
|
+
|
|
222
|
+
## Cost
|
|
223
|
+
|
|
224
|
+
Claude sessions typically use < 50MB. Syncing is effectively **free** on any provider:
|
|
225
|
+
|
|
226
|
+
| Provider | Free Tier |
|
|
227
|
+
|----------|-----------|
|
|
228
|
+
| **Cloudflare R2** | 10GB storage, 1M writes, 10M reads/month |
|
|
229
|
+
| **AWS S3** | 5GB for 12 months (then ~$0.023/GB) |
|
|
230
|
+
| **Google Cloud Storage** | 5GB, 5K writes, 50K reads/month |
|
|
231
|
+
|
|
232
|
+
## Installation Options
|
|
233
|
+
|
|
234
|
+
### npm (recommended)
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# One-time use
|
|
238
|
+
npx claude-sync init
|
|
239
|
+
|
|
240
|
+
# Global install
|
|
241
|
+
npm install -g claude-sync
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Go Install
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
go install github.com/tawanorg/claude-sync/cmd/claude-sync@latest
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Build Manually
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
git clone https://github.com/tawanorg/claude-sync
|
|
254
|
+
cd claude-sync
|
|
255
|
+
make build
|
|
256
|
+
./bin/claude-sync --version
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Download Binary
|
|
260
|
+
|
|
261
|
+
Download from [GitHub Releases](https://github.com/tawanorg/claude-sync/releases):
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# macOS ARM (M1/M2/M3)
|
|
265
|
+
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-darwin-arm64 -o claude-sync
|
|
266
|
+
chmod +x claude-sync
|
|
267
|
+
sudo mv claude-sync /usr/local/bin/
|
|
268
|
+
|
|
269
|
+
# macOS Intel
|
|
270
|
+
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-darwin-amd64 -o claude-sync
|
|
271
|
+
|
|
272
|
+
# Linux AMD64
|
|
273
|
+
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-linux-amd64 -o claude-sync
|
|
274
|
+
|
|
275
|
+
# Linux ARM64
|
|
276
|
+
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-linux-arm64 -o claude-sync
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
make test # Run tests
|
|
283
|
+
make fmt # Format code
|
|
284
|
+
make check # Run all pre-commit checks
|
|
285
|
+
make build-all # Build for all platforms
|
|
286
|
+
make setup-hooks # Enable git pre-commit hooks
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
function getBinaryPath() {
|
|
8
|
+
const platform = process.platform;
|
|
9
|
+
const binaryName = platform === "win32" ? "claude-sync.exe" : "claude-sync";
|
|
10
|
+
const binaryPath = path.join(__dirname, binaryName);
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(binaryPath)) {
|
|
13
|
+
console.error("Error: claude-sync binary not found.");
|
|
14
|
+
console.error("Try reinstalling: npm install -g claude-sync");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return binaryPath;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const binary = getBinaryPath();
|
|
22
|
+
const args = process.argv.slice(2);
|
|
23
|
+
|
|
24
|
+
const child = spawn(binary, args, {
|
|
25
|
+
stdio: "inherit",
|
|
26
|
+
env: process.env,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
child.on("error", (err) => {
|
|
30
|
+
console.error(`Failed to start claude-sync: ${err.message}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
child.on("close", (code) => {
|
|
35
|
+
process.exit(code || 0);
|
|
36
|
+
});
|
package/install.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require("https");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { execSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
const VERSION = require("./package.json").version;
|
|
9
|
+
const REPO = "tawanorg/claude-sync";
|
|
10
|
+
|
|
11
|
+
function getPlatform() {
|
|
12
|
+
const platform = process.platform;
|
|
13
|
+
switch (platform) {
|
|
14
|
+
case "darwin":
|
|
15
|
+
return "darwin";
|
|
16
|
+
case "linux":
|
|
17
|
+
return "linux";
|
|
18
|
+
case "win32":
|
|
19
|
+
return "windows";
|
|
20
|
+
default:
|
|
21
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getArch() {
|
|
26
|
+
const arch = process.arch;
|
|
27
|
+
switch (arch) {
|
|
28
|
+
case "x64":
|
|
29
|
+
return "amd64";
|
|
30
|
+
case "arm64":
|
|
31
|
+
return "arm64";
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unsupported architecture: ${arch}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getBinaryName() {
|
|
38
|
+
const platform = getPlatform();
|
|
39
|
+
const arch = getArch();
|
|
40
|
+
const ext = platform === "windows" ? ".exe" : "";
|
|
41
|
+
return `claude-sync-${platform}-${arch}${ext}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getDownloadUrl() {
|
|
45
|
+
const binaryName = getBinaryName();
|
|
46
|
+
return `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function download(url, dest) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const file = fs.createWriteStream(dest);
|
|
52
|
+
|
|
53
|
+
const request = (url) => {
|
|
54
|
+
https
|
|
55
|
+
.get(url, (response) => {
|
|
56
|
+
// Handle redirects
|
|
57
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
58
|
+
request(response.headers.location);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (response.statusCode !== 200) {
|
|
63
|
+
reject(new Error(`Failed to download: ${response.statusCode}`));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
response.pipe(file);
|
|
68
|
+
file.on("finish", () => {
|
|
69
|
+
file.close();
|
|
70
|
+
resolve();
|
|
71
|
+
});
|
|
72
|
+
})
|
|
73
|
+
.on("error", (err) => {
|
|
74
|
+
fs.unlink(dest, () => {});
|
|
75
|
+
reject(err);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
request(url);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function install() {
|
|
84
|
+
const binDir = path.join(__dirname, "bin");
|
|
85
|
+
const platform = getPlatform();
|
|
86
|
+
const binaryName = platform === "windows" ? "claude-sync.exe" : "claude-sync";
|
|
87
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
88
|
+
|
|
89
|
+
// Create bin directory
|
|
90
|
+
if (!fs.existsSync(binDir)) {
|
|
91
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const url = getDownloadUrl();
|
|
95
|
+
console.log(`Downloading claude-sync v${VERSION}...`);
|
|
96
|
+
console.log(` Platform: ${getPlatform()}-${getArch()}`);
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
await download(url, binaryPath);
|
|
100
|
+
|
|
101
|
+
// Make executable on Unix
|
|
102
|
+
if (platform !== "windows") {
|
|
103
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(` Installed to: ${binaryPath}`);
|
|
107
|
+
console.log(`\n✓ claude-sync installed successfully!`);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.error(`\n✗ Failed to install claude-sync: ${err.message}`);
|
|
110
|
+
console.error(`\nYou can manually download from:`);
|
|
111
|
+
console.error(` ${url}`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
install();
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tawandotorg/claude-sync",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Sync Claude Code sessions across devices with encrypted cloud storage",
|
|
5
|
+
"bin": {
|
|
6
|
+
"claude-sync": "./bin/claude-sync.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node install.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"claude",
|
|
13
|
+
"claude-code",
|
|
14
|
+
"sync",
|
|
15
|
+
"cli",
|
|
16
|
+
"anthropic",
|
|
17
|
+
"ai",
|
|
18
|
+
"r2",
|
|
19
|
+
"s3",
|
|
20
|
+
"gcs",
|
|
21
|
+
"encryption"
|
|
22
|
+
],
|
|
23
|
+
"author": "tawanorg",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/tawanorg/claude-sync.git"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/tawanorg/claude-sync/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/tawanorg/claude-sync#readme",
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=14"
|
|
35
|
+
},
|
|
36
|
+
"os": [
|
|
37
|
+
"darwin",
|
|
38
|
+
"linux",
|
|
39
|
+
"win32"
|
|
40
|
+
],
|
|
41
|
+
"cpu": [
|
|
42
|
+
"x64",
|
|
43
|
+
"arm64"
|
|
44
|
+
]
|
|
45
|
+
}
|