wezard 2.6.0 → 2.6.1

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,6 +1,6 @@
1
1
  {
2
2
  "name": "wezard",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Remote-control Claude Code from WeCom via WebSocket smart bot. Cards for tool approval, skills for doc r/w.",
5
5
  "author": {
6
6
  "name": "zyy"
@@ -17,6 +17,7 @@ import { fileURLToPath } from "node:url";
17
17
  // while a `--resume` injection is in flight; Claude Code locks aren't strict.
18
18
  import { spawn } from "node:child_process";
19
19
  import { randomUUID } from "node:crypto";
20
+ import { pasteTmuxBuffer } from "./tmux-buffer.js";
20
21
  import { existsSync, readdirSync, readFileSync, statSync, watch, openSync, readSync, closeSync } from "node:fs";
21
22
  import { join, dirname } from "node:path";
22
23
  import { newStewardSpec, resumedStewardSpec } from "./steward-model.js";
@@ -1521,18 +1522,6 @@ const withImageRefs = (text, images) => {
1521
1522
  // 证人不作声 (忙时排队、slash 命令、无注册表的后端) 才看框回没回到贴之前的样子。
1522
1523
  // 框认得出来时这条判据可信, 于是允许多补回车 (空框上的回车在 CLI 里是 no-op);
1523
1524
  // 每次补之前再问一遍证人, 已提交就不补。
1524
- // tmux < 2.0 的 buffer 命令只认内部名 (bufferNNNN): 自定义名在 load/show/delete 上
1525
- // 一律 "buffer invalid" (devcloud tmux 1.8 实测, 与内容无关), 默认 buffer (不带 -b)
1526
- // 正常 —— 跨 pane 并发隔离不能靠具名 buffer。改用默认 buffer + 进程内串行: load→paste
1527
- // 这段临界区里不许第二个注入插进来, 否则共用 buffer 会让两段文本互换 pane (具名 buffer
1528
- // 防的正是这个实测坑; 守护进程单进程, 一把 promise 锁就够)。临界区只有两条 tmux 命令
1529
- // (<100ms), 串行不构成分延迟。
1530
- let pasteQueue = Promise.resolve();
1531
- const withPasteLock = (fn) => {
1532
- const r = pasteQueue.then(fn);
1533
- pasteQueue = r.then(() => undefined, () => undefined);
1534
- return r;
1535
- };
1536
1525
  const injectViaTmuxText = async (target, text, log, freshSpawn, witness = NO_WITNESS) => {
1537
1526
  // Warm pane: tight timings, low latency. Fresh spawn (claude --resume just
1538
1527
  // started, transcript still loading): extended timings — bracketed-paste
@@ -1570,20 +1559,7 @@ const injectViaTmuxText = async (target, text, log, freshSpawn, witness = NO_WIT
1570
1559
  const baseBody = alreadyTyped ? "" : preBox.body;
1571
1560
  /** 框里还是贴之前那样 (或彻底空了) = 我们的文本不在框里。 */
1572
1561
  const boxIntact = (b) => boxVerify && b.known && (b.body === "" || b.body === baseBody);
1573
- const loadAndPaste = async () => {
1574
- // stdin variant of the shared exec path — it carries the same hard timeout,
1575
- // which a hand-rolled spawn here did not.
1576
- // 默认 buffer (不带 -b) 是新旧 tmux 都支持的唯一公共形式; 隔离由 withPasteLock 保证。
1577
- return withPasteLock(async () => {
1578
- const loaded = await runTmux(["load-buffer", "-"], { stdin: text });
1579
- if (!loaded.ok)
1580
- return { ok: false, reason: `tmux load-buffer failed: ${loaded.stderr.slice(-200) || loaded.code}` };
1581
- const pasted = await runTmux(["paste-buffer", "-p", "-d", "-t", target]);
1582
- if (!pasted.ok)
1583
- return { ok: false, reason: `tmux paste-buffer failed: ${pasted.stderr.slice(-200)}` };
1584
- return { ok: true };
1585
- });
1586
- };
1562
+ const loadAndPaste = () => pasteTmuxBuffer(target, text);
1587
1563
  // 框认得出来 → 看它变没变; 认不出来 → 退回宽窗口找 headFp (长文本会换行,
1588
1564
  // 头部可能在框顶, 所以窗口要宽)。
1589
1565
  const sawLanded = async (timeoutMs) => {