@co0ontty/wand 1.21.8 → 1.21.9

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.
@@ -1,5 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { spawn } from "node:child_process";
3
+ import { createRequire } from "node:module";
4
+ import { existsSync } from "node:fs";
3
5
  import { prepareSessionWorktree } from "./git-worktree.js";
4
6
  import { truncateMessagesForTransport } from "./message-truncator.js";
5
7
  function defaultStructuredRunner(provider) {
@@ -24,6 +26,47 @@ const ARCHIVE_AFTER_MS = 1000 * 60 * 60 * 24;
24
26
  function isRunningAsRoot() {
25
27
  return process.getuid?.() === 0 || process.geteuid?.() === 0;
26
28
  }
29
+ /**
30
+ * 检测当前系统是否使用 musl libc(Alpine Linux 等)。
31
+ * Node.js 进程报告中 glibcVersionRuntime 仅在 glibc 系统存在;musl 系统为 undefined。
32
+ */
33
+ function isMuslSystem() {
34
+ try {
35
+ const header = process.report?.getReport()?.header;
36
+ return !header?.glibcVersionRuntime;
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * 解析 claude-agent-sdk 应使用的 native binary 路径。
44
+ * SDK 默认在 Linux 上优先选 musl 包,但 glibc 系统(Debian/Ubuntu 等)跑不动 musl binary,
45
+ * 会抛 "Claude Code native binary not found" 错误。这里手动按 libc 类型选正确的包,
46
+ * 找不到时回退到系统 PATH 上的 `claude`。
47
+ */
48
+ function resolveSdkClaudeBinary() {
49
+ if (process.platform !== "linux")
50
+ return undefined;
51
+ const musl = isMuslSystem();
52
+ const arch = process.arch;
53
+ const require = createRequire(import.meta.url);
54
+ // 按当前 libc 类型决定优先顺序
55
+ const candidates = musl
56
+ ? [`@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`, `@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`]
57
+ : [`@anthropic-ai/claude-agent-sdk-linux-${arch}/claude`, `@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude`];
58
+ for (const pkg of candidates) {
59
+ try {
60
+ const resolved = require.resolve(pkg);
61
+ if (existsSync(resolved))
62
+ return resolved;
63
+ }
64
+ catch {
65
+ // 包不存在,继续
66
+ }
67
+ }
68
+ return undefined;
69
+ }
27
70
  /**
28
71
  * 找出最后一条 assistant turn 中尚未配对 tool_result 的 AskUserQuestion tool_use。
29
72
  * 用来识别"刚被 SIGTERM 中断、正在等用户提交答案"的状态。
@@ -1491,6 +1534,7 @@ export class StructuredSessionManager {
1491
1534
  ? "请使用中文回复。所有解释、注释和对话文本都使用中文。"
1492
1535
  : `Please respond in ${language}. Use ${language} for all your explanations, comments, and conversational text.`);
1493
1536
  }
1537
+ const sdkClaudeBinary = resolveSdkClaudeBinary();
1494
1538
  const sdkOptions = {
1495
1539
  cwd: session.cwd,
1496
1540
  abortController,
@@ -1500,6 +1544,7 @@ export class StructuredSessionManager {
1500
1544
  ...(isManaged ? { disallowedTools: ["AskUserQuestion"] } : {}),
1501
1545
  includePartialMessages: true,
1502
1546
  ...(systemPromptParts.length > 0 ? { appendSystemPrompt: systemPromptParts.join("\n\n") } : {}),
1547
+ ...(sdkClaudeBinary ? { pathToClaudeCodeExecutable: sdkClaudeBinary } : {}),
1503
1548
  };
1504
1549
  if (session.claudeSessionId)
1505
1550
  sdkOptions.resume = session.claudeSessionId;
@@ -15597,7 +15597,7 @@
15597
15597
  // ── Native Live Progress Sync ──
15598
15598
 
15599
15599
  var _progressSyncTimers = {};
15600
- var _PROGRESS_SYNC_DEBOUNCE_MS = 300;
15600
+ var _PROGRESS_SYNC_DEBOUNCE_MS = 100;
15601
15601
 
15602
15602
  // Strip markdown formatting and clamp to a single short line so the
15603
15603
  // native Live Activity / lock-screen card stays readable. 100 chars
@@ -15647,6 +15647,7 @@
15647
15647
  var todos = null;
15648
15648
  var latestUserText = "";
15649
15649
  var latestAssistantText = "";
15650
+ var recentUserTexts = [];
15650
15651
  var messages = session.messages || [];
15651
15652
  for (var i = messages.length - 1; i >= 0; i--) {
15652
15653
  var msg = messages[i];
@@ -15662,7 +15663,7 @@
15662
15663
  }
15663
15664
  }
15664
15665
 
15665
- if (!latestUserText && msg.role === "user") {
15666
+ if (msg.role === "user") {
15666
15667
  // Skip queued / synthetic placeholder turns — they don't represent
15667
15668
  // user-visible "I just asked this" prompts.
15668
15669
  var isPlaceholder = msg.content.some(function(b) { return b && b.__queued; });
@@ -15670,7 +15671,9 @@
15670
15671
  for (var ui = 0; ui < msg.content.length; ui++) {
15671
15672
  var ublock = msg.content[ui];
15672
15673
  if (ublock && ublock.type === "text" && ublock.text && ublock.text.trim()) {
15673
- latestUserText = _compactNotificationText(ublock.text);
15674
+ var utext = _compactNotificationText(ublock.text);
15675
+ if (!latestUserText) latestUserText = utext;
15676
+ if (recentUserTexts.length < 4) recentUserTexts.push(utext);
15674
15677
  break;
15675
15678
  }
15676
15679
  }
@@ -15688,8 +15691,9 @@
15688
15691
  }
15689
15692
  }
15690
15693
 
15691
- if (todos && latestUserText && latestAssistantText) break;
15694
+ if (todos && recentUserTexts.length >= 4 && latestAssistantText) break;
15692
15695
  }
15696
+ recentUserTexts.reverse();
15693
15697
 
15694
15698
  // Get current task
15695
15699
  var currentTask = "";
@@ -15703,7 +15707,8 @@
15703
15707
  currentTask: currentTask,
15704
15708
  latestUserText: latestUserText,
15705
15709
  latestAssistantText: latestAssistantText,
15706
- todos: todos || []
15710
+ todos: todos || [],
15711
+ recentUserTexts: recentUserTexts
15707
15712
  };
15708
15713
 
15709
15714
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.21.8",
3
+ "version": "1.21.9",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {