@fengye404/termpilot 0.1.7 → 0.1.8
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.md +49 -200
- package/dist/cli.js +12 -1
- package/docs/.vitepress/config.mts +64 -0
- package/docs/.vitepress/dist/404.html +23 -0
- package/docs/.vitepress/dist/README.html +26 -0
- package/docs/.vitepress/dist/architecture.html +42 -0
- package/docs/.vitepress/dist/assets/README.md.B4-OJVNQ.js +1 -0
- package/docs/.vitepress/dist/assets/README.md.B4-OJVNQ.lean.js +1 -0
- package/docs/.vitepress/dist/assets/app.BG4pRgiG.js +1 -0
- package/docs/.vitepress/dist/assets/architecture.md.JnC1zyYV.js +17 -0
- package/docs/.vitepress/dist/assets/architecture.md.JnC1zyYV.lean.js +1 -0
- package/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.l5vdUGaZ.js +1 -0
- package/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.DMeTzGam.js +9 -0
- package/docs/.vitepress/dist/assets/chunks/framework.BZohXCq9.js +19 -0
- package/docs/.vitepress/dist/assets/chunks/theme.D0_6rd9F.js +2 -0
- package/docs/.vitepress/dist/assets/development.md.iwUVjeO6.js +7 -0
- package/docs/.vitepress/dist/assets/development.md.iwUVjeO6.lean.js +1 -0
- package/docs/.vitepress/dist/assets/getting-started.md.Cirp1CHi.js +1 -0
- package/docs/.vitepress/dist/assets/getting-started.md.Cirp1CHi.lean.js +1 -0
- package/docs/.vitepress/dist/assets/index.md.D9XElNRh.js +1 -0
- package/docs/.vitepress/dist/assets/index.md.D9XElNRh.lean.js +1 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/docs/.vitepress/dist/assets/operations-guide.md.DfNiIg5F.js +18 -0
- package/docs/.vitepress/dist/assets/operations-guide.md.DfNiIg5F.lean.js +1 -0
- package/docs/.vitepress/dist/assets/protocol.md.CCXFJUPR.js +40 -0
- package/docs/.vitepress/dist/assets/protocol.md.CCXFJUPR.lean.js +1 -0
- package/docs/.vitepress/dist/assets/style.B0lvUXq1.css +1 -0
- package/docs/.vitepress/dist/assets/tech-selection-2026.md.Dk_ymWTx.js +1 -0
- package/docs/.vitepress/dist/assets/tech-selection-2026.md.Dk_ymWTx.lean.js +1 -0
- package/docs/.vitepress/dist/development.html +32 -0
- package/docs/.vitepress/dist/favicon.svg +6 -0
- package/docs/.vitepress/dist/getting-started.html +26 -0
- package/docs/.vitepress/dist/hashmap.json +1 -0
- package/docs/.vitepress/dist/index.html +26 -0
- package/docs/.vitepress/dist/operations-guide.html +43 -0
- package/docs/.vitepress/dist/protocol.html +65 -0
- package/docs/.vitepress/dist/tech-selection-2026.html +26 -0
- package/docs/.vitepress/dist/vp-icons.css +1 -0
- package/docs/.vitepress/theme/custom.css +42 -0
- package/docs/.vitepress/theme/index.ts +10 -0
- package/docs/README.md +10 -7
- package/docs/getting-started.md +136 -0
- package/docs/index.md +57 -0
- package/docs/operations-guide.md +6 -6
- package/docs/public/favicon.svg +6 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,99 +1,60 @@
|
|
|
1
1
|
# TermPilot
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@fengye404/termpilot)
|
|
4
|
+
[](https://www.npmjs.com/package/@fengye404/termpilot)
|
|
5
|
+
[](https://github.com/fengye404/TermPilot/actions)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
TermPilot 是一个终端优先的远程控制工具。它把电脑上的 `tmux` 会话暴露给手机浏览器,让你在电脑和手机之间无缝切换,同步查看和控制同一批任务。
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 产品形态
|
|
9
|
+
## 为什么是它
|
|
10
10
|
|
|
11
11
|
- 一个 npm 包:`@fengye404/termpilot`
|
|
12
12
|
- 一个服务器命令:`termpilot relay`
|
|
13
13
|
- 一个电脑命令:`termpilot agent`
|
|
14
14
|
- 手机端不安装,直接打开 relay 域名
|
|
15
|
-
- relay
|
|
16
|
-
|
|
17
|
-
## 5 分钟快速上手
|
|
18
|
-
|
|
19
|
-
### 1. 启动 relay
|
|
15
|
+
- relay 同时负责 Web UI 托管和 WebSocket 中继
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
## 30 秒理解工作流
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
1. 在服务器执行 `termpilot relay`
|
|
20
|
+
2. 在电脑执行 `termpilot agent`
|
|
21
|
+
3. 手机上打开 relay 域名并输入配对码
|
|
22
|
+
4. 在电脑直接执行 `termpilot claude code`
|
|
23
|
+
5. 手机和电脑同时看到同一个会话输出
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
## 快速开始
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
### 1. 启动 relay
|
|
31
28
|
|
|
32
29
|
```bash
|
|
30
|
+
npm install -g @fengye404/termpilot
|
|
33
31
|
termpilot relay
|
|
34
|
-
termpilot relay stop
|
|
35
|
-
termpilot relay run
|
|
36
32
|
```
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
- `termpilot relay stop`:停止后台 relay
|
|
40
|
-
- `termpilot relay run`:前台运行,适合看日志和排查问题
|
|
41
|
-
|
|
42
|
-
如果你只是先本地体验,也可以直接在自己电脑上跑 relay,然后让手机走局域网访问。
|
|
43
|
-
|
|
44
|
-
### 2. 启动电脑 agent
|
|
45
|
-
|
|
46
|
-
在你的电脑上执行:
|
|
34
|
+
### 2. 启动 agent
|
|
47
35
|
|
|
48
36
|
```bash
|
|
49
37
|
npm install -g @fengye404/termpilot
|
|
50
38
|
termpilot agent
|
|
51
39
|
```
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
第一次运行时,`termpilot agent` 会交互式询问:
|
|
54
42
|
|
|
55
|
-
1.
|
|
56
|
-
2.
|
|
57
|
-
3. 自动保存本机配置
|
|
58
|
-
4. 后台启动 agent
|
|
59
|
-
5. 输出一次性配对码
|
|
43
|
+
1. relay 域名或 IP
|
|
44
|
+
2. 端口,默认 `8787`
|
|
60
45
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
termpilot agent
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
这条命令会根据当前状态自动处理:
|
|
68
|
-
|
|
69
|
-
- 没有后台 agent:按本机已保存配置启动
|
|
70
|
-
- 已经有后台 agent:直接显示当前状态
|
|
71
|
-
- 想重新给手机配对:执行 `termpilot agent --pair`
|
|
72
|
-
|
|
73
|
-
常用管理命令:
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
termpilot agent status
|
|
77
|
-
termpilot agent stop
|
|
78
|
-
termpilot agent --pair
|
|
79
|
-
```
|
|
46
|
+
然后它会自动保存配置、后台启动 agent,并打印一次性配对码。
|
|
80
47
|
|
|
81
48
|
### 3. 手机完成配对
|
|
82
49
|
|
|
83
|
-
|
|
50
|
+
手机浏览器打开:
|
|
84
51
|
|
|
85
52
|
- `http://your-domain.com:8787`
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
然后:
|
|
89
|
-
|
|
90
|
-
1. 输入电脑端刚打印出来的配对码
|
|
91
|
-
2. 点“配对”
|
|
92
|
-
3. 成功后直接进入会话列表
|
|
53
|
+
- 或 `https://your-domain.com`
|
|
93
54
|
|
|
94
|
-
|
|
55
|
+
输入配对码后,直接进入会话列表。
|
|
95
56
|
|
|
96
|
-
|
|
57
|
+
### 4. 直接启动任务
|
|
97
58
|
|
|
98
59
|
```bash
|
|
99
60
|
termpilot claude code
|
|
@@ -105,163 +66,51 @@ termpilot claude code
|
|
|
105
66
|
termpilot open code
|
|
106
67
|
```
|
|
107
68
|
|
|
108
|
-
|
|
69
|
+
这会直接创建一个受 TermPilot 管理的 `tmux` 会话并 attach 到当前终端,手机端会同步看到同一个会话。
|
|
109
70
|
|
|
110
|
-
|
|
111
|
-
- 把命令写进这个会话
|
|
112
|
-
- 当前终端自动 attach 进去
|
|
113
|
-
- 手机端同步看到同一个会话
|
|
114
|
-
|
|
115
|
-
### 5. 你现在应该能做到什么
|
|
116
|
-
|
|
117
|
-
此时你可以:
|
|
118
|
-
|
|
119
|
-
- 在电脑上看 `claude code` / `open code` 的流式输出
|
|
120
|
-
- 在手机上看同一份输出
|
|
121
|
-
- 在手机上补一条命令、发快捷键、关闭会话
|
|
122
|
-
- 随时在电脑和手机之间切换
|
|
123
|
-
|
|
124
|
-
### 服务器
|
|
125
|
-
|
|
126
|
-
发布后:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
npm install -g @fengye404/termpilot
|
|
130
|
-
termpilot relay
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
当前仓库内本地验证:
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
pnpm install
|
|
137
|
-
pnpm build
|
|
138
|
-
npm install -g .
|
|
139
|
-
termpilot relay
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
常用参数:
|
|
71
|
+
## 常用命令
|
|
143
72
|
|
|
144
73
|
```bash
|
|
145
74
|
termpilot relay
|
|
146
|
-
termpilot relay run
|
|
147
75
|
termpilot relay stop
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### 电脑
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
npm install -g @fengye404/termpilot
|
|
76
|
+
termpilot relay run
|
|
155
77
|
termpilot agent
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
如果你只是想看调试日志,可以显式前台运行:
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
termpilot agent --foreground
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
查看后台状态:
|
|
165
|
-
|
|
166
|
-
```bash
|
|
78
|
+
termpilot agent --pair
|
|
167
79
|
termpilot agent status
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
停止后台 agent:
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
80
|
termpilot agent stop
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
本地测试:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
termpilot agent
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### 手机
|
|
183
|
-
|
|
184
|
-
直接打开 relay 域名:
|
|
185
|
-
|
|
186
|
-
- `https://your-domain.com`
|
|
187
|
-
|
|
188
|
-
首次使用时,直接执行上面的 `termpilot agent` 就会进入配置引导并拿到配对码;如果你已经跑着后台 agent、只是想重新给手机配对,用 `termpilot agent --pair`。
|
|
189
|
-
|
|
190
|
-
配对成功后:
|
|
191
|
-
|
|
192
|
-
- 访问令牌会自动写回页面
|
|
193
|
-
- 手机端默认先显示会话列表
|
|
194
|
-
- 点进一个会话后才进入终端详情页
|
|
195
|
-
- 连接信息和设备设置都在页面底部折叠区
|
|
196
|
-
|
|
197
|
-
## 日常使用
|
|
198
|
-
|
|
199
|
-
### 直接把命令交给 TermPilot
|
|
200
|
-
|
|
201
|
-
```bash
|
|
202
|
-
termpilot agent
|
|
203
81
|
termpilot claude code
|
|
204
82
|
termpilot open code
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
如果你想跑别的命令,也可以直接:
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
termpilot npm run dev
|
|
211
|
-
termpilot python worker.py
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### 手动管理会话
|
|
215
|
-
|
|
216
|
-
创建会话并进入:
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
termpilot create --name claude-main --cwd /path/to/project
|
|
83
|
+
termpilot create --name my-task --cwd /path/to/project
|
|
220
84
|
termpilot list
|
|
221
85
|
termpilot attach --sid <sid>
|
|
86
|
+
termpilot kill --sid <sid>
|
|
222
87
|
```
|
|
223
88
|
|
|
224
|
-
|
|
89
|
+
## 文档
|
|
225
90
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
91
|
+
- [文档首页](./docs/index.md)
|
|
92
|
+
- [快速开始](./docs/getting-started.md)
|
|
93
|
+
- [部署与运维指南](./docs/operations-guide.md)
|
|
94
|
+
- [当前架构](./docs/architecture.md)
|
|
95
|
+
- [当前协议](./docs/protocol.md)
|
|
96
|
+
- [开发文档](./docs/development.md)
|
|
231
97
|
|
|
232
|
-
|
|
98
|
+
## 最佳实践
|
|
233
99
|
|
|
234
|
-
|
|
100
|
+
1. 需要跨端同步的任务,一开始就用 `termpilot claude code`、`termpilot open code` 或 `termpilot create` 启动,不要先在普通终端里跑再想着接管。
|
|
101
|
+
2. `termpilot agent` 适合作为长期后台入口。第一次配置完之后,日常只需要记住这一条命令。
|
|
102
|
+
3. relay 长期使用时,优先挂到 HTTPS/WSS 域名后面;本地演示再用裸 IP 和 `8787`。
|
|
103
|
+
4. 手机更适合看输出、发短命令和轻控制;电脑前的重输入仍然建议在本地终端完成。
|
|
104
|
+
|
|
105
|
+
## 本地开发
|
|
235
106
|
|
|
236
107
|
```bash
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
termpilot agent status
|
|
243
|
-
termpilot agent stop
|
|
244
|
-
termpilot create --name claude-main
|
|
245
|
-
termpilot list
|
|
246
|
-
termpilot attach --sid <sid>
|
|
247
|
-
termpilot kill --sid <sid>
|
|
248
|
-
termpilot grants
|
|
249
|
-
termpilot audit --limit 30
|
|
250
|
-
termpilot revoke --token <accessToken>
|
|
251
|
-
termpilot doctor
|
|
108
|
+
pnpm install
|
|
109
|
+
pnpm build
|
|
110
|
+
pnpm docs:dev
|
|
111
|
+
pnpm test:ui-smoke
|
|
112
|
+
pnpm check:stability
|
|
252
113
|
```
|
|
253
|
-
|
|
254
|
-
## 最佳实践
|
|
255
|
-
|
|
256
|
-
1. 需要跨端同步的任务,一开始就用 `termpilot create` 创建,不要先在普通终端里跑再想着接管。
|
|
257
|
-
2. 第一次先跑一次 `termpilot agent` 完成本机配置,之后日常就只需要记住这一条命令。
|
|
258
|
-
3. 如果只是想“开一个会话然后立刻跑起来”,优先用 `termpilot claude code` 这类直达命令,不必手动 `create + attach`。
|
|
259
|
-
4. 一个长期任务用一个独立会话,名称直接写任务语义,比如 `claude-main`、`deploy-watch`、`batch-fix`。
|
|
260
|
-
5. 电脑前重操作优先 `termpilot attach`;手机更适合看进度、发短命令、补快捷键和关闭会话。
|
|
261
|
-
6. 普通 iTerm / Terminal 标签页不是 TermPilot 管理对象,不要指望后面“无缝接管”进来。
|
|
262
|
-
7. 手机优先走一次性配对码,不要长期传播访问令牌。
|
|
263
|
-
8. 要长期使用 relay,优先放到 HTTPS/WSS 域名后面,并接 PostgreSQL;本地演示可以先用内存模式。
|
|
264
|
-
9. 换手机或访问权变更时,先 `termpilot grants`,再 `termpilot revoke --token ...`。
|
|
265
114
|
10. 想排查控制历史时先看 `termpilot audit --limit 30`。
|
|
266
115
|
11. 服务器上日常用 `termpilot relay` 后台运行;只有排查问题时才用 `termpilot relay run`。
|
|
267
116
|
|
package/dist/cli.js
CHANGED
|
@@ -1842,7 +1842,18 @@ function createStaticPath(webDir, urlPath) {
|
|
|
1842
1842
|
return resolvedPath;
|
|
1843
1843
|
}
|
|
1844
1844
|
function resolveDefaultWebDir(moduleUrl = import.meta.url) {
|
|
1845
|
-
|
|
1845
|
+
const candidates = [
|
|
1846
|
+
"../../app/dist",
|
|
1847
|
+
"../app/dist",
|
|
1848
|
+
"./app/dist"
|
|
1849
|
+
];
|
|
1850
|
+
for (const candidate of candidates) {
|
|
1851
|
+
const resolvedDir = fileURLToPath(new URL(candidate, moduleUrl));
|
|
1852
|
+
if (existsSync(path3.join(resolvedDir, "index.html"))) {
|
|
1853
|
+
return resolvedDir;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
return fileURLToPath(new URL("../app/dist", moduleUrl));
|
|
1846
1857
|
}
|
|
1847
1858
|
async function startRelayServer(options = {}) {
|
|
1848
1859
|
const config = {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineConfig } from "vitepress";
|
|
2
|
+
|
|
3
|
+
const repo = process.env.GITHUB_REPOSITORY?.split("/")[1] ?? "TermPilot";
|
|
4
|
+
const base = process.env.GITHUB_ACTIONS ? `/${repo}/` : "/";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
lang: "zh-CN",
|
|
8
|
+
title: "TermPilot",
|
|
9
|
+
description: "手机和电脑共享同一个 tmux 会话的终端远程控制工具。",
|
|
10
|
+
base,
|
|
11
|
+
lastUpdated: true,
|
|
12
|
+
cleanUrls: true,
|
|
13
|
+
head: [
|
|
14
|
+
["meta", { name: "theme-color", content: "#1f7a53" }],
|
|
15
|
+
],
|
|
16
|
+
themeConfig: {
|
|
17
|
+
siteTitle: "TermPilot",
|
|
18
|
+
logo: "/favicon.svg",
|
|
19
|
+
nav: [
|
|
20
|
+
{ text: "首页", link: "/" },
|
|
21
|
+
{ text: "快速开始", link: "/getting-started" },
|
|
22
|
+
{ text: "部署与运维", link: "/operations-guide" },
|
|
23
|
+
{ text: "架构", link: "/architecture" },
|
|
24
|
+
{ text: "协议", link: "/protocol" },
|
|
25
|
+
],
|
|
26
|
+
sidebar: [
|
|
27
|
+
{
|
|
28
|
+
text: "开始",
|
|
29
|
+
items: [
|
|
30
|
+
{ text: "文档首页", link: "/" },
|
|
31
|
+
{ text: "快速开始", link: "/getting-started" },
|
|
32
|
+
{ text: "部署与运维指南", link: "/operations-guide" },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
text: "参考",
|
|
37
|
+
items: [
|
|
38
|
+
{ text: "代码架构", link: "/architecture" },
|
|
39
|
+
{ text: "协议说明", link: "/protocol" },
|
|
40
|
+
{ text: "开发文档", link: "/development" },
|
|
41
|
+
{ text: "技术选型", link: "/tech-selection-2026" },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
search: {
|
|
46
|
+
provider: "local",
|
|
47
|
+
},
|
|
48
|
+
socialLinks: [
|
|
49
|
+
{ icon: "github", link: "https://github.com/fengye404/TermPilot" },
|
|
50
|
+
],
|
|
51
|
+
editLink: {
|
|
52
|
+
pattern: "https://github.com/fengye404/TermPilot/edit/main/docs/:path",
|
|
53
|
+
text: "在 GitHub 上编辑此页",
|
|
54
|
+
},
|
|
55
|
+
outline: {
|
|
56
|
+
level: [2, 3],
|
|
57
|
+
label: "本页目录",
|
|
58
|
+
},
|
|
59
|
+
footer: {
|
|
60
|
+
message: "为长期任务和跨端终端控制而构建。",
|
|
61
|
+
copyright: "Copyright © 2026 Fengye",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN" dir="ltr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>404 | TermPilot</title>
|
|
7
|
+
<meta name="description" content="Not Found">
|
|
8
|
+
<meta name="generator" content="VitePress v1.6.4">
|
|
9
|
+
<link rel="preload stylesheet" href="/assets/style.B0lvUXq1.css" as="style">
|
|
10
|
+
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
|
|
11
|
+
|
|
12
|
+
<script type="module" src="/assets/app.BG4pRgiG.js"></script>
|
|
13
|
+
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
+
<meta name="theme-color" content="#1f7a53">
|
|
15
|
+
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
16
|
+
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="app"></div>
|
|
20
|
+
<script>window.__VP_HASH_MAP__=JSON.parse("{\"architecture.md\":\"JnC1zyYV\",\"development.md\":\"iwUVjeO6\",\"getting-started.md\":\"Cirp1CHi\",\"index.md\":\"D9XElNRh\",\"operations-guide.md\":\"DfNiIg5F\",\"protocol.md\":\"CCXFJUPR\",\"readme.md\":\"B4-OJVNQ\",\"tech-selection-2026.md\":\"Dk_ymWTx\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"TermPilot\",\"description\":\"手机和电脑共享同一个 tmux 会话的终端远程控制工具。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"siteTitle\":\"TermPilot\",\"logo\":\"/favicon.svg\",\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维\",\"link\":\"/operations-guide\"},{\"text\":\"架构\",\"link\":\"/architecture\"},{\"text\":\"协议\",\"link\":\"/protocol\"}],\"sidebar\":[{\"text\":\"开始\",\"items\":[{\"text\":\"文档首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维指南\",\"link\":\"/operations-guide\"}]},{\"text\":\"参考\",\"items\":[{\"text\":\"代码架构\",\"link\":\"/architecture\"},{\"text\":\"协议说明\",\"link\":\"/protocol\"},{\"text\":\"开发文档\",\"link\":\"/development\"},{\"text\":\"技术选型\",\"link\":\"/tech-selection-2026\"}]}],\"search\":{\"provider\":\"local\"},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/fengye404/TermPilot\"}],\"editLink\":{\"pattern\":\"https://github.com/fengye404/TermPilot/edit/main/docs/:path\",\"text\":\"在 GitHub 上编辑此页\"},\"outline\":{\"level\":[2,3],\"label\":\"本页目录\"},\"footer\":{\"message\":\"为长期任务和跨端终端控制而构建。\",\"copyright\":\"Copyright © 2026 Fengye\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
|
|
21
|
+
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN" dir="ltr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>docs 目录 | TermPilot</title>
|
|
7
|
+
<meta name="description" content="手机和电脑共享同一个 tmux 会话的终端远程控制工具。">
|
|
8
|
+
<meta name="generator" content="VitePress v1.6.4">
|
|
9
|
+
<link rel="preload stylesheet" href="/assets/style.B0lvUXq1.css" as="style">
|
|
10
|
+
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
|
|
11
|
+
|
|
12
|
+
<script type="module" src="/assets/app.BG4pRgiG.js"></script>
|
|
13
|
+
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
+
<link rel="modulepreload" href="/assets/chunks/theme.D0_6rd9F.js">
|
|
15
|
+
<link rel="modulepreload" href="/assets/chunks/framework.BZohXCq9.js">
|
|
16
|
+
<link rel="modulepreload" href="/assets/README.md.B4-OJVNQ.lean.js">
|
|
17
|
+
<meta name="theme-color" content="#1f7a53">
|
|
18
|
+
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
19
|
+
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div id="app"><div class="Layout" data-v-1bdd7537><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0a4b5d46></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0a4b5d46>Skip to content</a><!--]--><!----><header class="VPNav" data-v-1bdd7537 data-v-07e0ee65><div class="VPNavBar" data-v-07e0ee65 data-v-bfcfe748><div class="wrapper" data-v-bfcfe748><div class="container" data-v-bfcfe748><div class="title" data-v-bfcfe748><div class="VPNavBarTitle has-sidebar" data-v-bfcfe748 data-v-6ce24249><a class="title" href="/" data-v-6ce24249><!--[--><!--]--><!--[--><img class="VPImage logo" src="/favicon.svg" alt data-v-105fdaa6><!--]--><span data-v-6ce24249>TermPilot</span><!--[--><!--]--></a></div></div><div class="content" data-v-bfcfe748><div class="content-body" data-v-bfcfe748><!--[--><!--]--><div class="VPNavBarSearch search" data-v-bfcfe748><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-bfcfe748 data-v-d1dc8fec><span id="main-nav-aria-label" class="visually-hidden" data-v-d1dc8fec> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>首页</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/getting-started" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>快速开始</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/operations-guide" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>部署与运维</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/architecture" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>架构</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/protocol" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>协议</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-bfcfe748 data-v-d994237e><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-d994237e data-v-9a85cf30 data-v-b1949eaf><span class="check" data-v-b1949eaf><span class="icon" data-v-b1949eaf><!--[--><span class="vpi-sun sun" data-v-9a85cf30></span><span class="vpi-moon moon" data-v-9a85cf30></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-bfcfe748 data-v-a61e22dd data-v-f3c77898><!--[--><a class="VPSocialLink no-icon" href="https://github.com/fengye404/TermPilot" aria-label="github" target="_blank" rel="noopener" data-v-f3c77898 data-v-8a10446f><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-bfcfe748 data-v-6d16081b data-v-35350ec6><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-35350ec6><span class="vpi-more-horizontal icon" data-v-35350ec6></span></button><div class="menu" data-v-35350ec6><div class="VPMenu" data-v-35350ec6 data-v-52b08d90><!----><!--[--><!--[--><!----><div class="group" data-v-6d16081b><div class="item appearance" data-v-6d16081b><p class="label" data-v-6d16081b>Appearance</p><div class="appearance-action" data-v-6d16081b><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-6d16081b data-v-9a85cf30 data-v-b1949eaf><span class="check" data-v-b1949eaf><span class="icon" data-v-b1949eaf><!--[--><span class="vpi-sun sun" data-v-9a85cf30></span><span class="vpi-moon moon" data-v-9a85cf30></span><!--]--></span></span></button></div></div></div><div class="group" data-v-6d16081b><div class="item social-links" data-v-6d16081b><div class="VPSocialLinks social-links-list" data-v-6d16081b data-v-f3c77898><!--[--><a class="VPSocialLink no-icon" href="https://github.com/fengye404/TermPilot" aria-label="github" target="_blank" rel="noopener" data-v-f3c77898 data-v-8a10446f><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-bfcfe748 data-v-1e510fee><span class="container" data-v-1e510fee><span class="top" data-v-1e510fee></span><span class="middle" data-v-1e510fee></span><span class="bottom" data-v-1e510fee></span></span></button></div></div></div></div><div class="divider" data-v-bfcfe748><div class="divider-line" data-v-bfcfe748></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-1bdd7537 data-v-18894e30><div class="container" data-v-18894e30><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-18894e30><span class="vpi-align-left menu-icon" data-v-18894e30></span><span class="menu-text" data-v-18894e30>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-18894e30 data-v-bdfacdf2><button data-v-bdfacdf2>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-1bdd7537 data-v-1d1d7027><div class="curtain" data-v-1d1d7027></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-1d1d7027><span class="visually-hidden" id="sidebar-aria-label" data-v-1d1d7027> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-594fed9e><section class="VPSidebarItem level-0" data-v-594fed9e data-v-cd30f15d><div class="item" role="button" tabindex="0" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><h2 class="text" data-v-cd30f15d>开始</h2><!----></div><div class="items" data-v-cd30f15d><!--[--><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>文档首页</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/getting-started" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>快速开始</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/operations-guide" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>部署与运维指南</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-594fed9e><section class="VPSidebarItem level-0" data-v-594fed9e data-v-cd30f15d><div class="item" role="button" tabindex="0" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><h2 class="text" data-v-cd30f15d>参考</h2><!----></div><div class="items" data-v-cd30f15d><!--[--><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/architecture" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>代码架构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/protocol" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>协议说明</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/development" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>开发文档</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/tech-selection-2026" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>技术选型</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-1bdd7537 data-v-f89b4fb6><div class="VPDoc has-sidebar has-aside" data-v-f89b4fb6 data-v-1870bdbd><!--[--><!--]--><div class="container" data-v-1870bdbd><div class="aside" data-v-1870bdbd><div class="aside-curtain" data-v-1870bdbd></div><div class="aside-container" data-v-1870bdbd><div class="aside-content" data-v-1870bdbd><div class="VPDocAside" data-v-1870bdbd data-v-2bdf3a15><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-2bdf3a15 data-v-3d03f0c2><div class="content" data-v-3d03f0c2><div class="outline-marker" data-v-3d03f0c2></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-3d03f0c2>本页目录</div><ul class="VPDocOutlineItem root" data-v-3d03f0c2 data-v-87a812ef><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-2bdf3a15></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-1870bdbd><div class="content-container" data-v-1870bdbd><!--[--><!--]--><main class="main" data-v-1870bdbd><div style="position:relative;" class="vp-doc _README" data-v-1870bdbd><div><h1 id="docs-目录" tabindex="-1">docs 目录 <a class="header-anchor" href="#docs-目录" aria-label="Permalink to "docs 目录""></a></h1><p>如果你在 GitHub 仓库里浏览源码,推荐从下面几个入口开始:</p><ul><li><a href="./">文档首页</a></li><li><a href="./getting-started">快速开始</a></li><li><a href="./operations-guide">部署与运维指南</a></li><li><a href="./architecture">代码架构</a></li><li><a href="./development">开发文档</a></li></ul><p>如果 GitHub Pages 已经启用,优先看站点版本,它会带导航、目录和搜索。</p></div></div></main><footer class="VPDocFooter" data-v-1870bdbd data-v-b170fa4f><!--[--><!--]--><div class="edit-info" data-v-b170fa4f><div class="edit-link" data-v-b170fa4f><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/fengye404/TermPilot/edit/main/docs/README.md" target="_blank" rel="noreferrer" data-v-b170fa4f><!--[--><span class="vpi-square-pen edit-link-icon" data-v-b170fa4f></span> 在 GitHub 上编辑此页<!--]--></a></div><div class="last-updated" data-v-b170fa4f><p class="VPLastUpdated" data-v-b170fa4f data-v-33a4642e>Last updated: <time datetime="2026-03-11T17:35:45.000Z" data-v-33a4642e></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-b170fa4f><span class="visually-hidden" id="doc-footer-aria-label" data-v-b170fa4f>Pager</span><div class="pager" data-v-b170fa4f><!----></div><div class="pager" data-v-b170fa4f><a class="VPLink link pager-link next" href="/" data-v-b170fa4f><!--[--><span class="desc" data-v-b170fa4f>Next page</span><span class="title" data-v-b170fa4f>文档首页</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-1bdd7537 data-v-9a5ea44b><div class="container" data-v-9a5ea44b><p class="message" data-v-9a5ea44b>为长期任务和跨端终端控制而构建。</p><p class="copyright" data-v-9a5ea44b>Copyright © 2026 Fengye</p></div></footer><!--[--><!--]--></div></div>
|
|
23
|
+
<script>window.__VP_HASH_MAP__=JSON.parse("{\"architecture.md\":\"JnC1zyYV\",\"development.md\":\"iwUVjeO6\",\"getting-started.md\":\"Cirp1CHi\",\"index.md\":\"D9XElNRh\",\"operations-guide.md\":\"DfNiIg5F\",\"protocol.md\":\"CCXFJUPR\",\"readme.md\":\"B4-OJVNQ\",\"tech-selection-2026.md\":\"Dk_ymWTx\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"TermPilot\",\"description\":\"手机和电脑共享同一个 tmux 会话的终端远程控制工具。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"siteTitle\":\"TermPilot\",\"logo\":\"/favicon.svg\",\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维\",\"link\":\"/operations-guide\"},{\"text\":\"架构\",\"link\":\"/architecture\"},{\"text\":\"协议\",\"link\":\"/protocol\"}],\"sidebar\":[{\"text\":\"开始\",\"items\":[{\"text\":\"文档首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维指南\",\"link\":\"/operations-guide\"}]},{\"text\":\"参考\",\"items\":[{\"text\":\"代码架构\",\"link\":\"/architecture\"},{\"text\":\"协议说明\",\"link\":\"/protocol\"},{\"text\":\"开发文档\",\"link\":\"/development\"},{\"text\":\"技术选型\",\"link\":\"/tech-selection-2026\"}]}],\"search\":{\"provider\":\"local\"},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/fengye404/TermPilot\"}],\"editLink\":{\"pattern\":\"https://github.com/fengye404/TermPilot/edit/main/docs/:path\",\"text\":\"在 GitHub 上编辑此页\"},\"outline\":{\"level\":[2,3],\"label\":\"本页目录\"},\"footer\":{\"message\":\"为长期任务和跨端终端控制而构建。\",\"copyright\":\"Copyright © 2026 Fengye\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
|
|
24
|
+
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN" dir="ltr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>TermPilot 当前代码架构 | TermPilot</title>
|
|
7
|
+
<meta name="description" content="手机和电脑共享同一个 tmux 会话的终端远程控制工具。">
|
|
8
|
+
<meta name="generator" content="VitePress v1.6.4">
|
|
9
|
+
<link rel="preload stylesheet" href="/assets/style.B0lvUXq1.css" as="style">
|
|
10
|
+
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
|
|
11
|
+
|
|
12
|
+
<script type="module" src="/assets/app.BG4pRgiG.js"></script>
|
|
13
|
+
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
+
<link rel="modulepreload" href="/assets/chunks/theme.D0_6rd9F.js">
|
|
15
|
+
<link rel="modulepreload" href="/assets/chunks/framework.BZohXCq9.js">
|
|
16
|
+
<link rel="modulepreload" href="/assets/architecture.md.JnC1zyYV.lean.js">
|
|
17
|
+
<meta name="theme-color" content="#1f7a53">
|
|
18
|
+
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
19
|
+
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div id="app"><div class="Layout" data-v-1bdd7537><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0a4b5d46></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0a4b5d46>Skip to content</a><!--]--><!----><header class="VPNav" data-v-1bdd7537 data-v-07e0ee65><div class="VPNavBar" data-v-07e0ee65 data-v-bfcfe748><div class="wrapper" data-v-bfcfe748><div class="container" data-v-bfcfe748><div class="title" data-v-bfcfe748><div class="VPNavBarTitle has-sidebar" data-v-bfcfe748 data-v-6ce24249><a class="title" href="/" data-v-6ce24249><!--[--><!--]--><!--[--><img class="VPImage logo" src="/favicon.svg" alt data-v-105fdaa6><!--]--><span data-v-6ce24249>TermPilot</span><!--[--><!--]--></a></div></div><div class="content" data-v-bfcfe748><div class="content-body" data-v-bfcfe748><!--[--><!--]--><div class="VPNavBarSearch search" data-v-bfcfe748><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-bfcfe748 data-v-d1dc8fec><span id="main-nav-aria-label" class="visually-hidden" data-v-d1dc8fec> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>首页</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/getting-started" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>快速开始</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/operations-guide" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>部署与运维</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink active" href="/architecture" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>架构</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/protocol" tabindex="0" data-v-d1dc8fec data-v-82ee0671><!--[--><span data-v-82ee0671>协议</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-bfcfe748 data-v-d994237e><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-d994237e data-v-9a85cf30 data-v-b1949eaf><span class="check" data-v-b1949eaf><span class="icon" data-v-b1949eaf><!--[--><span class="vpi-sun sun" data-v-9a85cf30></span><span class="vpi-moon moon" data-v-9a85cf30></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-bfcfe748 data-v-a61e22dd data-v-f3c77898><!--[--><a class="VPSocialLink no-icon" href="https://github.com/fengye404/TermPilot" aria-label="github" target="_blank" rel="noopener" data-v-f3c77898 data-v-8a10446f><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-bfcfe748 data-v-6d16081b data-v-35350ec6><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-35350ec6><span class="vpi-more-horizontal icon" data-v-35350ec6></span></button><div class="menu" data-v-35350ec6><div class="VPMenu" data-v-35350ec6 data-v-52b08d90><!----><!--[--><!--[--><!----><div class="group" data-v-6d16081b><div class="item appearance" data-v-6d16081b><p class="label" data-v-6d16081b>Appearance</p><div class="appearance-action" data-v-6d16081b><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-6d16081b data-v-9a85cf30 data-v-b1949eaf><span class="check" data-v-b1949eaf><span class="icon" data-v-b1949eaf><!--[--><span class="vpi-sun sun" data-v-9a85cf30></span><span class="vpi-moon moon" data-v-9a85cf30></span><!--]--></span></span></button></div></div></div><div class="group" data-v-6d16081b><div class="item social-links" data-v-6d16081b><div class="VPSocialLinks social-links-list" data-v-6d16081b data-v-f3c77898><!--[--><a class="VPSocialLink no-icon" href="https://github.com/fengye404/TermPilot" aria-label="github" target="_blank" rel="noopener" data-v-f3c77898 data-v-8a10446f><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-bfcfe748 data-v-1e510fee><span class="container" data-v-1e510fee><span class="top" data-v-1e510fee></span><span class="middle" data-v-1e510fee></span><span class="bottom" data-v-1e510fee></span></span></button></div></div></div></div><div class="divider" data-v-bfcfe748><div class="divider-line" data-v-bfcfe748></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-1bdd7537 data-v-18894e30><div class="container" data-v-18894e30><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-18894e30><span class="vpi-align-left menu-icon" data-v-18894e30></span><span class="menu-text" data-v-18894e30>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-18894e30 data-v-bdfacdf2><button data-v-bdfacdf2>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-1bdd7537 data-v-1d1d7027><div class="curtain" data-v-1d1d7027></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-1d1d7027><span class="visually-hidden" id="sidebar-aria-label" data-v-1d1d7027> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-594fed9e><section class="VPSidebarItem level-0" data-v-594fed9e data-v-cd30f15d><div class="item" role="button" tabindex="0" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><h2 class="text" data-v-cd30f15d>开始</h2><!----></div><div class="items" data-v-cd30f15d><!--[--><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>文档首页</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/getting-started" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>快速开始</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/operations-guide" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>部署与运维指南</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-594fed9e><section class="VPSidebarItem level-0 has-active" data-v-594fed9e data-v-cd30f15d><div class="item" role="button" tabindex="0" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><h2 class="text" data-v-cd30f15d>参考</h2><!----></div><div class="items" data-v-cd30f15d><!--[--><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/architecture" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>代码架构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/protocol" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>协议说明</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/development" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>开发文档</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cd30f15d data-v-cd30f15d><div class="item" data-v-cd30f15d><div class="indicator" data-v-cd30f15d></div><a class="VPLink link link" href="/tech-selection-2026" data-v-cd30f15d><!--[--><p class="text" data-v-cd30f15d>技术选型</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-1bdd7537 data-v-f89b4fb6><div class="VPDoc has-sidebar has-aside" data-v-f89b4fb6 data-v-1870bdbd><!--[--><!--]--><div class="container" data-v-1870bdbd><div class="aside" data-v-1870bdbd><div class="aside-curtain" data-v-1870bdbd></div><div class="aside-container" data-v-1870bdbd><div class="aside-content" data-v-1870bdbd><div class="VPDocAside" data-v-1870bdbd data-v-2bdf3a15><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-2bdf3a15 data-v-3d03f0c2><div class="content" data-v-3d03f0c2><div class="outline-marker" data-v-3d03f0c2></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-3d03f0c2>本页目录</div><ul class="VPDocOutlineItem root" data-v-3d03f0c2 data-v-87a812ef><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-2bdf3a15></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-1870bdbd><div class="content-container" data-v-1870bdbd><!--[--><!--]--><main class="main" data-v-1870bdbd><div style="position:relative;" class="vp-doc _architecture" data-v-1870bdbd><div><h1 id="termpilot-当前代码架构" tabindex="-1">TermPilot 当前代码架构 <a class="header-anchor" href="#termpilot-当前代码架构" aria-label="Permalink to "TermPilot 当前代码架构""></a></h1><h2 id="_1-当前产品形态" tabindex="-1">1. 当前产品形态 <a class="header-anchor" href="#_1-当前产品形态" aria-label="Permalink to "1. 当前产品形态""></a></h2><ul><li>一个 npm 包:<code>termpilot</code></li><li>一个服务器命令:<code>termpilot relay</code></li><li>一个电脑命令:<code>termpilot agent</code></li><li>手机端不安装,直接打开 relay 域名</li><li>relay 同时负责 WebSocket 中继和 Web UI 托管</li></ul><p>对应拓扑:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>手机浏览器 --https/ws--> relay <--ws--> PC 端 agent</span></span>
|
|
23
|
+
<span class="line"><span> |</span></span>
|
|
24
|
+
<span class="line"><span> 配对、设备权限、消息路由、</span></span>
|
|
25
|
+
<span class="line"><span> 输出缓冲、审计日志、会话元数据、</span></span>
|
|
26
|
+
<span class="line"><span> 静态网页托管</span></span></code></pre></div><h2 id="_2-目录结构" tabindex="-1">2. 目录结构 <a class="header-anchor" href="#_2-目录结构" aria-label="Permalink to "2. 目录结构""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>src/</span></span>
|
|
27
|
+
<span class="line"><span> cli.ts</span></span>
|
|
28
|
+
<span class="line"><span>agent/</span></span>
|
|
29
|
+
<span class="line"><span> src/</span></span>
|
|
30
|
+
<span class="line"><span>app/</span></span>
|
|
31
|
+
<span class="line"><span> src/</span></span>
|
|
32
|
+
<span class="line"><span> components/</span></span>
|
|
33
|
+
<span class="line"><span>relay/</span></span>
|
|
34
|
+
<span class="line"><span> src/</span></span>
|
|
35
|
+
<span class="line"><span>packages/</span></span>
|
|
36
|
+
<span class="line"><span> protocol/</span></span>
|
|
37
|
+
<span class="line"><span>scripts/</span></span>
|
|
38
|
+
<span class="line"><span>docs/</span></span></code></pre></div><h3 id="src-cli-ts" tabindex="-1"><code>src/cli.ts</code> <a class="header-anchor" href="#src-cli-ts" aria-label="Permalink to "`src/cli.ts`""></a></h3><p>统一 CLI 入口,负责把内部多模块收敛成外部单命令产品:</p><ul><li><code>termpilot relay</code></li><li><code>termpilot agent</code></li><li><code>termpilot agent/claude code/open code/pair/create/list/attach/kill/...</code></li></ul><h3 id="agent" tabindex="-1"><code>agent/</code> <a class="header-anchor" href="#agent" aria-label="Permalink to "`agent/`""></a></h3><p>PC 端常驻进程和本地命令实现:</p><ul><li><code>src/cli.ts</code>:agent 侧命令实现</li><li><code>src/index.ts</code>:开发态入口包装</li><li><code>src/daemon.ts</code>:常驻连接、轮询 <code>tmux</code>、同步输出与状态</li><li><code>src/tmux-backend.ts</code>:<code>tmux</code> 会话创建、输入、关闭、附着、抓屏</li><li><code>src/relay-admin.ts</code>:agent 调用 relay 管理接口的轻量客户端</li><li><code>src/state-store.ts</code>:本地 JSON 状态文件</li></ul><h3 id="relay" tabindex="-1"><code>relay/</code> <a class="header-anchor" href="#relay" aria-label="Permalink to "`relay/`""></a></h3><p>中继和网页托管层:</p><ul><li><code>src/server.ts</code>:WebSocket 路由、HTTP 接口、消息转发、静态网页托管</li><li><code>src/index.ts</code>:开发态入口包装</li><li><code>src/session-store.ts</code>:会话元数据存储</li><li><code>src/auth-store.ts</code>:配对码与访问令牌存储</li><li><code>src/audit-store.ts</code>:审计事件存储</li><li><code>src/config.ts</code>:环境变量配置</li></ul><h3 id="app" tabindex="-1"><code>app/</code> <a class="header-anchor" href="#app" aria-label="Permalink to "`app/`""></a></h3><p>手机端 PWA:</p><ul><li><code>src/App.tsx</code>:状态、副作用、WebSocket 协调</li><li><code>src/components/ConnectionPanel.tsx</code>:连接与配对 UI</li><li><code>src/components/CreateSessionPanel.tsx</code>:创建会话 UI</li><li><code>src/components/SessionListPanel.tsx</code>:会话搜索、筛选、置顶、关闭</li><li><code>src/components/TerminalWorkspace.tsx</code>:终端区域、快捷键和粘贴发送</li><li><code>src/components/chrome.tsx</code>:通用面板与字段组件</li></ul><h3 id="packages-protocol" tabindex="-1"><code>packages/protocol/</code> <a class="header-anchor" href="#packages-protocol" aria-label="Permalink to "`packages/protocol/`""></a></h3><p>三端共享协议类型:</p><ul><li>会话消息</li><li>配对与令牌数据结构</li><li>审计事件结构</li></ul><h2 id="_3-运行时数据流" tabindex="-1">3. 运行时数据流 <a class="header-anchor" href="#_3-运行时数据流" aria-label="Permalink to "3. 运行时数据流""></a></h2><h3 id="启动链路" tabindex="-1">启动链路 <a class="header-anchor" href="#启动链路" aria-label="Permalink to "启动链路""></a></h3><ol><li>服务器执行 <code>termpilot relay</code></li><li>relay 监听 HTTP/WebSocket,并托管 <code>app/dist</code></li><li>电脑第一次执行 <code>termpilot agent</code>,在终端里输入 relay 域名和端口</li><li>agent 保存本地配置,并在后台启动常驻进程</li><li>以后电脑直接执行 <code>termpilot agent</code>,自动按已保存配置启动或显示状态</li><li>手机上直接打开 relay 域名</li></ol><h3 id="会话创建" tabindex="-1">会话创建 <a class="header-anchor" href="#会话创建" aria-label="Permalink to "会话创建""></a></h3><ol><li>手机端或电脑端发起 <code>session.create</code></li><li>relay 把请求转发给对应 device 的 agent</li><li>agent 在本地创建 <code>tmux</code> 会话</li><li>agent 回推 <code>session.created</code></li><li>relay 广播给有权限的 client</li></ol><h3 id="输出同步" tabindex="-1">输出同步 <a class="header-anchor" href="#输出同步" aria-label="Permalink to "输出同步""></a></h3><ol><li>agent 周期性 <code>capture-pane</code></li><li>如果缓冲变化,生成新的 <code>session.output</code></li><li>relay 缓冲最近一段输出帧</li><li>app 渲染最新快照</li><li>client 重连后可用 <code>session.replay</code> 补拉</li></ol><h3 id="配对与访问控制" tabindex="-1">配对与访问控制 <a class="header-anchor" href="#配对与访问控制" aria-label="Permalink to "配对与访问控制""></a></h3><ol><li>电脑端执行 <code>termpilot agent</code></li><li>如果本机还没有配置 relay,agent 会提示输入域名和端口,并保存到本地配置文件</li><li>relay 创建一次性配对码</li><li>手机端输入配对码,兑换设备访问令牌</li><li>client WebSocket 以后携带设备令牌</li><li>relay 只向该 client 暴露允许访问的设备和会话</li></ol><h2 id="_4-当前实现边界" tabindex="-1">4. 当前实现边界 <a class="header-anchor" href="#_4-当前实现边界" aria-label="Permalink to "4. 当前实现边界""></a></h2><ul><li>当前终端同步策略仍是“快照替换”,不是字节级增量流</li><li>relay 输出缓冲只保留最近一段,不做长期日志归档</li><li>不接管 TermPilot 体系外的历史终端</li><li>手机端定位是“查看、轻输入、轻控制”,不追求桌面级重度编辑体验</li></ul><h2 id="_5-当前代码取舍" tabindex="-1">5. 当前代码取舍 <a class="header-anchor" href="#_5-当前代码取舍" aria-label="Permalink to "5. 当前代码取舍""></a></h2><ul><li>对外形态已经统一成单一 CLI,但仓库内部仍保留 <code>agent/app/relay</code> 三个目录,方便独立开发</li><li><code>app</code> 的状态和副作用仍集中在 <code>App.tsx</code>,但渲染层已经拆到独立组件</li><li><code>relay</code> 已从单文件脚本式入口拆成 <code>server.ts + index.ts</code></li><li><code>agent</code> 已从单文件 CLI 拆成 <code>cli.ts + index.ts + daemon.ts + tmux-backend.ts</code></li></ul><h2 id="_6-当前验证方式" tabindex="-1">6. 当前验证方式 <a class="header-anchor" href="#_6-当前验证方式" aria-label="Permalink to "6. 当前验证方式""></a></h2><p>最有价值的检查命令:</p><ul><li><code>pnpm typecheck</code></li><li><code>pnpm build</code></li><li><code>pnpm test:ui-smoke</code></li><li><code>pnpm check:stability</code></li></ul><p>它们覆盖的重点是:</p><ul><li><code>termpilot relay</code> 和 <code>termpilot agent</code> 主链路</li><li>输出缓冲与重连一致性</li><li>手机端配对、切会话、关会话、清除绑定</li></ul></div></div></main><footer class="VPDocFooter" data-v-1870bdbd data-v-b170fa4f><!--[--><!--]--><div class="edit-info" data-v-b170fa4f><div class="edit-link" data-v-b170fa4f><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/fengye404/TermPilot/edit/main/docs/architecture.md" target="_blank" rel="noreferrer" data-v-b170fa4f><!--[--><span class="vpi-square-pen edit-link-icon" data-v-b170fa4f></span> 在 GitHub 上编辑此页<!--]--></a></div><div class="last-updated" data-v-b170fa4f><p class="VPLastUpdated" data-v-b170fa4f data-v-33a4642e>Last updated: <time datetime="2026-03-11T17:24:53.000Z" data-v-33a4642e></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-b170fa4f><span class="visually-hidden" id="doc-footer-aria-label" data-v-b170fa4f>Pager</span><div class="pager" data-v-b170fa4f><a class="VPLink link pager-link prev" href="/operations-guide" data-v-b170fa4f><!--[--><span class="desc" data-v-b170fa4f>Previous page</span><span class="title" data-v-b170fa4f>部署与运维指南</span><!--]--></a></div><div class="pager" data-v-b170fa4f><a class="VPLink link pager-link next" href="/protocol" data-v-b170fa4f><!--[--><span class="desc" data-v-b170fa4f>Next page</span><span class="title" data-v-b170fa4f>协议说明</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-1bdd7537 data-v-9a5ea44b><div class="container" data-v-9a5ea44b><p class="message" data-v-9a5ea44b>为长期任务和跨端终端控制而构建。</p><p class="copyright" data-v-9a5ea44b>Copyright © 2026 Fengye</p></div></footer><!--[--><!--]--></div></div>
|
|
39
|
+
<script>window.__VP_HASH_MAP__=JSON.parse("{\"architecture.md\":\"JnC1zyYV\",\"development.md\":\"iwUVjeO6\",\"getting-started.md\":\"Cirp1CHi\",\"index.md\":\"D9XElNRh\",\"operations-guide.md\":\"DfNiIg5F\",\"protocol.md\":\"CCXFJUPR\",\"readme.md\":\"B4-OJVNQ\",\"tech-selection-2026.md\":\"Dk_ymWTx\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"TermPilot\",\"description\":\"手机和电脑共享同一个 tmux 会话的终端远程控制工具。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"siteTitle\":\"TermPilot\",\"logo\":\"/favicon.svg\",\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维\",\"link\":\"/operations-guide\"},{\"text\":\"架构\",\"link\":\"/architecture\"},{\"text\":\"协议\",\"link\":\"/protocol\"}],\"sidebar\":[{\"text\":\"开始\",\"items\":[{\"text\":\"文档首页\",\"link\":\"/\"},{\"text\":\"快速开始\",\"link\":\"/getting-started\"},{\"text\":\"部署与运维指南\",\"link\":\"/operations-guide\"}]},{\"text\":\"参考\",\"items\":[{\"text\":\"代码架构\",\"link\":\"/architecture\"},{\"text\":\"协议说明\",\"link\":\"/protocol\"},{\"text\":\"开发文档\",\"link\":\"/development\"},{\"text\":\"技术选型\",\"link\":\"/tech-selection-2026\"}]}],\"search\":{\"provider\":\"local\"},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/fengye404/TermPilot\"}],\"editLink\":{\"pattern\":\"https://github.com/fengye404/TermPilot/edit/main/docs/:path\",\"text\":\"在 GitHub 上编辑此页\"},\"outline\":{\"level\":[2,3],\"label\":\"本页目录\"},\"footer\":{\"message\":\"为长期任务和跨端终端控制而构建。\",\"copyright\":\"Copyright © 2026 Fengye\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
|
|
40
|
+
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,o as t,c as r,ag as i}from"./chunks/framework.BZohXCq9.js";const f=JSON.parse('{"title":"docs 目录","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1773250545000}'),o={name:"README.md"};function s(l,e,d,c,n,_){return t(),r("div",null,[...e[0]||(e[0]=[i('<h1 id="docs-目录" tabindex="-1">docs 目录 <a class="header-anchor" href="#docs-目录" aria-label="Permalink to "docs 目录""></a></h1><p>如果你在 GitHub 仓库里浏览源码,推荐从下面几个入口开始:</p><ul><li><a href="./">文档首页</a></li><li><a href="./getting-started">快速开始</a></li><li><a href="./operations-guide">部署与运维指南</a></li><li><a href="./architecture">代码架构</a></li><li><a href="./development">开发文档</a></li></ul><p>如果 GitHub Pages 已经启用,优先看站点版本,它会带导航、目录和搜索。</p>',4)])])}const h=a(o,[["render",s]]);export{f as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,o as t,c as r,ag as i}from"./chunks/framework.BZohXCq9.js";const f=JSON.parse('{"title":"docs 目录","description":"","frontmatter":{},"headers":[],"relativePath":"README.md","filePath":"README.md","lastUpdated":1773250545000}'),o={name:"README.md"};function s(l,e,d,c,n,_){return t(),r("div",null,[...e[0]||(e[0]=[i("",4)])])}const h=a(o,[["render",s]]);export{f as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as p}from"./chunks/theme.D0_6rd9F.js";import{R as s,a2 as i,a3 as u,a4 as c,a5 as l,a6 as f,a7 as d,a8 as m,a9 as h,aa as g,ab as A,d as v,u as y,v as C,s as P,ac as b,ad as w,ae as R,af as E}from"./chunks/framework.BZohXCq9.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=y();return C(()=>{P(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&b(),w(),R(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
|