@summerxzp/termbridge-win32-x64 0.3.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/README.txt +53 -0
- package/SKILL.md +274 -0
- package/mcp-config.json +8 -0
- package/package.json +15 -0
- package/termbridge-auth-helper.exe +0 -0
- package/termbridge-mcp.exe +0 -0
- package/termbridge.exe +0 -0
package/README.txt
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
TermBridge
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
Remote Terminal Runtime for AI Agents.
|
|
5
|
+
|
|
6
|
+
Quick Start
|
|
7
|
+
-----------
|
|
8
|
+
|
|
9
|
+
1. Place termbridge-mcp and termbridge-auth-helper in the same directory.
|
|
10
|
+
2. Import mcp-config.json into your MCP client (TraeCode / Claude Code / Codex / OpenCode).
|
|
11
|
+
3. Adjust the "command" path in mcp-config.json to point to termbridge-mcp.
|
|
12
|
+
4. Install SKILL.md into your AI Agent's skill directory.
|
|
13
|
+
5. Restart your MCP client.
|
|
14
|
+
|
|
15
|
+
Files
|
|
16
|
+
-----
|
|
17
|
+
|
|
18
|
+
termbridge-mcp MCP server binary (main entry point)
|
|
19
|
+
termbridge CLI binary (human admin tool, optional)
|
|
20
|
+
termbridge-auth-helper Credential helper (must be in same directory as termbridge-mcp)
|
|
21
|
+
mcp-config.json MCP server configuration template
|
|
22
|
+
SKILL.md Agent Terminal Protocol operational guide
|
|
23
|
+
resources/agentd/ Remote daemon binary (auto-deployed to target host by
|
|
24
|
+
bootstrap_host, do not run locally; Linux x86_64 only)
|
|
25
|
+
|
|
26
|
+
Upgrading
|
|
27
|
+
---------
|
|
28
|
+
|
|
29
|
+
1. Replace termbridge-mcp, termbridge-auth-helper (and termbridge if present).
|
|
30
|
+
2. IMPORTANT: Overwrite the SKILL.md in your AI Agent's skill directory as well.
|
|
31
|
+
It is a separate copy outside this folder, e.g.:
|
|
32
|
+
- Claude Code / OpenCode: ~/.claude/skills/termbridge/SKILL.md
|
|
33
|
+
- Trae: .trae/skills/termbridge/SKILL.md
|
|
34
|
+
SKILL.md evolves with each release; agents only read their own copy.
|
|
35
|
+
3. Restart your MCP client. Existing terminal sessions are unaffected.
|
|
36
|
+
|
|
37
|
+
First Connection
|
|
38
|
+
----------------
|
|
39
|
+
|
|
40
|
+
Use the bootstrap_host MCP tool for first-time SSH key deployment.
|
|
41
|
+
Password is prompted via native OS dialog (never enters LLM context).
|
|
42
|
+
|
|
43
|
+
Documentation
|
|
44
|
+
-------------
|
|
45
|
+
|
|
46
|
+
Full docs: https://github.com/summerxzp/TermBridge#readme
|
|
47
|
+
Getting started: docs/getting-started.md
|
|
48
|
+
Architecture decisions: docs/adr/
|
|
49
|
+
|
|
50
|
+
License
|
|
51
|
+
-------
|
|
52
|
+
|
|
53
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "termbridge"
|
|
3
|
+
description: "Operate remote Linux hosts via TermBridge terminal runtime. Invoke when user asks to run commands on, manage, debug, or deploy to a remote SSH host."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "0.3.0"
|
|
6
|
+
mcp-server: termbridge
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# TermBridge
|
|
10
|
+
|
|
11
|
+
TermBridge is a persistent, recoverable terminal runtime for AI agents. It exposes a remote SSH host's shell as a PTY session you can send input to, read output from, and resume after disconnect.
|
|
12
|
+
|
|
13
|
+
> **Version check**: `metadata.version` in this file is the TermBridge release this SKILL.md was packaged with. The MCP server reports its own version in the `serverInfo.version` field of the initialize handshake. If the two differ (e.g. the user updated termbridge but this skill was not re-synced from the release package), tell the user: "SKILL.md 版本落后,请从 release 包重新复制 SKILL.md 到 agent 的 skill 目录" and do not assume behaviors from newer releases.
|
|
14
|
+
|
|
15
|
+
Use it when the user wants to operate on a remote Linux host: run commands, debug services, edit files, deploy code, inspect logs.
|
|
16
|
+
|
|
17
|
+
## Core Workflow
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
1. list_hosts → confirm host alias is visible
|
|
21
|
+
2. bootstrap_host (first time) → deploy SSH public key (one-time, key-auth hosts only)
|
|
22
|
+
3. open_session(host) → get session_id
|
|
23
|
+
4. send_input(cmd) → run command (raw bytes, no auto-\n)
|
|
24
|
+
5. read_output(wait_for=marker) → wait for completion
|
|
25
|
+
6. read_output(since_cursor=...) → read full output
|
|
26
|
+
7. close_session → done
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For an already-running persistent session, skip step 3 and `attach_remote_session` instead.
|
|
30
|
+
|
|
31
|
+
> **Host policy (ADR-0017 §3.3)**: `hosts.toml` defines per-host defaults (`auth` = `key` / `password` / `auto`; `session` = `standard` / `persistent`).
|
|
32
|
+
> - **`auth=password` host** → every `open_session` prompts the user for a password (out-of-band, never via MCP args). **Never call `bootstrap_host` on such a host** unless the user explicitly asks to switch to key auth.
|
|
33
|
+
> - **`bootstrap_host` does not modify host policy** — hosts.toml stays untouched; `open_session` keeps prompting until the user edits it.
|
|
34
|
+
|
|
35
|
+
> **Scope guidance**: For standard commands (ls, cat, grep, systemctl status), the workflow above is sufficient. For timeout / disconnect / TUI programs / retry scenarios, consult the **7 Rules** and **Decision Table** below.
|
|
36
|
+
|
|
37
|
+
## Input Semantics
|
|
38
|
+
|
|
39
|
+
`send_input()` sends **exactly the bytes you provide**. Nothing is added or modified.
|
|
40
|
+
|
|
41
|
+
### For shell commands: always include terminating LF
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
# BAD: command stays in input buffer, never submitted
|
|
45
|
+
send_input("ls -la")
|
|
46
|
+
|
|
47
|
+
# GOOD: LF terminates the command, shell executes it
|
|
48
|
+
send_input("ls -la\n")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### For interactive input: do NOT add LF unless submitting
|
|
52
|
+
|
|
53
|
+
Interactive prompts (sudo password, `read -p`, vim, REPL, mysql) expect input without automatic LF. Only add `\n` when the user intends to submit the input.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
# sudo password prompt: send password + LF to submit
|
|
57
|
+
send_input("my_password\n")
|
|
58
|
+
|
|
59
|
+
# vim normal mode command: no LF
|
|
60
|
+
send_input(":w")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Empty output ≠ command not executed
|
|
64
|
+
|
|
65
|
+
PTY is a stream. `read_output` immediately after `send_input` may return empty because the command is still running. Use the marker pattern (Rule 1) to wait for completion before reading.
|
|
66
|
+
|
|
67
|
+
## Tool Reference
|
|
68
|
+
|
|
69
|
+
| Tool | Purpose |
|
|
70
|
+
|------|---------|
|
|
71
|
+
| `list_hosts` | List hosts from `~/.ssh/config` |
|
|
72
|
+
| `bootstrap_host` | Deploy ed25519 public key (first-time only, idempotent). Do NOT call on `auth=password` hosts unless the user asks to switch to key auth |
|
|
73
|
+
| `open_session` | Open new PTY session (persistent=true for cross-restart). May trigger a user password prompt on `auth=password` hosts — do not assume immediate return |
|
|
74
|
+
| `attach_remote_session` | Attach to existing persistent session on daemon |
|
|
75
|
+
| `list_remote_sessions` | List daemon-hosted sessions on a host |
|
|
76
|
+
| `send_input` | Write raw bytes to PTY (no auto-append `\n`) |
|
|
77
|
+
| `read_output` | Read output: default / wait_for / tail_lines / since_cursor. `strip_ansi=true` removes terminal control sequences |
|
|
78
|
+
| `send_control` | Ctrl+C / Ctrl+D / Ctrl+Z |
|
|
79
|
+
| `resize` | Resize PTY (cols, rows) |
|
|
80
|
+
| `detach_session` | Detach but keep remote PTY alive |
|
|
81
|
+
| `close_session` | Close and terminate remote shell |
|
|
82
|
+
| `reconnect_session` | Recover a Lost session |
|
|
83
|
+
| `sftp_*` | File transfer / mkdir / list / remove / chmod |
|
|
84
|
+
| `detect_remote_env` | Probe remote OS / shell / tools (independent SSH exec) |
|
|
85
|
+
| `get_session_timeline` | Get session event timeline |
|
|
86
|
+
|
|
87
|
+
## The 7 Rules
|
|
88
|
+
|
|
89
|
+
### Rule 1: Completion — use marker, not prompt guessing
|
|
90
|
+
|
|
91
|
+
For commands that return control to the shell, use a completion marker with a unique request ID and exit code:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
command
|
|
95
|
+
printf '\n__TB_DONE__:%s:%s\n' "$REQID" "$?"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- `$REQID`: unique ID per command (e.g. 5-hex `a3f1c`), prevents stale marker match
|
|
99
|
+
- `$?`: exit code (0 = success)
|
|
100
|
+
- `\n` prefix isolates marker on its own line
|
|
101
|
+
- `printf` (not `echo`) avoids PTY echo re-matching the marker literal
|
|
102
|
+
|
|
103
|
+
**Never** use `command && echo DONE` (fails on error, marker disappears) or `command; echo DONE` (no exit code).
|
|
104
|
+
|
|
105
|
+
### Rule 2: Timeout ≠ failure
|
|
106
|
+
|
|
107
|
+
`read_output` timeout only ends this call. The remote command keeps running, session stays Ready.
|
|
108
|
+
|
|
109
|
+
On timeout, choose:
|
|
110
|
+
- **Continue waiting** → call `read_output(wait_for=marker)` again
|
|
111
|
+
- **Interrupt** → `send_control("ctrl_c")`, then `read_output` to confirm
|
|
112
|
+
- **Let it run in background** → use `since_cursor` to poll periodically
|
|
113
|
+
|
|
114
|
+
**Never auto-retry on timeout.** The original command may still be running; retrying creates duplicate execution.
|
|
115
|
+
|
|
116
|
+
### Rule 3: Disconnect = UNKNOWN state
|
|
117
|
+
|
|
118
|
+
If `send_input` or `read_output` returns a connection error, the remote execution state is **UNKNOWN** (not FAILED). The command may have:
|
|
119
|
+
- completed before disconnect
|
|
120
|
+
- partially executed
|
|
121
|
+
- never started
|
|
122
|
+
|
|
123
|
+
**Never blindly retry.** Instead:
|
|
124
|
+
1. `reconnect_session(session_id)`
|
|
125
|
+
2. Run an idempotency check (see Rule 4)
|
|
126
|
+
3. Only retry if confirmed NOT-RUN
|
|
127
|
+
|
|
128
|
+
### Rule 4: Retry = reconnect + idempotency check first
|
|
129
|
+
|
|
130
|
+
Before retrying any command with side effects:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Idempotency check examples
|
|
134
|
+
test -f /tmp/marker && echo EXISTS || echo MISSING # file created?
|
|
135
|
+
systemctl is-active <service> # service restarted?
|
|
136
|
+
dpkg -l | grep -q "^ii <pkg> " && echo INSTALLED # package installed?
|
|
137
|
+
grep -q "expected" /etc/config && echo APPLIED # config applied?
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- EXISTS / INSTALLED / APPLIED / active → command already ran, do NOT retry
|
|
141
|
+
- MISSING / inactive → safe to retry
|
|
142
|
+
|
|
143
|
+
### Rule 5: Interactive/TUI — no marker
|
|
144
|
+
|
|
145
|
+
These programs occupy the foreground PTY and never return to shell, so markers never appear:
|
|
146
|
+
|
|
147
|
+
| Type | Examples | Exit with |
|
|
148
|
+
|------|----------|-----------|
|
|
149
|
+
| Full-screen TUI | `vim`, `nano`, `htop`, `top`, `less` | `:q` / `q` |
|
|
150
|
+
| Long-running monitor | `tail -f`, `journalctl -f`, `watch` | `send_control("ctrl_c")` |
|
|
151
|
+
| Nested shell | `ssh`, `bash`, `python`, `mysql` | `exit` / `send_control("ctrl_d")` |
|
|
152
|
+
| Interactive prompt | `read -p`, `passwd`, `sudo` (no TTY) | complete input, returns to shell |
|
|
153
|
+
|
|
154
|
+
For these, do NOT use completion markers. Use application-specific exit keys or `send_control`.
|
|
155
|
+
|
|
156
|
+
**Judgment criterion**: if the shell prompt will NOT reappear after the command, do not use marker mode.
|
|
157
|
+
|
|
158
|
+
### Rule 6: Cursor — for full output, use since_cursor
|
|
159
|
+
|
|
160
|
+
`wait_for` returns only the match context (matched line ± context_lines), **not** the full command output.
|
|
161
|
+
|
|
162
|
+
To get full output:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
1. cursor_before = read_output(tail_lines=0).cursor
|
|
166
|
+
2. reqid = generate_unique_id()
|
|
167
|
+
3. send_input("command; printf '\\n__TB_DONE__:%s:%s\\n' \"$reqid\" \"$?\"\n")
|
|
168
|
+
4. r = read_output(wait_for="__TB_DONE__:<reqid>:", timeout_secs=60)
|
|
169
|
+
5. exit_code = parse from r.matched_text
|
|
170
|
+
6. full_output = read_output(since_cursor=cursor_before)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Never** pass both `wait_for` and `since_cursor` in the same call — `since_cursor` takes priority and `wait_for` is silently ignored.
|
|
174
|
+
|
|
175
|
+
For precise text matching, strip ANSI sequences with regex `\x1b\[[0-9;?]*[a-zA-Z]`.
|
|
176
|
+
|
|
177
|
+
### Rule 7: Persistent — detach keeps PTY alive, attach resumes
|
|
178
|
+
|
|
179
|
+
- `detach_session` → local client disconnects, remote PTY keeps running, RingBuffer keeps accumulating
|
|
180
|
+
- `list_remote_sessions(host)` → list daemon-hosted sessions
|
|
181
|
+
- `attach_remote_session(host, remote_session_id)` → resume, returns buffered output since last cursor
|
|
182
|
+
|
|
183
|
+
Daemon crash = all detached sessions lost (Phase 3 does not recover). Must `open_session(persistent=true)` to rebuild.
|
|
184
|
+
|
|
185
|
+
## Decision Table
|
|
186
|
+
|
|
187
|
+
| Situation | Action |
|
|
188
|
+
|-----------|--------|
|
|
189
|
+
| First connection to a key-auth host | `bootstrap_host` (one-time, deploys SSH key) |
|
|
190
|
+
| First connection to an `auth=password` host | `open_session` directly — user is prompted for password; do NOT `bootstrap_host` unless the user explicitly asks to switch to key auth |
|
|
191
|
+
| `open_session` on an `auth=password` host | expect a user password prompt (out-of-band); do not assume immediate return |
|
|
192
|
+
| Subsequent connections | `open_session` (key auth, no password) |
|
|
193
|
+
| Plain command (ls, cat, grep) | `send_input` + marker + `read_output(wait_for)` |
|
|
194
|
+
| Need full command output | record cursor → send → wait_for → `read_output(since_cursor)` |
|
|
195
|
+
| Need clean text output (no ANSI) | `read_output(..., strip_ansi=true)` — removes CSI/OSC/DCS sequences |
|
|
196
|
+
| Long-running command (build) | do NOT retry on timeout; `since_cursor` poll |
|
|
197
|
+
| Watch output (tail -f) | `send_input` + `read_output(tail_lines)` periodically; `ctrl_c` to stop |
|
|
198
|
+
| vim / top / htop | no marker; use app exit keys (`:q`, `q`) or `ctrl_c` |
|
|
199
|
+
| `sudo -n` (non-interactive) | Auto-passthrough: `sudo -n ls`, `sudo -n du`, `sudo -n stat` etc. execute without confirmation. Must be `sudo -n` at line start, no shell chaining (`;` `&&` `|` etc.) |
|
|
200
|
+
| sudo (interactive, no `-n`) | Triggers `POLICY_NEEDS_CONFIRM`. Do NOT send password via `send_input`. Options: (1) use `sudo -n` if NOPASSWD; (2) ask user to run `termbridge session approve <session_id>` for unrestricted session; (3) execute manually in target terminal |
|
|
201
|
+
| SSH disconnect mid-command | state UNKNOWN → `reconnect_session` + idempotency check |
|
|
202
|
+
| Retry a side-effecting command | reconnect first, idempotency check, retry only if NOT-RUN |
|
|
203
|
+
| Cross-restart resume | `list_remote_sessions` → `attach_remote_session` |
|
|
204
|
+
| Resize terminal | `resize(session_id, cols, rows)` before running TUI |
|
|
205
|
+
| Edit remote file | `sftp_transfer(download)` → Edit → `sftp_transfer(upload)`. Local paths allowed under cwd or `$TEMP/termbridge` |
|
|
206
|
+
| Done with session | `close_session` (terminates remote shell) |
|
|
207
|
+
| Want to keep session for later | `detach_session` (PTY keeps running) |
|
|
208
|
+
|
|
209
|
+
## Key Constraints
|
|
210
|
+
|
|
211
|
+
- **`send_input` is raw bytes**: no auto-append `\n`. You must include `\n` yourself for Enter. No command boundary parsing.
|
|
212
|
+
- **`\r` is preserved**: do not strip carriage returns from input.
|
|
213
|
+
- **PTY echo**: the shell echoes input back. `wait_for("MARKER")` may match the echo — use `$REQID` variable so echo contains the variable name, not the value.
|
|
214
|
+
- **ANSI noise**: PTY output contains control sequences (bracketed paste `\x1b[?2004h/l`, OSC 7 `\x1b]7;...`, color codes, `\x1b[K`). Use `read_output(strip_ansi=true)` for clean text; RingBuffer keeps raw bytes, so cursor stays valid.
|
|
215
|
+
- **Credentials never in MCP params**: `bootstrap_host` accepts only `host`. Passwords are prompted via separate `termbridge-auth-helper` process, never exposed to MCP stdio.
|
|
216
|
+
- **Host policy is user intent (ADR-0017 §2.2)**: `hosts.toml` `auth=password` means password for every connection — it is NOT a gap to "fix". `bootstrap_host` never modifies host policy (returns a `hint` instead), so an `auth=password` host keeps prompting until the user edits hosts.toml. Never bootstrap a password-policy host as a convenience optimization.
|
|
217
|
+
- **Session approval mode (0.2.1+)**: Sessions start in `standard` mode (PolicyManager enforces blocklist + confirm). Users can elevate a session to `unrestricted` via `termbridge session approve <session_id>` (CLI, human-only). In unrestricted mode, **only confirm guardrails are skipped** (sudo, `rm -rf /tmp/x`, etc. execute without confirmation); **hard-deny rules still apply** (`rm -rf /`, `mkfs`, `dd of=/dev/`, etc. are still blocked). This does NOT bypass SSH credentials, path safety, or protocol invariants. Approval is session-scoped — closing the session resets to standard. Agent cannot self-approve; only the human user can via CLI. TermBridge Policy is a secondary guardrail (defense-in-depth), not a primary approval system — command approval is the Coding Agent's responsibility.
|
|
218
|
+
|
|
219
|
+
## Anti-Patterns
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
# BAD: timeout → retry (creates duplicate execution)
|
|
223
|
+
r = read_output(wait_for="MARKER", timeout_secs=5)
|
|
224
|
+
if r.timed_out: send_input("command\n") # original may still be running!
|
|
225
|
+
|
|
226
|
+
# BAD: send_input error → retry without reconnect (session Lost)
|
|
227
|
+
try: send_input("cmd\n")
|
|
228
|
+
except: send_input("cmd\n") # will fail again, session is Lost
|
|
229
|
+
|
|
230
|
+
# BAD: marker on top (never appears, false "hung" diagnosis)
|
|
231
|
+
send_input("top\n")
|
|
232
|
+
read_output(wait_for="__TB_DONE__:", timeout_secs=10) # top is TUI!
|
|
233
|
+
|
|
234
|
+
# BAD: depend on wait_for return as full output
|
|
235
|
+
r = read_output(wait_for="MARKER")
|
|
236
|
+
full = r.output # only match context, not full output
|
|
237
|
+
|
|
238
|
+
# BAD: echo marker (PTY echo re-matches)
|
|
239
|
+
send_input("echo __TB_DONE__:abc:0\n") # echo itself contains the marker!
|
|
240
|
+
|
|
241
|
+
# BAD: auto-bootstrap on a password-policy host (violates user intent, ADR-0017 §3.3)
|
|
242
|
+
bootstrap_host(host="prod") # policy says auth=password — user wants password auth;
|
|
243
|
+
# bootstrap also does NOT change hosts.toml, so the prompt stays
|
|
244
|
+
|
|
245
|
+
# BAD: sudo without -n (triggers POLICY_NEEDS_CONFIRM, blocks automation)
|
|
246
|
+
send_input("sudo systemctl restart nginx\n") # blocked!
|
|
247
|
+
|
|
248
|
+
# GOOD: sudo -n for NOPASSWD hosts (auto-passthrough)
|
|
249
|
+
send_input("sudo -n systemctl restart nginx\n")
|
|
250
|
+
|
|
251
|
+
# GOOD: if sudo needs password, ask user to approve session first
|
|
252
|
+
# User runs: termbridge session approve <session_id>
|
|
253
|
+
# Then: sudo commands execute without policy confirmation
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Quick Reference: Happy Path
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
# First time on a host
|
|
260
|
+
list_hosts
|
|
261
|
+
bootstrap_host(host="myserver") # key-auth host only; auth=password hosts: skip (rule §3.3)
|
|
262
|
+
open_session(host="myserver", persistent=true, name="work")
|
|
263
|
+
|
|
264
|
+
# Run a command with completion marker
|
|
265
|
+
reqid = "a3f1c"
|
|
266
|
+
cursor = read_output(session_id, tail_lines=0).cursor
|
|
267
|
+
send_input(session_id, "systemctl status nginx; printf '\\n__TB_DONE__:%s:%s\\n' \"$reqid\" \"$?\"\n")
|
|
268
|
+
r = read_output(session_id, wait_for="__TB_DONE__:a3f1c:", timeout_secs=30)
|
|
269
|
+
exit_code = parse_exit_code(r.matched_text)
|
|
270
|
+
full_output = read_output(session_id, since_cursor=cursor)
|
|
271
|
+
|
|
272
|
+
# Done
|
|
273
|
+
close_session(session_id)
|
|
274
|
+
```
|
package/mcp-config.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@summerxzp/termbridge-win32-x64",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "TermBridge runtime for win32-x64 (完整 release 目录,含 trio 二进制 / resources/agentd / SKILL.md)",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"os": [
|
|
7
|
+
"win32"
|
|
8
|
+
],
|
|
9
|
+
"cpu": [
|
|
10
|
+
"x64"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
"*"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
Binary file
|
|
Binary file
|
package/termbridge.exe
ADDED
|
Binary file
|