@ohmaseclaro/fleetwatch 0.1.2 → 0.1.3
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/README.md +209 -74
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,82 +2,189 @@
|
|
|
2
2
|
|
|
3
3
|
> Watch every Claude Code, Cowork, and Cursor session from your phone — live.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@ohmaseclaro/fleetwatch)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
|
|
9
|
+
A single command turns your laptop into a live dashboard for every AI coding
|
|
10
|
+
agent running on it. Pair your phone via QR code (or open from anywhere via
|
|
11
|
+
free ngrok tunnel) and watch sessions stream in real time — message-by-message,
|
|
12
|
+
tool-call-by-tool-call, screenshot-by-screenshot.
|
|
8
13
|
|
|
9
14
|
```bash
|
|
10
15
|
npx @ohmaseclaro/fleetwatch
|
|
11
|
-
# or install globally:
|
|
12
|
-
npm install -g @ohmaseclaro/fleetwatch && fleetwatch
|
|
13
16
|
```
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
That's the entire setup. No accounts, no signup, no config. Auto-discovers
|
|
19
|
+
Claude Code, Cowork, and Cursor data wherever you've installed them.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What you see
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
fleetwatch v0.1.2
|
|
27
|
+
─────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
Open this on your phone (works anywhere — via ngrok):
|
|
30
|
+
|
|
31
|
+
https://given-relapsing-plop.ngrok-free.dev/?token=HWRfx3wlwTrlS8ALSsA2nEuP9Gfv1M8l
|
|
32
|
+
|
|
33
|
+
Or scan the QR code below:
|
|
34
|
+
|
|
35
|
+
▄▄▄▄▄▄▄ ▄ ▄▄ ▄▄▄ ▄ ▄▄▄▄ ▄▄▄▄▄▄▄
|
|
36
|
+
█ ▄▄▄ █ █▀ ▄ ▀██▀ ▄▄▄█▀▄ ▀ █ ▄▄▄ █
|
|
37
|
+
█ ███ █ █ ████▀▀▄ ▄▀ ▄▀▀███ █ ███ █
|
|
38
|
+
█▄▄▄▄▄█ █▀█ ▄▀█▀▄▀▄▀▄▀▄ ▄▀▄ ▄ █▄▄▄▄▄█
|
|
39
|
+
▄ ▄ ▄▄█▄▀▀▀█▀█ █▀▀▀█▄██ █▄▄▄▄▄ ▄
|
|
40
|
+
▄ █▄▄▄▄▀ █▄ ▄ ███ ▀█▀▄▄ ▄█▀ ▀▄▀▀▀▀
|
|
41
|
+
██▀▀▀█▄▀▀█ ▀ █ ▄ █▀▄▄██▀▄ █▄██▀▄██▄
|
|
42
|
+
▀█▀▀▄▄▄▄▄ ▀█▄ ██ █ ▄█████▀▄▄▄██▄█
|
|
43
|
+
█▄█▄▄▄▄██▀ ▀▀▄▀▀ █ █ ▀▄ █▄▀█▄█▄▀▀▄█▄▀
|
|
44
|
+
▀▄█ ▀▀▄▀▀█ ▀▄▄▄▄ ▄▀▄▀ ▄ ▀ █▄██▀██▄▀
|
|
45
|
+
▄██▄▄▀▀ ▄█▄▀█ █ ▄▀█▄█▄ ▀█▀▄▄█▀ █▀
|
|
46
|
+
█▀▀█ █▄▄ █▄ █ ██ ▄ ▄▄██ ▀▄█▄▀ ██▄▄▄
|
|
47
|
+
█ █ ▀▄██ ▄▄ ▀▄▄ █▄█▀█ ▄▀ ▄▄▄██▀▄███
|
|
48
|
+
▀▀▀█▀▀▄▀ ▀▄▀▀▄▄██ ▄▄███▀ ██▀▀▄▀▀▀
|
|
49
|
+
▄▄▄██▀▄██▀▄▀▄ ██▀█ ▄██▀ ▄ ▄███▄ █ █
|
|
50
|
+
▄▄▄▄▄▄▄ █▀█▄▄ ▀█ ▄▀ ▄█▄█ █ ▄ █ ▀
|
|
51
|
+
█ ▄▄▄ █ ▄ ▄▀▄█▀▄▀▀▀████ █▄▄▄███▄▄
|
|
52
|
+
█ ███ █ ▄▀ ▀▀██ ▄█▀ ▀ ▄ █▀▀▄██▀ ▀▀▀
|
|
53
|
+
█▄▄▄▄▄█ ▄▄▀█ ███ █▀▀█████ ▀█ ▀ ▄▀ ██▄
|
|
54
|
+
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
|
55
|
+
|
|
56
|
+
Host: YA-MN9RV4054G
|
|
57
|
+
Port: 7878
|
|
58
|
+
Tunnel: https://given-relapsing-plop.ngrok-free.dev (token via ngrok.yml (~/Library/Application Support/ngrok/ngrok.yml))
|
|
59
|
+
Auth: pairing token only (set PASSWORD to add a password)
|
|
60
|
+
Cowork: off (toggle in Settings)
|
|
61
|
+
|
|
62
|
+
Press Ctrl+C to stop.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Scan the QR or paste the URL into your phone's browser. You'll see every
|
|
66
|
+
session sorted by most-recent activity, with live status (running / waiting /
|
|
67
|
+
errored / idle), source icons (Claude / Cowork / Cursor), and message-level
|
|
68
|
+
streaming as the agents work.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Features
|
|
16
73
|
|
|
17
|
-
- **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
- **
|
|
23
|
-
|
|
24
|
-
colored stripe on the left edge for in-flight sessions.
|
|
74
|
+
- **Three providers, auto-discovered**
|
|
75
|
+
- Claude Code (`~/.claude/projects/*.jsonl`)
|
|
76
|
+
- Cowork (`~/Library/Application Support/Claude/local-agent-mode-sessions/`)
|
|
77
|
+
- Cursor IDE (`~/Library/Application Support/Cursor/User/globalStorage/state.vscdb`)
|
|
78
|
+
- **Filterable tabs** — All / Claude / Cowork / Cursor, each with a brand icon
|
|
79
|
+
- **Live streaming** — WebSocket; events arrive on your phone within
|
|
80
|
+
milliseconds of being written
|
|
25
81
|
- **Image attachments** — screenshots from the screenshot tool, user-pasted
|
|
26
|
-
images
|
|
82
|
+
images render inline with a tap-to-zoom lightbox
|
|
27
83
|
- **Session info modal** — tap (i) on any session to see the full transcript
|
|
28
|
-
path, project, git branch, session ID, file size, with copy-to-clipboard
|
|
29
|
-
- **Auto
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- **Optional password** — set `PASSWORD=…` in `.env` to require a
|
|
33
|
-
before any device can connect
|
|
34
|
-
|
|
35
|
-
|
|
84
|
+
path, project, git branch, session ID, file size, with copy-to-clipboard
|
|
85
|
+
- **Auto ngrok tunnel** — works on any network when you have a free authtoken;
|
|
86
|
+
auto-picks it up from existing `~/.../ngrok.yml` if you've run
|
|
87
|
+
`ngrok config add-authtoken …` before
|
|
88
|
+
- **Optional password gate** — set `PASSWORD=…` in `.env` to require a
|
|
89
|
+
password before any device can connect (bcrypt-hashed in memory, never on
|
|
90
|
+
disk)
|
|
91
|
+
- **JWT auth** — 30-day tokens issued on login; WebSocket and attachment
|
|
92
|
+
endpoints all authed
|
|
93
|
+
- **Read-only by design** — never writes to source data; opens DBs read-only;
|
|
94
|
+
never follows symlinks during discovery; respects file inodes for safe
|
|
95
|
+
rotation
|
|
96
|
+
- **Robust file discovery** — env var → known paths → bounded filesystem
|
|
97
|
+
search, with mandatory verify predicates so VSCode's `state.vscdb` never
|
|
98
|
+
gets mistaken for Cursor's
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Install
|
|
103
|
+
|
|
104
|
+
### Run without installing (recommended)
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx @ohmaseclaro/fleetwatch
|
|
108
|
+
```
|
|
36
109
|
|
|
37
|
-
|
|
110
|
+
> ⚠ If you're hacking on the fleetwatch source itself, run `npm start` or
|
|
111
|
+
> `node dist/server/index.js` from the repo — running `npx` from inside the
|
|
112
|
+
> repo will collide with the in-repo `package.json` and fail with
|
|
113
|
+
> `command not found`.
|
|
114
|
+
|
|
115
|
+
### Install globally
|
|
38
116
|
|
|
39
117
|
```bash
|
|
40
|
-
# Install globally
|
|
41
118
|
npm install -g @ohmaseclaro/fleetwatch
|
|
42
|
-
|
|
43
|
-
# Run — auto-discovers Claude / Cursor data, prints QR code
|
|
44
119
|
fleetwatch
|
|
45
120
|
```
|
|
46
121
|
|
|
47
|
-
|
|
122
|
+
After global install, the `fleetwatch` command is on your PATH.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## ngrok setup (optional — for access from anywhere)
|
|
127
|
+
|
|
128
|
+
By default fleetwatch only works on the same Wi-Fi as your laptop. To reach
|
|
129
|
+
it from cellular, coffee shops, anywhere — start ngrok automatically:
|
|
48
130
|
|
|
49
|
-
|
|
131
|
+
1. **Sign up free** (no credit card): <https://dashboard.ngrok.com/signup>
|
|
132
|
+
2. **Copy your authtoken**: <https://dashboard.ngrok.com/get-started/your-authtoken>
|
|
133
|
+
3. **Run with the token**:
|
|
50
134
|
|
|
51
|
-
|
|
52
|
-
ngrok
|
|
135
|
+
```bash
|
|
136
|
+
fleetwatch --ngrok-authtoken <your-token>
|
|
137
|
+
```
|
|
53
138
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
3. `fleetwatch --ngrok-authtoken <your-token>` (persisted for future runs)
|
|
139
|
+
The token is persisted to `~/.config/fleetwatch/config.json` so future
|
|
140
|
+
runs Just Work.
|
|
57
141
|
|
|
58
|
-
|
|
59
|
-
|
|
142
|
+
Already ran `ngrok config add-authtoken …` for another project? Fleetwatch
|
|
143
|
+
finds it automatically — zero extra config.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Password protection (recommended with ngrok)
|
|
148
|
+
|
|
149
|
+
Once you put a tunnel on the public internet, anyone with the URL can
|
|
150
|
+
connect. Add a password:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
echo 'PASSWORD=correct horse battery staple' >> .env
|
|
154
|
+
fleetwatch
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Or use the **Password protection** section of the Settings screen in the UI
|
|
158
|
+
(visible only from the desktop, not the phone). Devices must enter the
|
|
159
|
+
password before connecting; bcrypt hash lives in memory only.
|
|
160
|
+
|
|
161
|
+
After successful login the client gets a 30-day JWT and the pairing token
|
|
162
|
+
is no longer used — the QR URL can leak without compromising the daemon.
|
|
163
|
+
|
|
164
|
+
---
|
|
60
165
|
|
|
61
166
|
## Configuration
|
|
62
167
|
|
|
63
|
-
All optional. Defaults work out of the box.
|
|
168
|
+
All env vars are optional. Defaults work out of the box.
|
|
64
169
|
|
|
65
170
|
| Env var | Description |
|
|
66
171
|
|---|---|
|
|
67
|
-
| `NGROK_AUTHTOKEN` | ngrok free-tier authtoken.
|
|
172
|
+
| `NGROK_AUTHTOKEN` | ngrok free-tier authtoken. Enables the public tunnel. |
|
|
68
173
|
| `NGROK_DISABLED=1` | Skip the ngrok tunnel even if a token is available. |
|
|
69
174
|
| `CURSOR_DISABLED=1` | Skip the Cursor provider entirely. |
|
|
70
|
-
| `PASSWORD` | Optional password —
|
|
71
|
-
| `JWT_SECRET` | JWT signing secret (auto-generated
|
|
175
|
+
| `PASSWORD` | Optional password — required to connect when set. Bcrypt-hashed in memory only. |
|
|
176
|
+
| `JWT_SECRET` | JWT signing secret (auto-generated and persisted if not set). |
|
|
72
177
|
| `CLAUDE_PROJECTS_DIR` | Override Claude Code projects dir. |
|
|
73
178
|
| `COWORK_DIR` | Override Cowork sessions dir. |
|
|
74
179
|
| `CLAUDE_HISTORY_FILE` | Override `history.jsonl` path. |
|
|
75
180
|
| `CURSOR_DB_PATH` | Override Cursor `state.vscdb` path. |
|
|
181
|
+
| `PORT` | Override default port (`7878`). |
|
|
182
|
+
| `HOST` | Override default bind address (`0.0.0.0`). |
|
|
76
183
|
|
|
77
|
-
`.env` files are read from `./.env`
|
|
78
|
-
|
|
184
|
+
`.env` files are read from `./.env` then `~/.config/fleetwatch/.env`.
|
|
185
|
+
Shell env always wins.
|
|
79
186
|
|
|
80
|
-
|
|
187
|
+
### CLI flags
|
|
81
188
|
|
|
82
189
|
```
|
|
83
190
|
fleetwatch [options]
|
|
@@ -93,37 +200,45 @@ fleetwatch [options]
|
|
|
93
200
|
--help, -h Show help
|
|
94
201
|
```
|
|
95
202
|
|
|
203
|
+
---
|
|
204
|
+
|
|
96
205
|
## Providers
|
|
97
206
|
|
|
98
|
-
|
|
207
|
+
Each "provider" surfaces sessions from one source. Discovery is robust —
|
|
208
|
+
every provider tries the default path, then OS-specific alternatives, then
|
|
209
|
+
a bounded filesystem search, with a `verify()` predicate that confirms
|
|
210
|
+
the candidate is actually that provider's data.
|
|
99
211
|
|
|
100
|
-
| Provider |
|
|
101
|
-
|
|
102
|
-
| **Claude Code** | `~/.claude/projects/*.jsonl` (
|
|
103
|
-
| **Cowork** | `~/Library/Application Support/Claude/local-agent-mode-sessions
|
|
104
|
-
| **Cursor** | `~/Library/Application Support/Cursor/User/globalStorage/state.vscdb` |
|
|
212
|
+
| Provider | Discovers | Format |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| **Claude Code** | `~/.claude/projects/*.jsonl` (plus `$CLAUDE_PROJECTS_DIR`, XDG dirs, fallback search) | Append-only JSONL |
|
|
215
|
+
| **Cowork** | `~/Library/Application Support/Claude/local-agent-mode-sessions/` | Append-only JSONL (same schema as Claude Code) |
|
|
216
|
+
| **Cursor** | `~/Library/Application Support/Cursor/User/globalStorage/state.vscdb` (plus Linux/Windows paths) | SQLite, read-only |
|
|
217
|
+
|
|
218
|
+
### Adding a new provider
|
|
105
219
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
confirms it's actually that provider's data (so VSCode's `state.vscdb`
|
|
111
|
-
never gets mistaken for Cursor's).
|
|
220
|
+
Aider? Continue? GitHub Copilot Chat? Custom internal agents? Extending
|
|
221
|
+
fleetwatch with a new source is intentionally small: declare a
|
|
222
|
+
`ProviderInfo`, declare a `DiscoverySpec`, implement `onStart` /
|
|
223
|
+
`backfillSession`.
|
|
112
224
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
225
|
+
Full guide: [`docs/ADD_A_PROVIDER.md`](docs/ADD_A_PROVIDER.md)
|
|
226
|
+
|
|
227
|
+
---
|
|
116
228
|
|
|
117
229
|
## Security
|
|
118
230
|
|
|
119
|
-
- All
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
- No telemetry. No external calls
|
|
231
|
+
- All HTTP and WebSocket endpoints require auth (pairing token OR JWT).
|
|
232
|
+
- Image attachments served from content-addressed (sha256) URLs — no
|
|
233
|
+
enumeration possible.
|
|
234
|
+
- Daemon is **read-only**:
|
|
235
|
+
- JSONL files opened with append-only tailing (rotation-safe via inode)
|
|
236
|
+
- SQLite opened with `readonly: true` + `fileMustExist: true`
|
|
237
|
+
- Never follows symlinks during discovery
|
|
238
|
+
- No telemetry. No external network calls except ngrok (when enabled).
|
|
239
|
+
- All state lives in `~/.config/fleetwatch/` — a single JSON file.
|
|
240
|
+
|
|
241
|
+
---
|
|
127
242
|
|
|
128
243
|
## Development
|
|
129
244
|
|
|
@@ -131,26 +246,46 @@ Adding a new provider (Aider, Continue, anything else) is small — extend
|
|
|
131
246
|
git clone https://github.com/ohmaseclaro/fleetwatch
|
|
132
247
|
cd fleetwatch
|
|
133
248
|
npm install
|
|
134
|
-
|
|
135
|
-
|
|
249
|
+
|
|
250
|
+
# In one terminal: Vite HMR for the PWA
|
|
251
|
+
npm run dev:web
|
|
252
|
+
|
|
253
|
+
# In another: daemon in watch mode
|
|
254
|
+
npm run dev:server
|
|
136
255
|
```
|
|
137
256
|
|
|
138
257
|
Production build:
|
|
139
258
|
|
|
140
259
|
```bash
|
|
141
|
-
npm run build
|
|
142
|
-
npm start
|
|
260
|
+
npm run build
|
|
261
|
+
npm start # serves built bundle on :7878
|
|
143
262
|
```
|
|
144
263
|
|
|
264
|
+
---
|
|
265
|
+
|
|
145
266
|
## Releasing
|
|
146
267
|
|
|
268
|
+
[`scripts/release.sh`](scripts/release.sh) handles everything:
|
|
269
|
+
|
|
147
270
|
```bash
|
|
148
|
-
|
|
271
|
+
./scripts/release.sh patch # 0.1.2 → 0.1.3
|
|
272
|
+
./scripts/release.sh minor # 0.1.2 → 0.2.0
|
|
273
|
+
./scripts/release.sh major # 0.1.2 → 1.0.0
|
|
274
|
+
./scripts/release.sh patch --otp=123456 # if 2FA is enforced
|
|
149
275
|
```
|
|
150
276
|
|
|
151
|
-
|
|
152
|
-
|
|
277
|
+
The script:
|
|
278
|
+
- verifies clean tree + on `main`/`master`
|
|
279
|
+
- runs typecheck + build
|
|
280
|
+
- bumps the version
|
|
281
|
+
- creates a `vX.Y.Z` commit + tag
|
|
282
|
+
- publishes to npm (token from `.env` via project `.npmrc`)
|
|
283
|
+
- pushes to GitHub
|
|
284
|
+
|
|
285
|
+
First-time setup: [`docs/PUBLISHING.md`](docs/PUBLISHING.md).
|
|
286
|
+
|
|
287
|
+
---
|
|
153
288
|
|
|
154
289
|
## License
|
|
155
290
|
|
|
156
|
-
MIT
|
|
291
|
+
[MIT](LICENSE) © Augusto Claro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ohmaseclaro/fleetwatch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Watch every Claude Code, Cowork, and Cursor session from your phone — multi-provider agent observability with live updates over LAN or ngrok.",
|
|
6
6
|
"keywords": [
|