hop2 0.9.1 β†’ 0.11.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 (48) hide show
  1. package/INTEGRATION.md +77 -85
  2. package/MULTI-AGENT-CHECKLIST.md +16 -9
  3. package/README-MCP.md +105 -52
  4. package/README.md +201 -225
  5. package/demo/30s-product-demo.md +98 -0
  6. package/demo/README.md +106 -0
  7. package/demo/director.mjs +236 -0
  8. package/demo/drive-hop-terminal.mjs +70 -0
  9. package/demo/hop-demo-lib.mjs +525 -0
  10. package/demo/record-hop-view.mjs +26 -0
  11. package/demo/static-preview-server.mjs +45 -0
  12. package/demo/stitch-demo-video.mjs +128 -0
  13. package/hay/CHANGELOG.md +31 -1
  14. package/hay/DEV_NOTES.md +25 -0
  15. package/hay/README.md +182 -199
  16. package/hay/apps/cli/package.json +1 -1
  17. package/hay/apps/cli/src/index.ts +1146 -167
  18. package/hay/apps/server/package.json +1 -1
  19. package/hay/apps/server/src/lib.ts +1 -1
  20. package/hay/apps/server/src/rooms.ts +204 -17
  21. package/hay/apps/server/test/rooms.test.ts +75 -0
  22. package/hay/apps/web/package.json +1 -1
  23. package/hay/apps/web/src/App.tsx +731 -168
  24. package/hay/apps/web/src/components/MobileKeyboard.tsx +32 -11
  25. package/hay/apps/web/src/styles.css +464 -55
  26. package/hay/package-lock.json +0 -1
  27. package/hay/packages/shared/package.json +1 -1
  28. package/hay/packages/shared/src/protocol.ts +12 -2
  29. package/hay/packages/shared/test/protocol.test.ts +32 -0
  30. package/hay-web/assets/index-BzJB9r_I.js +64 -0
  31. package/hay-web/assets/index-BzJB9r_I.js.map +1 -0
  32. package/hay-web/assets/index-DG8Ntznc.css +32 -0
  33. package/hay-web/index.html +2 -2
  34. package/hop +2399 -786
  35. package/lib/naming-themes.js +208 -0
  36. package/mcp/hop-mcp.js +594 -104
  37. package/package.json +1 -1
  38. package/scripts/hay-host.js +8 -1
  39. package/sessions.html +230 -35
  40. package/setup-mcp.js +37 -19
  41. package/.hop-tmux.conf +0 -18
  42. package/hay-web/assets/index-B7rkCY1_.css +0 -32
  43. package/hay-web/assets/index-kr4B-B06.js +0 -60
  44. package/hay-web/assets/index-kr4B-B06.js.map +0 -1
  45. package/hop.bak2 +0 -8071
  46. package/mcp/hop-mcp.js.bak +0 -4492
  47. package/mcp/hop-mcp.js.bak2 +0 -4530
  48. package/tunnel-shell.js +0 -254
package/README.md CHANGED
@@ -1,12 +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
- Hop also ships with a built-in MCP server, so Claude Code, Codex, Gemini, Cursor, and other MCP clients can create terminals, stream output, and drive agent sessions through Hop.
8
-
9
- > **🍎 macOS/Linux** β€” Requires cloudflared for tunneling
7
+ > **macOS/Linux** β€” Requires cloudflared for tunneling
10
8
 
11
9
  ```
12
10
  (\(\
@@ -14,22 +12,19 @@ Hop also ships with a built-in MCP server, so Claude Code, Codex, Gemini, Cursor
14
12
  o_(")(")
15
13
  ```
16
14
 
17
- ## ✨ Features
15
+ ## Why Hop
18
16
 
19
- - πŸ” **Password + 2FA** β€” Optional password plus TOTP (required for custom domains)
20
- - 🌍 **Access Anywhere** β€” Cloudflare tunnel, no port forwarding
21
- - πŸ€– **Built-in MCP Server** β€” Turn Hop into an agent-facing terminal platform for Claude Code, Codex, Gemini, Cursor, and more
22
- - 🌐 **Custom Domains + Multi‑User** β€” Share subdomains with per‑user credentials
23
- - πŸ“± **Mobile Virtual Keyboard** β€” Custom keyboard with Esc, Ctrl, Alt, arrows, and more
24
- - ⌨️ **Native Keyboard Support** β€” Tap the blue button for dictation, spellcheck & autocomplete
25
- - πŸͺŸ **Multi-Session** β€” Create and switch between named sessions
26
- - πŸ”Œ **Port Sessions** β€” Proxy a local HTTP/WS service via hop
27
- - πŸ”„ **Quick Session Switching** β€” Floating menu to switch sessions without leaving the terminal
28
- - 🎨 **Modern UI** β€” Clean, minimal iOS-style design
29
- - ⚑ **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
30
23
 
31
24
  ## πŸš€ Quick Install
32
25
 
26
+ Most users only need the npm install. Source install is mainly for development or local hacking.
27
+
33
28
  ### From npm (easiest)
34
29
 
35
30
  ```bash
@@ -41,12 +36,18 @@ This installs:
41
36
  - `hop-mcp` β€” MCP server exposing Hop terminals and sessions
42
37
  - `hop-mcp-setup` β€” MCP client auto-config helper
43
38
 
44
- Then just run:
39
+ Then:
45
40
  ```bash
46
41
  hop
47
42
  ```
48
43
 
49
- ### 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)
50
51
 
51
52
  ```bash
52
53
  git clone https://github.com/jzthree/hop.git ~/.hop && \
@@ -54,7 +55,7 @@ cd ~/.hop && npm install && \
54
55
  sudo ln -sf ~/.hop/hop /usr/local/bin/hop
55
56
  ```
56
57
 
57
- ### Manual Install from source
58
+ ### From source (manual)
58
59
 
59
60
  ```bash
60
61
  # Clone the repo
@@ -72,36 +73,22 @@ echo 'export PATH="$HOME/.hop:$PATH"' >> ~/.zshrc
72
73
  source ~/.zshrc
73
74
  ```
74
75
 
75
- ## 🐰 Usage
76
+ ## Quick Start
76
77
 
78
+ ### Browser access
77
79
  ```bash
78
- # Start hopping!
79
80
  hop
80
81
  ```
81
82
 
82
- **First time:**
83
- 1. (Optional) Set a password: `hop password set`
84
- 2. Scan the QR code with your authenticator app (Google Authenticator, Authy, 1Password, etc.)
85
- 3. Note the URL displayed
86
- 4. Press Enter to start your local session
87
-
88
- **From your phone:**
89
- 1. Open the URL in your browser
90
- 2. Enter your password (if enabled) and 6‑digit code
91
- 3. Pick or create a session
92
- 4. 🐰 You're in! Use the virtual keyboard for terminal keys, or tap the blue button for native input
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
93
88
 
94
- ## πŸ€– Hop MCP
89
+ Then open the URL from another device, sign in, and pick or create a session.
95
90
 
96
- Hop is not just a browser terminal. It also exposes terminals and sessions over MCP so agents can safely operate through the same platform.
97
-
98
- Use cases:
99
- - Launch a dedicated Claude Code / Codex / Gemini terminal and drive it over multiple turns
100
- - Create isolated agent sessions with per-session history and audit logs
101
- - Read terminal output incrementally instead of screen-scraping a browser
102
- - Build higher-level agent workflows on top of stable terminal/session primitives
103
-
104
- Quick start:
91
+ ### MCP access
105
92
 
106
93
  ```bash
107
94
  hop
@@ -110,251 +97,240 @@ hop-mcp-setup
110
97
 
111
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.
112
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
+
113
106
  For full MCP usage, tools, and subagent workflows, see [README-MCP.md](./README-MCP.md).
114
107
 
115
- ## πŸͺŸ Sessions
108
+ ## Everyday Workflows
109
+
110
+ ### Create and Reuse Sessions
116
111
 
117
112
  Create multiple independent terminal sessions from the Session Picker (`/sessions`):
118
113
 
119
- - **Create**: Type a name and click Create
120
- - **Join**: Click Join on any existing session
121
- - **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:
122
120
 
123
- You can also create **Port Sessions** that proxy to a local HTTP/WS service on your machine.
124
- Use the Session Picker or:
125
121
  ```bash
126
- hop session add myapp --port 3000
127
- hop session add workspace-shell --cwd ~/src/my-project
122
+ hop session add workspace-shell --cwd ~/src/my-project --workspace dev
123
+ hop session add myapp --port 3000 --workspace dev
128
124
  ```
