hop2 0.9.1 β 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.
- package/INTEGRATION.md +77 -85
- package/MULTI-AGENT-CHECKLIST.md +16 -9
- package/README-MCP.md +42 -23
- package/README.md +186 -225
- package/demo/30s-product-demo.md +98 -0
- package/demo/README.md +106 -0
- package/demo/director.mjs +236 -0
- package/demo/drive-hop-terminal.mjs +70 -0
- package/demo/hop-demo-lib.mjs +525 -0
- package/demo/record-hop-view.mjs +26 -0
- package/demo/static-preview-server.mjs +45 -0
- package/demo/stitch-demo-video.mjs +128 -0
- package/hay/DEV_NOTES.md +25 -0
- package/hay/README.md +136 -198
- package/hay/apps/cli/src/index.ts +52 -35
- package/hay/apps/server/src/lib.ts +1 -1
- package/hay/apps/server/src/rooms.ts +136 -3
- package/hay/apps/web/src/App.tsx +252 -90
- package/hay/apps/web/src/styles.css +250 -27
- package/hay/packages/shared/src/protocol.ts +4 -0
- package/hay-web/assets/index-BmWjq_Nh.css +32 -0
- package/hay-web/assets/index-D9aOC5Zt.js +63 -0
- package/hay-web/assets/{index-kr4B-B06.js.map β index-D9aOC5Zt.js.map} +1 -1
- package/hay-web/index.html +2 -2
- package/hop +1443 -667
- package/lib/naming-themes.js +194 -0
- package/mcp/hop-mcp.js +227 -27
- package/package.json +1 -1
- package/sessions.html +78 -14
- package/.hop-tmux.conf +0 -18
- package/hay-web/assets/index-B7rkCY1_.css +0 -32
- package/hay-web/assets/index-kr4B-B06.js +0 -60
- package/hop.bak2 +0 -8071
- package/mcp/hop-mcp.js.bak +0 -4492
- package/mcp/hop-mcp.js.bak2 +0 -4530
- package/tunnel-shell.js +0 -254
package/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# π° hop
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Terminal access for humans and agents.**
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
15
|
+
## Why Hop
|
|
18
16
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
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
|
|
39
|
+
Then:
|
|
45
40
|
```bash
|
|
46
41
|
hop
|
|
47
42
|
```
|
|
48
43
|
|
|
49
|
-
|
|
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
|
-
###
|
|
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
|
-
##
|
|
76
|
+
## Quick Start
|
|
76
77
|
|
|
78
|
+
### Browser access
|
|
77
79
|
```bash
|
|
78
|
-
# Start hopping!
|
|
79
80
|
hop
|
|
80
81
|
```
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
1.
|
|
84
|
-
2. Scan the QR code
|
|
85
|
-
3. Note the URL
|
|
86
|
-
4. Press Enter to start your local
|
|
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
|
|
87
88
|
|
|
88
|
-
|
|
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
|
|
89
|
+
Then open the URL from another device, sign in, and pick or create a session.
|
|
93
90
|
|
|
94
|
-
|
|
95
|
-
|
|
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,225 @@ 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
|
-
##
|
|
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
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
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
|
|
127
|
-
hop session add
|
|
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
|
-
|
|
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
|
-
|
|
179
|
-
hop
|
|
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
|
-
|
|
135
|
+
### Drive a Subagent Over MCP
|
|
136
|
+
|
|
137
|
+
Use one dedicated terminal per subagent.
|
|
185
138
|
|
|
186
|
-
|
|
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`.
|
|
187
145
|
|
|
188
|
-
|
|
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
|
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
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.
|
|
197
151
|
|
|
198
|
-
|
|
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
|
-
|
|
154
|
+
Expose a local HTTP or WebSocket service through your Hop tunnel:
|
|
204
155
|
|
|
205
156
|
```bash
|
|
206
|
-
hop
|
|
157
|
+
hop session add myapp --port 3000
|
|
207
158
|
```
|
|
208
159
|
|
|
209
|
-
|
|
160
|
+
Result:
|
|
210
161
|
|
|
211
|
-
|
|
162
|
+
- local service stays on localhost
|
|
163
|
+
- Hop exposes it at `https://your-tunnel-url/s/myapp/`
|
|
164
|
+
- WebSocket apps work too
|
|
212
165
|
|
|
213
|
-
|
|
166
|
+
### Reattach Locally
|
|
167
|
+
|
|
168
|
+
Attach your local terminal client to an existing terminal session:
|
|
214
169
|
|
|
215
170
|
```bash
|
|
216
|
-
hop session
|
|
217
|
-
# Access at: https://your-tunnel-url/s/myapp/
|
|
171
|
+
hop attach <session>
|
|
218
172
|
```
|
|
219
173
|
|
|
220
|
-
|
|
174
|
+
This is useful when you want a browser, an MCP client, and a local shell to converge on the same named session.
|
|
221
175
|
|
|
222
|
-
|
|
176
|
+
### Use Hop on Mobile
|
|
223
177
|
|
|
224
|
-
|
|
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 |
|
|
178
|
+
Hopβs mobile UI includes:
|
|
248
179
|
|
|
249
|
-
|
|
250
|
-
-
|
|
251
|
-
-
|
|
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
|
|
252
184
|
|
|
253
|
-
|
|
254
|
-
- Hop reconciles already-running external Hay sessions first, then applies the default workspace as additional startup state.
|
|
185
|
+
## Operations
|
|
255
186
|
|
|
256
|
-
|
|
187
|
+
### Logging and History
|
|
257
188
|
|
|
258
|
-
Hop always
|
|
189
|
+
Hop always writes per-session audit logs.
|
|
259
190
|
|
|
260
|
-
|
|
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.
|
|
191
|
+
Default behavior:
|
|
266
192
|
|
|
267
|
-
|
|
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
|
|
268
196
|
|
|
269
|
-
|
|
270
|
-
- `cloudflared` β Cloudflare tunnel
|
|
197
|
+
Paths:
|
|
271
198
|
|
|
272
|
-
|
|
273
|
-
-
|
|
274
|
-
-
|
|
275
|
-
-
|
|
276
|
-
- `cookie` β Session cookies
|
|
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`
|
|
277
203
|
|
|
278
|
-
|
|
204
|
+
Key tunables:
|
|
279
205
|
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
-
|
|
284
|
-
-
|
|
285
|
-
-
|
|
286
|
-
-
|
|
287
|
-
-
|
|
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`
|
|
288
215
|
|
|
289
|
-
|
|
216
|
+
### Users, Domains, and Sharing
|
|
290
217
|
|
|
291
|
-
|
|
292
|
-
Set `HOP_PERSIST_SESSION_SECRET=0` to force a fresh login cookie secret every daemon restart.
|
|
218
|
+
Admin flow:
|
|
293
219
|
|
|
294
|
-
|
|
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`.
|
|
295
224
|
|
|
296
|
-
|
|
225
|
+
User flow:
|
|
297
226
|
|
|
298
227
|
```bash
|
|
299
|
-
npm
|
|
228
|
+
npm install -g hop2
|
|
229
|
+
hop client ./credentials.json
|
|
300
230
|
```
|
|
301
231
|
|
|
302
|
-
|
|
303
|
-
If `./hay` exists and the dist folder is missing, `hop` will auto-build hay on startup.
|
|
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`.
|
|
304
233
|
|
|
305
|
-
|
|
234
|
+
### Security
|
|
306
235
|
|
|
307
|
-
|
|
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
|
|
308
241
|
|
|
309
|
-
|
|
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`.
|
|
242
|
+
Secrets are stored in `~/.hop2/`. Set `HOP_PERSIST_SESSION_SECRET=0` if you want login cookies invalidated on every daemon restart.
|
|
317
243
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
|
322
253
|
|
|
323
|
-
##
|
|
254
|
+
## Reference
|
|
324
255
|
|
|
325
|
-
|
|
326
|
-
Run `hop qr auth` to re-show the current TOTP setup QR for Duo/Authy/1Password.
|
|
256
|
+
### Related Docs
|
|
327
257
|
|
|
328
|
-
|
|
329
|
-
|
|
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
|
|
330
261
|
|
|
331
|
-
|
|
332
|
-
|
|
262
|
+
### Commands
|
|
263
|
+
|
|
264
|
+
| Command | Description |
|
|
265
|
+
|---------|-------------|
|
|
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) |
|
|
269
|
+
| `hop url` | Print current tunnel URL |
|
|
270
|
+
| `hop qr` | Show QR code for current tunnel URL |
|
|
271
|
+
| `hop qr auth` | Show QR code for authenticator app setup |
|
|
272
|
+
| `hop domain <hostname>` | Set custom domain (named tunnel) |
|
|
273
|
+
| `hop domain-clear` | Remove custom domain, use random URLs |
|
|
274
|
+
| `hop password set` | Set/change password |
|
|
275
|
+
| `hop password clear` | Remove password protection |
|
|
276
|
+
| `hop user list` | List users |
|
|
277
|
+
| `hop user add <name>` | Add user + subdomain |
|
|
278
|
+
| `hop user remove <name>` | Remove user |
|
|
279
|
+
| `hop user export <name>` | Export user credentials |
|
|
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 |
|
|
290
|
+
| `hop session remove <name>` | Remove a session |
|
|
291
|
+
| `hop client <credentials>` | Run hop with exported credentials |
|
|
292
|
+
| `hop wipe [--all]` | Remove workspace-defined sessions (`--all` also kills live sessions) |
|
|
293
|
+
| `quit` | Type at exit prompt to shut down the tunnel |
|
|
333
294
|
|
|
334
|
-
|
|
335
|
-
Make sure `cloudflared` is installed: `brew install cloudflared`
|
|
295
|
+
### Development
|
|
336
296
|
|
|
337
|
-
|
|
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.
|
|
297
|
+
The Hay source is vendored in `./hay`. Hop serves `hay/apps/web/dist` when present.
|
|
339
298
|
|
|
340
|
-
**Stuck processes?**
|
|
341
299
|
```bash
|
|
342
|
-
|
|
300
|
+
npm run build
|
|
301
|
+
npm test
|
|
343
302
|
```
|
|
344
303
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
MIT
|
|
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.
|
|
348
305
|
|
|
349
|
-
|
|
306
|
+
## Troubleshooting
|
|
350
307
|
|
|
351
|
-
|
|
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:
|
|
352
314
|
|
|
315
|
+
```bash
|
|
316
|
+
pkill cloudflared
|
|
353
317
|
```
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
\ -- /
|
|
359
|
-
||||
|
|
360
|
-
```
|
|
318
|
+
|
|
319
|
+
## License
|
|
320
|
+
|
|
321
|
+
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
|