conductor-remote 1.30.3 → 1.31.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/README.md CHANGED
@@ -65,9 +65,10 @@ across re-deploys.
65
65
  (React, installable) │
66
66
  ├─ reads: node:sqlite ⟶ conductor.db (workspaces, sessions, transcripts)
67
67
  ├─ reads: git ⟶ each worktree (diffs vs target branch)
68
- └─ writes: Actuator ⟶ Conductor
69
- ├─ applescript (default): osascript ⟶ focused session
70
- └─ sidecar (opt-in): unix socket ⟶ exact session
68
+ ├─ writes: Actuator ⟶ Conductor
69
+ ├─ applescript (default): osascript ⟶ focused session
70
+ └─ sidecar (opt-in): unix socket ⟶ exact session
71
+ └─ push: turn ended ⟶ Web Push ⟶ your lock screen
71
72
  ```
72
73
 
73
74
  - **Two halves.** A **Node relay** on the Mac (reads Conductor's state, drives
@@ -77,6 +78,9 @@ across re-deploys.
77
78
  git worktrees outlive UI changes.
78
79
  - **Writes are the one fragile nerve** and are isolated behind a swappable
79
80
  `Actuator` (`src/writes.ts`).
81
+ - **Notifications ride the durable side.** The relay watches the same SQLite for
82
+ turns ending and sends a Web Push straight to the phone — no Conductor process
83
+ involved, and it works with the app closed.
80
84
 
81
85
  ## Stack
82
86
 
@@ -162,6 +166,8 @@ env. `EXPOSE`/`--expose` is documented under Install above.
162
166
  | `AUTO_UPDATE` | `--auto-update` | `auto` | Self-update mode: `auto` / `check` / `off` |
163
167
  | `CONDUCTOR_DB` | `--db` | `~/Library/Application Support/com.conductor.app/conductor.db` | State DB |
164
168
  | `CONDUCTOR_WORKSPACES` | `--workspaces` | `~/conductor/workspaces` | Worktree root |
169
+ | `PUSH_NOTIFY` | — | `on` | `off` disables push notifications entirely |
170
+ | `PUSH_SUBJECT` | — | the project's repo URL | VAPID `sub` (a `mailto:` or `https:` URL identifying the sender) |
165
171
 
166
172
  The token is auto-generated once and persisted, so the home-screen icon keeps
167
173
  working across restarts without any env var. To pin a specific secret (e.g. to
@@ -174,7 +180,9 @@ RELAY_TOKEN=$(openssl rand -hex 16) yarn start
174
180
  ## What works today
175
181
 
176
182
  - ✅ Live list of active workspaces with agent status (working / idle / done),
177
- repo, branch, model, context %, unread badge.
183
+ repo, branch, model, context %, and an unread mark on any workspace whose chats
184
+ finished something you haven't looked at — reading it *on the phone* clears it,
185
+ which Conductor itself only does when you open the workspace on the Mac.
178
186
  - ✅ Live transcript per session (assistant text, tool calls, queued messages),
179
187
  incremental polling.
180
188
  - ✅ Diff vs the workspace's target branch (file list + colorized patch,
@@ -187,6 +195,33 @@ RELAY_TOKEN=$(openssl rand -hex 16) yarn start
187
195
  target `sessionId` over Conductor's dispatch socket — precise per-workspace
188
196
  targeting, no focus needed. Speaks a private, versioned IPC (see FINDINGS ▸
189
197
  Writes), so it's the more fragile of the two.
198
+ - ✅ **Push notifications** when an agent finishes its turn or hits an error —
199
+ see below.
200
+
201
+ ## Notifications
202
+
203
+ Turn them on from the **Connect sheet** (the QR button in the workspace list
204
+ header) ▸ *Notifications*. The relay then pings that phone whenever an agent
205
+ **ends a turn** — which covers finishing, asking you a question, and stopping at
206
+ a permission prompt — or **errors**. The notification carries the workspace name,
207
+ the repo, and the agent's last line; tapping it opens that workspace.
208
+
209
+ Notifications arrive with the app closed. There's a *Send a test notification*
210
+ link right under the switch to prove the path end to end.
211
+
212
+ **On iPhone/iPad you must add the app to your Home Screen first** — iOS only
213
+ exposes notifications to installed web apps, never to a Safari tab. The switch
214
+ says so if you haven't. The connection also has to be `https://` (the Tailscale
215
+ URL `yarn deploy` sets up, or `127.0.0.1` locally); a plain LAN IP is not a
216
+ secure context and browsers refuse push there.
217
+
218
+ Under the hood: standard Web Push (VAPID + `aes128gcm`), implemented directly on
219
+ `node:crypto` so the package keeps its zero runtime dependencies. Subscriptions
220
+ and the VAPID keypair live in
221
+ `~/Library/Application Support/conductor-remote/push.json` (mode `0600`). The
222
+ relay only ever POSTs to Apple's/Google's/Mozilla's push endpoint for the phones
223
+ you subscribed; nothing else leaves the Mac. `PUSH_NOTIFY=off` disables the whole
224
+ thing.
190
225
 
191
226
  ## Layout
192
227
 
@@ -200,10 +235,13 @@ src/ the Node relay (no build step)
200
235
  git.ts workspace diff vs target branch (incl. untracked)
201
236
  sidecar.ts Conductor sidecar IPC client (precise write path)
202
237
  writes.ts Actuator interface + AppleScript (default) + Sidecar (opt-in)
238
+ notify.ts watches session status for ended turns → push; subscription store
239
+ webpush.ts Web Push (VAPID + aes128gcm) on node:crypto — no dependencies
203
240
  logbuf.ts console capture + log-file tail behind /api/logs (token redacted)
204
241
  web/ the React PWA (Vite)
205
242
  index.html, src/ app shell, components, hooks, api client
206
243
  public/ icon.svg + PWA PNGs (repo-root so Conductor's icon lookup finds them)
244
+ push-sw.js push / notification-click handlers, imported into the generated SW
207
245
  scripts/
208
246
  dev.ts runs Vite + relay together
209
247
  gen-icons.ts rasterizes icon.svg → PWA PNGs (sharp)