@co0ontty/wand 4.80.0 → 4.80.1-beta.g1fbbefb
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/ai-team-availability.js +0 -1
- package/dist/ai-team-live.d.ts +3 -1
- package/dist/ai-team-live.js +31 -2
- package/dist/ai-team-runner.d.ts +2 -1
- package/dist/ai-team-runner.js +17 -7
- package/dist/ai-team-types.d.ts +8 -0
- package/dist/ai-team-types.js +4 -0
- package/dist/build-info.json +4 -4
- package/dist/claude-pty-bridge.js +16 -1
- package/dist/cli.js +0 -9
- package/dist/config.d.ts +2 -10
- package/dist/config.js +1 -73
- package/dist/git-quick-commit.d.ts +3 -6
- package/dist/git-quick-commit.js +38 -75
- package/dist/language-prompt.d.ts +1 -1
- package/dist/language-prompt.js +1 -1
- package/dist/native-session-title.d.ts +17 -0
- package/dist/native-session-title.js +257 -0
- package/dist/process-manager.d.ts +3 -0
- package/dist/process-manager.js +37 -6
- package/dist/server-session-routes.js +4 -29
- package/dist/server-settings-routes.js +2 -177
- package/dist/server-task-routes.js +1 -1
- package/dist/server-workspace-routes.js +1 -1
- package/dist/server.js +1 -13
- package/dist/session-ai-context.d.ts +3 -7
- package/dist/session-ai-context.js +0 -25
- package/dist/session-topic.d.ts +19 -0
- package/dist/session-topic.js +53 -3
- package/dist/session-transport.js +0 -1
- package/dist/silicon-employee-draft.d.ts +1 -1
- package/dist/storage.js +12 -18
- package/dist/structured-claude-adapter.d.ts +0 -6
- package/dist/structured-claude-adapter.js +1 -5
- package/dist/structured-provider-common.d.ts +8 -4
- package/dist/structured-provider-common.js +14 -15
- package/dist/structured-session-manager.d.ts +4 -40
- package/dist/structured-session-manager.js +53 -773
- package/dist/types.d.ts +12 -27
- package/dist/web-ui/content/ai-teams.js +9 -9
- package/dist/web-ui/content/scripts.js +70 -70
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.js +3 -3
- package/dist/ws-broadcast.js +19 -7
- package/package.json +1 -2
- package/dist/claude-sdk-runner.d.ts +0 -59
- package/dist/claude-sdk-runner.js +0 -188
- package/dist/claude-skills.d.ts +0 -6
- package/dist/claude-skills.js +0 -53
- package/dist/system-ai.d.ts +0 -27
- package/dist/system-ai.js +0 -424
package/dist/ws-broadcast.js
CHANGED
|
@@ -13,6 +13,7 @@ const QUEUE_RESUME_SIZE = Math.floor(MAX_QUEUE_SIZE * 0.8);
|
|
|
13
13
|
const SEND_BATCH_SIZE = 8;
|
|
14
14
|
const MAX_BLOCK_BUDGET = 2_000;
|
|
15
15
|
const OUTPUT_DEBOUNCE_MS = 16;
|
|
16
|
+
const MAX_DEBOUNCED_CHUNK_CHARS = 256 * 1024;
|
|
16
17
|
/**
|
|
17
18
|
* 服务端心跳节奏。20s 一次,比常见 NAT/代理空闲超时(30~60s)更短,可以保活;
|
|
18
19
|
* 也不至于让 idle 连接每秒都在跑 timer。前后端在心跳间窗内任何方向消息都会
|
|
@@ -276,8 +277,14 @@ export class WsBroadcastManager {
|
|
|
276
277
|
}
|
|
277
278
|
return;
|
|
278
279
|
}
|
|
279
|
-
//
|
|
280
|
+
// Coalesce within the first event's deadline; continuous output must not starve.
|
|
280
281
|
if (event.type === "output") {
|
|
282
|
+
const eventData = asEventData(event.data);
|
|
283
|
+
if (typeof eventData.chunk === "string" && eventData.chunk.length >= MAX_DEBOUNCED_CHUNK_CHARS) {
|
|
284
|
+
this.flushOutput(event.sessionId);
|
|
285
|
+
this.broadcast(event);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
281
288
|
const existing = this.outputDebounceCache.get(event.sessionId);
|
|
282
289
|
if (existing) {
|
|
283
290
|
const prevData = asEventData(existing.event.data);
|
|
@@ -293,14 +300,15 @@ export class WsBroadcastManager {
|
|
|
293
300
|
// 形状不一致时 flush 上一条立即广播,新事件单独开窗口。这样客户端永远
|
|
294
301
|
// 不会在一条 WS 消息里同时看到 messages 和 lastMessage 两种语义。
|
|
295
302
|
const shapeMismatch = outputEventShapeMismatch(prevData, curData);
|
|
296
|
-
|
|
303
|
+
const chunkChars = (typeof prevData.chunk === "string" ? prevData.chunk.length : 0)
|
|
304
|
+
+ (typeof curData.chunk === "string" ? curData.chunk.length : 0);
|
|
305
|
+
if (shapeMismatch || chunkChars > MAX_DEBOUNCED_CHUNK_CHARS) {
|
|
297
306
|
clearTimeout(existing.timer);
|
|
298
307
|
this.outputDebounceCache.delete(event.sessionId);
|
|
299
308
|
this.broadcast(existing.event);
|
|
300
309
|
// Fall through to schedule cur on a fresh debounce window
|
|
301
310
|
}
|
|
302
311
|
else {
|
|
303
|
-
clearTimeout(existing.timer);
|
|
304
312
|
// Merge prev + cur. Cur takes precedence for identically-named fields,
|
|
305
313
|
// but fields only present on prev (e.g. chunk while cur carries
|
|
306
314
|
// messages, or messages while cur carries chunk) survive — the old
|
|
@@ -314,14 +322,18 @@ export class WsBroadcastManager {
|
|
|
314
322
|
else if (prevChunk && !curChunk) {
|
|
315
323
|
merged.chunk = prevChunk;
|
|
316
324
|
}
|
|
317
|
-
event = { ...event, data: merged };
|
|
325
|
+
existing.event = { ...event, data: merged };
|
|
326
|
+
return;
|
|
318
327
|
}
|
|
319
328
|
}
|
|
320
|
-
const
|
|
329
|
+
const pending = { event, timer: undefined };
|
|
330
|
+
pending.timer = setTimeout(() => {
|
|
331
|
+
if (this.outputDebounceCache.get(event.sessionId) !== pending)
|
|
332
|
+
return;
|
|
321
333
|
this.outputDebounceCache.delete(event.sessionId);
|
|
322
|
-
this.broadcast(event);
|
|
334
|
+
this.broadcast(pending.event);
|
|
323
335
|
}, OUTPUT_DEBOUNCE_MS);
|
|
324
|
-
this.outputDebounceCache.set(event.sessionId,
|
|
336
|
+
this.outputDebounceCache.set(event.sessionId, pending);
|
|
325
337
|
return;
|
|
326
338
|
}
|
|
327
339
|
// Preserve PTY ordering: the final debounced bytes must arrive before an
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@co0ontty/wand",
|
|
3
|
-
"version": "4.80.
|
|
3
|
+
"version": "4.80.1-beta.g1fbbefb",
|
|
4
4
|
"description": "A web console for Claude Code, Codex, OpenCode, and other local CLI tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
"node": ">=26.10.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.138",
|
|
51
50
|
"@anthropic-ai/sdk": "^0.81.0",
|
|
52
51
|
"@xterm/addon-serialize": "^0.14.0",
|
|
53
52
|
"@xterm/addon-unicode11": "^0.9.0",
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export type ClaudeRunErrorCode = "CLAUDE_CLI_MISSING" | "CLAUDE_TIMEOUT" | "CLAUDE_CLI_FAILED" | "CLAUDE_EMPTY_RESULT";
|
|
2
|
-
export declare class ClaudeRunError extends Error {
|
|
3
|
-
readonly code: ClaudeRunErrorCode;
|
|
4
|
-
constructor(message: string, code: ClaudeRunErrorCode);
|
|
5
|
-
}
|
|
6
|
-
export interface RunClaudePrintOptions {
|
|
7
|
-
cwd?: string;
|
|
8
|
-
timeoutMs: number;
|
|
9
|
-
/** Optional Claude model id / alias. Empty or "default" keeps Claude Code's own default. */
|
|
10
|
-
model?: string;
|
|
11
|
-
/** Optional adaptive-thinking effort. CLI 动态档位(high / xhigh 等)原样传给 SDK。 */
|
|
12
|
-
effort?: string;
|
|
13
|
-
/**
|
|
14
|
-
* 用户偏好的回复语言(取自 config.language)。传进来时会以
|
|
15
|
-
* `appendSystemPrompt` 形式灌给 Claude,保证 quick-commit / prompt-optimizer
|
|
16
|
-
* 这种一次性调用也跟用户主会话同语言——之前 wand 的 git commit message 会
|
|
17
|
-
* 莫名其妙变中英混搭,根因就在这。
|
|
18
|
-
*/
|
|
19
|
-
language?: string;
|
|
20
|
-
/**
|
|
21
|
-
* 本次调用的规则 / 角色 / 输出格式。走 appendSystemPrompt,不拼进用户串,
|
|
22
|
-
* 避免规则被当成待处理内容,也避免它进 provider 历史时冒充用户输入。
|
|
23
|
-
*/
|
|
24
|
-
systemInstructions?: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 解析 SDK 应使用的 claude binary:**优先系统安装的 claude,回退 SDK 内置 native binary**。
|
|
28
|
-
*
|
|
29
|
-
* 优先系统版的原因:node_modules 里的内置 binary 版本在装包那刻就钉死了,会随时间
|
|
30
|
-
* 越来越旧,最终可能被 API 端拒绝(实测内置 2.1.138 对部分端点持续 502 重试到超时,
|
|
31
|
-
* 而系统侧日常更新的 2.1.170 正常)。系统 claude 跟交互式 PTY 会话同源,用户平时
|
|
32
|
-
* 一直在用、一直在更新,是最可靠的选择。
|
|
33
|
-
*
|
|
34
|
-
* 内置 binary 仅作兜底(系统没装 claude 时仍可用)。Linux 上必须显式按 libc 选包:
|
|
35
|
-
* SDK 默认解析在 glibc 系统上可能错选 musl 包直接抛 "native binary not found"。
|
|
36
|
-
*/
|
|
37
|
-
export declare function resolveSdkClaudeBinary(): string | undefined;
|
|
38
|
-
/**
|
|
39
|
-
* 用 `@anthropic-ai/claude-agent-sdk` 跑一次"prompt → 单段纯文本"调用,
|
|
40
|
-
* 等价以前的 `claude -p --output-format text`。
|
|
41
|
-
*
|
|
42
|
-
* 行为对齐 Claude Code 默认:
|
|
43
|
-
* - 不指定 model / appendSystemPrompt / agent / mcpServers / hooks 等覆盖项,
|
|
44
|
-
* 完全由 `~/.claude/settings.json`、OAuth 凭据、`CLAUDE_*` 环境变量等
|
|
45
|
-
* 用户侧配置接管,与 Claude Code 自身一致。
|
|
46
|
-
* - `tools: []` 关掉所有内置工具:这两个调用点(commit message / prompt 优化)
|
|
47
|
-
* 本质就是"纯文本生成",关掉工具能 (1) 防止 Claude 随手开个工具卡住权限询问;
|
|
48
|
-
* (2) 避免一次性短调用还顺便加载文件 / 跑 bash 这种副作用。
|
|
49
|
-
* - `mcpServers: {}` + `strictMcpConfig: true` 跳过用户配置的全部 MCP 服务器:
|
|
50
|
-
* 纯文本生成用不上 MCP,但不禁的话每次调用都要连接 MCP(启动慢好几秒)、
|
|
51
|
-
* 还把所有 MCP 工具 schema 灌进 system prompt(实测一次多写 1.6 万 token 的
|
|
52
|
-
* prompt cache,白花钱)。
|
|
53
|
-
* - `persistSession: false`:这些 ephemeral 调用不应该污染 `~/.claude/projects/`
|
|
54
|
-
* 的会话历史;用户在 wand UI 里也压根看不到这些"虚拟会话"。
|
|
55
|
-
*
|
|
56
|
-
* binary 解析见 `resolveSdkClaudeBinary()`:优先系统 claude(与 PTY 会话同源、
|
|
57
|
-
* 版本新),回退 SDK 内置 native binary(系统没装时的零 PATH 依赖兜底)。
|
|
58
|
-
*/
|
|
59
|
-
export declare function runClaudePrint(prompt: string, options: RunClaudePrintOptions): Promise<string>;
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { accessSync, constants as fsConstants, existsSync, statSync } from "node:fs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { query as sdkQuery, } from "@anthropic-ai/claude-agent-sdk";
|
|
5
|
-
import { buildLanguageDirective } from "./language-prompt.js";
|
|
6
|
-
import { getErrorMessage } from "./error-utils.js";
|
|
7
|
-
export class ClaudeRunError extends Error {
|
|
8
|
-
code;
|
|
9
|
-
constructor(message, code) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.code = code;
|
|
12
|
-
this.name = "ClaudeRunError";
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* 判断当前 Linux 是否是 musl 系(Alpine 等)。glibc 系跑不动 musl native binary,
|
|
17
|
-
* 反之亦然,SDK 默认的优先级与本机不匹配时会抛 "Claude Code native binary not found"。
|
|
18
|
-
*/
|
|
19
|
-
function isMuslSystem() {
|
|
20
|
-
try {
|
|
21
|
-
const header = process.report?.getReport()?.header;
|
|
22
|
-
return !header?.glibcVersionRuntime;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 在 PATH 上找系统安装的 `claude`。wand 的交互式 PTY 会话本来就 spawn PATH 上的
|
|
30
|
-
* claude(service 模式下 path-repair 已先把 PATH 补全),SDK 调用对齐同一个 binary
|
|
31
|
-
* 才能保证两边版本、认证、API 端点兼容性完全一致。
|
|
32
|
-
*/
|
|
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
|
-
}
|
|
68
|
-
if (process.platform !== "linux")
|
|
69
|
-
return undefined;
|
|
70
|
-
const musl = isMuslSystem();
|
|
71
|
-
const arch = process.arch;
|
|
72
|
-
const require = createRequire(import.meta.url);
|
|
73
|
-
const candidates = musl
|
|
74
|
-
? [
|
|
75
|
-
`@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`,
|
|
76
|
-
`@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`,
|
|
77
|
-
]
|
|
78
|
-
: [
|
|
79
|
-
`@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`,
|
|
80
|
-
`@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`,
|
|
81
|
-
];
|
|
82
|
-
for (const pkg of candidates) {
|
|
83
|
-
try {
|
|
84
|
-
const resolved = require.resolve(pkg);
|
|
85
|
-
if (existsSync(resolved))
|
|
86
|
-
return resolved;
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
// 包不存在,尝试下一个
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* 用 `@anthropic-ai/claude-agent-sdk` 跑一次"prompt → 单段纯文本"调用,
|
|
96
|
-
* 等价以前的 `claude -p --output-format text`。
|
|
97
|
-
*
|
|
98
|
-
* 行为对齐 Claude Code 默认:
|
|
99
|
-
* - 不指定 model / appendSystemPrompt / agent / mcpServers / hooks 等覆盖项,
|
|
100
|
-
* 完全由 `~/.claude/settings.json`、OAuth 凭据、`CLAUDE_*` 环境变量等
|
|
101
|
-
* 用户侧配置接管,与 Claude Code 自身一致。
|
|
102
|
-
* - `tools: []` 关掉所有内置工具:这两个调用点(commit message / prompt 优化)
|
|
103
|
-
* 本质就是"纯文本生成",关掉工具能 (1) 防止 Claude 随手开个工具卡住权限询问;
|
|
104
|
-
* (2) 避免一次性短调用还顺便加载文件 / 跑 bash 这种副作用。
|
|
105
|
-
* - `mcpServers: {}` + `strictMcpConfig: true` 跳过用户配置的全部 MCP 服务器:
|
|
106
|
-
* 纯文本生成用不上 MCP,但不禁的话每次调用都要连接 MCP(启动慢好几秒)、
|
|
107
|
-
* 还把所有 MCP 工具 schema 灌进 system prompt(实测一次多写 1.6 万 token 的
|
|
108
|
-
* prompt cache,白花钱)。
|
|
109
|
-
* - `persistSession: false`:这些 ephemeral 调用不应该污染 `~/.claude/projects/`
|
|
110
|
-
* 的会话历史;用户在 wand UI 里也压根看不到这些"虚拟会话"。
|
|
111
|
-
*
|
|
112
|
-
* binary 解析见 `resolveSdkClaudeBinary()`:优先系统 claude(与 PTY 会话同源、
|
|
113
|
-
* 版本新),回退 SDK 内置 native binary(系统没装时的零 PATH 依赖兜底)。
|
|
114
|
-
*/
|
|
115
|
-
export async function runClaudePrint(prompt, options) {
|
|
116
|
-
const cwd = options.cwd && options.cwd.length > 0 ? options.cwd : undefined;
|
|
117
|
-
const abortController = new AbortController();
|
|
118
|
-
const timeoutHandle = setTimeout(() => abortController.abort(), options.timeoutMs);
|
|
119
|
-
const sdkClaudeBinary = resolveSdkClaudeBinary();
|
|
120
|
-
const languageDirective = options.language ? buildLanguageDirective(options.language) : "";
|
|
121
|
-
const appendSystemPrompt = [languageDirective, options.systemInstructions?.trim() ?? ""].filter(Boolean).join("\n\n");
|
|
122
|
-
const model = options.model?.trim();
|
|
123
|
-
const sdkOptions = {
|
|
124
|
-
abortController,
|
|
125
|
-
tools: [],
|
|
126
|
-
mcpServers: {},
|
|
127
|
-
strictMcpConfig: true,
|
|
128
|
-
persistSession: false,
|
|
129
|
-
...(cwd ? { cwd } : {}),
|
|
130
|
-
...(sdkClaudeBinary ? { pathToClaudeCodeExecutable: sdkClaudeBinary } : {}),
|
|
131
|
-
...(appendSystemPrompt ? { appendSystemPrompt } : {}),
|
|
132
|
-
...(model && model !== "default" ? { model } : {}),
|
|
133
|
-
...(options.effort ? { effort: options.effort } : {}),
|
|
134
|
-
};
|
|
135
|
-
// 单条 user message → AsyncGenerator,SDK 的 streaming input 协议要求。
|
|
136
|
-
async function* singleShot() {
|
|
137
|
-
yield {
|
|
138
|
-
type: "user",
|
|
139
|
-
message: {
|
|
140
|
-
role: "user",
|
|
141
|
-
content: [{ type: "text", text: prompt }],
|
|
142
|
-
},
|
|
143
|
-
parent_tool_use_id: null,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
let resultText = "";
|
|
147
|
-
let resultError = null;
|
|
148
|
-
try {
|
|
149
|
-
for await (const msg of sdkQuery({
|
|
150
|
-
prompt: singleShot(),
|
|
151
|
-
options: sdkOptions,
|
|
152
|
-
})) {
|
|
153
|
-
if (msg.type !== "result")
|
|
154
|
-
continue;
|
|
155
|
-
if (msg.subtype === "success" && typeof msg.result === "string") {
|
|
156
|
-
resultText = msg.result.trim();
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
const errs = Array.isArray(msg.errors)
|
|
160
|
-
? msg.errors.join("; ")
|
|
161
|
-
: msg.subtype;
|
|
162
|
-
resultError = new ClaudeRunError(`Claude SDK 失败:${errs}`, "CLAUDE_CLI_FAILED");
|
|
163
|
-
}
|
|
164
|
-
break; // 一次性调用,拿到 result 即退出
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (err) {
|
|
168
|
-
if (abortController.signal.aborted) {
|
|
169
|
-
throw new ClaudeRunError("Claude 调用超时。", "CLAUDE_TIMEOUT");
|
|
170
|
-
}
|
|
171
|
-
const message = getErrorMessage(err);
|
|
172
|
-
// SDK 找不到 native binary 时会抛 "Claude Code native binary not found"。
|
|
173
|
-
// 极少数情况下也可能透出 ENOENT。两种都归到"CLI_MISSING",文案给用户。
|
|
174
|
-
if (/Claude Code native binary not found|ENOENT/i.test(message)) {
|
|
175
|
-
throw new ClaudeRunError("未找到 claude CLI。", "CLAUDE_CLI_MISSING");
|
|
176
|
-
}
|
|
177
|
-
throw new ClaudeRunError(`Claude SDK 失败:${message}`, "CLAUDE_CLI_FAILED");
|
|
178
|
-
}
|
|
179
|
-
finally {
|
|
180
|
-
clearTimeout(timeoutHandle);
|
|
181
|
-
}
|
|
182
|
-
if (resultError)
|
|
183
|
-
throw resultError;
|
|
184
|
-
if (!resultText) {
|
|
185
|
-
throw new ClaudeRunError("Claude 返回了空结果。", "CLAUDE_EMPTY_RESULT");
|
|
186
|
-
}
|
|
187
|
-
return resultText;
|
|
188
|
-
}
|
package/dist/claude-skills.d.ts
DELETED
package/dist/claude-skills.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
function parseFrontmatter(source) {
|
|
5
|
-
if (!source.startsWith("---"))
|
|
6
|
-
return {};
|
|
7
|
-
const end = source.indexOf("\n---", 3);
|
|
8
|
-
if (end === -1)
|
|
9
|
-
return {};
|
|
10
|
-
const frontmatter = source.slice(3, end);
|
|
11
|
-
const name = frontmatter.match(/^name:\s*(.+?)\s*$/m)?.[1]?.trim().replace(/^['"]|['"]$/g, "");
|
|
12
|
-
const description = frontmatter.match(/^description:\s*(.+?)\s*$/m)?.[1]?.trim().replace(/^['"]|['"]$/g, "");
|
|
13
|
-
return { name, description };
|
|
14
|
-
}
|
|
15
|
-
function readSkills(directory, source) {
|
|
16
|
-
if (!existsSync(directory))
|
|
17
|
-
return [];
|
|
18
|
-
let entries;
|
|
19
|
-
try {
|
|
20
|
-
entries = readdirSync(directory, { withFileTypes: true, encoding: "utf8" });
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
return entries.flatMap((entry) => {
|
|
26
|
-
if (!entry.isDirectory())
|
|
27
|
-
return [];
|
|
28
|
-
const skillFile = path.join(directory, entry.name, "SKILL.md");
|
|
29
|
-
if (!existsSync(skillFile))
|
|
30
|
-
return [];
|
|
31
|
-
try {
|
|
32
|
-
const metadata = parseFrontmatter(readFileSync(skillFile, "utf8"));
|
|
33
|
-
return [{
|
|
34
|
-
name: metadata.name || entry.name,
|
|
35
|
-
description: metadata.description || "",
|
|
36
|
-
source,
|
|
37
|
-
}];
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
export function listClaudeSkills(cwd) {
|
|
45
|
-
const byName = new Map();
|
|
46
|
-
for (const skill of [
|
|
47
|
-
...readSkills(path.join(os.homedir(), ".claude", "skills"), "user"),
|
|
48
|
-
...readSkills(path.join(cwd, ".claude", "skills"), "project"),
|
|
49
|
-
]) {
|
|
50
|
-
byName.set(skill.name, skill);
|
|
51
|
-
}
|
|
52
|
-
return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
53
|
-
}
|
package/dist/system-ai.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { SessionProvider, SystemAiConfig } from "./types.js";
|
|
2
|
-
export declare function normalizeSystemAiConfig(value: unknown, fallback?: SystemAiConfig): SystemAiConfig;
|
|
3
|
-
/** Copy every usable direct-API profile from the user's configured CLIs. */
|
|
4
|
-
export declare function discoverCliSystemAiConfigs(preferred?: SessionProvider, home?: string): SystemAiConfig[];
|
|
5
|
-
/** Backward-compatible first-profile discovery. */
|
|
6
|
-
export declare function discoverCliSystemAiConfig(preferred?: SessionProvider, home?: string): SystemAiConfig | null;
|
|
7
|
-
/** Return the configured API chain in call order, excluding incomplete entries. */
|
|
8
|
-
export declare function systemAiProfiles(config: SystemAiConfig | undefined, forceEnabled?: boolean): SystemAiConfig[];
|
|
9
|
-
/**
|
|
10
|
-
* Flatten and combine direct-API groups in caller-defined priority order.
|
|
11
|
-
* Later groups are appended after earlier groups and duplicate routes are skipped.
|
|
12
|
-
*/
|
|
13
|
-
export declare function mergeSystemAiConfigs(...groups: Array<SystemAiConfig | SystemAiConfig[] | undefined>): SystemAiConfig | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* 一次性 AI 请求:规则 / 角色走系统提示,内容走用户消息。
|
|
16
|
-
* 直连 API 用各协议的 system 通道;CLI 用各 provider 自己的系统提示开关
|
|
17
|
-
* (`systemPromptFlag`),没有开关的 provider 退回把规则并在内容前面。
|
|
18
|
-
*/
|
|
19
|
-
export interface AiTextRequest {
|
|
20
|
-
/** 规则、角色、输出格式。空字符串表示这次调用不需要系统提示。 */
|
|
21
|
-
system: string;
|
|
22
|
-
/** 本次要处理的内容(diff、用户原话、对话摘要…)。 */
|
|
23
|
-
prompt: string;
|
|
24
|
-
}
|
|
25
|
-
export declare function callSystemAiText(request: AiTextRequest, config: SystemAiConfig, timeoutMs?: number): Promise<string>;
|
|
26
|
-
/** Try every configured API in order. Empty responses are treated as unavailable. */
|
|
27
|
-
export declare function callSystemAiTextWithFallback(request: AiTextRequest, config: SystemAiConfig, timeoutMs?: number): Promise<string>;
|