129
125
 
130
- ## 🧾 Session History & Audit Logs
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:
131
129
 
132
- Hop always writes per-session audit logs.
133
- Shell history isolation is role-based by default:
134
-
135
- - Agent-created terminal sessions: isolated history file per session
136
- - User-created terminal sessions: keep your shell default history file (opt-in isolation available)
137
-
138
- - Isolated history file path: `~/.hop2/workspaces/<workspace>/history/<internal-session>.history`
139
- - Audit log (NDJSON): `~/.hop2/workspaces/<workspace>/logs/<internal-session>/audit.ndjson`
140
- - Audit events include `session_start`, `input`, `resize`, `session_end`, plus:
141
- - `audit_mode` / `pty_state` transitions (auto-switches between `stream` and `tui_keyframe`)
142
- - `tui_keyframe` snapshots (diff-suppressed; emitted only when content changes)
143
- - `command_launch` metadata (captures launched command token and detected agent CLI type)
144
- - Large input/output chunks are truncated with metadata (`bytes`, `omittedBytes`, `dataHead`, `dataTail`)
145
-
146
- Tunable defaults:
147
-
148
- - `HOP_SESSION_HISTORY_SIZE` (default `5000`)
149
- - `HOP_AGENT_HISTORY_ISOLATION` (default `1`)
150
- - `HOP_USER_HISTORY_ISOLATION` (default `0`)
151
- - `HOP_AGENT_POST_START_HISTORY_INIT` (default `1`)
152
- - `HOP_POST_START_HISTORY_INIT` (default `0`, forces post-start history init for all sessions)
153
- - `HOP_SESSION_AUDIT_INLINE_MAX_BYTES` (default `4096`)
154
- - `HOP_SESSION_TUI_KEYFRAME_INTERVAL_MS` (default `750`)
155
- - `HOP_SESSION_TUI_KEYFRAME_TAIL_CHARS` (default `20000`)
156
- - `HOP_SESSION_TUI_KEYFRAME_MAX_LINES` (default `80`)
157
-
158
- ## 🌐 Custom Domains & Multi‑User
159
-
160
- ### Admin (your machine)
161
- 1. Set a password (required for custom domains):
162
- ```bash
163
- hop password set
164
- ```
165
- 2. Configure your domain:
166
- ```bash
167
- hop domain hop.yourdomain.com
168
- ```
169
- 3. Add a user + export credentials:
170
- ```bash
171
- hop user add alice
172
- hop user export alice
173
- ```
174
- 4. Send the exported folder to the user.
175
-
176
- ### User (their machine)
177
130
  ```bash
178
- npm install -g hop2
179
- hop client ./credentials.json
131
+ hop workspace show dev
132
+ hop workspace delete dev
180
133
  ```
181
- First run prompts them to set a password + scan a TOTP QR code.
182
- They then log in at their URL, e.g. `https://alice.hop.yourdomain.com`.
183
134
 
184
- ## πŸ“± Mobile Keyboard
135
+ ### Drive a Subagent Over MCP
136
+
137
+ Use one dedicated terminal per subagent.
185
138
 
186
- 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_terminal(async=true, ...)` + `hop_wait_poll(...)` (`hop_wait_start` remains only as a legacy alias).
144
+ 6. Interrupt with `hop_send_key(key="ctrl_c")` and close with `hop_close_terminal`.
187
145
 
188
- **Accessory Row:**
189
- - `Esc` `Tab` `Ctrl` `Alt` β€” Essential terminal keys
190
- - `← ↓ ↑ β†’` β€” Arrow keys for navigation
191
- - πŸ”΅ **Blue keyboard button** β€” Opens native iOS keyboard for dictation, spellcheck & autocomplete
146
+ Safety tips:
192
147
 
193
- **Floating Menu (top-right button):**
194
- - **Toggle Keyboard** β€” Show/hide the virtual keyboard
195
- - **Session List** β€” Quick-switch between sessions
196
- - **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 (grant it with `hop session permit <name>`).
197
151
 
198
- **Tips:**
199
- - The floating button is draggable β€” move it anywhere
200
- - First-time users will see a tooltip pointing to the native keyboard button
201
- - Use the native keyboard for longer text input with autocomplete
152
+ ### Share a Local Web App
202
153
 
203
- ## πŸ–₯️ Local Attach
154
+ Expose a local HTTP or WebSocket service through your Hop tunnel:
204
155
 
205
156
  ```bash
