hop2 0.9.0 β†’ 0.10.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 (46) hide show
  1. package/AGENTS.md +33 -0
  2. package/INTEGRATION.md +77 -85
  3. package/MULTI-AGENT-CHECKLIST.md +37 -0
  4. package/README-MCP.md +232 -0
  5. package/README.md +209 -148
  6. package/demo/30s-product-demo.md +98 -0
  7. package/demo/README.md +106 -0
  8. package/demo/director.mjs +236 -0
  9. package/demo/drive-hop-terminal.mjs +70 -0
  10. package/demo/hop-demo-lib.mjs +525 -0
  11. package/demo/record-hop-view.mjs +26 -0
  12. package/demo/static-preview-server.mjs +45 -0
  13. package/demo/stitch-demo-video.mjs +128 -0
  14. package/hay/CHANGELOG.md +6 -0
  15. package/hay/DEV_NOTES.md +25 -0
  16. package/hay/README.md +136 -198
  17. package/hay/apps/cli/src/index.ts +321 -67
  18. package/hay/apps/server/src/index.ts +4 -3
  19. package/hay/apps/server/src/lib.ts +5 -4
  20. package/hay/apps/server/src/pty.ts +20 -7
  21. package/hay/apps/server/src/rooms.ts +226 -12
  22. package/hay/apps/server/test/rooms.test.ts +82 -3
  23. package/hay/apps/web/src/App.tsx +487 -112
  24. package/hay/apps/web/src/components/MobileKeyboard.tsx +43 -2
  25. package/hay/apps/web/src/styles.css +259 -29
  26. package/hay/package-lock.json +4 -4
  27. package/hay/packages/shared/src/protocol.ts +8 -0
  28. package/hay-web/assets/index-BmWjq_Nh.css +32 -0
  29. package/hay-web/assets/index-D9aOC5Zt.js +63 -0
  30. package/hay-web/assets/{index-FDfdolCs.js.map β†’ index-D9aOC5Zt.js.map} +1 -1
  31. package/hay-web/index.html +2 -2
  32. package/hop +6801 -1714
  33. package/lib/naming-themes.js +194 -0
  34. package/lib/terminal-access.js +17 -0
  35. package/mcp/hop-mcp.js +4730 -0
  36. package/package.json +6 -3
  37. package/scripts/hay-host.js +189 -0
  38. package/sessions.html +378 -26
  39. package/setup-mcp.js +443 -0
  40. package/tests/hop-mcp.integration.test.cjs +3014 -0
  41. package/tests/terminal-access.unit.test.cjs +21 -0
  42. package/tests/terminal-api.integration.test.cjs +298 -0
  43. package/.hop-tmux.conf +0 -18
  44. package/hay-web/assets/index-CTTzApRp.css +0 -32
  45. package/hay-web/assets/index-FDfdolCs.js +0 -60
  46. package/tunnel-shell.js +0 -254
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # 🐰 hop
2
2
 
3
- **Hop into your terminal from anywhere in the world.**
3
+ **Terminal access for humans and agents.**
4
4
 
5
- Access your Mac's terminal from your phone, tablet, or any browser β€” secured with password + 2FA, tunneled through Cloudflare.
5
+ Hop gives you secure browser access to local terminals and a built-in MCP server for creating, driving, and auditing agent sessions over the same runtime.
6
6
 
7
- > **🍎 macOS/Linux** β€” Requires cloudflared for tunneling
7
+ > **macOS/Linux** β€” Requires cloudflared for tunneling
8
8
 
9
9
  ```
10
10
  (\(\
@@ -12,33 +12,42 @@ Access your Mac's terminal from your phone, tablet, or any browser β€” secured w
12
12
  o_(")(")
13
13
  ```
14
14
 
15
- ## ✨ Features
15
+ ## Why Hop
16
16
 
