@caoruhua/open-claude-remote 0.1.7 → 0.2.4

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.
Files changed (133) hide show
  1. package/README.md +534 -11
  2. package/dist/backend/src/api/config-routes.d.ts +2 -2
  3. package/dist/backend/src/api/config-routes.d.ts.map +1 -1
  4. package/dist/backend/src/api/config-routes.js +24 -6
  5. package/dist/backend/src/api/config-routes.js.map +1 -1
  6. package/dist/backend/src/api/health-routes.d.ts +4 -1
  7. package/dist/backend/src/api/health-routes.d.ts.map +1 -1
  8. package/dist/backend/src/api/health-routes.js +20 -2
  9. package/dist/backend/src/api/health-routes.js.map +1 -1
  10. package/dist/backend/src/api/hook-routes.d.ts +2 -2
  11. package/dist/backend/src/api/hook-routes.d.ts.map +1 -1
  12. package/dist/backend/src/api/hook-routes.js +10 -3
  13. package/dist/backend/src/api/hook-routes.js.map +1 -1
  14. package/dist/backend/src/api/instance-routes.d.ts +5 -3
  15. package/dist/backend/src/api/instance-routes.d.ts.map +1 -1
  16. package/dist/backend/src/api/instance-routes.js +48 -45
  17. package/dist/backend/src/api/instance-routes.js.map +1 -1
  18. package/dist/backend/src/api/router.d.ts +4 -12
  19. package/dist/backend/src/api/router.d.ts.map +1 -1
  20. package/dist/backend/src/api/router.js +28 -20
  21. package/dist/backend/src/api/router.js.map +1 -1
  22. package/dist/backend/src/api/status-routes.d.ts +2 -2
  23. package/dist/backend/src/api/status-routes.d.ts.map +1 -1
  24. package/dist/backend/src/api/status-routes.js +11 -6
  25. package/dist/backend/src/api/status-routes.js.map +1 -1
  26. package/dist/backend/src/attach.d.ts +1 -1
  27. package/dist/backend/src/attach.d.ts.map +1 -1
  28. package/dist/backend/src/attach.js +25 -71
  29. package/dist/backend/src/attach.js.map +1 -1
  30. package/dist/backend/src/cli-utils.d.ts +24 -1
  31. package/dist/backend/src/cli-utils.d.ts.map +1 -1
  32. package/dist/backend/src/cli-utils.js +73 -37
  33. package/dist/backend/src/cli-utils.js.map +1 -1
  34. package/dist/backend/src/cli.d.ts +23 -2
  35. package/dist/backend/src/cli.d.ts.map +1 -1
  36. package/dist/backend/src/cli.js +359 -22
  37. package/dist/backend/src/cli.js.map +1 -1
  38. package/dist/backend/src/config.d.ts +48 -15
  39. package/dist/backend/src/config.d.ts.map +1 -1
  40. package/dist/backend/src/config.js +124 -24
  41. package/dist/backend/src/config.js.map +1 -1
  42. package/dist/backend/src/daemon/daemon-client.d.ts +91 -0
  43. package/dist/backend/src/daemon/daemon-client.d.ts.map +1 -0
  44. package/dist/backend/src/daemon/daemon-client.js +258 -0
  45. package/dist/backend/src/daemon/daemon-client.js.map +1 -0
  46. package/dist/backend/src/daemon/daemon-entry.d.ts +8 -0
  47. package/dist/backend/src/daemon/daemon-entry.d.ts.map +1 -0
  48. package/dist/backend/src/daemon/daemon-entry.js +37 -0
  49. package/dist/backend/src/daemon/daemon-entry.js.map +1 -0
  50. package/dist/backend/src/daemon/daemon-launcher.d.ts +13 -0
  51. package/dist/backend/src/daemon/daemon-launcher.d.ts.map +1 -0
  52. package/dist/backend/src/daemon/daemon-launcher.js +62 -0
  53. package/dist/backend/src/daemon/daemon-launcher.js.map +1 -0
  54. package/dist/backend/src/index.d.ts.map +1 -1
  55. package/dist/backend/src/index.js +115 -251
  56. package/dist/backend/src/index.js.map +1 -1
  57. package/dist/backend/src/instance/index.d.ts +4 -0
  58. package/dist/backend/src/instance/index.d.ts.map +1 -0
  59. package/dist/backend/src/instance/index.js +3 -0
  60. package/dist/backend/src/instance/index.js.map +1 -0
  61. package/dist/backend/src/instance/instance-manager.d.ts +62 -0
  62. package/dist/backend/src/instance/instance-manager.d.ts.map +1 -0
  63. package/dist/backend/src/instance/instance-manager.js +194 -0
  64. package/dist/backend/src/instance/instance-manager.js.map +1 -0
  65. package/dist/backend/src/instance/instance-session.d.ts +87 -0
  66. package/dist/backend/src/instance/instance-session.d.ts.map +1 -0
  67. package/dist/backend/src/instance/instance-session.js +359 -0
  68. package/dist/backend/src/instance/instance-session.js.map +1 -0
  69. package/dist/backend/src/instance/types.d.ts +39 -0
  70. package/dist/backend/src/instance/types.d.ts.map +1 -0
  71. package/dist/backend/src/instance/types.js +2 -0
  72. package/dist/backend/src/instance/types.js.map +1 -0
  73. package/dist/backend/src/notification/notification-manager.js +1 -1
  74. package/dist/backend/src/notification/notification-manager.js.map +1 -1
  75. package/dist/backend/src/notification/notification-service-factory.js +1 -1
  76. package/dist/backend/src/notification/notification-service-factory.js.map +1 -1
  77. package/dist/backend/src/pty/virtual-pty.d.ts.map +1 -1
  78. package/dist/backend/src/pty/virtual-pty.js +6 -0
  79. package/dist/backend/src/pty/virtual-pty.js.map +1 -1
  80. package/dist/backend/src/registry/shared-token.d.ts +2 -2
  81. package/dist/backend/src/registry/shared-token.js +11 -11
  82. package/dist/backend/src/registry/shared-token.js.map +1 -1
  83. package/dist/backend/src/registry/stop-instances.d.ts +0 -25
  84. package/dist/backend/src/registry/stop-instances.d.ts.map +1 -1
  85. package/dist/backend/src/registry/stop-instances.js +6 -206
  86. package/dist/backend/src/registry/stop-instances.js.map +1 -1
  87. package/dist/backend/src/skills/index.d.ts +4 -0
  88. package/dist/backend/src/skills/index.d.ts.map +1 -0
  89. package/dist/backend/src/skills/index.js +4 -0
  90. package/dist/backend/src/skills/index.js.map +1 -0
  91. package/dist/backend/src/skills/skill-command-merger.d.ts +32 -0
  92. package/dist/backend/src/skills/skill-command-merger.d.ts.map +1 -0
  93. package/dist/backend/src/skills/skill-command-merger.js +76 -0
  94. package/dist/backend/src/skills/skill-command-merger.js.map +1 -0
  95. package/dist/backend/src/skills/skill-commands.d.ts +20 -0
  96. package/dist/backend/src/skills/skill-commands.d.ts.map +1 -0
  97. package/dist/backend/src/skills/skill-commands.js +34 -0
  98. package/dist/backend/src/skills/skill-commands.js.map +1 -0
  99. package/dist/backend/src/skills/skill-scanner.d.ts +40 -0
  100. package/dist/backend/src/skills/skill-scanner.d.ts.map +1 -0
  101. package/dist/backend/src/skills/skill-scanner.js +160 -0
  102. package/dist/backend/src/skills/skill-scanner.js.map +1 -0
  103. package/dist/backend/src/terminal/terminal-relay.d.ts +1 -0
  104. package/dist/backend/src/terminal/terminal-relay.d.ts.map +1 -1
  105. package/dist/backend/src/terminal/terminal-relay.js +6 -0
  106. package/dist/backend/src/terminal/terminal-relay.js.map +1 -1
  107. package/dist/backend/src/update.d.ts.map +1 -1
  108. package/dist/backend/src/update.js +46 -1
  109. package/dist/backend/src/update.js.map +1 -1
  110. package/dist/backend/src/utils/banner.d.ts +15 -0
  111. package/dist/backend/src/utils/banner.d.ts.map +1 -0
  112. package/dist/backend/src/utils/banner.js +95 -0
  113. package/dist/backend/src/utils/banner.js.map +1 -0
  114. package/dist/backend/src/ws/ws-server.d.ts +13 -54
  115. package/dist/backend/src/ws/ws-server.d.ts.map +1 -1
  116. package/dist/backend/src/ws/ws-server.js +57 -155
  117. package/dist/backend/src/ws/ws-server.js.map +1 -1
  118. package/dist/shared/constants.d.ts +2 -1
  119. package/dist/shared/constants.d.ts.map +1 -1
  120. package/dist/shared/constants.js +2 -1
  121. package/dist/shared/constants.js.map +1 -1
  122. package/dist/shared/defaults.d.ts +1 -0
  123. package/dist/shared/defaults.d.ts.map +1 -1
  124. package/dist/shared/defaults.js +1 -5
  125. package/dist/shared/defaults.js.map +1 -1
  126. package/dist/shared/instance.d.ts +4 -9
  127. package/dist/shared/instance.d.ts.map +1 -1
  128. package/dist/shared/instance.js +0 -2
  129. package/dist/shared/instance.js.map +1 -1
  130. package/frontend-dist/assets/index-CM2xfmS8.js +152 -0
  131. package/frontend-dist/index.html +1 -1
  132. package/package.json +2 -2
  133. package/frontend-dist/assets/index-Cfhr3h3e.js +0 -152