206
- hop attach <session>
157
+ hop session add myapp --port 3000 --workspace dev
207
158
  ```
208
159
 
209
- Attach your local terminal client to an existing hop terminal session.
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
210
165
 
211
- ## πŸ”Œ Port Sessions
166
+ ### Reattach Locally
212
167
 
213
- Expose local HTTP/WebSocket services through your tunnel:
168
+ Attach your local terminal client to an existing terminal session:
214
169
 
215
170
  ```bash
216
- hop session add myapp --port 3000
217
- # Access at: https://your-tunnel-url/s/myapp/
171
+ hop attach <session>
218
172
  ```
219
173
 
220
- 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
+ Local terminal sessions are persistent by default: they keep running in the Hay host if the local CLI detaches or the Hop daemon restarts. The local CLI status line shows `persists`; use `Ctrl+Q` inside the local Hop view to kill the session.
221
176
 
222
- ## πŸ”§ Commands
177
+ ### Use Hop on Mobile
223
178
 
224
- | Command | Description |
225
- |---------|-------------|
226
- | `hop` | Start hop daemon/tunnel if needed, then launch a local terminal |
227
- | `hop attach all` | Attach sequentially to all terminal sessions |
228
- | `hop local [session]` | Start a daemonless local terminal (`[session]` attaches if it exists) |
229
- | `hop url` | Print current tunnel URL |
230
- | `hop qr` | Show QR code for current tunnel URL |
231
- | `hop qr auth` | Show QR code for authenticator app setup |
232
- | `hop domain <hostname>` | Set custom domain (named tunnel) |
233
- | `hop domain-clear` | Remove custom domain, use random URLs |
234
- | `hop password set` | Set/change password |
235
- | `hop password clear` | Remove password protection |
236
- | `hop user list` | List users |
237
- | `hop user add <name>` | Add user + subdomain |
238
- | `hop user remove <name>` | Remove user |
239
- | `hop user export <name>` | Export user credentials |
240
- | `hop session list` | List sessions with `LIVE` vs `SAVED` terminal status |
241
- | `hop session add <name> [--cwd P]` | Create a terminal session |
242
- | `hop session add <name> --port N` | Create a port session (proxy) |
243
- | `hop session rename <old> <new>` | Rename a session |
244
- | `hop session remove <name>` | Remove a session |
245
- | `hop client <credentials>` | Run hop with exported credentials |
246
- | `hop wipe [--all]` | Remove saved sessions (`--all` also kills live sessions) |
247
- | `quit` | Type at exit prompt to shutdown tunnel |
179
+ Hop’s mobile UI includes:
248
180
 
249
- Additional installed binaries:
250
- - `hop-mcp` β€” Start the Hop MCP server directly
251
- - `hop-mcp-setup` β€” Auto-configure supported MCP clients
181
+ - a terminal-oriented accessory row with `Esc`, `Tab`, `Ctrl`, `Alt`, and arrows
182
+ - a native keyboard button for dictation, spellcheck, and autocomplete
183
+ - a floating menu for keyboard toggle and session switching
184
+ - draggable controls designed for one-handed use
252
185
 
253
- Startup behavior:
254
- - Hop reconciles already-running external Hay sessions first, then applies the default workspace as additional startup state.
186
+ ## Operations
255
187
 
256
- ## πŸ§ͺ Terminal Backend
188
+ ### Logging and History
257
189
 
258
- Hop always uses the `external` terminal runtime (PTYs in a separate local hay host process).
190
+ Hop always writes per-session audit logs.
259
191
 
260
- - The host persists across hop daemon restarts.
261
- - Host state is tracked in `~/.hop2/.hay-host-state`.
262
- - On startup and session listing, Hop discovers live hay-host processes and adopts the one(s) that still own runtime rooms if the state file is stale.
263
- - Local CLI transport is direct to hay-host; daemon restarts do not terminate local terminal sessions.
264
- - Bare `hop` prompts on cwd match (`Attach existing` vs `Create new`, default `Create new`); non-interactive runs always create new.
265
- - `HOP_TERMINAL_BACKEND` is accepted for compatibility but ignored.
192
+ Default behavior:
266
193
 
267
- ## πŸ“¦ Dependencies
194
+ - agent-created sessions get isolated shell history files
195
+ - user-created sessions keep normal shell history unless you opt into isolation
196
+ - TUI apps switch to diff-suppressed keyframe capture automatically
268
197
 
269
- Installed automatically via Homebrew:
270
- - `cloudflared` β€” Cloudflare tunnel
198
+ Paths:
271
199
 
272
- Node.js packages:
273
- - `http-proxy` β€” Request proxying
274
- - `otplib` β€” TOTP authentication
275
- - `qrcode-terminal` β€” QR code display
276
- - `cookie` β€” Session cookies
200
+ - scratch sessions: `~/.hop2/runtime/history/<internal-session>.history`
201
+ - scratch audit logs: `~/.hop2/runtime/logs/<internal-session>/audit.ndjson`
202
+ - workspace-backed sessions: `~/.hop2/workspaces/<workspace>/history/<internal-session>.history`
203
+ - workspace-backed audit logs: `~/.hop2/workspaces/<workspace>/logs/<internal-session>/audit.ndjson`
277
204
 
278
- ## πŸ›‘οΈ Security
205
+ Key tunables:
279
206
 
280
- - **Password + TOTP** β€” Password optional, but required for custom domains
281
- - **Rate Limiting** β€” Exponential backoff on failed attempts
282
- - **Secure Cookies** β€” `httpOnly`, `secure`, `sameSite=lax`
283
- - **Session persistence** β€” Login cookies are signed with a stable session secret by default, so browser sessions can survive `hop stop/start` without reauth.
284
- - **Random URL** β€” Unguessable tunnel URL for quick tunnels
285
- - **Fixed URL** β€” Custom domains keep a stable URL
286
- - **Local Binding** β€” Server only listens on 127.0.0.1
287
- - **End-to-End TLS** β€” Cloudflare Tunnel encryption
207
+ - `HOP_SESSION_HISTORY_SIZE`
208
+ - `HOP_AGENT_HISTORY_ISOLATION`
209
+ - `HOP_USER_HISTORY_ISOLATION`
210
+ - `HOP_AGENT_POST_START_HISTORY_INIT`
211
+ - `HOP_POST_START_HISTORY_INIT`
212
+ - `HOP_SESSION_AUDIT_INLINE_MAX_BYTES`
213
+ - `HOP_SESSION_TUI_KEYFRAME_INTERVAL_MS`
214
+ - `HOP_SESSION_TUI_KEYFRAME_TAIL_CHARS`
215
+ - `HOP_SESSION_TUI_KEYFRAME_MAX_LINES`
288
216
 
289
- **Passwords:** Recommended for any public URL; required for custom domains.
217
+ ### Users, Domains, and Sharing
290
218
 
291
- **Secrets:** Stored in `~/.hop2/` (treat like `~/.ssh/`)
292
- Set `HOP_PERSIST_SESSION_SECRET=0` to force a fresh login cookie secret every daemon restart.
219
+ Admin flow:
293
220
 
294
- ## πŸ›  Development (Hay)
221
+ 1. Set a password with `hop password set`.
222
+ 2. Configure a hostname with `hop domain hop.yourdomain.com`.
223
+ 3. Add a user with `hop user add alice`.
224
+ 4. Export credentials with `hop user export alice`.
295
225
 
296
- The hay source is vendored in `./hay`. Hop will serve `hay/apps/web/dist` when present.
226
+ User flow:
297
227
 
298
228
  ```bash