17
- - πŸ” **Password + 2FA** β€” Optional password plus TOTP (required for custom domains)
18
- - 🌍 **Access Anywhere** β€” Cloudflare tunnel, no port forwarding
19
- - 🌐 **Custom Domains + Multi‑User** β€” Share subdomains with per‑user credentials
20
- - πŸ“± **Mobile Virtual Keyboard** β€” Custom keyboard with Esc, Ctrl, Alt, arrows, and more
21
- - ⌨️ **Native Keyboard Support** β€” Tap the blue button for dictation, spellcheck & autocomplete
22
- - πŸͺŸ **Multi-Session** β€” Create and switch between named sessions
23
- - πŸ”Œ **Port Sessions** β€” Proxy a local HTTP/WS service via hop
24
- - πŸ”„ **Quick Session Switching** β€” Floating menu to switch sessions without leaving the terminal
25
- - 🎨 **Modern UI** β€” Clean, minimal iOS-style design
26
- - ⚑ **Auto-Attach** β€” Multiple terminals share the same tunnel
17
+ - **Browser terminal from anywhere** β€” Tunnel through Cloudflare with no port forwarding
18
+ - **MCP-native terminal control** β€” Claude Code, Codex, Gemini, Cursor, and other MCP clients can create terminals, stream output, and send input through Hop
19
+ - **One runtime for humans and agents** β€” The browser UI, local CLI, and MCP server operate on the same sessions
20
+ - **Operationally useful primitives** β€” Named sessions, port sessions, auto-attach, and explicit workspace snapshots
21
+ - **Auditability built in** β€” Per-session logs, isolated agent history, and TUI-aware capture defaults
22
+ - **Security when you need it** β€” Password + 2FA, custom domains, and multi-user support
27
23
 
28
24
  ## πŸš€ Quick Install
29
25
 
26
+ Most users only need the npm install. Source install is mainly for development or local hacking.
27
+
30
28
  ### From npm (easiest)
31
29
 
32
30
  ```bash
33
31
  npm install -g hop2
34
32
  ```
35
33
 
36
- Then just run:
34
+ This installs:
35
+ - `hop` β€” main CLI / daemon / browser terminal entrypoint
36
+ - `hop-mcp` β€” MCP server exposing Hop terminals and sessions
37
+ - `hop-mcp-setup` β€” MCP client auto-config helper
38
+
39
+ Then:
37
40
  ```bash
38
41
  hop
39
42
  ```
40
43
 
41
- ### One-liner from source
44
+ If you want agent access too:
45
+
46
+ ```bash
47
+ hop-mcp-setup
48
+ ```
49
+
50
+ ### From source (one-liner)
42
51
 
43
52
  ```bash
44
53
  git clone https://github.com/jzthree/hop.git ~/.hop && \
@@ -46,7 +55,7 @@ cd ~/.hop && npm install && \
46
55
  sudo ln -sf ~/.hop/hop /usr/local/bin/hop
47
56
  ```
48
57
 
49
- ### Manual Install from source
58
+ ### From source (manual)
50
59
 
51
60
  ```bash
52
61
  # Clone the repo
@@ -64,114 +73,202 @@ echo 'export PATH="$HOME/.hop:$PATH"' >> ~/.zshrc
64
73
  source ~/.zshrc
65
74
  ```
66
75
 
67
- ## 🐰 Usage
76
+ ## Quick Start
68
77
 
78
+ ### Browser access
69
79
  ```bash
70
- # Start hopping!
71
80
  hop
81
+ ```
82
+
83
+ First run:
84
+ 1. Optionally set a password with `hop password set`
85
+ 2. Scan the authenticator QR code
86
+ 3. Note the URL
87
+ 4. Press Enter to start your first local terminal
88
+
89
+ Then open the URL from another device, sign in, and pick or create a session.
72
90
 
73
- # Use iTerm control mode for local session
74
- hop --iterm
91
+ ### MCP access
92
+
93
+ ```bash
94
+ hop
95
+ hop-mcp-setup
75
96
  ```
76
97
 
