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.
- package/AGENTS.md +33 -0
- package/INTEGRATION.md +77 -85
- package/MULTI-AGENT-CHECKLIST.md +37 -0
- package/README-MCP.md +232 -0
- package/README.md +209 -148
- 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/CHANGELOG.md +6 -0
- package/hay/DEV_NOTES.md +25 -0
- package/hay/README.md +136 -198
- package/hay/apps/cli/src/index.ts +321 -67
- package/hay/apps/server/src/index.ts +4 -3
- package/hay/apps/server/src/lib.ts +5 -4
- package/hay/apps/server/src/pty.ts +20 -7
- package/hay/apps/server/src/rooms.ts +226 -12
- package/hay/apps/server/test/rooms.test.ts +82 -3
- package/hay/apps/web/src/App.tsx +487 -112
- package/hay/apps/web/src/components/MobileKeyboard.tsx +43 -2
- package/hay/apps/web/src/styles.css +259 -29
- package/hay/package-lock.json +4 -4
- package/hay/packages/shared/src/protocol.ts +8 -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-FDfdolCs.js.map β index-D9aOC5Zt.js.map} +1 -1
- package/hay-web/index.html +2 -2
- package/hop +6801 -1714
- package/lib/naming-themes.js +194 -0
- package/lib/terminal-access.js +17 -0
- package/mcp/hop-mcp.js +4730 -0
- package/package.json +6 -3
- package/scripts/hay-host.js +189 -0
- package/sessions.html +378 -26
- package/setup-mcp.js +443 -0
- package/tests/hop-mcp.integration.test.cjs +3014 -0
- package/tests/terminal-access.unit.test.cjs +21 -0
- package/tests/terminal-api.integration.test.cjs +298 -0
- package/.hop-tmux.conf +0 -18
- package/hay-web/assets/index-CTTzApRp.css +0 -32
- package/hay-web/assets/index-FDfdolCs.js +0 -60
- package/tunnel-shell.js +0 -254
package/README.md
CHANGED
|
@@ -1,10 +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
|
-
>
|
|
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
|
-
##
|
|
15
|
+
## Why Hop
|
|
16
16
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
##
|
|
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
|
-
|
|
74
|
-
|
|
91
|
+
### MCP access
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
hop
|
|
95
|
+
hop-mcp-setup
|
|
75
96
|
```
|
|
76
97
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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
|
-
|
|
110
|
+
### Create and Reuse Sessions
|
|
90
111
|
|
|
91
112
|
Create multiple independent terminal sessions from the Session Picker (`/sessions`):
|
|
92
113
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
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
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
124
|
-
hop
|
|
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
|
-
|
|
135
|
+
### Drive a Subagent Over MCP
|
|
136
|
+
|
|
137
|
+
Use one dedicated terminal per subagent.
|
|
130
138
|
|
|
131
|
-
|
|
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
|
-
|
|
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
|
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
+
Expose a local HTTP or WebSocket service through your Hop tunnel:
|
|
149
155
|
|
|
150
156
|
```bash
|
|
151
|
-
hop --
|
|
157
|
+
hop session add myapp --port 3000
|
|
152
158
|
```
|
|
153
159
|
|
|
154
|
-
|
|
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
|
-
|
|
166
|
+
### Reattach Locally
|
|
157
167
|
|
|
158
|
-
|
|
168
|
+
Attach your local terminal client to an existing terminal session:
|
|
159
169
|
|
|
160
170
|
```bash
|
|
161
|
-
hop session
|
|
162
|
-
# Access at: https://your-tunnel-url/s/myapp/
|
|
171
|
+
hop attach <session>
|
|
163
172
|
```
|
|
164
173
|
|
|
165
|
-
|
|
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
|
-
|
|
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
|
|
172
|
-
| `hop
|
|
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
|
|
185
|
-
| `hop session add <name> --
|
|
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` |
|
|
189
|
-
| `quit` | Type at exit prompt to
|
|
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
|
-
|
|
295
|
+
### Development
|
|
217
296
|
|
|
218
|
-
|
|
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
|
|
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
|
-
|
|
232
|
-
Delete `.auth_secret` and restart hop to generate a new code.
|
|
306
|
+
## Troubleshooting
|
|
233
307
|
|
|
234
|
-
|
|
235
|
-
|
|
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
|
|
316
|
+
pkill cloudflared
|
|
243
317
|
```
|
|
244
318
|
|
|
245
|
-
##
|
|
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.
|