299
- npm run build
229
+ npm install -g hop2
230
+ hop client ./credentials.json
300
231
  ```
301
232
 
302
- This builds hay (web + cli) and syncs `hay/apps/web/dist` into `hay-web/` for Hop to serve.
303
- If `./hay` exists and the dist folder is missing, `hop` will auto-build hay on startup.
233
+ 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`.
304
234
 
305
- ## πŸ€– Hop MCP (One Subagent Terminal)
235
+ ### Security
306
236
 
307
- Use one dedicated terminal when driving a subagent CLI through Hop MCP.
237
+ - Password + TOTP is supported; password is required for custom domains
238
+ - Login cookies are `httpOnly`, `secure`, and `sameSite=lax`
239
+ - Browser sessions persist across `hop stop/start` by default through a stable session secret
240
+ - The local server binds only to `127.0.0.1`
241
+ - Cloudflare Tunnel provides end-to-end TLS
308
242
 
309
- 1. Create a terminal with `hop_create_terminal` (set `name` and `cwd`).
310
- 2. Start the agent CLI with `hop_write_terminal` (`claude` or `codex`).
311
- 3. Wait for readiness with `hop_wait_terminal(until_prompt=true)`.
312
- 4. Send one instruction at a time via `hopx_send_and_wait` (or `hop_write_terminal` + `hop_wait_terminal`).
313
- 5. Optional helper path: use `hopx_agent_turn(mode="auto")` for a single send+wait turn with mode-aware output (`ui` for TUI screens, `readable_raw` otherwise); it auto-promotes to `ui` if alternate-screen starts mid-turn and uses lean capture defaults (`capture_max_events=60` for readable modes, `0` for `ui` unless overridden, plus `text_only=true` by default for readable waits).
314
- 6. For long waits, prefer `hopx_agent_turn(async=true, ...)` and continue with `hopx_agent_turn(wait_id=..., wait=true, control="wait")`; fall back to `hop_wait_start(...)` / `hop_wait_poll(...)` when you want the lower-level primitives directly.
315
- 7. After each turn, collect output with `hop_wait_terminal` or incremental `hop_read_terminal` cursor reads.
316
- 8. Interrupt with `hop_send_key(key="ctrl_c")` and close using `hop_close_terminal`.
243
+ Secrets are stored in `~/.hop2/`. Set `HOP_PERSIST_SESSION_SECRET=0` if you want login cookies invalidated on every daemon restart.
317
244
 
