@threadbase-sh/streamer 1.15.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ronen Mars
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,154 @@
1
+ # @threadbase-sh/streamer
2
+
3
+ PTY session management, WebSocket streaming, and REST API server for Claude Code conversations. Manages live Claude sessions via `node-pty`, broadcasts terminal output over WebSocket, and serves a REST API for conversation history, search, and session control.
4
+
5
+ ## Quick Start
6
+
7
+ ### Install via Homebrew (recommended, macOS + Linux)
8
+
9
+ ```bash
10
+ brew tap RonenMars/threadbase
11
+ brew install tb-streamer
12
+
13
+ # One-time setup:
14
+ tb-streamer set-key <YOUR_API_KEY>
15
+
16
+ # Start the service (also starts on login):
17
+ brew services start tb-streamer
18
+ ```
19
+
20
+ To stop or restart: `brew services stop tb-streamer` / `brew services restart tb-streamer`. Optional automatic updates: see [docs/guides/auto-update.md](docs/guides/auto-update.md).
21
+
22
+ > **Note:** the Homebrew install is mutually exclusive with the manual `scripts/deploy.sh` install. If you previously installed via that path, run `launchctl bootout gui/$UID/com.threadbase.streamer` before starting the Homebrew service.
23
+
24
+ ### Run from source
25
+
26
+ ```bash
27
+ npm install
28
+ npm run build
29
+ node dist/cli.cjs serve --verbose --local-no-auth
30
+ ```
31
+
32
+ The server starts on `http://localhost:8766` by default with WebSocket at `ws://localhost:8766/ws`.
33
+
34
+ ## Persistence
35
+
36
+ Conversation metadata lives in a SQLite cache at `~/.threadbase/cache/cache.db` — created and migrated automatically on startup, no configuration needed. Managed sessions are in-memory: a restart drops the live PTYs, but conversation history is on disk and every session can be resumed via `POST /api/sessions/resume`.
37
+
38
+ PostgreSQL is optional and currently dormant (it stores upload records only — not session state). Enable it by setting `THREADBASE_DATABASE_URL` (e.g. `docker compose up -d postgres` and `export THREADBASE_DATABASE_URL="postgresql://threadbase:threadbase@localhost:5432/threadbase"`); migrations run automatically. Related knobs: `THREADBASE_DATABASE_SSL`, `THREADBASE_DATABASE_POOL_MAX`, `THREADBASE_DATABASE_STATEMENT_TIMEOUT_MS`.
39
+
40
+ ## Architecture
41
+
42
+ Three layers: **core engine** (`src/*.ts`) → **API layer** (`src/api/` + `src/index.ts` exports) → **CLI wrapper** (`cli/`).
43
+
44
+ The short version:
45
+
46
+ - `POST /api/sessions/start` / `resume` spawns a `claude` process in a PTY; output streams to all WebSocket clients as `terminal_output`, with a `terminal_replay` snapshot on subscribe.
47
+ - `SessionStore` registers managed (PTY) sessions plus externally-running `claude` processes found by process discovery.
48
+ - A chokidar-backed watcher tails conversation JSONL files into the SQLite cache, which backs the conversation/list endpoints without filesystem scans.
49
+ - When the last WebSocket subscriber disconnects, a grace timer (default 4.5 minutes) puts the PTY on hold — history intact, resumable any time.
50
+
51
+ Full runtime flow and module reference: [docs/how-it-works.md](docs/how-it-works.md). Dated design documents: [docs/architecture/](docs/architecture/README.md).
52
+
53
+ ## Relationship to Claude Code dynamic workflows
54
+
55
+ [Claude Code dynamic workflows](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code) live *inside* a Claude Code session — the kind of session **PTY mode** hosts. The meaningful comparison is with **`--multi-agent-flow` mode**, where the streamer hands each turn off to a Temporal pipeline in `tb-multi-agent` instead of a `node-pty` Claude session: developer-triggered in-session orchestration vs. durable per-turn orchestration with webhook → WebSocket result delivery.
56
+
57
+ Details: [docs/comparisons/claude-code-dynamic-workflows.md](docs/comparisons/claude-code-dynamic-workflows.md); multi-agent mode itself: [docs/multi-agent-mode.md](docs/multi-agent-mode.md).
58
+
59
+ ## REST API
60
+
61
+ | Method | Endpoint | Description |
62
+ |--------|----------|-------------|
63
+ | GET | `/healthz` | Health check (version) |
64
+ | GET | `/api/info` | Server info (version, platform, active sessions) |
65
+ | GET | `/api/sessions` | List managed + discovered sessions |
66
+ | GET | `/api/sessions/count` | Count of active managed sessions |
67
+ | GET | `/api/sessions/:id` | Get single session |
68
+ | POST | `/api/sessions/start` | Start a new Claude session in a given directory |
69
+ | POST | `/api/sessions/resume` | Resume a conversation (creates managed session) |
70
+ | POST | `/api/sessions/:id/input` | Send input to a managed session |
71
+ | POST | `/api/sessions/:id/cancel` | Cancel a managed session |
72
+ | GET | `/api/sessions/:id/output` | Get terminal output buffer |
73
+ | POST | `/api/sessions/:id/files` | Upload a file attachment to a session |
74
+ | GET | `/api/conversations` | Paginated conversation history |
75
+ | GET | `/api/conversations/count` | Count conversations matching optional filters |
76
+ | GET | `/api/conversations/:id` | Full conversation with messages |
77
+ | GET | `/project-chats` | Unified active-sessions + historical-conversations list (discriminated union); accepts `?refreshConversations=1` |
78
+ | GET | `/api/search?q=...` | Full-text search across conversations |
79
+ | GET | `/api/browse` | Browse the file system |
80
+ | POST | `/api/browse/mkdir` | Create a directory |
81
+ | GET | `/api/profiles` | List scan profiles |
82
+ | POST | `/api/push/register` | Register a push notification token |
83
+ | POST | `/api/pair/start` | Mint a short-lived pair token (authenticated) |
84
+ | POST | `/api/pair/exchange` | Trade a pair token + client public key for a sealed API key (unauthenticated) |
85
+
86
+ ## Remote Access (tunnels, funnels, proxies)
87
+
88
+ By default the streamer binds to `127.0.0.1:8766` and isn't reachable from the network. For the mobile app to pair from outside your LAN you need something forwarding HTTPS traffic to that local port. The fastest path is a Cloudflare quick-tunnel — no account, no domain, ~30 seconds:
89
+
90
+ ```sh
91
+ # macOS / Linux / WSL / Git Bash
92
+ bash scripts/remote-access/cloudflare.sh
93
+
94
+ # Anywhere `pwsh` is installed (Windows native, or macOS/Linux via Homebrew)
95
+ pwsh scripts/remote-access/cloudflare.ps1
96
+ ```
97
+
98
+ - **Hub:** [docs/guides/remote-access/](docs/guides/remote-access/) — concept overview, provider comparison, security baseline
99
+ - **Cloudflare Tunnel:** [docs/guides/remote-access/cloudflare.md](docs/guides/remote-access/cloudflare.md) — quick-tunnel + named-tunnel + Access
100
+ - **Other providers:** [ngrok](docs/guides/remote-access/ngrok.md), [Tailscale Funnel](docs/guides/remote-access/tailscale-funnel.md), [VPS reverse proxy](docs/guides/remote-access/vps-reverse-proxy.md)
101
+
102
+ The Claude Code skill `setup-cloudflare-tunnel` runs the same script with prereq checks and named-tunnel guidance.
103
+
104
+ ## Mobile Pairing (QR)
105
+
106
+ Mobile clients pair by scanning a QR that encodes a `threadbase://pair?url=…&token=…&exp=…` URL. The token is single-use and expires after 180 seconds; the client then trades it (with its X25519 public key) at `/api/pair/exchange` for a sealed-box-encrypted API key, so the key never appears in the QR.
107
+
108
+ A QR is printed automatically when the server starts (skip with `--no-pair-qr`). To re-print a fresh QR while a server is already running:
109
+
110
+ ```bash
111
+ tb-streamer pair # uses default port 8766
112
+ tb-streamer pair -p 4000
113
+ ```
114
+
115
+ If the mobile device can't reach `localhost`, point clients at a reachable address so the QR encodes it. In order of precedence:
116
+
117
+ 1. `--public-url <https-url>` flag on `serve`
118
+ 2. `THREADBASE_PUBLIC_URL` environment variable
119
+ 3. `public_url:` in `~/.threadbase/server.yaml`
120
+
121
+ `https://` is required (except for `localhost`).
122
+
123
+ ## Global commands (`tb-streamer` / `threadbase-streamer`)
124
+
125
+ `npm run deploy` automatically installs two global commands that wrap the deployed CLI at `~/.threadbase/cli.js`: `tb-streamer` (short name) and `threadbase-streamer` (long name, used by the auto-update docs and scheduled-job scripts). Both work for every subcommand: `tb-streamer pair`, `threadbase-streamer update`, etc. The deploy prompts for the install dir on first run and persists the choice to `~/.threadbase/shim.conf`.
126
+
127
+ Install dirs, non-interactive flags, PATH handling, and the legacy `tb` shim: [docs/guides/deploy-internals.md](docs/guides/deploy-internals.md).
128
+
129
+ > **Lazy-nvm note:** if your shell wraps `node`/`npm` in a lazy nvm function, `node` is not on `PATH` in fresh shells until you invoke it once, and the shims fail with "node not found". Cheapest fix: run `node -v` once per session, or eager-load nvm.
130
+
131
+ ## Development
132
+
133
+ ```bash
134
+ npm test # Run all tests
135
+ npm run lint # Type-check + Biome lint
136
+ npm run format # Auto-format
137
+ npm run build # Build ESM/CJS + copy SQLite + Postgres migrations
138
+ npm run dev # Watch mode
139
+ npm run migrate # Apply SQLite migrations to ~/.threadbase/cache/cache.db (override --db <path>)
140
+ npm run migrate:projects # Backfill projects + conversation.project_id from existing cache (idempotent)
141
+ npm run db:validate # Report conversations missing project_id, duplicate project paths, orphans
142
+ ```
143
+
144
+ ## Dependencies
145
+
146
+ - `@threadbase-sh/scanner` + `@threadbase-sh/agent-types` — public npm packages (installed by `npm install`)
147
+ - `node-pty` — native PTY management
148
+ - `ws` — WebSocket server
149
+ - `better-sqlite3` — SQLite driver for the conversation cache
150
+ - `chokidar` — JSONL tail + directory watcher
151
+ - `zod` — runtime validation at HTTP and scanner boundaries
152
+ - `date-fns` — ISO timestamp parsing and comparison helpers
153
+ - `pg` — PostgreSQL client (lazy-loaded, only when `THREADBASE_DATABASE_URL` is configured)
154
+ - `commander` — CLI argument parsing