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.
- package/INTEGRATION.md +77 -85
- package/MULTI-AGENT-CHECKLIST.md +16 -9
- package/README-MCP.md +105 -52
- package/README.md +201 -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/CHANGELOG.md +31 -1
- package/hay/DEV_NOTES.md +25 -0
- package/hay/README.md +182 -199
- package/hay/apps/cli/package.json +1 -1
- package/hay/apps/cli/src/index.ts +1146 -167
- package/hay/apps/server/package.json +1 -1
- package/hay/apps/server/src/lib.ts +1 -1
- package/hay/apps/server/src/rooms.ts +204 -17
- package/hay/apps/server/test/rooms.test.ts +75 -0
- package/hay/apps/web/package.json +1 -1
- package/hay/apps/web/src/App.tsx +731 -168
- package/hay/apps/web/src/components/MobileKeyboard.tsx +32 -11
- package/hay/apps/web/src/styles.css +464 -55
- package/hay/package-lock.json +0 -1
- package/hay/packages/shared/package.json +1 -1
- package/hay/packages/shared/src/protocol.ts +12 -2
- package/hay/packages/shared/test/protocol.test.ts +32 -0
- package/hay-web/assets/index-BzJB9r_I.js +64 -0
- package/hay-web/assets/index-BzJB9r_I.js.map +1 -0
- package/hay-web/assets/index-DG8Ntznc.css +32 -0
- package/hay-web/index.html +2 -2
- package/hop +2399 -786
- package/lib/naming-themes.js +208 -0
- package/mcp/hop-mcp.js +594 -104
- package/package.json +1 -1
- package/scripts/hay-host.js +8 -1
- package/sessions.html +230 -35
- package/setup-mcp.js +37 -19
- 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/hay-web/assets/index-kr4B-B06.js.map +0 -1
- 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/INTEGRATION.md
CHANGED
|
@@ -1,92 +1,84 @@
|
|
|
1
|
-
# Hop +
|
|
1
|
+
# Hop + Hay Architecture
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This document describes the current Hop terminal architecture.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The historical `ttyd`/`tmux` backend has been removed from the active runtime.
|
|
6
|
+
Hop now uses Hay, a local terminal-sharing stack built on WebSocket plus
|
|
7
|
+
`node-pty`, with browser, CLI, and MCP clients all operating on the same
|
|
8
|
+
session model.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- **Built-in presence** - See who's connected, typing indicators
|
|
9
|
-
- **Control modes** - Collaborative or locked single-controller
|
|
10
|
-
- **No injection hacks** - Direct control over web UI
|
|
11
|
-
- **Mobile-ready** - Responsive design with iOS-style keyboard built-in
|
|
12
|
-
- **CLI client** - Connect from real terminals too
|
|
10
|
+
## Current Stack
|
|
13
11
|
|
|
14
|
-
## Architecture Change
|
|
15
|
-
|
|
16
|
-
### Before (ttyd)
|
|
17
12
|
```
|
|
18
|
-
Browser
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
Browser / Hay CLI / Hop MCP
|
|
14
|
+
|
|
|
15
|
+
v
|
|
16
|
+
Hop daemon
|
|
17
|
+
|
|
|
18
|
+
v
|
|
19
|
+
local hay-host process
|
|
20
|
+
|
|
|
21
|
+
v
|
|
22
|
+
Hay room manager
|
|
23
|
+
|
|
|
24
|
+
v
|
|
25
|
+
node-pty
|
|
26
|
+
|
|
|
27
|
+
v
|
|
28
|
+
shell
|
|
21
29
|
```
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
1. Start hop: `node hop`
|
|
78
|
-
2. Open browser to tunnel URL
|
|
79
|
-
3. Verify:
|
|
80
|
-
- [ ] Login with TOTP works
|
|
81
|
-
- [ ] Terminal session works
|
|
82
|
-
- [ ] Multiple clients see same session
|
|
83
|
-
- [ ] Presence indicators show
|
|
84
|
-
- [ ] Control modes work
|
|
85
|
-
- [ ] Mobile UI works without injection
|
|
86
|
-
|
|
87
|
-
## Migration Notes
|
|
88
|
-
|
|
89
|
-
- Sessions are not persistent (by design) - shell exits when all clients disconnect
|
|
90
|
-
- tmux scrollback replaced by termshare's output buffer (200KB)
|
|
91
|
-
- iOS keyboard injection replaced by termshare's built-in mobile keyboard
|
|
92
|
-
- The old ttyd/tmux code paths are still present but no longer used; can be removed in a cleanup pass
|
|
31
|
+
Key properties:
|
|
32
|
+
|
|
33
|
+
- No `ttyd` dependency
|
|
34
|
+
- No `tmux` dependency
|
|
35
|
+
- Shared session model across browser, CLI, and MCP
|
|
36
|
+
- Session-aware audit logging and history isolation
|
|
37
|
+
- Native mobile UI and virtual keyboard support
|
|
38
|
+
- Local host process survives hop daemon restarts
|
|
39
|
+
|
|
40
|
+
## Main Components
|
|
41
|
+
|
|
42
|
+
- `hop`
|
|
43
|
+
- user-facing CLI and daemon
|
|
44
|
+
- auth, Cloudflare tunnel management, session metadata, workspace handling
|
|
45
|
+
- serves the built Hay web client from `hay-web/`
|
|
46
|
+
- `scripts/hay-host.js`
|
|
47
|
+
- persistent local host process for active Hay rooms
|
|
48
|
+
- isolates PTY/runtime ownership from the daemon lifecycle
|
|
49
|
+
- `hay/apps/server`
|
|
50
|
+
- room manager, PTY lifecycle, websocket protocol handling
|
|
51
|
+
- `hay/apps/web`
|
|
52
|
+
- browser terminal client
|
|
53
|
+
- `hay/apps/cli`
|
|
54
|
+
- local terminal client used by Hop for direct attach flows
|
|
55
|
+
- `mcp/hop-mcp.js`
|
|
56
|
+
- MCP server exposing Hop terminal/session primitives
|
|
57
|
+
|
|
58
|
+
## Session Model
|
|
59
|
+
|
|
60
|
+
- Terminal sessions are identified by stable Hop session names.
|
|
61
|
+
- MCP attaches to daemon-scoped terminal handles, but can recover across daemon
|
|
62
|
+
restart by reattaching through the stable session identity.
|
|
63
|
+
- Active PTYs live in Hay rooms managed by the host process.
|
|
64
|
+
- Browser users, local CLI attaches, and agents all talk to the same underlying
|
|
65
|
+
room runtime.
|
|
66
|
+
|
|
67
|
+
## Build Outputs
|
|
68
|
+
|
|
69
|
+
- `hay/apps/web/dist/` is the source web build output.
|
|
70
|
+
- `hay-web/` is the synced bundle served by `hop`.
|
|
71
|
+
- `npm run build` from the repo root rebuilds Hay and syncs `hay-web/`.
|
|
72
|
+
|
|
73
|
+
## Operational Notes
|
|
74
|
+
|
|
75
|
+
- Hop always uses the external Hay host runtime.
|
|
76
|
+
- `HOP_TERMINAL_BACKEND` is accepted only for compatibility and ignored.
|
|
77
|
+
- Session history and audit logging are per-session and workspace-aware.
|
|
78
|
+
- Alternate-screen/TUI applications are captured with TUI-aware audit behavior.
|
|
79
|
+
|
|
80
|
+
## Legacy Notes
|
|
81
|
+
|
|
82
|
+
The earlier `ttyd`/`tmux` approach is now only historical context.
|
|
83
|
+
If you see older references in commit history or archived notes, treat them as
|
|
84
|
+
obsolete unless the current code still uses them explicitly.
|
package/MULTI-AGENT-CHECKLIST.md
CHANGED
|
@@ -12,19 +12,26 @@ Ensure concurrent agent sessions stay isolated, time-bounded, and recoverable.
|
|
|
12
12
|
## Execution Loop
|
|
13
13
|
|
|
14
14
|
1. **Create session** — one `hop_create_terminal` per agent.
|
|
15
|
-
2. **Validate prompt** —
|
|
16
|
-
3. **
|
|
17
|
-
4. **
|
|
18
|
-
5. **Assert state** — verify
|
|
19
|
-
6. **Repeat**
|
|
15
|
+
2. **Validate prompt** — use `hop_wait_terminal(until_prompt=true, start_from="latest")` before the first command.
|
|
16
|
+
3. **Preferred turn helper** — use `hopx_agent_turn` or `hopx_send_and_wait` for normal multi-turn work.
|
|
17
|
+
4. **Manual fallback** — drop to `hop_write_terminal` + `hop_wait_terminal` only when you need custom wait conditions or lower-level control.
|
|
18
|
+
5. **Assert state** — verify expected output before continuing.
|
|
19
|
+
6. **Repeat** the loop; never write into a terminal that is still busy.
|
|
20
|
+
|
|
21
|
+
Recommended defaults:
|
|
22
|
+
|
|
23
|
+
- `capture="readable_raw"`
|
|
24
|
+
- `start_from="latest"` for prompt waits, `start_from="cursor"` for deltas
|
|
25
|
+
- explicit `max_wait_ms`
|
|
26
|
+
- explicit `idle_ms` when using raw wait conditions
|
|
20
27
|
|
|
21
28
|
## Recovery
|
|
22
29
|
|
|
23
30
|
| Step | Action |
|
|
24
31
|
|------|--------|
|
|
25
|
-
| 1 | Send `ctrl_c` via `hop_send_key` |
|
|
26
|
-
| 2 | If
|
|
27
|
-
| 3 |
|
|
28
|
-
| 4 |
|
|
32
|
+
| 1 | Send `ctrl_c` via `hop_send_key` or `control="interrupt"` via `hopx_agent_turn` |
|
|
33
|
+
| 2 | If still running, continue waiting or poll an async wait job instead of blind-resending |
|
|
34
|
+
| 3 | If unresponsive after deadline, `hop_close_terminal(killSession=true)` |
|
|
35
|
+
| 4 | On orchestrator crash, close all child terminals and verify there are no orphaned sessions |
|
|
29
36
|
|
|
30
37
|
**Rule:** Never skip escalation. Always tear down — never leave orphaned sessions.
|
package/README-MCP.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# Hop MCP Server
|
|
2
2
|
|
|
3
|
-
The Hop MCP server exposes
|
|
3
|
+
The Hop MCP server exposes Hop terminal and session APIs over MCP so agents can
|
|
4
|
+
create terminals, stream output, send input, and recover cleanly across daemon
|
|
5
|
+
restarts.
|
|
4
6
|
|
|
5
7
|
## Quick Start
|
|
6
8
|
|
|
7
|
-
1
|
|
9
|
+
1. Ensure the Hop daemon is running locally by running `hop` (interactive) or `hop start` (daemon only).
|
|
8
10
|
|
|
9
|
-
2
|
|
11
|
+
2. Auto-configure supported MCP clients:
|
|
10
12
|
|
|
11
13
|
```bash
|
|
12
14
|
hop-mcp-setup
|
|
@@ -27,7 +29,7 @@ Supported auto-detected clients:
|
|
|
27
29
|
- VS Code / GitHub Copilot (workspace via `.vscode/mcp.json`)
|
|
28
30
|
- Antigravity
|
|
29
31
|
|
|
30
|
-
3
|
|
32
|
+
3. Or configure your MCP client manually:
|
|
31
33
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
@@ -39,51 +41,73 @@ Supported auto-detected clients:
|
|
|
39
41
|
}
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
4
|
|
44
|
+
4. Restart your MCP client.
|
|
43
45
|
|
|
44
46
|
The server auto-connects to the local Hop daemon via `~/.hop2/.tunnel-state`.
|
|
45
47
|
|
|
46
|
-
## One
|
|
48
|
+
## Recommended Flow: One Agent Terminal
|
|
47
49
|
|
|
48
|
-
Recommended flow for driving one
|
|
50
|
+
Recommended flow for driving one Claude/Codex/Gemini terminal safely:
|
|
49
51
|
|
|
50
|
-
1
|
|
52
|
+
1. Launch a dedicated terminal (the returned `id` is the `terminal_id` used by every other tool):
|
|
51
53
|
|
|
52
54
|
```
|
|
53
55
|
hop_create_terminal(name="subagent", cwd="/path/to/repo")
|
|
54
56
|
```
|
|
55
57
|
|
|
56
|
-
2
|
|
58
|
+
2. Start the agent CLI:
|
|
57
59
|
|
|
58
60
|
```
|
|
59
|
-
hop_write_terminal(data="claude\n")
|
|
61
|
+
hop_write_terminal(terminal_id=<id>, data="claude\n")
|
|
60
62
|
# or
|
|
61
|
-
hop_write_terminal(data="codex\n")
|
|
63
|
+
hop_write_terminal(terminal_id=<id>, data="codex\n")
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
3
|
|
66
|
+
3. Wait for a prompt before sending work:
|
|
65
67
|
|
|
66
68
|
```
|
|
67
|
-
hop_wait_terminal(until_prompt=true, start_from="latest")
|
|
69
|
+
hop_wait_terminal(terminal_id=<id>, until_prompt=true, start_from="latest")
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
4
|
|
71
|
-
-
|
|
72
|
-
- helper
|
|
73
|
-
-
|
|
74
|
-
- send
|
|
75
|
-
- wait
|
|
76
|
-
- continue
|
|
77
|
-
- send the next instruction only after output is captured
|
|
72
|
+
4. Run a multi-turn loop:
|
|
73
|
+
- Preferred: `hopx_agent_turn(terminal_id=<id>, data="<task>", mode="auto")`
|
|
74
|
+
- Good lower-level helper: `hopx_send_and_wait(terminal_id=<id>, data="<task>", press_enter=true, capture="readable_raw")`
|
|
75
|
+
- Manual split only when needed:
|
|
76
|
+
- send with `hop_write_terminal(terminal_id=<id>, data="<task>\n")`
|
|
77
|
+
- wait with `hop_wait_terminal(terminal_id=<id>, capture="readable_raw")`
|
|
78
|
+
- continue via cursor deltas from `hop_read_terminal(terminal_id=<id>, start_from="cursor", cursor=...)`
|
|
78
79
|
|
|
79
|
-
5
|
|
80
|
-
- interrupt with `hop_send_key(key="ctrl_c")`
|
|
81
|
-
- close with `hop_close_terminal(killSession=false)`
|
|
80
|
+
5. Stop or clean up:
|
|
81
|
+
- interrupt with `hop_send_key(terminal_id=<id>, key="ctrl_c")`
|
|
82
|
+
- close with `hop_close_terminal(terminal_id=<id>, killSession=false)`
|
|
82
83
|
|
|
83
84
|
Safety notes:
|
|
84
85
|
- Keep one subagent per terminal (no multiplexing multiple agent CLIs in one PTY).
|
|
85
86
|
- For existing user sessions, verify `agentPermitted` (or set with `hop_set_agent_permission`) before writing input.
|
|
86
87
|
|
|
88
|
+
## Shell Commands: `hopx_exec`
|
|
89
|
+
|
|
90
|
+
For plain shell work (not interactive TUIs), `hopx_exec` behaves like a Bash
|
|
91
|
+
tool on a persistent terminal: it sends the command, waits for the next shell
|
|
92
|
+
prompt, and returns clean plain-text output.
|
|
93
|
+
|
|
94
|
+
Worked example:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
hop_create_terminal(name="builder", cwd="/path/to/repo") # returns id
|
|
98
|
+
hopx_exec(terminal_id=<id>, command="npm test")
|
|
99
|
+
# -> { "ok": true, "exit_code": 0, "stdout": "...", "next_cursor": ... }
|
|
100
|
+
hopx_exec(terminal_id=<id>, command="ls /nope")
|
|
101
|
+
# -> { "ok": true, "exit_code": 1, "stdout": "ls: /nope: No such file or directory", ... }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Semantics:
|
|
105
|
+
- `ok` means the shell prompt returned within `timeout_ms` — NOT that the command succeeded.
|
|
106
|
+
- `exit_code` is the command's real exit status, captured by appending a POSIX sentinel (`<cmd>; printf '\n__HOPX_RC_<nonce>=%d\n' "$?"`). It is `null` when the sentinel was never observed (timeout, or a shell without POSIX `$?` semantics) — in that case behavior degrades gracefully to prompt-based capture.
|
|
107
|
+
- The sentinel line, the echoed command, the trailing prompt, and ANSI codes are stripped from `stdout`.
|
|
108
|
+
- On timeout, `timed_out: true` is set and `ok` is `false`.
|
|
109
|
+
- For SSH sessions or unusual prompts, pass `prompt_regex`; for commands with non-standard output endings, pass `idle_ms` as a fallback condition.
|
|
110
|
+
|
|
87
111
|
## Remote Hop
|
|
88
112
|
|
|
89
113
|
To connect to a remote hop instance, set env vars or use `connect_server`:
|
|
@@ -107,29 +131,32 @@ connect_server(base_url="https://hop2.example.com", token="<token>", verify=true
|
|
|
107
131
|
## Tools
|
|
108
132
|
|
|
109
133
|
Core tools (`hop_`): stable atomic operations.
|
|
110
|
-
- `connect_server`
|
|
111
|
-
- `hop_server_info`
|
|
112
|
-
- `hop_list_sessions`
|
|
113
|
-
- `hop_list_terminals`
|
|
114
|
-
- `hop_create_terminal`
|
|
115
|
-
- `hop_attach_terminal`
|
|
116
|
-
- `hop_write_terminal`
|
|
117
|
-
- `hop_send_key`
|
|
118
|
-
- `hop_wait_terminal`
|
|
119
|
-
- `hop_wait_start`
|
|
120
|
-
- `hop_wait_poll`
|
|
121
|
-
- `hop_resize_terminal`
|
|
122
|
-
- `hop_read_terminal`
|
|
123
|
-
- `hop_close_terminal`
|
|
124
|
-
- `hop_set_agent_permission`
|
|
125
|
-
- `hop_list_workspaces`
|
|
126
|
-
- `
|
|
127
|
-
- `
|
|
128
|
-
- `
|
|
134
|
+
- `connect_server` — connect to a Hop API base_url (optional token); use for remote hop instances
|
|
135
|
+
- `hop_server_info` — hop-mcp runtime diagnostics (version, script path, read-mode capabilities)
|
|
136
|
+
- `hop_list_sessions` — list Hop sessions and metadata
|
|
137
|
+
- `hop_list_terminals` — list terminal API sessions (created via `hop_create_terminal` / `hop_attach_terminal`)
|
|
138
|
+
- `hop_create_terminal` — create a terminal session and optionally run a startup command; returns the `id` used as `terminal_id` everywhere else
|
|
139
|
+
- `hop_attach_terminal` — attach to an existing terminal session by name or internalName
|
|
140
|
+
- `hop_write_terminal` — write raw input to a terminal session
|
|
141
|
+
- `hop_send_key` — send a named keypress (enter, esc, tab, shift_tab, arrows, f1-f12, ctrl+[a-z], ...)
|
|
142
|
+
- `hop_wait_terminal` — wait for output conditions (regex, prompt, idle, agent_done); `async=true` returns a `wait_id`
|
|
143
|
+
- `hop_wait_start` — deprecated legacy alias for `hop_wait_terminal(async=true)`
|
|
144
|
+
- `hop_wait_poll` — poll or await completion of a background wait job
|
|
145
|
+
- `hop_resize_terminal` — resize the terminal PTY
|
|
146
|
+
- `hop_read_terminal` — read terminal output events (default `mode="readable_raw"`); returns a cursor for incremental reads
|
|
147
|
+
- `hop_close_terminal` — detach the terminal API session; optionally kill the underlying hop session
|
|
148
|
+
- `hop_set_agent_permission` — allow or block agent access for a session
|
|
149
|
+
- `hop_list_workspaces` — list available workspaces
|
|
150
|
+
- `hop_create_workspace` — create an empty workspace by name
|
|
151
|
+
- `hop_show_workspace` — show saved definitions in a workspace
|
|
152
|
+
- `hop_save_workspace` — save a workspace snapshot from live sessions
|
|
153
|
+
- `hop_delete_workspace` — delete a workspace by name
|
|
154
|
+
- `hop_load_workspace` — load a workspace and optionally start sessions
|
|
129
155
|
|
|
130
156
|
Helper tools (`hopx_`): convenience wrappers built on top of core tools.
|
|
131
|
-
- `hopx_send_and_wait`
|
|
132
|
-
- `
|
|
157
|
+
- `hopx_send_and_wait` — single-call send + wait wrapper
|
|
158
|
+
- `hopx_exec` — Bash-tool-style shell execution: command in, clean stdout + `exit_code` out (see section above)
|
|
159
|
+
- `hopx_agent_turn` — single-turn send + wait + mode-aware output, default `mode="auto"`
|
|
133
160
|
|
|
134
161
|
## Resources
|
|
135
162
|
|
|
@@ -143,6 +170,18 @@ Helper tools (`hopx_`): convenience wrappers built on top of core tools.
|
|
|
143
170
|
- `terminal_id` is an ephemeral daemon attachment handle; underlying hop `sessionName` is the stable identity.
|
|
144
171
|
- On daemon restart, terminal-scoped tools auto-reattach once using stored session identity and retry transparently when possible.
|
|
145
172
|
- `hop_read_terminal` returns a cursor for incremental polling.
|
|
173
|
+
- Default fallback terminal size is `140x40` when no explicit `cols`/`rows` are provided.
|
|
174
|
+
- `hop_create_terminal` and `hop_attach_terminal` do a short output warmup before returning, reducing first-command races.
|
|
175
|
+
- Hop isolates shell history per session and writes per-session NDJSON audit logs under `~/.hop2/workspaces/<workspace>/logs/<session>/audit.ndjson`.
|
|
176
|
+
- Audit logging automatically switches to diff-suppressed `tui_keyframe` snapshots for alternate-screen/TUI apps while still capturing all input.
|
|
177
|
+
|
|
178
|
+
### `hop_read_terminal`
|
|
179
|
+
|
|
180
|
+
- Defaults are token-thrifty:
|
|
181
|
+
- `mode` defaults to `"readable_raw"` (pass `"raw"` or `"ui"` explicitly when needed)
|
|
182
|
+
- `maxEvents` defaults to `200` and `maxBytes` to `65536`; pass `0` explicitly for unlimited (the buffer keeps the last 2000 events)
|
|
183
|
+
- when these caps truncate a read, the payload includes `truncated: true` plus a `hint`; continue with `start_from="cursor"`, `cursor=<next_cursor>`
|
|
184
|
+
- `start_from` defaults to `cursor` when `cursor` is provided, otherwise `beginning`
|
|
146
185
|
- `hop_read_terminal` supports `mode: "ui"` for structured terminal snapshots:
|
|
147
186
|
- `ui.lines`: visible screen lines
|
|
148
187
|
- `ui.cursor`: cursor position
|
|
@@ -166,6 +205,9 @@ Helper tools (`hopx_`): convenience wrappers built on top of core tools.
|
|
|
166
205
|
- parses incrementally across chunk boundaries to avoid split ANSI artifacts
|
|
167
206
|
- reconstructs common inline edits (backspace/cursor rewrites) so text is cleaner for agent parsing
|
|
168
207
|
- avoids full ANSI noise while retaining interaction structure
|
|
208
|
+
|
|
209
|
+
### `hop_wait_terminal`
|
|
210
|
+
|
|
169
211
|
- `hop_send_key` sends normalized named keys (for example `enter`, `esc`, `up`, `ctrl_c`) to improve interactive TUI control without raw escape-string handling.
|
|
170
212
|
- `hop_wait_terminal` blocks on output conditions without client polling loops:
|
|
171
213
|
- `start_from` controls where matching begins:
|
|
@@ -180,15 +222,24 @@ Helper tools (`hopx_`): convenience wrappers built on top of core tools.
|
|
|
180
222
|
- quiet-period detection via `idle_ms`
|
|
181
223
|
- bounded event capture in `raw` or `readable_raw`
|
|
182
224
|
- for `capture="readable_raw"`, supports `control_level`, `noise_filter`, `coalesce_ms`, `coalesce_max_chars`, and optional `includeMetaEvents`
|
|
183
|
-
|
|
184
|
-
|
|
225
|
+
|
|
226
|
+
### Async wait helpers
|
|
227
|
+
|
|
228
|
+
- For long-running conditions, start a background wait with `hop_wait_terminal(terminal_id=<id>, async=true, ...)` (returns `wait_id` immediately) and poll with `hop_wait_poll(wait_id=..., wait=true)`
|
|
185
229
|
- use `consume=true` on poll to remove completed jobs
|
|
230
|
+
- `hop_wait_start` is a deprecated legacy alias for `hop_wait_terminal(async=true)`; prefer the latter
|
|
231
|
+
|
|
232
|
+
### `hopx_send_and_wait`
|
|
233
|
+
|
|
186
234
|
- `hopx_send_and_wait` combines input send + optional enter/key + wait, and defaults to cursor-based delta capture from just before send.
|
|
187
235
|
- helper defaults are token-thrifty for interactive loops: `capture_max_events=60`, `control_level=none`, `noise_filter=balanced`, `coalesce_ms=350` (unless overridden)
|
|
188
236
|
- for `capture="readable_raw"`, `text_only` defaults to `true`; this condenses wait payloads by returning joined `wait.text`, setting `wait.events=[]`, `wait.eventCount=0`, and preserving prior count in `wait.originalEventCount` (set `text_only=false` to keep full events)
|
|
189
237
|
- `hop_read_terminal` supports deterministic delta reads:
|
|
190
238
|
- `start_from`: `beginning` (default), `cursor`, or `latest`
|
|
191
239
|
- response includes `cursorStart`, `cursorEnd`, and `next_cursor`
|
|
240
|
+
|
|
241
|
+
### `hopx_agent_turn`
|
|
242
|
+
|
|
192
243
|
- `hopx_agent_turn` is a helper wrapper (not a core primitive):
|
|
193
244
|
- default `mode="auto"` chooses `ui` when terminal is in alternate-screen, otherwise `readable_raw`
|
|
194
245
|
- in `mode="auto"`, if alternate-screen starts during the same turn, it auto-promotes to `ui` for that response
|
|
@@ -202,12 +253,14 @@ Helper tools (`hopx_`): convenience wrappers built on top of core tools.
|
|
|
202
253
|
- `mode="ui"` defaults wait capture to `capture_max_events=0` (override when you need readable wait-event diagnostics)
|
|
203
254
|
- when using default `until_agent_done` semantics in `mode="ui"`, hopx applies a short UI busy-guard pass to avoid returning while status lines still indicate active work (`esc to interrupt`, `working`, `waiting for process`, etc.)
|
|
204
255
|
- `mode="readable_raw"` / `mode="raw"` returns the same wait payload shape as `hopx_send_and_wait`
|
|
205
|
-
|
|
256
|
+
|
|
257
|
+
### Error model
|
|
258
|
+
|
|
259
|
+
- Tool calls that fail at the Hop API layer return MCP tool errors (`isError: true`) with normalized fields:
|
|
206
260
|
- `ok`
|
|
207
261
|
- `status`
|
|
208
262
|
- `endpoint`
|
|
209
263
|
- `error`
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
- `hop_create_terminal` / `hop_attach_terminal` now do a short output warmup before returning, reducing first-command races in interactive shells.
|
|
264
|
+
- `hint` (when a remedy is known)
|
|
265
|
+
- Connection-level failures (daemon not running, unreachable host, timeouts) also come back as normalized tool errors with `status: null` and a `hint` explaining how to start the daemon (`hop` or `hop start`) or reconnect via `connect_server(base_url=...)` — not as raw JSON-RPC protocol errors.
|
|
266
|
+
- A `403` "Agent access not permitted" error includes a hint to enable access with `hop_set_agent_permission(name=..., allowed=true)` or `hop session permit <name>`.
|