318
- Safety tips:
319
- - Keep one subagent per terminal.
320
- - Do not queue a second instruction before reading the first response.
321
- - For attached user sessions, confirm `agentPermitted` before sending input.
245
+ ### Runtime and Recovery
322
246
 
323
- ## πŸ› Troubleshooting
247
+ Hop uses the external Hay host runtime for PTY hosting and session recovery.
324
248
 
325
- **Authenticator QR code needed again?**
326
- Run `hop qr auth` to re-show the current TOTP setup QR for Duo/Authy/1Password.
249
+ - active PTYs live in a separate local hay-host process
250
+ - the host survives daemon restarts
251
+ - host state is tracked in `~/.hop2/.hay-host-state`
252
+ - startup reconciles already-running Hay sessions before applying workspace state
253
+ - `HOP_TERMINAL_BACKEND` is accepted only for compatibility and ignored
327
254
 
328
- **Need to reset TOTP entirely?**
329
- Delete `.auth_secret` and restart hop to generate a new authenticator secret and QR code.
255
+ ## Reference
330
256
 
331
- **Client reset (user mode)?**
332
- Delete `~/.hop2/clients/<tunnel-id>/` and run `hop client` again.
257
+ ### Related Docs
333
258
 
334
- **Tunnel not starting?**
335
- Make sure `cloudflared` is installed: `brew install cloudflared`
259
+ - [README-MCP.md](./README-MCP.md) for MCP tools, helper wrappers, and agent-driving patterns
260
+ - [INTEGRATION.md](./INTEGRATION.md) for the current Hop/Hay architecture
261
+ - [hay/README.md](./hay/README.md) for the vendored Hay workspace
336
262
 
