@co0ontty/wand 1.75.5 → 1.75.7-beta.g7ae7673

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 CHANGED
@@ -5,10 +5,10 @@
5
5
  [![node](https://img.shields.io/node/v/@co0ontty/wand.svg)](https://nodejs.org)
6
6
  [![GitHub last commit](https://img.shields.io/github/last-commit/co0ontty/wand)](https://github.com/co0ontty/wand/commits/master)
7
7
 
8
- 通过浏览器远程访问和管理本地 CLI 工具的 Web 控制台。专为 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) 和 [Codex](https://github.com/openai/codex) 设计,支持终端和结构化对话双视图、会话持久化与恢复、权限管控、文件浏览、Android 客户端等功能。
8
+ 通过浏览器远程访问和管理本地 CLI 工具的 Web 控制台。专为 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) 和 [Codex](https://github.com/openai/codex) 设计,支持终端和结构化对话双视图、会话持久化与恢复、权限管控、文件浏览、多平台客户端。
9
9
 
10
10
  <p align="center">
11
- <img src="docs/screenshots/chat-view.png" width="800" alt="结构化对话视图" />
11
+ <img src="docs/screenshots/hero.png" width="100%" alt="PTY 终端与结构化对话双视图" />
12
12
  </p>
13
13
 
14
14
  ## 安装
@@ -56,16 +56,12 @@ bash <(curl -Ls https://raw.githubusercontent.com/co0ontty/wand/master/install.s
56
56
 
57
57
  ## 功能
58
58
 
59
- <p align="center">
60
- <img src="docs/screenshots/home.png" width="800" alt="欢迎页" />
61
- </p>
62
-
63
59
  ### 核心
64
60
 
65
61
  - **双视图模式** — 终端原始输出和结构化对话视图可随时切换,同一会话两种呈现
66
62
  - **多 Provider 支持** — 同时支持 Claude Code 和 Codex,可按需创建不同类型的会话
67
- - **会话管理** — 创建、归档、恢复会话;支持从 Claude 原生历史记录恢复;会话列表显示摘要,懒加载
68
- - **权限控制** — 可视化权限提示,支持逐次确认、单次批准、本轮记忆等策略;工具调用自动分组与审批统计
63
+ - **会话管理** — 创建、归档、恢复会话;支持从 Claude 原生历史记录恢复;会话列表显示摘要
64
+ - **权限控制** — 可视化权限提示,支持逐次确认、单次批准、本轮记忆等策略
69
65
 
70
66
  ### 交互体验
71
67
 
@@ -73,22 +69,23 @@ bash <(curl -Ls https://raw.githubusercontent.com/co0ontty/wand/master/install.s
73
69
  - **个性化角色** — 像素风猫咪头像(赛博虎妞 / 勤劳初二),支持自定义对话角色名称
74
70
  - **消息排队** — 在 AI 思考时可继续输入,消息自动排队发送
75
71
  - **文件浏览器** — 内置路径浏览和搜索功能
72
+ - **快捷提交** — Git 变动快速提交入口,一键生成 commit message
76
73
 
77
74
  ### 部署与访问
78
75
 
79
- - **Android 客户端** WebView 壳应用,支持加密连接码分发、APK 自动更新检查、原生通知推送、启动器图标切换
76
+ - **多平台客户端** — Android / iOS / macOS 原生客户端,支持加密连接码分发、自动更新检查
80
77
  - **HTTPS** — 可选自签证书,适合远程或移动端访问
81
- - **版本管理** — 内置更新检查与升级提示
78
+ - **版本管理** — 内置更新检查与升级提示,支持 stable/beta 双通道
82
79
 
83
80
  ## 截图
84
81
 
85
- | 登录 | 对话视图 |
82
+ | 登录页 | 会话列表 |
86
83
  |:---:|:---:|
87
- | <img src="docs/screenshots/login.png" width="400" alt="登录页" /> | <img src="docs/screenshots/chat-view.png" width="400" alt="对话视图" /> |
84
+ | <img src="docs/screenshots/login.png" width="400" alt="登录页" /> | <img src="docs/screenshots/android-home.png" width="400" alt="安卓会话列表" /> |
88
85
 
89
- | 终端 PTY 视图 |
90
- |:---:|
91
- | <img src="docs/screenshots/terminal-pty.png" width="800" alt="终端 PTY 视图" /> |
86
+ | PTY 终端视图 | 聊天视图 |
87
+ |:---:|:---:|
88
+ | <img src="docs/screenshots/android-terminal.png" width="400" alt="安卓终端视图" /> | <img src="docs/screenshots/android-chat.png" width="400" alt="安卓聊天视图" /> |
92
89
 
93
90
  ## 配置
94
91
 
@@ -155,21 +152,19 @@ npm run dev -- -c /tmp/wand-test/config.json
155
152
  ## 项目结构
156
153
 
157
154
  ```
158
- src/
159
- cli.ts # CLI 入口,解析命令和参数
160
- server.ts # Express 服务器、REST API、WebSocket
161
- server-session-routes.ts # 会话/恢复/历史相关路由
162
- process-manager.ts # PTY 会话编排、输入输出路由、权限处理
163
- claude-pty-bridge.ts # PTY 输出解析为结构化对话数据
164
- storage.ts # SQLite 持久化
165
- config.ts # 配置加载与合并
166
- session-lifecycle.ts # 会话状态机(idle/thinking/waiting/archived)
167
- session-logger.ts # 文件日志 ~/.wand/sessions/
168
- resume-policy.ts # Claude 历史绑定与恢复策略
169
- web-ui/ # 服务端渲染的前端 HTML/CSS/JS
170
- android/ # Android 壳应用(submodule → co0ontty/wand-android)
171
- macos/ # macOS 壳应用(submodule → co0ontty/wand-macos)
172
- ios/ # iOS 壳应用(submodule → co0ontty/wand-ios)
155
+ wand/
156
+ ├── src/
157
+ │ ├── cli.ts # CLI 入口
158
+ │ ├── server.ts # Express 服务器 + WebSocket
159
+ │ ├── process-manager.ts # PTY 会话编排
160
+ │ ├── claude-pty-bridge.ts # PTY 输出解析为结构化对话
161
+ │ ├── storage.ts # SQLite 持久化
162
+ │ ├── config.ts # 配置加载
163
+ │ └── web-ui/ # 前端 HTML/CSS/JS
164
+ ├── android/ # Android 客户端(submodule)
165
+ ├── ios/ # iOS 客户端(submodule)
166
+ ├── macos/ # macOS 客户端(submodule)
167
+ └── docs/ # 文档与截图
173
168
  ```
174
169
 
175
170
  三个客户端壳应用是独立仓库,以 git submodule 引用。克隆源码开发时需要带上:
@@ -184,4 +179,4 @@ git submodule update --init
184
179
 
185
180
  ## License
186
181
 
187
- MIT
182
+ MIT
@@ -1,6 +1,6 @@
1
1
  {
2
- "commit": "a74a04334cece2fd930c0457f6f04b2249d0ec47",
3
- "builtAt": "2026-06-20T12:48:14.434Z",
4
- "version": "1.75.5",
5
- "channel": "stable"
2
+ "commit": "7ae7673cfd6236680dba087cbd52c1ddbf1e5d65",
3
+ "builtAt": "2026-06-26T11:17:55.175Z",
4
+ "version": "1.75.7-beta.g7ae7673",
5
+ "channel": "beta"
6
6
  }
@@ -961,7 +961,7 @@ export class ProcessManager extends EventEmitter {
961
961
  current.ptyBridge.onUserInput(initialInput);
962
962
  }
963
963
  current.ptyProcess.write(initialInput);
964
- current.ptyProcess.write("\n");
964
+ current.ptyProcess.write("\r");
965
965
  };
966
966
  child.onData((chunk) => {
967
967
  const rec = this.sessions.get(id);
@@ -179,9 +179,16 @@ function startResumedPtySession(processes, existingSession, sessionId, defaultMo
179
179
  thinkingEffort: existingSession.thinkingEffort ?? undefined,
180
180
  });
181
181
  }
182
- function getAutoResumeInitialInput(input, view, shortcutKey) {
183
- if (view === "terminal")
184
- return null;
182
+ function getAutoResumeInitialInput(snapshot, input, view, shortcutKey) {
183
+ if (view === "terminal") {
184
+ const isCodexPty = Boolean(snapshot?.provider === "codex" || /^codex\b/.test(snapshot?.command.trim() ?? ""));
185
+ if (!isCodexPty)
186
+ return null;
187
+ if (shortcutKey && shortcutKey !== "enter_text")
188
+ return null;
189
+ if (/[\x00-\x08\x0B-\x1F\x7F]/.test(input.replace(/[\r\n]+$/g, "")))
190
+ return null;
191
+ }
185
192
  if (shortcutKey && shortcutKey !== "enter_text")
186
193
  return null;
187
194
  const trimmedRight = input.replace(/[\r\n]+$/g, "").trimEnd();
@@ -852,8 +859,8 @@ export function registerSessionRoutes(app, processes, structured, storage, defau
852
859
  res.json(snapshot);
853
860
  return;
854
861
  }
855
- const autoResumeInput = getAutoResumeInitialInput(input, view, shortcutKey);
856
862
  const existingSession = processes.get(sessionId) || storage.getSession(sessionId);
863
+ const autoResumeInput = getAutoResumeInitialInput(existingSession, input, view, shortcutKey);
857
864
  if (autoResumeInput !== null && canAutoResumePtyForInput(existingSession, autoResumeInput)) {
858
865
  const snapshot = startResumedPtySession(processes, existingSession, sessionId, defaultMode, {}, autoResumeInput);
859
866
  res.json(snapshot);
package/dist/server.js CHANGED
@@ -2133,6 +2133,10 @@ export async function startServer(config, configPath) {
2133
2133
  return createHttpsServer({ key: ssl.key, cert: ssl.cert }, app);
2134
2134
  })()
2135
2135
  : createHttpServer(app);
2136
+ // Node's 5s default can close an idle socket just before iOS URLSession reuses
2137
+ // it for a later POST, surfacing as "network connection lost" on the client.
2138
+ server.keepAliveTimeout = 75_000;
2139
+ server.headersTimeout = 80_000;
2136
2140
  // 公开下载当前证书 —— 方便从手机/其他终端拉证书并导入信任链。
2137
2141
  // 不鉴权:证书本身是公开材料(不含私钥),泄露不影响安全。
2138
2142
  if (useHttps && activeSslCertPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.75.5",
3
+ "version": "1.75.7-beta.g7ae7673",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {