@dreb/coding-agent 2.35.0 → 2.36.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 (2) hide show
  1. package/docs/dashboard.md +106 -4
  2. package/package.json +1 -1
package/docs/dashboard.md CHANGED
@@ -18,6 +18,10 @@ dreb dashboard [--port 5343]
18
18
 
19
19
  # or directly
20
20
  dreb-dashboard [--port 5343]
21
+
22
+ # remote over Tailscale with HTTPS (PWA + notifications on mobile)
23
+ dreb dashboard --remote --allow you@example.com \
24
+ --https --cert /path/cert.pem --key /path/key.pem
21
25
  ```
22
26
 
23
27
  If `@dreb/dashboard` is not installed, `dreb dashboard` fails loudly with
@@ -94,10 +98,108 @@ When the agent is idle, send is a plain prompt.
94
98
 
95
99
  ## Notifications
96
100
 
97
- The settings tab exposes a browser-local permission toggle for needs-attention
98
- notifications. When permission is granted, a hidden dashboard tab sends a
99
- browser notification when a session newly needs input; all browsers still get a
100
- `◆` tab-title badge fallback.
101
+ Needs-attention notifications are delivered through a **service worker**
102
+ (`registration.showNotification()`), not the page-context `Notification`
103
+ constructor the constructor was removed from Android Chrome (throws
104
+ `Illegal constructor`) and is absent from iOS Safari entirely. The service
105
+ worker handles `notificationclick`: it focuses an open dashboard client and
106
+ navigates to the session that needs attention, or opens one. All browsers still
107
+ get a `◆` tab-title badge fallback when the tab is hidden.
108
+
109
+ The settings tab exposes a browser-local permission toggle. Gating is unchanged:
110
+ notifications fire only when permission is granted **and** the tab is hidden.
111
+
112
+ **iOS:** notifications exist only in the **installed PWA** (Add to Home Screen,
113
+ iOS 16.4+) — a plain Safari tab has no Notification API regardless of HTTPS.
114
+ The settings copy explains the install prerequisite when it detects an
115
+ un-installed iOS Safari session. (Note: iOS 17.4+ in the EU dropped standalone
116
+ PWA support — installed PWAs open as Safari tabs and push is unavailable there.)
117
+
118
+ ## Installable PWA + secure context
119
+
120
+ The dashboard ships a web app manifest (`display: standalone`, theme/background
121
+ colors, icon set), an apple-touch-icon, and service worker registration, so it
122
+ is **installable to the home screen** on Android Chrome and iOS Safari 16.4+ —
123
+ no URL bar, app-like presence, and (on iOS) the only context where
124
+ notifications work.
125
+
126
+ Service workers and the Notifications API require a **secure context**: HTTPS,
127
+ or `localhost`/`127.0.0.1`. Local mode (`http://127.0.0.1:<port>`) already
128
+ qualifies — install and notifications work with no TLS setup. **Remote mode
129
+ over the tailnet is plain HTTP**, which is not a secure context, so the service
130
+ worker will not register and notifications are unavailable until you enable
131
+ HTTPS. See [Native TLS](#native-tls-remote-https) below.
132
+
133
+ ## Native TLS (remote HTTPS)
134
+
135
+ For PWA install + notifications from a phone over the tailnet, the dashboard
136
+ terminates TLS itself using certificate files from
137
+ [`tailscale cert`](https://tailscale.com/docs/how-to/set-up-https-certificates)
138
+ (no reverse proxy, **no auth-model change**):
139
+
140
+ ```bash
141
+ dreb dashboard --remote --allow you@example.com \
142
+ --https --cert /etc/dreb/cert.pem --key /etc/dreb/key.pem
143
+ ```
144
+
145
+ Because the dashboard terminates TLS directly, `req.socket.remoteAddress` is
146
+ still the phone's real tailnet IP — Tailscale identity resolution, the
147
+ allowlist, and pairing all keep working exactly as in plain-HTTP remote mode.
148
+ There is no header trust, no proxy, no weakening of the auth model.
149
+
150
+ ### One-time cert setup with `tailscale cert`
151
+
152
+ ```bash
153
+ # Enable HTTPS certificates in the Tailscale admin console (DNS → HTTPS) first.
154
+ sudo tailscale cert \
155
+ --cert-file=/etc/dreb/cert.pem \
156
+ --key-file=/etc/dreb/key.pem \
157
+ hostname.tailXXXX.ts.net
158
+ sudo chown dreb:dreb /etc/dreb/cert.pem /etc/dreb/key.pem
159
+ sudo chmod 644 /etc/dreb/cert.pem && sudo chmod 600 /etc/dreb/key.pem
160
+ ```
161
+
162
+ Renewal is **manual** — `tailscale cert` certs are Let's Encrypt, 90-day
163
+ lifetime. The dashboard hot-reloads the cert files on change
164
+ (`setSecureContext`), so a renewal that rewrites the files is picked up with
165
+ zero downtime. A daily systemd timer with `--min-validity=720h` (only renews
166
+ when within 30 days of expiry) is the recommended cadence:
167
+
168
+ ```ini
169
+ # /etc/systemd/system/dreb-cert.service
170
+ [Service]
171
+ Type=oneshot
172
+ ExecStart=/usr/bin/tailscale cert --cert-file=/etc/dreb/cert.pem \
173
+ --key-file=/etc/dreb/key.pem --min-validity=720h hostname.tailXXXX.ts.net
174
+ ExecStartPost=/bin/chown dreb:dreb /etc/dreb/cert.pem /etc/dreb/key.pem
175
+
176
+ # /etc/systemd/system/dreb-cert.timer
177
+ [Timer]
178
+ OnCalendar=daily
179
+ RandomizedDelaySec=3600
180
+ [Install]
181
+ WantedBy=timers.target
182
+ ```
183
+
184
+ Then open `https://hostname.tailXXXX.ts.net:<port>` on the phone.
185
+
186
+ > **Hostname note (important):** the `tailscale cert` certificate is issued
187
+ > for your machine's tailnet name (`hostname.tailXXXX.ts.net`) **only** — not
188
+ > `127.0.0.1`, not a raw tailnet IP. When `--https` is enabled the server
189
+ > speaks TLS on every address it binds, so on the host itself:
190
+ >
191
+ > - `https://hostname.tailXXXX.ts.net:<port>` — works, cert validates (resolves
192
+ > to your tailnet IP). But it's a *remote* request: you go through the full
193
+ > Tailscale allowlist + pairing flow, not instant loopback local mode.
194
+ > - `https://127.0.0.1:<port>` — the server answers, but the browser rejects
195
+ > the cert (no `127.0.0.1` SAN) with a scary warning.
196
+ > - `http://127.0.0.1:<port>` — **dead**: the server only speaks TLS now.
197
+ >
198
+ > If you want the host dashboard tab to stay instant (loopback local mode, no
199
+ > pairing, no warning), run a **second** dashboard process without `--https` on
200
+ > a different port for local-only use, and keep the TLS-enabled one for remote.
201
+ > `--https` is primarily for the `--remote` path; pure-local setups don't need
202
+ > it (`127.0.0.1` is already a secure context).
101
203
 
102
204
  ## Subagent observability
103
205
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dreb/coding-agent",
3
- "version": "2.35.0",
3
+ "version": "2.36.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "drebConfig": {