337
- **Tunnel returns 502 or died after network changes?**
338
- Run `hop health --restart`. Hop now waits for the public URL to become healthy again instead of only sending a fire-and-forget restart request.
263
+ ### Commands
264
+
265
+ | Command | Description |
266
+ |---------|-------------|
267
+ | `hop` | Start hop daemon/tunnel if needed, then launch a local terminal. Unnamed launches do not reuse a session that already has a local CLI attached. |
268
+ | `hop start` | Start the hop daemon and print QR codes |
269
+ | `hop attach [session]` | Attach to an existing terminal session |
270
+ | `hop attach all` | Attach sequentially to all terminal sessions |
271
+ | `hop local [session]` | Start a daemonless local terminal (`[session]` attaches if it exists) |
272
+ | `hop stop` | Stop the hop daemon (terminal sessions keep running) |
273
+ | `hop stop --all` | Stop the daemon, the hay-host, and all terminal sessions |
274
+ | `hop status` | Show daemon, tunnel, and session status |
275
+ | `hop doctor` | Run environment/health checks |
276
+ | `hop logs [-f]` | Show daemon logs (`-f` to follow) |
277
+ | `hop health [--restart]` | Check tunnel health (`--restart` forces a tunnel restart) |
278
+ | `hop url` | Print current tunnel URL |
279
+ | `hop qr` | Show QR code for current tunnel URL |
280
+ | `hop qr auth` | Show QR code for authenticator app setup |
281
+ | `hop config theme [name]` | Show or set the session naming theme |
282
+ | `hop domain <hostname>` | Set custom domain (named tunnel) |
283
+ | `hop domain-clear` | Remove custom domain, use random URLs |
284
+ | `hop password set` | Set/change password |
285
+ | `hop password clear` | Remove password protection |
286
+ | `hop user list` | List users |
287
+ | `hop user add <name>` | Add user + subdomain |
288
+ | `hop user remove <name>` | Remove user |
289
+ | `hop user export <name>` | Export user credentials |
290
+ | `hop session list` | List live terminal sessions |
291
+ | `hop session list --all` | Include saved definitions from all workspaces alongside live sessions (`-a` is shorthand) |
292
+ | `hop session add <name> [--cwd P] --workspace W` | Save a terminal session definition to a named workspace |
293
+ | `hop session add <name> --port N --workspace W` | Save a port session definition to a named workspace |
294
+ | `hop session permit <name>` | Allow agent access to a session |
295
+ | `hop session block <name>` | Block agent access to a session |
296
+ | `hop workspace list` | List workspaces |
297
+ | `hop workspace create <name>` | Create an empty workspace |
298
+ | `hop workspace show <name>` | Show saved definitions in a workspace |
299
+ | `hop workspace save <name>` | Save selected live terminal sessions into a workspace |
300
+ | `hop workspace load <name>` | Start sessions defined in a workspace |
301
+ | `hop workspace delete <name> [--yes]` | Delete a workspace (asks before deleting a non-empty one) |
302
+ | `hop session rename <old> <new>` | Rename a session |
303
+ | `hop session remove <name>` | Remove a session |
304
+ | `hop client <credentials>` | Run hop with exported credentials |
305
+ | `hop wipe [--all] [--yes]` | Remove workspace-defined sessions (`--all` also kills live sessions after a confirmation; `--yes` skips it) |
306
+ | `hop wipe --agent` | Close all agent-created terminal API sessions |
307
+
308
+ Local CLI mouse capture is off by default so terminal-native selection and context menus keep working. Use Option+M / Alt+M inside the local Hop view to toggle Hop mouse selection when needed. Use Option+B / Alt+B to toggle the status bar. CLI defaults live under `hay-cli` in `~/.hop.json`.
309
+
310
+ ### Development
311
+
312
+ The Hay source is vendored in `./hay`. Hop serves `hay/apps/web/dist` when present.
339
313
 
340
- **Stuck processes?**
341
314
  ```bash
342
- pkill cloudflared
315
+ npm run build
316
+ npm test
343
317
  ```
344
318
 
345
- ## πŸ“ License
319
+ 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.
346
320
 
347
- MIT
348
-
349
- ---
321
+ ## Troubleshooting
350
322
 
351
- Made with 🐰 for hopping around
323
+ - Authenticator QR again: run `hop qr auth`
324
+ - Reset TOTP entirely: delete `.auth_secret` and restart Hop
325
+ - Reset a client install: delete `~/.hop2/clients/<tunnel-id>/` and run `hop client` again
326
+ - Tunnel not starting: install `cloudflared` with `brew install cloudflared`
327
+ - Tunnel returning `502` after a network change: run `hop health --restart`
328
+ - Stuck tunnel processes:
352
329
 
330
+ ```bash
331
+ pkill cloudflared
353
332
  ```
354
- ____
355
- / \
356
- | ^ ^ | hop hop hop
357
- | .. |
358
- \ -- /
359
- ||||
360
- ```
333
+
334
+ ## License
335
+
336
+ MIT
@@ -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