@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.
@@ -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!"
@@ -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
+ [![Release](https://img.shields.io/github/v/release/tawanorg/claude-sync)](https://github.com/tawanorg/claude-sync/releases)
10
+ [![Go](https://img.shields.io/badge/Go-1.21+-00ADD8?logo=go)](https://go.dev)
11
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](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
+ }