77
- **First time:**
78
- 1. (Optional) Set a password: `hop password set`
79
- 2. Scan the QR code with your authenticator app (Google Authenticator, Authy, 1Password, etc.)
80
- 3. Note the URL displayed
81
- 4. Press Enter to start your local session
98
+ Then restart your MCP client. `hop-mcp-setup` auto-detects and configures supported clients such as Claude Code, Claude Desktop, Cursor, Gemini CLI, Codex CLI, VS Code / Copilot, and Antigravity.
99
+
100
+ Typical use cases:
101
+ - Launch a dedicated Claude Code / Codex / Gemini terminal and drive it over multiple turns
102
+ - Create isolated agent sessions with per-session history and audit logs
103
+ - Read terminal output incrementally instead of screen-scraping a browser
104
+ - Build higher-level agent workflows on top of stable terminal/session primitives
105
+
106
+ For full MCP usage, tools, and subagent workflows, see [README-MCP.md](./README-MCP.md).
82
107
 
83
- **From your phone:**
84
- 1. Open the URL in your browser
85
- 2. Enter your password (if enabled) and 6‑digit code
86
- 3. Pick or create a session
87
- 4. 🐰 You're in! Use the virtual keyboard for terminal keys, or tap the blue button for native input
108
+ ## Everyday Workflows
88
109
 
89
- ## πŸͺŸ Sessions
110
+ ### Create and Reuse Sessions
90
111
 
91
112
  Create multiple independent terminal sessions from the Session Picker (`/sessions`):
92
113
 
93
- - **Create**: Type a name and click Create
94
- - **Join**: Click Join on any existing session
95
- - **Sessions are shared**: Multiple devices can view the same session
114
+ - Create a new named shell session
115
+ - Join any existing session
116
+ - Share a live session between multiple devices
117
+ - Save selected live terminal sessions into a named workspace when you want to reuse them later
118
+
119
+ Scratch sessions stay live-only unless you explicitly save them into a workspace. To save reusable definitions from the CLI:
96
120
 
97
- You can also create **Port Sessions** that proxy to a local HTTP/WS service on your machine.
98
- Use the Session Picker or:
99
121
  ```bash
100
- hop session add myapp --port 3000
122
+ hop session add workspace-shell --cwd ~/src/my-project --workspace dev
123
+ hop session add myapp --port 3000 --workspace dev
101
124
  ```
102
125
 
103
- ## 🌐 Custom Domains & Multi‑User
104
-
105
- ### Admin (your machine)
106
- 1. Set a password (required for custom domains):
107
- ```bash
108
- hop password set
109
- ```
110
- 2. Configure your domain:
111
- ```bash
112
- hop domain hop.yourdomain.com
113
- ```
114
- 3. Add a user + export credentials:
115
- ```bash
116
- hop user add alice
117
- hop user export alice
118
- ```
119
- 4. Send the exported folder to the user.
120
-
121
- ### User (their machine)
126
+ Use `hop workspace save <name>` to snapshot selected live terminal sessions, or `hop session add ... --workspace <name>` when you want to define a reusable terminal or port entry directly.
127
+
128
+ Inspect or remove saved workspace definitions with:
129
+
122
130
  ```bash
123
- npm install -g hop2
124
- hop client ./credentials.json
131
+ hop workspace show dev
132
+ hop workspace delete dev
125
133
  ```
126
- First run prompts them to set a password + scan a TOTP QR code.
127
- They then log in at their URL, e.g. `https://alice.hop.yourdomain.com`.
128
134
 
129
- ## πŸ“± Mobile Keyboard
135
+ ### Drive a Subagent Over MCP
136
+
137
+ Use one dedicated terminal per subagent.
130
138
 
131
- On mobile devices, Hop provides a custom virtual keyboard designed for terminal use:
139
+ 1. Create a terminal with `hop_create_terminal` and set `name` / `cwd`.
140
+ 2. Start the agent CLI with `hop_write_terminal`.
141
+ 3. Wait for readiness with `hop_wait_terminal(until_prompt=true)`.
142
+ 4. Prefer `hopx_agent_turn(mode="auto")` or `hopx_send_and_wait(...)` for one turn at a time.
143
+ 5. For long waits, use `hopx_agent_turn(async=true, ...)` or the lower-level `hop_wait_start(...)` / `hop_wait_poll(...)`.
144
+ 6. Interrupt with `hop_send_key(key="ctrl_c")` and close with `hop_close_terminal`.
132
145
 
133
- **Accessory Row:**
134
- - `Esc` `Tab` `Ctrl` `Alt` β€” Essential terminal keys
135
- - `← ↓ ↑ β†’` β€” Arrow keys for navigation
136
- - πŸ”΅ **Blue keyboard button** β€” Opens native iOS keyboard for dictation, spellcheck & autocomplete
146
+ Safety tips:
137
147
 
138
- **Floating Menu (top-right button):**
139
- - **Toggle Keyboard** β€” Show/hide the virtual keyboard
140
- - **Session List** β€” Quick-switch between sessions
141
- - **All Sessions** β€” Return to session picker
148
+ - Keep one subagent per terminal.
149
+ - Do not queue a second instruction before reading the first response.
150
+ - For attached user sessions, confirm `agentPermitted` before sending input.
142
151
 
143
- **Tips:**
144
- - The floating button is draggable β€” move it anywhere
145
- - First-time users will see a tooltip pointing to the native keyboard button
146
- - Use the native keyboard for longer text input with autocomplete
152
+ ### Share a Local Web App
147
153
 
148
- ## πŸ–₯️ iTerm Integration
154
+ Expose a local HTTP or WebSocket service through your Hop tunnel:
149
155
 
150
156
  ```bash
151
- hop --iterm
157
+ hop session add myapp --port 3000
152
158
  ```
153
159
 
154
- Uses tmux control mode (`-CC`) for native scrolling, copy/paste, splits, and search. Session remains accessible via web.
160
+ Result:
161
+
162
+ - local service stays on localhost
163
+ - Hop exposes it at `https://your-tunnel-url/s/myapp/`
164
+ - WebSocket apps work too
155
165
 
156
- ## πŸ”Œ Port Sessions
166
+ ### Reattach Locally
157
167
 
158
- Expose local HTTP/WebSocket services through your tunnel:
168
+ Attach your local terminal client to an existing terminal session:
159
169
 
160
170
  ```bash
161
- hop session add myapp --port 3000
162
- # Access at: https://your-tunnel-url/s/myapp/
171
+ hop attach <session>
163
172
  ```
164
173
 
165
- Works with dev servers, Jupyter, APIs β€” anything on localhost. Supports WebSocket.
174
+ This is useful when you want a browser, an MCP client, and a local shell to converge on the same named session.
175
+
176
+ ### Use Hop on Mobile
177
+
178
+ Hop’s mobile UI includes:
179
+
180
+ - a terminal-oriented accessory row with `Esc`, `Tab`, `Ctrl`, `Alt`, and arrows
181
+ - a native keyboard button for dictation, spellcheck, and autocomplete
182
+ - a floating menu for keyboard toggle and session switching
183
+ - draggable controls designed for one-handed use
184
+
185
+ ## Operations
186
+
187
+ ### Logging and History
188
+
189
+ Hop always writes per-session audit logs.
190
+
191
+ Default behavior:
192
+
193
+ - agent-created sessions get isolated shell history files
194
+ - user-created sessions keep normal shell history unless you opt into isolation
195
+ - TUI apps switch to diff-suppressed keyframe capture automatically
196
+
197
+ Paths:
198
+
199
+ - scratch sessions: `~/.hop2/runtime/history/<internal-session>.history`
200
+ - scratch audit logs: `~/.hop2/runtime/logs/<internal-session>/audit.ndjson`
201
+ - workspace-backed sessions: `~/.hop2/workspaces/<workspace>/history/<internal-session>.history`
202
+ - workspace-backed audit logs: `~/.hop2/workspaces/<workspace>/logs/<internal-session>/audit.ndjson`
203
+
204
+ Key tunables:
166
205
 