package/README.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  **Control Claude Code from your mobile browser over LAN.**
4
4
 
5
+ [English](#english) | [中文](#中文)
6
+
7
+ ---
8
+
9
+ <a name="english"></a>
10
+ ## English
11
+
12
+ **Control Claude Code from your mobile browser over LAN.**
13
+
5
14
  View terminal output, send commands, and approve tool calls from your phone — keep working even when you step away from your desktop.
6
15
 
7
16
  ---
@@ -54,12 +63,14 @@ Scan the QR code shown in your terminal with your phone. The auth token is auto-
54
63
  - Auto-skips on subsequent visits
55
64
 
56
65
  ### Multi-Instance
57
- - Run multiple `claude-remote` instances simultaneously
66
+ - Run multiple `claude-remote` instances simultaneously in a single daemon process
67
+ - Fixed port 8866 — all instances share same origin, no cross-port auth needed
58
68
  - Browser tab bar for switching — no re-authentication needed
59
69
  - Auto-switch when an instance goes offline
60
70
  - Spawn new instances from the web UI ("+" button)
61
71
  - Copy instance via long-press/right-click tab — pre-fills working directory, settings, and arguments
62
- - `claude-remote attach <port|name>` to take over a web-spawned instance
72
+ - `claude-remote attach <name|id>` to take over a web-spawned instance
73
+ - `claude-remote stop` to stop the daemon and all instances
63
74
 
64
75
  ### Window Resize Priority
65
76
 
@@ -125,7 +136,7 @@ Get notified when Claude is waiting for input. All notifications include the ins
125
136
  ## Usage
126
137
 
127
138
  ```bash
128
- # Start Claude Code
139
+ # Start Claude Code (starts daemon + first instance)
129
140
  claude-remote
130
141
 
131
142
  # Pass arguments to Claude
@@ -133,13 +144,21 @@ claude-remote chat
133
144
  claude-remote -- --dangerously-skip-permissions
134
145
 
135
146
  # Custom options
136
- claude-remote --port 8080
137
147
  claude-remote --name my-project
138
148
  claude-remote --token my-secret-token
139
149
 
140
- # Attach to a web-spawned instance
141
- claude-remote attach 3001 # by port
150
+ # Attach to an existing instance
142
151
  claude-remote attach my-project # by name
152
+ claude-remote attach 550e8400 # by instance ID prefix
153
+
154
+ # List all running instances
155
+ claude-remote list
156
+
157
+ # Show daemon status (PID, port, uptime, instance count, three-version info)
158
+ claude-remote status
159
+
160
+ # Stop the daemon and all instances
161
+ claude-remote stop
143
162
 
144
163
  # Headless mode (no local terminal, web UI only)
145
164
  claude-remote --no-terminal
@@ -151,6 +170,18 @@ claude-remote --version
151
170
  claude-remote update
152
171
  ```
153
172
 
173
+ ### Version Checks
174
+
175
+ `claude-remote status` displays three versions with actionable advice:
176
+
177
+ - **Installed** — CLI version on disk
178
+ - **Daemon** — version cached by the running daemon (✓ or "outdated")
179
+ - **Latest** — newest version on npm (✓ or "new")
180
+
181
+ On startup, a background npm check runs without blocking. If a newer version exists, a one-line hint is printed to stderr.
182
+
183
+ After `claude-remote update`, the daemon is automatically restarted if no instances are running. If instances exist, you'll see a reminder to restart manually.
184
+
154
185
  ### Stopping
155
186
 
156
187
  - **Single Ctrl+C** — sent to Claude Code (cancels current task)
@@ -160,11 +191,10 @@ claude-remote update
160
191
 
161
192
  ## Configuration
162
193
 
163
- Config file: `~/.claude-remote/config.json`
194
+ Config file: `~/.claude-remote/settings.json` (legacy `config.json` is auto-migrated)
164
195
 
165
196
  | Option | Type | Default | Description |
166
197
  |--------|------|---------|-------------|
167
- | `port` | number | 3000 | Server port (auto-increments if busy) |
168
198
  | `host` | string | "0.0.0.0" | Bind address |
169
199
  | `token` | string \| null | null | Auth token; `null` = auto-generated shared token |
170
200
  | `claudeCommand` | string | "claude" | Claude CLI path |
@@ -180,6 +210,8 @@ Config file: `~/.claude-remote/config.json`
180
210
  | `settingsDirs` | string[] | ["~/.claude/", "~/.claude-remote/settings/"] | Directories to scan for settings files |
181
211
  | `notifications` | object | — | Notification channels config (see below) |
182
212
 
213
+ > **Note**: Port is fixed at 8866. All instances run in a single daemon process.
214
+
183
215
  **Notification channel config:**
184
216
 
185
217
  | Field | Type | Default | Description |
@@ -248,6 +280,14 @@ Custom command buttons in the shortcut bar.
248
280
  | /stats | Statistics |
249
281
  | /exit | Exit |
250
282
 
283
+ **Skills as Commands:**
284
+
285
+ Skills defined in `~/.claude/skills/*/SKILL.md` or `<project>/.claude/skills/*/SKILL.md` are automatically converted to slash commands. For example, a skill named `finish-task` becomes `/finish-task` in the command bar.
286
+
287
+ - Skills are scanned on each `/api/config` request
288
+ - Project-level skills override global skills with the same name
289
+ - User modifications (enabled, autoSend) are preserved across scans
290
+
251
291
  **Custom example:**
252
292
 
253
293
  ```json
@@ -320,13 +360,12 @@ When creating instances from the web UI, you can select a custom settings file t
320
360
  }
321
361
  ```
322
362
 
323
- > **Note**: Files like `3000.json` (port configs) are automatically excluded from the settings file list.
363
+ > **Note**: Port-numbered JSON files are automatically excluded from the settings file list.
324
364
 
325
365
  ### Complete Example
326
366
 
327
367
  ```json
328
368
  {
329
- "port": 3000,
330
369
  "host": "0.0.0.0",
331
370
  "token": null,
332
371
 
@@ -396,7 +435,7 @@ Install build tools:
396
435
 
397
436
  ### Phone can't connect?
398
437
 
399
- 1. Check your PC firewall allows the port (default: 3000)
438
+ 1. Check your PC firewall allows port 8866
400
439
  2. Verify the URL shows the correct LAN IP
401
440
  3. If using a VPN, try setting the `host` option explicitly
402
441
 
@@ -447,3 +486,487 @@ pnpm stop
447
486
  ## License
448
487
 
449
488
  MIT
489
+
490
+ ---
491
+ ---
492
+
493
+ <a name="中文"></a>
494
+ ## 中文
495
+
496
+ **通过局域网在手机浏览器中控制 Claude Code。**
497
+
498
+ 在手机上查看终端输出、发送命令、审批工具调用 — 即使离开桌面也能继续工作。
499
+
500
+ ---
501
+
502
+ ## 快速开始
503
+
504
+ ### 1. 安装
505
+
506
+ ```bash
507
+ # npm
508
+ npm install -g @caoruhua/open-claude-remote
509
+
510
+ # pnpm(推荐)
511
+ pnpm add -g @caoruhua/open-claude-remote
512
+ ```
513
+
514
+ > **pnpm 用户注意**:pnpm v10 可能显示 "Ignored build scripts: node-pty" 警告。这是正常的,**不影响功能** — 包含预编译的二进制文件,开箱即用。要消除警告,运行 `pnpm approve-builds -g`(可选)。
515
+
516
+ ### 2. 运行
517
+
518
+ ```bash
519
+ claude-remote
520
+ ```
521
+
522
+ ### 3. 连接
523
+
524
+ 用手机扫描终端显示的二维码。认证令牌自动填充 — 就可以开始使用了。
525
+
526
+ > 首次运行时,`claude-remote` 会自动检查并安装缺失的依赖(pnpm、Claude CLI)。Hook 也会自动配置 — 无需手动设置。
527
+
528
+ ---
529
+
530
+ ## 功能特性
531
+
532
+ ### 终端同步
533
+ - 实时终端输出推送到手机
534
+ - 通过 xterm.js 完整渲染 ANSI 颜色
535
+ - 1万行滚动缓冲区,重连时自动恢复
536
+ - 局域网 IP 变更通知,附带新连接地址
537
+ - 智能自动滚动,配有"滚动到底部"悬浮按钮
538
+
539
+ ### 快捷操作
540
+ - 一键发送:Esc、Enter、Tab、方向键、Shift+Tab
541
+ - 自定义快捷键(设置中配置)
542
+ - 预设命令(/clear、/compact、/resume 等)
543
+
544
+ ### 新手引导
545
+ - 首次访问时显示交互式高亮引导
546
+ - 聚焦关键 UI 元素并显示提示标记
547
+ - 后续访问自动跳过
548
+
549
+ ### 多实例支持
550
+ - 在单个守护进程中同时运行多个 `claude-remote` 实例
551
+ - 固定端口 8866 — 所有实例共享同源,无需跨端口认证
552
+ - 浏览器标签栏切换 — 无需重新认证
553
+ - 实例离线时自动切换
554
+ - 从 Web UI 生成新实例("+" 按钮)
555
+ - 长按/右键标签复制实例 — 预填充工作目录、设置和参数
556
+ - `claude-remote attach <名称|ID>` 接管 Web 生成的实例
557
+ - `claude-remote stop` 停止守护进程和所有实例
558
+
559
+ ### 窗口大小优先级
560
+
561
+ 当多个客户端连接时,窗口大小由以下优先级控制:
562
+ **WebApp(手机)> Attach(PC)> PC 终端**
563
+
564
+ | 场景 | 控制方 | 行为 |
565
+ |------|--------|------|
566
+ | 无客户端连接 | PC 终端 | 正常本地使用 |
567
+ | 仅 WebApp | WebApp | 手机控制窗口大小 |
568
+ | 仅 Attach | Attach | PC attach 控制大小 |
569
+ | WebApp + Attach | WebApp | 手机优先,PC 跟随 |
570
+
571
+ - WebApp 在线时,Attach 的调整大小请求被忽略
572
+ - Attach 连接时自动同步 WebApp 的窗口大小
573
+
574
+ ### 通知
575
+
576
+ 当 Claude 等待输入时收到通知。所有通知都包含实例 URL,即使 IP 变更也能快速重连。
577
+
578
+ **Web 推送** — 即使浏览器在后台或屏幕锁定也能工作。只需在提示时允许通知即可。
579
+
580
+ **渠道开关** — 每个通知渠道在设置中都有开关。切换即可启用/禁用,无需删除配置。更改立即生效于所有运行中的实例。
581
+
582
+ **钉钉** — 配置钉钉机器人 webhook,在团队群中接收通知:
583
+
584
+ ```json
585
+ {
586
+ "notifications": {
587
+ "dingtalk": {
588
+ "webhookUrl": "https://oapi.dingtalk.com/robot/send?access_token=your-token"
589
+ }
590
+ }
591
+ }
592
+ ```
593
+
594
+ > **注意**:旧版配置文件中的根级 `dingtalk` 字段会在首次加载时自动迁移到 `notifications.dingtalk`。
595
+
596
+ **设置步骤:**
597
+ 1. 打开钉钉群 → 群设置 → 智能群助手 → 添加机器人 → 自定义
598
+ 2. 安全设置选择"自定义关键词",添加 `Claude`(消息标题包含此关键词)
599
+ 3. 将 Webhook URL 复制到配置文件或粘贴到 Web UI 设置中
600
+
601
+ **微信(Server酱³)** — 配置 Server酱³ 在微信中接收通知:
602
+
603
+ ```json
604
+ {
605
+ "notifications": {
606
+ "wechat_work": {
607
+ "sendKey": "SCTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
608
+ }
609
+ }
610
+ }
611
+ ```
612
+
613
+ **设置步骤:**
614
+ 1. 访问 [Server酱 Sendkey](https://sct.ftqq.com/sendkey) 并用微信登录
615
+ 2. 复制你的 SendKey(以 `SCT` 开头)
616
+ 3. 粘贴到配置文件或 Web UI 设置中
617
+
618
+ ---
619
+
620
+ ## 使用方法
621
+
622
+ ```bash
623
+ # 启动 Claude Code(启动守护进程 + 第一个实例)
624
+ claude-remote
625
+
626
+ # 向 Claude 传递参数
627
+ claude-remote chat
628
+ claude-remote -- --dangerously-skip-permissions
629
+
630
+ # 自定义选项
631
+ claude-remote --name my-project
632
+ claude-remote --token my-secret-token
633
+
634
+ # 附加到现有实例
635
+ claude-remote attach my-project # 按名称
636
+ claude-remote attach 550e8400 # 按实例 ID 前缀
637
+
638
+ # 列出所有运行中的实例
639
+ claude-remote list
640
+
641
+ # 显示守护进程状态(PID、端口、运行时间、实例数、三版本信息)
642
+ claude-remote status
643
+
644
+ # 停止守护进程和所有实例
645
+ claude-remote stop
646
+
647
+ # 无头模式(无本地终端,仅 Web UI)
648
+ claude-remote --no-terminal
649
+
650
+ # 查看版本
651
+ claude-remote --version
652
+
653
+ # 更新到最新版本
654
+ claude-remote update
655
+ ```
656
+
657
+ ### 版本检查
658
+
659
+ `claude-remote status` 显示三个版本及操作建议:
660
+
661
+ - **Installed** — 磁盘上的 CLI 版本
662
+ - **Daemon** — 运行中 daemon 缓存的版本(✓ 或 "outdated")
663
+ - **Latest** — npm 上的最新版本(✓ 或 "new")
664
+
665
+ 启动时会后台检查 npm 新版本(不阻塞),如有更新会在 stderr 输出一行提示。
666
+
667
+ 执行 `claude-remote update` 后,如果没有运行中的实例,守护进程会自动重启。如有实例运行,会提示手动重启。
668
+
669
+ ### 停止运行
670
+
671
+ - **单次 Ctrl+C** — 发送给 Claude Code(取消当前任务)
672
+ - **双次 Ctrl+C**(500毫秒内)— 停止代理服务器
673
+
674
+ ---
675
+
676
+ ## 配置
677
+
678
+ 配置文件:`~/.claude-remote/settings.json`(旧版 `config.json` 会自动迁移)
679
+
680
+ | 选项 | 类型 | 默认值 | 说明 |
681
+ |------|------|--------|------|
682
+ | `host` | string | "0.0.0.0" | 绑定地址 |
683
+ | `token` | string \| null | null | 认证令牌;`null` = 自动生成的共享令牌 |
684
+ | `claudeCommand` | string | "claude" | Claude CLI 路径 |
685
+ | `claudeArgs` | string[] | [] | 额外的 Claude CLI 参数(与 CLI 参数合并,去重) |
686
+ | `claudeCwd` | string \| null | null | Claude 工作目录;`null` = 当前目录 |
687
+ | `sessionTtlMs` | number | 86400000 | 会话 TTL(毫秒,默认 24 小时) |
688
+ | `authRateLimit` | number | 20 | 认证速率限制(每分钟每 IP) |
689
+ | `maxBufferLines` | number | 10000 | 输出缓冲区最大行数 |
690
+ | `instanceName` | string \| null | null | 实例名称;`null` = 工作目录名 |
691
+ | `shortcuts` | array | 见下文 | 快捷输入按钮 |
692
+ | `commands` | array | 见下文 | 自定义命令按钮 |
693
+ | `workspaces` | string[] | [] | Web 生成实例允许的工作目录 |
694
+ | `settingsDirs` | string[] | ["~/.claude/", "~/.claude-remote/settings/"] | 设置文件扫描目录 |
695
+ | `notifications` | object | — | 通知渠道配置(见下文) |
696
+
697
+ > **注意**:端口固定为 8866。所有实例运行在单个守护进程中。
698
+
699
+ **通知渠道配置:**
700
+
701
+ | 字段 | 类型 | 默认值 | 说明 |
702
+ |------|------|--------|------|
703
+ | `webhookUrl` | string | — | 钉钉 webhook URL |
704
+ | `sendKey` | string | — | Server酱³ SendKey(微信) |
705
+ | `enabled` | boolean | true | 渠道是否启用 |
706
+
707
+ **优先级**:CLI 参数 > 配置文件 > 默认值(`claudeArgs` 除外,它是合并的)
708
+
709
+ ### 快捷键
710
+
711
+ 终端下方显示的快捷输入按钮。
712
+
713
+ **默认快捷键:**
714
+
715
+ | 按键 | 数据 | 说明 |
716
+ |------|------|------|
717
+ | Esc | `\u001b` | ESC 键 |
718
+ | Enter | `\r` | 回车键 |
719
+ | Tab | `\t` | Tab 键 |
720
+ | ↑ | `\u001b[A` | 上箭头 |
721
+ | ↓ | `\u001b[B` | 下箭头 |
722
+ | ← | `\u001b[D` | 左箭头 |
723
+ | → | `\u001b[C` | 右箭头 |
724
+ | S-Tab | `\u001b[Z` | Shift+Tab |
725
+ | Ctrl+O | `\u000f` | Ctrl+O |
726
+ | Ctrl+E | `\u0005` | Ctrl+E |
727
+
728
+ **自定义示例:**
729
+
730
+ ```json
731
+ {
732
+ "shortcuts": [
733
+ { "label": "Yes", "data": "y", "enabled": true, "desc": "确认" },
734
+ { "label": "Esc", "data": "\u001b", "enabled": true, "desc": "取消 (ESC)" },
735
+ { "label": "Ctrl+C", "data": "\u0003", "enabled": true, "desc": "中断" }
736
+ ]
737
+ }
738
+ ```
739
+
740
+ | 字段 | 类型 | 说明 |
741
+ |------|------|------|
742
+ | `label` | string | 按钮显示文本 |
743
+ | `data` | string | 发送的数据(支持转义序列,如 `\u001b` 表示 ESC) |
744
+ | `enabled` | boolean | 按钮是否启用 |
745
+ | `desc` | string | 描述(可选) |
746
+
747
+ **常用转义值:**
748
+ - `\u001b` - ESC
749
+ - `\r` - 回车
750
+ - `\u0003` - Ctrl+C
751
+ - `\u0004` - Ctrl+D
752
+
753
+ ### 命令
754
+
755
+ 快捷栏中的自定义命令按钮。
756
+
757
+ **默认命令:**
758
+
759
+ | 命令 | 说明 |
760
+ |------|------|
761
+ | /clear | 清屏 |
762
+ | /compact | 压缩对话 |
763
+ | /resume | 恢复会话 |
764
+ | /stats | 统计信息 |
765
+ | /exit | 退出 |
766
+
767
+ **Skill 自动转换为命令:**
768
+
769
+ 定义在 `~/.claude/skills/*/SKILL.md` 或 `<项目>/.claude/skills/*/SKILL.md` 中的 Skill 会自动转换为斜杠命令。例如,名为 `finish-task` 的 Skill 会变成命令栏中的 `/finish-task`。
770
+
771
+ - 每次请求 `/api/config` 时扫描 Skill
772
+ - 项目级 Skill 覆盖同名的全局 Skill
773
+ - 用户的修改(enabled、autoSend)在扫描时保留
774
+
775
+ **自定义示例:**
776
+
777
+ ```json
778
+ {
779
+ "commands": [
780
+ { "label": "/help", "command": "/help", "enabled": true },
781
+ { "label": "Git 状态", "command": "git status", "enabled": true, "autoSend": false }
782
+ ]
783
+ }
784
+ ```
785
+
786
+ | 字段 | 类型 | 默认值 | 说明 |
787
+ |------|------|--------|------|
788
+ | `label` | string | — | 按钮显示文本 |
789
+ | `command` | string | — | 要执行的命令 |
790
+ | `enabled` | boolean | — | 按钮是否启用 |
791
+ | `autoSend` | boolean | `true` | `true` = 立即发送,`false` = 填入输入框 |
792
+
793
+ > 以 `/` 开头的命令是 Claude Code 斜杠命令。其他命令在终端中执行。
794
+
795
+ ### 工作空间
796
+
797
+ 限制 Web 生成的实例可以使用哪些目录:
798
+
799
+ ```json
800
+ {
801
+ "workspaces": [
802
+ "/home/user/projects/api",
803
+ "/home/user/projects/web"
804
+ ]
805
+ }
806
+ ```
807
+
808
+ 如未配置,Web 生成的实例只能从已存在的 claude 实例中选择项目
809
+
810
+ ### 设置文件
811
+
812
+ 从 Web UI 创建实例时,可以选择自定义设置文件通过 `--settings` 传递。设置文件必须:
813
+
814
+ 1. 以 `settings` 为前缀命名(如 `settings-project-a.json`、`settings.idea.json`)
815
+ 2. 是有效的 `.json` 结尾的 JSON 文件
816
+ 3. 位于配置的扫描目录中
817
+
818
+ **默认扫描目录:**
819
+ - `~/.claude/` — Claude Code 配置目录
820
+ - `~/.claude-remote/settings/` — Claude Remote 自定义设置
821
+
822
+ **自定义目录:**
823
+
824
+ ```json
825
+ {
826
+ "settingsDirs": [
827
+ "~/.claude/",
828
+ "~/.claude-remote/settings/",
829
+ "~/my-custom-settings/"
830
+ ]
831
+ }
832
+ ```
833
+
834
+ **设置文件示例**(`~/.claude/settings-project-a.json`):
835
+
836
+ ```json
837
+ {
838
+ "env": {
839
+ "ANTHROPIC_BASE_URL": "https://api.anthropic.com"
840
+ },
841
+ "permissions": {
842
+ "allow": ["Bash(git:*)", "Bash(npm:*)"]
843
+ }
844
+ }
845
+ ```
846
+
847
+ > **注意**:带端口号的 JSON 文件会自动从设置文件列表中排除。
848
+
849
+ ### 完整示例
850
+
851
+ ```json
852
+ {
853
+ "host": "0.0.0.0",
854
+ "token": null,
855
+
856
+ "claudeCommand": "claude",
857
+ "claudeArgs": ["--no-telemetry"],
858
+ "claudeCwd": null,
859
+
860
+ "sessionTtlMs": 86400000,
861
+ "authRateLimit": 20,
862
+ "maxBufferLines": 10000,
863
+ "instanceName": null,
864
+
865
+ "shortcuts": [
866
+ { "label": "Yes", "data": "y", "enabled": true },
867
+ { "label": "Esc", "data": "\u001b", "enabled": true },
868
+ { "label": "Enter", "data": "\r", "enabled": true },
869
+ { "label": "Ctrl+C", "data": "\u0003", "enabled": true }
870
+ ],
871
+
872
+ "commands": [
873
+ { "label": "Git 状态", "command": "git status", "enabled": true },
874
+ { "label": "Git 日志", "command": "git log --oneline -10", "enabled": true }
875
+ ],
876
+
877
+ "workspaces": [
878
+ "/home/user/projects/api",
879
+ "/home/user/projects/web"
880
+ ],
881
+
882
+ "notifications": {
883
+ "dingtalk": {
884
+ "webhookUrl": "https://oapi.dingtalk.com/robot/send?access_token=your-token"
885
+ }
886
+ }
887
+ }
888
+ ```
889
+
890
+ ---
891
+
892
+ ## 安全性
893
+
894
+ - **令牌认证** — 32 字节随机令牌,首次运行生成
895
+ - **会话 Cookie** — HttpOnly + SameSite=Lax,24 小时 TTL
896
+ - **网络隔离** — 仅绑定局域网 IP,无公网暴露
897
+ - **速率限制** — 每个 IP 每分钟 20 次认证尝试
898
+ - **Hook 安全** — 仅接受 localhost 请求
899
+
900
+ ---
901
+
902
+ ## 故障排除
903
+
904
+ ### `node-pty` 编译失败
905
+
906
+ 安装编译工具:
907
+
908
+ | 操作系统 | 命令 |
909
+ |---------|------|
910
+ | macOS | `xcode-select --install` |
911
+ | Ubuntu/Debian | `sudo apt-get install build-essential python3` |
912
+ | Fedora/RHEL | `sudo dnf groupinstall 'Development Tools'` |
913
+ | Arch Linux | `sudo pacman -S base-devel python` |
914
+
915
+ ### 二维码扫不了?
916
+
917
+ 1. 确保手机和 PC 在同一网络
918
+ 2. 手动打开终端显示的 URL 并输入令牌
919
+
920
+ ### 手机连不上?
921
+
922
+ 1. 检查 PC 防火墙允许端口 8866
923
+ 2. 验证 URL 显示正确的局域网 IP
924
+ 3. 如使用 VPN,尝试显式设置 `host` 选项
925
+
926
+ ---
927
+
928
+ ## 前置要求
929
+
930
+ - **Node.js** >= 20
931
+ - **Claude Code CLI** — [安装指南](https://docs.anthropic.com/en/docs/claude-code)
932
+
933
+ > `pnpm` 和 Claude CLI 会在首次运行时自动安装(如缺失)。
934
+
935
+ ---
936
+
937
+ ## 开发
938
+
939
+ **源码开发:**
940
+
941
+ ```bash
942
+ # 克隆并安装
943
+ git clone https://github.com/StephenTowne/open-claude-remote.git
944
+ cd open-claude-remote
945
+ pnpm install
946
+
947
+ # 开发模式(热重载)
948
+ pnpm dev:cli
949
+
950
+ # 生产模式
951
+ pnpm build && pnpm link -g && claude-remote
952
+ ```
953
+
954
+ **项目结构:**
955
+
956
+ - 后端:`backend/src/`(Express + node-pty + WebSocket)
957
+ - 前端:`frontend/src/`(React + xterm.js)
958
+ - 共享类型:`shared/`(通过 `#shared` 别名导入)
959
+ - 测试:`pnpm test`(Vitest)
960
+ - 构建:`pnpm build`(TypeScript + Vite)
961
+
962
+ ### 停止所有实例
963
+
964
+ ```bash
965
+ pnpm stop
966
+ ```
967
+
968
+ ---
969
+
970
+ ## 许可证
971
+
972
+ MIT
@@ -2,6 +2,6 @@ import { Router } from 'express';
2
2
  import { AuthModule } from '../auth/auth-middleware.js';
3
3
  import type { NotificationManager } from '../notification/notification-manager.js';
4
4
  import type { NotificationServiceFactory } from '../notification/notification-service-factory.js';
5
- import type { WsServer } from '../ws/ws-server.js';
6
- export declare function createConfigRoutes(authModule: AuthModule, notificationManager?: NotificationManager, notificationServiceFactory?: NotificationServiceFactory, wsServer?: WsServer): Router;
5
+ import type { InstanceManager } from '../instance/instance-manager.js';
6
+ export declare function createConfigRoutes(authModule: AuthModule, notificationManager?: NotificationManager, notificationServiceFactory?: NotificationServiceFactory, instanceManager?: InstanceManager): Router;
7
7
  //# sourceMappingURL=config-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-routes.d.ts","sourceRoot":"","sources":["../../../../backend/src/api/config-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAexD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAClG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA+GnD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,0BAA0B,CAAC,EAAE,0BAA0B,EACvD,QAAQ,CAAC,EAAE,QAAQ,GAClB,MAAM,CA4LR"}
1
+ {"version":3,"file":"config-routes.d.ts","sourceRoot":"","sources":["../../../../backend/src/api/config-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAoBxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA+GvE,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,0BAA0B,CAAC,EAAE,0BAA0B,EACvD,eAAe,CAAC,EAAE,eAAe,GAChC,MAAM,CA+MR"}