@claudecollab/cli 0.1.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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/package.json +36 -0
  4. package/packages/cli/bin/claude-share.js +1319 -0
  5. package/packages/cli/package.json +15 -0
  6. package/packages/cli/src/brain/card.js +157 -0
  7. package/packages/cli/src/brain/commands.js +122 -0
  8. package/packages/cli/src/brain/drafts.js +557 -0
  9. package/packages/cli/src/brain/gate.js +134 -0
  10. package/packages/cli/src/brain/knocks.js +27 -0
  11. package/packages/cli/src/brain/log.js +123 -0
  12. package/packages/cli/src/brain/queue.js +81 -0
  13. package/packages/cli/src/brain/state.js +245 -0
  14. package/packages/cli/src/hooks.js +243 -0
  15. package/packages/cli/src/invite.js +43 -0
  16. package/packages/cli/src/known-relays.js +66 -0
  17. package/packages/cli/src/pty.js +175 -0
  18. package/packages/cli/src/relay-client.js +271 -0
  19. package/packages/cli/src/renderer.js +230 -0
  20. package/packages/cli/src/screen-snapshot.js +139 -0
  21. package/packages/cli/src/term-chatter.js +89 -0
  22. package/packages/relay/auth.js +18 -0
  23. package/packages/relay/bin/serve.js +73 -0
  24. package/packages/relay/names.js +27 -0
  25. package/packages/relay/package.json +13 -0
  26. package/packages/relay/public/client.js +1553 -0
  27. package/packages/relay/public/index.html +110 -0
  28. package/packages/relay/public/style.css +952 -0
  29. package/packages/relay/rooms.js +149 -0
  30. package/packages/relay/server.js +652 -0
  31. package/packages/relay/web.js +334 -0
  32. package/packages/relay/wordlists.js +38 -0
  33. package/packages/shared/package.json +8 -0
  34. package/packages/shared/protocol.js +189 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ian Roybal
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,109 @@
1
+ # claude-share
2
+
3
+ **Make your Claude Code session multiplayer.** You run one command. Friends open a link — no install — and drive the same Claude with you: live cursors, shared drafts, a visible queue, roles.
4
+
5
+ Think **screen-share where they can type too**.
6
+
7
+ ```mermaid
8
+ flowchart LR
9
+ H["you (host)<br/>terminal runs Claude"] <--> R["relay<br/>forwards bytes, stores nothing"]
10
+ R <--> HT["your host tab<br/>(admit · roles · pause · end)"]
11
+ R <--> G["friends' browsers"]
12
+ ```
13
+
14
+ Your terminal stays plain Claude plus one status line. Everything multiplayer happens in the browser.
15
+
16
+ ## Run it locally
17
+
18
+ ```bash
19
+ npm install
20
+ ```
21
+
22
+ **Terminal 1 — relay:**
23
+
24
+ ```bash
25
+ node packages/relay/bin/serve.js
26
+ ```
27
+
28
+ **Terminal 2 — host:**
29
+
30
+ ```bash
31
+ node packages/cli/bin/claude-share.js --relay ssh://127.0.0.1:2222
32
+ ```
33
+
34
+ Open the link from the status line — that's your host tab. The invite link is on your clipboard.
35
+
36
+ ## Deploy the relay (permanent links)
37
+
38
+ ```bash
39
+ fly launch --no-deploy # keep the provided fly.toml
40
+ fly secrets set HOST_KEY="$(node packages/relay/bin/serve.js --make-key)"
41
+ fly secrets set ROOM_SECRET="$(openssl rand -hex 16)"
42
+ fly deploy
43
+ ```
44
+
45
+ Then host with `--relay ssh://your-app.fly.dev:2222`. Links print your public https origin automatically.
46
+
47
+ Two protections kick in on a deployed relay:
48
+
49
+ - **Room secret** — with `ROOM_SECRET` set, only hosts that present it (`CLAUDE_SHARE_SECRET` env or `--secret`) can create rooms; strangers who find your relay can't. Guests are unaffected — they enter with a room link.
50
+ - **Identity pinning** — the CLI pins the relay's ssh key fingerprint on first connect (like ssh's `known_hosts`) and refuses to connect if it ever changes, so nobody can impersonate your relay. The relay prints its fingerprint at boot; pass it as `--fingerprint SHA256:…` to pin explicitly. Loopback relays are exempt (dev relays regenerate keys).
51
+
52
+ ## Two links — don't mix them up
53
+
54
+ | Link | Who it's for |
55
+ |---|---|
56
+ | `…/room?host=abc` | **you only** — opening it grants the host seat |
57
+ | `…/room` | **share this** — friends land on the request-to-join flow |
58
+
59
+ The Invite button and your clipboard always hold the safe one.
60
+
61
+ Want a lock in front of the knock? Host with `--room-password <pw>` — guests must
62
+ enter it (browser field / ssh prompt) before their request ever reaches you.
63
+ Admitting stays your call either way.
64
+
65
+ ## Roles
66
+
67
+ | Role | See | Type · answer asks · slash/bash | Admit · kick · pause · end |
68
+ |---|---|---|---|
69
+ | 👁 viewer | ✅ | ❌ | ❌ |
70
+ | ✎ prompter *(default)* | ✅ | ✅ | ❌ |
71
+ | ★ host | ✅ | ✅ | ✅ |
72
+
73
+ ## How it feels
74
+
75
+ - The whole page is the terminal. Type with no draft open → keys go **straight into Claude** — menus, asks, everything.
76
+ - **+ draft** (or double-click) opens a floating glass box. Everyone's caret shows; Enter sends; Esc steps out; drag ⠿ to move, ◢ to resize, ✕ to delete.
77
+ - Sent while Claude is busy? It waits in the **queue** chip — edit or delete before it fires.
78
+ - Scroll the mirror like a real terminal. Scrolling is shared — one screen for everyone.
79
+ - Reloaded guests glide straight back in. Kicked guests are out for good.
80
+
81
+ ## The one thing to really understand
82
+
83
+ A guest prompt **runs on your machine, as you**. Admitting someone = trusting them with your Claude under the current mode. The relay sees your screen — treat a room like a screen-share, not a vault. You have **Pause** and **End** (with an optional `session.md` receipt).
84
+
85
+ ## Tests
86
+
87
+ ```bash
88
+ npm test
89
+ ```
90
+
91
+ <details>
92
+ <summary>Architecture</summary>
93
+
94
+ Three packages, plain ESM JavaScript, Node 22, no build step.
95
+
96
+ ```
97
+ packages/shared/ protocol.js — host↔relay wire messages
98
+ packages/relay/ server.js (ssh door) · web.js (browser door) · public/ (client)
99
+ packages/cli/ bin/claude-share.js — the "brain": drafts, queue, roles, gate
100
+ test/ end-to-end: host + host tab + guest on localhost
101
+ ```
102
+
103
+ - The CLI wraps Claude in a PTY one row short — the bottom row is the status line.
104
+ - State (busy/idle/ask) comes from injected Claude Code hooks, never screen-scraping. Ambiguity fails closed.
105
+ - The relay stores nothing: kill it and the host reconnects; kill the host and the room is over.
106
+
107
+ </details>
108
+
109
+ **TL;DR:** relay up → `claude-share` → open your link, share the invite. Guests need nothing. Roles keep control; prompts are real — admit people you trust.
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@claudecollab/cli",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "description": "Make your Claude Code session multiplayer — friends join from a browser link, no install: live cursors, shared drafts, a visible queue, roles.",
9
+ "homepage": "https://claudecollab.org",
10
+ "type": "module",
11
+ "bin": {
12
+ "collab": "packages/cli/bin/claude-share.js",
13
+ "collab-relay": "packages/relay/bin/serve.js"
14
+ },
15
+ "files": [
16
+ "packages/cli",
17
+ "packages/relay",
18
+ "packages/shared",
19
+ "!**/*.test.js"
20
+ ],
21
+ "workspaces": [
22
+ "packages/*"
23
+ ],
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "dependencies": {
28
+ "@xterm/xterm": "^5.5.0",
29
+ "node-pty": "^1.1.0",
30
+ "ssh2": "^1.17.0",
31
+ "ws": "^8.18.0"
32
+ },
33
+ "scripts": {
34
+ "test": "node --test \"packages/**/*.test.js\" \"test/**/*.test.js\""
35
+ }
36
+ }