167
- ## πŸ”§ Commands
206
+ - `HOP_SESSION_HISTORY_SIZE`
207
+ - `HOP_AGENT_HISTORY_ISOLATION`
208
+ - `HOP_USER_HISTORY_ISOLATION`
209
+ - `HOP_AGENT_POST_START_HISTORY_INIT`
210
+ - `HOP_POST_START_HISTORY_INIT`
211
+ - `HOP_SESSION_AUDIT_INLINE_MAX_BYTES`
212
+ - `HOP_SESSION_TUI_KEYFRAME_INTERVAL_MS`
213
+ - `HOP_SESSION_TUI_KEYFRAME_TAIL_CHARS`
214
+ - `HOP_SESSION_TUI_KEYFRAME_MAX_LINES`
215
+
216
+ ### Users, Domains, and Sharing
217
+
218
+ Admin flow:
219
+
220
+ 1. Set a password with `hop password set`.
221
+ 2. Configure a hostname with `hop domain hop.yourdomain.com`.
222
+ 3. Add a user with `hop user add alice`.
223
+ 4. Export credentials with `hop user export alice`.
224
+
225
+ User flow:
226
+
227
+ ```bash
228
+ npm install -g hop2
229
+ hop client ./credentials.json
230
+ ```
231
+
232
+ First run prompts for password setup and TOTP enrollment, then the user logs in at their assigned URL such as `https://alice.hop.yourdomain.com`.
233
+
234
+ ### Security
235
+
236
+ - Password + TOTP is supported; password is required for custom domains
237
+ - Login cookies are `httpOnly`, `secure`, and `sameSite=lax`
238
+ - Browser sessions persist across `hop stop/start` by default through a stable session secret
239
+ - The local server binds only to `127.0.0.1`
240
+ - Cloudflare Tunnel provides end-to-end TLS
241
+
242
+ Secrets are stored in `~/.hop2/`. Set `HOP_PERSIST_SESSION_SECRET=0` if you want login cookies invalidated on every daemon restart.
243
+
244
+ ### Runtime and Recovery
245
+
246
+ Hop uses the external Hay host runtime for PTY hosting and session recovery.
247
+
248
+ - active PTYs live in a separate local hay-host process
249
+ - the host survives daemon restarts
250
+ - host state is tracked in `~/.hop2/.hay-host-state`
251
+ - startup reconciles already-running Hay sessions before applying workspace state
252
+ - `HOP_TERMINAL_BACKEND` is accepted only for compatibility and ignored
253
+
254
+ ## Reference
255
+
256
+ ### Related Docs
257
+
258
+ - [README-MCP.md](./README-MCP.md) for MCP tools, helper wrappers, and agent-driving patterns
259
+ - [INTEGRATION.md](./INTEGRATION.md) for the current Hop/Hay architecture
260
+ - [hay/README.md](./hay/README.md) for the vendored Hay workspace
261
+
262
+ ### Commands
168
263
 
169
264
  | Command | Description |
170
265
  |---------|-------------|
171
- | `hop` | Start hop (or attach to existing tunnel) |
172
- | `hop --iterm` | Use iTerm tmux control mode for local session |
266
+ | `hop` | Start hop daemon/tunnel if needed, then launch a local terminal |
267
+ | `hop attach all` | Attach sequentially to all terminal sessions |
268
+ | `hop local [session]` | Start a daemonless local terminal (`[session]` attaches if it exists) |
173
269
  | `hop url` | Print current tunnel URL |
174
- | `hop qr` | Show QR code for current URL |
270
+ | `hop qr` | Show QR code for current tunnel URL |
271
+ | `hop qr auth` | Show QR code for authenticator app setup |
175
272
  | `hop domain <hostname>` | Set custom domain (named tunnel) |
176
273
  | `hop domain-clear` | Remove custom domain, use random URLs |
177
274
  | `hop password set` | Set/change password |
@@ -180,81 +277,45 @@ Works with dev servers, Jupyter, APIs β€” anything on localhost. Supports WebSoc
180
277
  | `hop user add <name>` | Add user + subdomain |
181
278
  | `hop user remove <name>` | Remove user |
182
279
  | `hop user export <name>` | Export user credentials |
