cync-cli 0.3.0__py3-none-any.whl

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,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: cync-cli
3
+ Version: 0.3.0
4
+ Summary: Sync Claude Code conversations across machines — GitHub-authed CLI + server (Postgres metadata, R2 blobs).
5
+ Project-URL: Homepage, https://github.com/03hgryan/cync
6
+ Project-URL: Repository, https://github.com/03hgryan/cync
7
+ Author: 03hgryan
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 03hgryan
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ License-File: LICENSE
30
+ Keywords: claude,claude-code,cli,conversations,sync
31
+ Classifier: Environment :: Console
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Topic :: Utilities
36
+ Requires-Python: >=3.11
37
+ Requires-Dist: httpx<1,>=0.27
38
+ Requires-Dist: python-dotenv<2,>=1.0
39
+ Requires-Dist: rich<15,>=13
40
+ Requires-Dist: typer<1,>=0.12
41
+ Provides-Extra: dev
42
+ Requires-Dist: boto3<2,>=1.34; extra == 'dev'
43
+ Requires-Dist: fastapi<1,>=0.110; extra == 'dev'
44
+ Requires-Dist: pydantic<3,>=2; extra == 'dev'
45
+ Requires-Dist: pytest<9,>=8; extra == 'dev'
46
+ Requires-Dist: ruff>=0.5; extra == 'dev'
47
+ Requires-Dist: uvicorn[standard]<1,>=0.29; extra == 'dev'
48
+ Provides-Extra: server
49
+ Requires-Dist: boto3<2,>=1.34; extra == 'server'
50
+ Requires-Dist: fastapi<1,>=0.110; extra == 'server'
51
+ Requires-Dist: pydantic<3,>=2; extra == 'server'
52
+ Requires-Dist: uvicorn[standard]<1,>=0.29; extra == 'server'
53
+ Description-Content-Type: text/markdown
54
+
55
+ # cync — code sync for Claude Code conversations
56
+
57
+ Sync your Claude Code conversations across machines, signed in with **GitHub**.
58
+ Your conversation **metadata** lives in your **Supabase** Postgres (per-user, RLS),
59
+ the **transcripts** live in your **Cloudflare R2** bucket, and a small FastAPI
60
+ server brokers both. Like git, but for your chats: `cync push` on one machine,
61
+ `cync pull` on another, and `claude --resume` picks up where you left off — plus
62
+ a web viewer to browse them.
63
+
64
+ ```
65
+ Browser / CLI ── GitHub login (Supabase Auth) ──┐
66
+ ▼ JWT
67
+ FastAPI ── Postgres (metadata, per-user RLS)
68
+ ── R2 (transcript blobs)
69
+ ```
70
+
71
+ ## How it works
72
+ - Sign in once per machine with `cync login` (GitHub via Supabase, browser PKCE).
73
+ - A **project** is a first-class record you own; create one with `cync init <name>`
74
+ and link a directory to it. Conversations are keyed by their Claude session UUID.
75
+ - `push` uploads `~/.claude/projects/<repo>/<id>.jsonl`; `pull` writes it back on the
76
+ other machine and rewrites the embedded `cwd` so `claude --resume` just works.
77
+ - Everything is scoped to your GitHub user — projects/conversations are private to you.
78
+
79
+ ## Install & use (hosted)
80
+
81
+ The CLI is on PyPI as **`cync-cli`** (the command is `cync`). No server setup —
82
+ it points at the hosted cync by default:
83
+
84
+ ```bash
85
+ pipx install cync-cli # or: uv tool install cync-cli
86
+ cync login # sign in with GitHub
87
+ cd ~/path/to/your/project
88
+ cync init myproject && cync push # machine A
89
+ cync link myproject && cync pull # machine B → claude --resume
90
+ ```
91
+
92
+ ## Self-hosting
93
+
94
+ Prefer your own stack? Point the CLI at your deployment via `CYNC_SERVER_URL`
95
+ (env or `~/.config/cync/config.toml`), then deploy the server + provision your
96
+ own Supabase + R2:
97
+
98
+ ### 1. Provision (one time)
99
+ - **Cloudflare R2:** create a bucket (default name `cync`) and an API token with
100
+ **Object Read & Write**.
101
+ - **Supabase:** create a project, then run [`supabase/schema.sql`](supabase/schema.sql)
102
+ in the SQL editor. Enable **Auth → Providers → GitHub** (create a GitHub OAuth App
103
+ with callback `https://<ref>.supabase.co/auth/v1/callback`). Under **Auth → URL
104
+ Configuration**, add redirect URLs `http://127.0.0.1:8765/callback` (CLI) and
105
+ `http://localhost:5173/auth/callback` (web).
106
+
107
+ ### 2. Server
108
+ ```bash
109
+ uv venv && source .venv/bin/activate
110
+ uv pip install -e ".[server]"
111
+ cp .env.example .env # fill in R2_* and SUPABASE_* (URL, anon, service_role)
112
+ cync-server # http://127.0.0.1:8787
113
+ ```
114
+ > For cross-machine use, expose the server over **HTTPS** (Tailscale, Fly.io, Railway).
115
+ > The CLI refuses non-HTTPS server URLs except on localhost.
116
+
117
+ ### 3. CLI (each machine)
118
+ ```bash
119
+ uv pip install -e . # base install
120
+ export CYNC_SERVER_URL=http://127.0.0.1:8787 # or your https URL / config.toml
121
+ cync login # sign in with GitHub (opens a browser)
122
+
123
+ cd ~/path/to/your/project
124
+ cync init droneforge # create + link a project (machine A)
125
+ cync push
126
+ # on machine B: cync link droneforge && cync pull → claude --resume
127
+ ```
128
+
129
+ ### 4. Web viewer (optional)
130
+ ```bash
131
+ cd client
132
+ pnpm install
133
+ cp .env.example .env # PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, CYNC_SERVER_URL
134
+ pnpm dev # http://localhost:5173 → "Sign in with GitHub"
135
+ ```
136
+ The SvelteKit server holds the token (Supabase SSR cookies); browse at `/p/<project>`.
137
+
138
+ ## Commands
139
+ | Command | What it does |
140
+ |---|---|
141
+ | `cync login` / `logout` / `whoami` | GitHub auth session |
142
+ | `cync init <name>` | create a project + link this directory |
143
+ | `cync link <name>` | link this directory to an existing project |
144
+ | `cync unlink` | remove this directory's link |
145
+ | `cync push [id]` | upload this project's conversation(s) |
146
+ | `cync pull [id]` | download into `~/.claude` (overwrite/add) |
147
+ | `cync list` | list this project's conversations |
148
+ | `cync project list` / `rm <name>` | manage your projects |
149
+
150
+ ## Migrating from v0.2
151
+ If you have v0.2 (static-token) data still in R2, after `cync login`:
152
+ ```bash
153
+ python scripts/migrate_legacy.py --slug <name> --email <your-github-email> [--purge]
154
+ ```
155
+ Or simply re-`cync push` from a machine that has the conversations locally.
156
+
157
+ ## Security
158
+ - Per-user GitHub auth (Supabase JWT); every project/conversation is owner-scoped,
159
+ with Postgres RLS as a backstop. The server holds R2 + Supabase keys; clients never do.
160
+ - CLI login uses PKCE + a single-use loopback callback; the session (refresh token)
161
+ is stored `0600` at `~/.config/cync/session.json`.
162
+ - Request bodies are capped (`CYNC_MAX_BODY_BYTES`, default 64 MB).
163
+
164
+ ## Layout
165
+ ```
166
+ src/cync/ server (FastAPI), CLI, auth, Supabase + R2 stores
167
+ client/ SvelteKit web viewer (GitHub login)
168
+ supabase/ Postgres schema + RLS
169
+ scripts/ legacy migration
170
+ ```
171
+
172
+ ## Limitations
173
+ - Last-writer-wins; no version history yet.
174
+ - Syncs the `.jsonl` transcript only (enough for `--resume`); not `todos/` sidecars.
175
+ - Don't `push` a conversation that's open in Claude Code — quit first so it isn't mid-write.
176
+ - Listing reads one object per conversation from Postgres (fine for personal scale).
@@ -0,0 +1,13 @@
1
+ cync/__init__.py,sha256=zLzi8QYdTRxMNwW8_UYz52doOLfruWhym0WJ2mTkXpo,86
2
+ cync/auth.py,sha256=EjmMk4YYFTrdjspc242Y32EJr_iJ-YssEtHXEpCU7h4,6208
3
+ cync/client.py,sha256=ZXKZgtflRa6rOCjTpq3YOO2ZJLd1XG1a3jMbZwX5EOs,10215
4
+ cync/common.py,sha256=X88MLWdvW8_0E-apyWWFqVSAzgOTi4s6X9hkaHudoyo,6129
5
+ cync/config.py,sha256=pTJTmOUuwnTooIepPF7y4DrygYdqUex4Mwem-bkWGzg,3284
6
+ cync/server.py,sha256=JwI9kCyAky_rGAl8SUlsIWdLUbrMDA-HC6LeZluDqzc,9155
7
+ cync/storage.py,sha256=PdI87L0NyWY7zxVBLPzTFVMNwpI7iLB2rdSfSR3nioI,3450
8
+ cync/supabase_store.py,sha256=LjmT82al5YI3sLMKmIu4G5tEqoN8MYTJKQTWJDZGPE0,7975
9
+ cync_cli-0.3.0.dist-info/METADATA,sha256=cmzr7k4j5RbCy5QZWsETAOmnyNutVKhR15lAnyYvnIU,7854
10
+ cync_cli-0.3.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
11
+ cync_cli-0.3.0.dist-info/entry_points.txt,sha256=BgC_BCWbrrdyQbkZUeU3O-uuhHvb90FlxVbb0Y5sLx0,72
12
+ cync_cli-0.3.0.dist-info/licenses/LICENSE,sha256=UpIdwVYVVw1dRHLxxn-OR_4Bctr34wj-nbFm-VzwplY,1065
13
+ cync_cli-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ cync = cync.client:main
3
+ cync-server = cync.server:run
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 03hgryan
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.