@co0ontty/wand 1.49.6 → 1.49.7-beta.g6e7deb1
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/dist/build-info.json +4 -4
- package/dist/claude-sdk-runner.d.ts +18 -6
- package/dist/claude-sdk-runner.js +48 -10
- package/dist/git-quick-commit.js +7 -3
- package/dist/structured-session-manager.js +2 -43
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.d.ts +1 -1
- package/dist/web-ui/embedded-assets.js +2 -2
- package/package.json +1 -1
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commit": "
|
|
3
|
-
"builtAt": "2026-06-
|
|
4
|
-
"version": "1.49.
|
|
5
|
-
"channel": "
|
|
2
|
+
"commit": "6e7deb10cf58099ca66d557f2e31f0be52cdaccf",
|
|
3
|
+
"builtAt": "2026-06-10T05:45:53.169Z",
|
|
4
|
+
"version": "1.49.7-beta.g6e7deb1",
|
|
5
|
+
"channel": "beta"
|
|
6
6
|
}
|
|
@@ -14,6 +14,18 @@ export interface RunClaudePrintOptions {
|
|
|
14
14
|
*/
|
|
15
15
|
language?: string;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* 解析 SDK 应使用的 claude binary:**优先系统安装的 claude,回退 SDK 内置 native binary**。
|
|
19
|
+
*
|
|
20
|
+
* 优先系统版的原因:node_modules 里的内置 binary 版本在装包那刻就钉死了,会随时间
|
|
21
|
+
* 越来越旧,最终可能被 API 端拒绝(实测内置 2.1.138 对部分端点持续 502 重试到超时,
|
|
22
|
+
* 而系统侧日常更新的 2.1.170 正常)。系统 claude 跟交互式 PTY 会话同源,用户平时
|
|
23
|
+
* 一直在用、一直在更新,是最可靠的选择。
|
|
24
|
+
*
|
|
25
|
+
* 内置 binary 仅作兜底(系统没装 claude 时仍可用)。Linux 上必须显式按 libc 选包:
|
|
26
|
+
* SDK 默认解析在 glibc 系统上可能错选 musl 包直接抛 "native binary not found"。
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveSdkClaudeBinary(): string | undefined;
|
|
17
29
|
/**
|
|
18
30
|
* 用 `@anthropic-ai/claude-agent-sdk` 跑一次"prompt → 单段纯文本"调用,
|
|
19
31
|
* 等价以前的 `claude -p --output-format text`。
|
|
@@ -25,14 +37,14 @@ export interface RunClaudePrintOptions {
|
|
|
25
37
|
* - `tools: []` 关掉所有内置工具:这两个调用点(commit message / prompt 优化)
|
|
26
38
|
* 本质就是"纯文本生成",关掉工具能 (1) 防止 Claude 随手开个工具卡住权限询问;
|
|
27
39
|
* (2) 避免一次性短调用还顺便加载文件 / 跑 bash 这种副作用。
|
|
40
|
+
* - `mcpServers: {}` + `strictMcpConfig: true` 跳过用户配置的全部 MCP 服务器:
|
|
41
|
+
* 纯文本生成用不上 MCP,但不禁的话每次调用都要连接 MCP(启动慢好几秒)、
|
|
42
|
+
* 还把所有 MCP 工具 schema 灌进 system prompt(实测一次多写 1.6 万 token 的
|
|
43
|
+
* prompt cache,白花钱)。
|
|
28
44
|
* - `persistSession: false`:这些 ephemeral 调用不应该污染 `~/.claude/projects/`
|
|
29
45
|
* 的会话历史;用户在 wand UI 里也压根看不到这些"虚拟会话"。
|
|
30
46
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* `node_modules` 里,**零** PATH 依赖。systemd / launchd / 双击图标启动
|
|
34
|
-
* wand server 时不会再因为 PATH 缺 nvm/npm-global 而报"未找到 claude CLI"。
|
|
35
|
-
* - 与现有 `structured-session-manager.ts` 的 SDK 调用路径同源,行为/认证/
|
|
36
|
-
* 更新策略统一。
|
|
47
|
+
* binary 解析见 `resolveSdkClaudeBinary()`:优先系统 claude(与 PTY 会话同源、
|
|
48
|
+
* 版本新),回退 SDK 内置 native binary(系统没装时的零 PATH 依赖兜底)。
|
|
37
49
|
*/
|
|
38
50
|
export declare function runClaudePrint(prompt: string, options: RunClaudePrintOptions): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { accessSync, constants as fsConstants, existsSync, statSync } from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { query as sdkQuery, } from "@anthropic-ai/claude-agent-sdk";
|
|
4
5
|
import { buildLanguageDirective } from "./language-prompt.js";
|
|
5
6
|
import { getErrorMessage } from "./error-utils.js";
|
|
@@ -25,10 +26,45 @@ function isMuslSystem() {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
29
|
+
* 在 PATH 上找系统安装的 `claude`。wand 的交互式 PTY 会话本来就 spawn PATH 上的
|
|
30
|
+
* claude(service 模式下 path-repair 已先把 PATH 补全),SDK 调用对齐同一个 binary
|
|
31
|
+
* 才能保证两边版本、认证、API 端点兼容性完全一致。
|
|
30
32
|
*/
|
|
31
|
-
function
|
|
33
|
+
function findClaudeOnPath() {
|
|
34
|
+
const dirs = (process.env.PATH || "").split(path.delimiter);
|
|
35
|
+
for (const dir of dirs) {
|
|
36
|
+
if (!dir)
|
|
37
|
+
continue;
|
|
38
|
+
const candidate = path.join(dir, "claude");
|
|
39
|
+
try {
|
|
40
|
+
accessSync(candidate, fsConstants.X_OK);
|
|
41
|
+
if (statSync(candidate).isFile())
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// 不存在或不可执行,继续找下一个目录
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 解析 SDK 应使用的 claude binary:**优先系统安装的 claude,回退 SDK 内置 native binary**。
|
|
52
|
+
*
|
|
53
|
+
* 优先系统版的原因:node_modules 里的内置 binary 版本在装包那刻就钉死了,会随时间
|
|
54
|
+
* 越来越旧,最终可能被 API 端拒绝(实测内置 2.1.138 对部分端点持续 502 重试到超时,
|
|
55
|
+
* 而系统侧日常更新的 2.1.170 正常)。系统 claude 跟交互式 PTY 会话同源,用户平时
|
|
56
|
+
* 一直在用、一直在更新,是最可靠的选择。
|
|
57
|
+
*
|
|
58
|
+
* 内置 binary 仅作兜底(系统没装 claude 时仍可用)。Linux 上必须显式按 libc 选包:
|
|
59
|
+
* SDK 默认解析在 glibc 系统上可能错选 musl 包直接抛 "native binary not found"。
|
|
60
|
+
*/
|
|
61
|
+
export function resolveSdkClaudeBinary() {
|
|
62
|
+
// Windows 上 PATH 命中的多是 .cmd shim,spawn 语义不同,维持 SDK 默认解析。
|
|
63
|
+
if (process.platform !== "win32") {
|
|
64
|
+
const systemClaude = findClaudeOnPath();
|
|
65
|
+
if (systemClaude)
|
|
66
|
+
return systemClaude;
|
|
67
|
+
}
|
|
32
68
|
if (process.platform !== "linux")
|
|
33
69
|
return undefined;
|
|
34
70
|
const musl = isMuslSystem();
|
|
@@ -66,15 +102,15 @@ function resolveSdkClaudeBinary() {
|
|
|
66
102
|
* - `tools: []` 关掉所有内置工具:这两个调用点(commit message / prompt 优化)
|
|
67
103
|
* 本质就是"纯文本生成",关掉工具能 (1) 防止 Claude 随手开个工具卡住权限询问;
|
|
68
104
|
* (2) 避免一次性短调用还顺便加载文件 / 跑 bash 这种副作用。
|
|
105
|
+
* - `mcpServers: {}` + `strictMcpConfig: true` 跳过用户配置的全部 MCP 服务器:
|
|
106
|
+
* 纯文本生成用不上 MCP,但不禁的话每次调用都要连接 MCP(启动慢好几秒)、
|
|
107
|
+
* 还把所有 MCP 工具 schema 灌进 system prompt(实测一次多写 1.6 万 token 的
|
|
108
|
+
* prompt cache,白花钱)。
|
|
69
109
|
* - `persistSession: false`:这些 ephemeral 调用不应该污染 `~/.claude/projects/`
|
|
70
110
|
* 的会话历史;用户在 wand UI 里也压根看不到这些"虚拟会话"。
|
|
71
111
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* `node_modules` 里,**零** PATH 依赖。systemd / launchd / 双击图标启动
|
|
75
|
-
* wand server 时不会再因为 PATH 缺 nvm/npm-global 而报"未找到 claude CLI"。
|
|
76
|
-
* - 与现有 `structured-session-manager.ts` 的 SDK 调用路径同源,行为/认证/
|
|
77
|
-
* 更新策略统一。
|
|
112
|
+
* binary 解析见 `resolveSdkClaudeBinary()`:优先系统 claude(与 PTY 会话同源、
|
|
113
|
+
* 版本新),回退 SDK 内置 native binary(系统没装时的零 PATH 依赖兜底)。
|
|
78
114
|
*/
|
|
79
115
|
export async function runClaudePrint(prompt, options) {
|
|
80
116
|
const cwd = options.cwd && options.cwd.length > 0 ? options.cwd : undefined;
|
|
@@ -85,6 +121,8 @@ export async function runClaudePrint(prompt, options) {
|
|
|
85
121
|
const sdkOptions = {
|
|
86
122
|
abortController,
|
|
87
123
|
tools: [],
|
|
124
|
+
mcpServers: {},
|
|
125
|
+
strictMcpConfig: true,
|
|
88
126
|
persistSession: false,
|
|
89
127
|
...(cwd ? { cwd } : {}),
|
|
90
128
|
...(sdkClaudeBinary ? { pathToClaudeCodeExecutable: sdkClaudeBinary } : {}),
|
package/dist/git-quick-commit.js
CHANGED
|
@@ -4,7 +4,9 @@ import { runGit as runGitBase, runGitRaw as runGitRawBase, getGitErrorMessage }
|
|
|
4
4
|
const GIT_TIMEOUT_MS = 1500;
|
|
5
5
|
const GIT_PUSH_TIMEOUT_MS = 30_000;
|
|
6
6
|
const MAX_FILE_ENTRIES = 200;
|
|
7
|
-
|
|
7
|
+
// AI 生成 message/tag 的超时。SDK 链路 = spawn claude + API 调用(带自动重试),
|
|
8
|
+
// 30s 在 API 抖动时不够用,放宽到 60s。
|
|
9
|
+
const CLAUDE_MESSAGE_TIMEOUT_MS = 60_000;
|
|
8
10
|
const MAX_DIFF_FOR_AI = 100_000;
|
|
9
11
|
const GIT_MAX_BUFFER = 16 * 1024 * 1024;
|
|
10
12
|
function runGit(args, cwd, timeoutMs = GIT_TIMEOUT_MS) {
|
|
@@ -240,8 +242,10 @@ export function getGitStatus(cwd) {
|
|
|
240
242
|
behind,
|
|
241
243
|
lastCommit,
|
|
242
244
|
latestTag,
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
+
// 供前端决定是否渲染 Submodule 球。status 全量条目(不受 files 的 200 条 slice 影响)
|
|
246
|
+
// 只能看到「有改动」的 submodule,clean submodule 不会出现在 status 里,所以再用
|
|
247
|
+
// .gitmodules 声明兜底——只要仓库声明了 submodule 就提供该选项。
|
|
248
|
+
hasSubmodule: allEntries.some((e) => e.isSubmodule) || repoDeclaresSubmodule(repoRoot),
|
|
245
249
|
};
|
|
246
250
|
}
|
|
247
251
|
export class QuickCommitError extends Error {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
-
import {
|
|
4
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { readFileSync, statSync } from "node:fs";
|
|
5
4
|
import { homedir } from "node:os";
|
|
6
5
|
import path from "node:path";
|
|
7
6
|
import { query as sdkQuery } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -9,6 +8,7 @@ import { prepareSessionWorktree } from "./git-worktree.js";
|
|
|
9
8
|
import { truncateMessagesForTransport } from "./message-truncator.js";
|
|
10
9
|
import { buildChildEnv, isRunningAsRoot } from "./env-utils.js";
|
|
11
10
|
import { getErrorMessage } from "./error-utils.js";
|
|
11
|
+
import { resolveSdkClaudeBinary } from "./claude-sdk-runner.js";
|
|
12
12
|
import { buildLanguageDirective, buildManagedAutonomyDirective } from "./language-prompt.js";
|
|
13
13
|
function defaultStructuredRunner(provider) {
|
|
14
14
|
return provider === "codex" ? "codex-cli-exec" : "claude-cli-print";
|
|
@@ -170,47 +170,6 @@ const STREAM_EMIT_DEBOUNCE_MS = 16;
|
|
|
170
170
|
* authoritative final snapshot. */
|
|
171
171
|
const STREAM_SAVE_THROTTLE_MS = 200;
|
|
172
172
|
const ARCHIVE_AFTER_MS = 1000 * 60 * 60 * 24;
|
|
173
|
-
/**
|
|
174
|
-
* 检测当前系统是否使用 musl libc(Alpine Linux 等)。
|
|
175
|
-
* Node.js 进程报告中 glibcVersionRuntime 仅在 glibc 系统存在;musl 系统为 undefined。
|
|
176
|
-
*/
|
|
177
|
-
function isMuslSystem() {
|
|
178
|
-
try {
|
|
179
|
-
const header = process.report?.getReport()?.header;
|
|
180
|
-
return !header?.glibcVersionRuntime;
|
|
181
|
-
}
|
|
182
|
-
catch {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* 解析 claude-agent-sdk 应使用的 native binary 路径。
|
|
188
|
-
* SDK 默认在 Linux 上优先选 musl 包,但 glibc 系统(Debian/Ubuntu 等)跑不动 musl binary,
|
|
189
|
-
* 会抛 "Claude Code native binary not found" 错误。这里手动按 libc 类型选正确的包,
|
|
190
|
-
* 找不到时回退到系统 PATH 上的 `claude`。
|
|
191
|
-
*/
|
|
192
|
-
function resolveSdkClaudeBinary() {
|
|
193
|
-
if (process.platform !== "linux")
|
|
194
|
-
return undefined;
|
|
195
|
-
const musl = isMuslSystem();
|
|
196
|
-
const arch = process.arch;
|
|
197
|
-
const require = createRequire(import.meta.url);
|
|
198
|
-
// 按当前 libc 类型决定优先顺序
|
|
199
|
-
const candidates = musl
|
|
200
|
-
? [`@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`, `@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`]
|
|
201
|
-
: [`@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`, `@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`];
|
|
202
|
-
for (const pkg of candidates) {
|
|
203
|
-
try {
|
|
204
|
-
const resolved = require.resolve(pkg);
|
|
205
|
-
if (existsSync(resolved))
|
|
206
|
-
return resolved;
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
// 包不存在,继续
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return undefined;
|
|
213
|
-
}
|
|
214
173
|
/**
|
|
215
174
|
* 找出最后一条 assistant turn 中尚未配对 tool_result 的 AskUserQuestion tool_use。
|
|
216
175
|
* 用来识别"刚被 SIGTERM 中断、正在等用户提交答案"的状态。
|