183
- | `hop session list` | List sessions |
184
- | `hop session add <name>` | Create a terminal session |
185
- | `hop session add <name> --port N` | Create a port session (proxy) |
280
+ | `hop session list` | List live terminal sessions |
281
+ | `hop session list --all` | Include saved definitions from all workspaces alongside live sessions |
282
+ | `hop session add <name> [--cwd P] --workspace W` | Save a terminal session definition to a named workspace |
283
+ | `hop session add <name> --port N --workspace W` | Save a port session definition to a named workspace |
284
+ | `hop workspace create <name>` | Create an empty workspace |
285
+ | `hop workspace show <name>` | Show saved definitions in a workspace |
286
+ | `hop workspace save <name>` | Save selected live terminal sessions into a workspace |
287
+ | `hop workspace load <name>` | Start sessions defined in a workspace |
288
+ | `hop workspace delete <name>` | Delete a workspace |
289
+ | `hop session rename <old> <new>` | Rename a session |
186
290
  | `hop session remove <name>` | Remove a session |
187
291
  | `hop client <credentials>` | Run hop with exported credentials |
188
- | `hop wipe` | Kill all hop tmux sessions |
189
- | `quit` | Type at exit prompt to shutdown tunnel |
190
-
191
- ## πŸ“¦ Dependencies
192
-
193
- Installed automatically via Homebrew:
194
- - `tmux` β€” Terminal multiplexer
195
- - `ttyd` β€” Web terminal
196
- - `cloudflared` β€” Cloudflare tunnel
197
-
198
- Node.js packages:
199
- - `http-proxy` β€” Request proxying
200
- - `otplib` β€” TOTP authentication
201
- - `qrcode-terminal` β€” QR code display
202
- - `cookie` β€” Session cookies
203
-
204
- ## πŸ›‘οΈ Security
205
-
206
- - **Password + TOTP** β€” Password optional, but required for custom domains
207
- - **Rate Limiting** β€” Exponential backoff on failed attempts
208
- - **Secure Cookies** β€” `httpOnly`, `secure`, `sameSite=lax`
209
- - **Random URL** β€” Unguessable tunnel URL for quick tunnels
210
- - **Fixed URL** β€” Custom domains keep a stable URL
211
- - **Local Binding** β€” Server only listens on 127.0.0.1
212
- - **End-to-End TLS** β€” Cloudflare Tunnel encryption
213
-
214
- **Passwords:** Recommended for any public URL; required for custom domains.
292
+ | `hop wipe [--all]` | Remove workspace-defined sessions (`--all` also kills live sessions) |
293
+ | `quit` | Type at exit prompt to shut down the tunnel |
215
294
 
216
- **Secrets:** Stored in `~/.hop2/` (treat like `~/.ssh/`)
295
+ ### Development
217
296
 
218
- ## πŸ›  Development (Hay)
219
-
220
- The hay source is vendored in `./hay`. Hop will serve `hay/apps/web/dist` when present.
297
+ The Hay source is vendored in `./hay`. Hop serves `hay/apps/web/dist` when present.
221
298
 
222
299
  ```bash
223
300
  npm run build
301
+ npm test
224
302
  ```
225
303
 
226
- This builds hay (web + cli) and syncs `hay/apps/web/dist` into `hay-web/` for Hop to serve.
227
- If `./hay` exists and the dist folder is missing, `hop` will auto-build hay on startup.
228
-
229
- ## πŸ› Troubleshooting
304
+ This rebuilds Hay and syncs `hay/apps/web/dist` into `hay-web/`. `npm test` runs a basic syntax sanity check on the main `hop` entrypoint. If `./hay` exists and the dist folder is missing, `hop` auto-builds Hay on startup.
230
305
 
231
- **QR code not working?**
232
- Delete `.auth_secret` and restart hop to generate a new code.
306
+ ## Troubleshooting
233
307
 
234
- **Client reset (user mode)?**
235
- Delete `~/.hop2/clients/<tunnel-id>/` and run `hop client` again.
308
+ - Authenticator QR again: run `hop qr auth`
309
+ - Reset TOTP entirely: delete `.auth_secret` and restart Hop
310
+ - Reset a client install: delete `~/.hop2/clients/<tunnel-id>/` and run `hop client` again
311
+ - Tunnel not starting: install `cloudflared` with `brew install cloudflared`
312
+ - Tunnel returning `502` after a network change: run `hop health --restart`
313
+ - Stuck tunnel processes:
236
314
 
237
- **Tunnel not starting?**
238
- Make sure `cloudflared` is installed: `brew install cloudflared`
239
-
240
- **Stuck processes?**
241
315
  ```bash
242
- pkill ttyd; pkill cloudflared; tmux kill-server
316
+ pkill cloudflared
243
317
  ```
244
318
 
245
- ## πŸ“ License
319
+ ## License
246
320
 
247
321
  MIT
248
-
249
- ---
250
-
251
- Made with 🐰 for hopping around
252
-
253
- ```
254
- ____
255
- / \
256
- | ^ ^ | hop hop hop
257
- | .. |
258
- \ -- /
259
- ||||
260
- ```
@@ -0,0 +1,98 @@
1
+ # 30s Product Demo Runbook
2
+
3
+ This is the first concrete demo built on top of the small Hop demo harness.
4
+
5
+ ## Goal
6
+
7
+ Show that Hop can:
8
+
9
+ 1. host a visible subagent terminal
10
+ 2. let the human watch and steer it live
11
+ 3. expose the resulting app through the same runtime
12
+ 4. reconnect cleanly on mobile
13
+
14
+ ## Recommended Structure
15
+
16
+ ### Clip 1: Session picker
17
+
18
+ Duration: 2 to 3 seconds
19
+
20
+ ```bash
21
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
22
+ --out demo-output/clip-01-sessions \
23
+ --duration 2500
24
+ ```
25
+
26
+ Use this under the caption:
27
+
28
+ `Terminal access for humans and agents`
29
+
30
+ ### Clip 2: Start a dedicated agent terminal
31
+
32
+ Create or attach a named session that will hold the agent:
33
+
34
+ ```bash
35
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/drive-hop-terminal.mjs \
36
+ --name demo-agent \
37
+ --cwd "$PWD"
38
+ ```
39
+
40
+ Then launch `codex` in that session with your preferred flags. For now this is still better driven explicitly rather than hidden behind another wrapper.
41
+
42
+ ### Clip 3: Record live terminal work
43
+
44
+ Once Codex is working in `demo-agent`, record the session page:
45
+
46
+ ```bash
47
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
48
+ --session demo-agent \
49
+ --out demo-output/clip-03-agent \
50
+ --duration 8000
51
+ ```
52
+
53
+ Suggested caption:
54
+
55
+ `Watch every step in real time`
56
+
57
+ ### Clip 4: Redirect mid-run
58
+
59
+ Send a second instruction into the same session while it is still running, then record a short follow-up clip.
60
+
61
+ Suggested caption:
62
+
63
+ `Interrupt. Redirect. Continue.`
64
+
65
+ ### Clip 5: Record mobile view
66
+
67
+ ```bash
68
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
69
+ --session demo-agent \
70
+ --mobile true \
71
+ --out demo-output/clip-05-mobile \
72
+ --duration 4000
73
+ ```
74
+
75
+ Suggested caption:
76
+
77
+ `Check progress from anywhere`
78
+
79
+ ### Clip 6: Optional second agent tease
80
+
81
+ Repeat the same flow with a second session such as `demo-reviewer` and end on a very short two-agent tease.
82
+
83
+ Keep this to 2 to 3 seconds. It should feel like a promise, not a second full story.
84
+
85
+ ## Editing Notes
86
+
87
+ - Prefer 5 to 8 second source clips, then trim aggressively
88
+ - Use hard cuts, not slow transitions
89
+ - Do not show login unless the login flow itself is the product being demoed
90
+ - Keep text overlays short and concrete
91
+ - Avoid dense terminal text overlays; let the UI and motion carry the demo
92
+
93
+ ## Current State
94
+
95
+ - Browser recording works
96
+ - Mobile recording works
97
+ - Local API terminal creation works
98
+ - The current driver is good enough to bootstrap sessions, but it is not yet a full turn-by-turn subagent director
package/demo/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # Hop Demo Harness
2
+
3
+ Small reusable pieces for recording real Hop browser footage and driving real Hop terminals.
4
+
5
+ ## What This Is
6
+
7
+ - `record-hop-view.mjs` records the Hop browser UI with Playwright
8
+ - `drive-hop-terminal.mjs` creates or attaches to a terminal over Hop's local API and sends input
9
+ - `director.mjs` runs the first single-agent 30s capture flow end to end
10
+ - `static-preview-server.mjs` serves the sanitized demo workspace for preview clips
11
+ - `stitch-demo-video.mjs` concatenates recorded WebM clips into one rough MP4
12
+ - `hop-demo-lib.mjs` holds the shared state, auth, browser, and API helpers
13
+
14
+ The harness uses the local Hop daemon port from `~/.hop2/.tunnel-state` and injects the Hop session cookie directly into Playwright. That avoids interactive login during capture while still exercising the real Hop UI.
15
+
16
+ For production demos, `director.mjs` now uses a sanitized workspace and filters non-demo sessions out of the captured UI so the recording does not show your normal session list, username, hostname, or personal directory path. Starting from an isolated Hop home is supported as an opt-in experiment with `--start-daemon true`.
17
+
18
+ ## Prerequisites
19
+
20
+ - Hop daemon is running
21
+ - `codex` or another terminal program is already installed if you want to demo an agent
22
+ - Homebrew Node is available at `/opt/homebrew/bin/node`
23
+ - Playwright is available from the vendored Hay workspace
24
+
25
+ ## Basic Examples
26
+
27
+ Create or attach a terminal and run a command:
28
+
29
+ ```bash
30
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/drive-hop-terminal.mjs \
31
+ --name demo-agent \
32
+ --cwd "$PWD" \
33
+ --exec "printf 'hello from hop demo\\n'"
34
+ ```
35
+
36
+ Wait for output after starting a program:
37
+
38
+ ```bash
39
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/drive-hop-terminal.mjs \
40
+ --name demo-agent \
41
+ --cwd "$PWD" \
42
+ --exec "codex" \
43
+ --wait-timeout 15000
44
+ ```
45
+
46
+ Record the session picker:
47
+
48
+ ```bash
49
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
50
+ --out demo-output/sessions \
51
+ --duration 3000
52
+ ```
53
+
54
+ Record one terminal session:
55
+
56
+ ```bash
57
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
58
+ --session demo-agent \
59
+ --out demo-output/demo-agent \
60
+ --duration 8000
61
+ ```
62
+
63
+ Record a mobile-sized view:
64
+
65
+ ```bash
66
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/record-hop-view.mjs \
67
+ --session demo-agent \
68
+ --mobile true \
69
+ --out demo-output/demo-agent-mobile \
70
+ --duration 5000
71
+ ```
72
+
73
+ Run the first end-to-end single-agent capture flow:
74
+
75
+ ```bash
76
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/director.mjs \
77
+ --name demo-agent \
78
+ --preset landing-page \
79
+ --launch "codex" \
80
+ --out demo-output/run-01
81
+ ```
82
+
83
+ Stitch the recorded clips into a rough cut:
84
+
85
+ ```bash
86
+ PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/node demo/stitch-demo-video.mjs \
87
+ --in demo-output/run-01 \
88
+ --out demo-output/run-01/hop-demo-rough.mp4
89
+ ```
90
+
91
+ ## Suggested 30s Demo Flow
92
+
93
+ 1. Record `/sessions`
94
+ 2. Start a dedicated `codex` terminal with `drive-hop-terminal.mjs`
95
+ 3. Record the live session page while Codex works
96
+ 4. Send a second instruction into the same terminal
97
+ 5. Record a mobile view of the same session
98
+ 6. Stitch the clips with `ffmpeg`
99
+
100
+ ## Notes
101
+
102
+ - The current scripts are intentionally small. The new `director.mjs` is still a thin orchestrator, not a large demo framework.
103
+ - Desktop recording now defaults to `1920x1080`. Mobile clips are normalized onto the same canvas during stitching.
104
+ - The default showcase flow now records a filtered session picker, the live agent terminal, a follow-up redirect clip, a preview-app clip through a Hop port session, and a mobile clip.
105
+ - `stitch-demo-video.mjs` now overlays short captions by default. Use `--overlay-captions false` to disable that.
106
+ - For a deterministic product video, prefer recording short clips and stitching them together rather than relying on one perfect live take.