@co0ontty/wand 4.72.2 → 4.75.0-beta.g1d477a2

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.
Files changed (101) hide show
  1. package/dist/build-info.json +4 -4
  2. package/dist/claude-sdk-runner.d.ts +2 -3
  3. package/dist/config.d.ts +1 -1
  4. package/dist/config.js +48 -0
  5. package/dist/daemon-connection.d.ts +9 -0
  6. package/dist/daemon-connection.js +86 -0
  7. package/dist/distribution-manager.d.ts +5 -0
  8. package/dist/distribution-manager.js +79 -1
  9. package/dist/git-quick-commit.js +12 -0
  10. package/dist/message-truncator.js +9 -3
  11. package/dist/models.d.ts +39 -2
  12. package/dist/models.js +302 -9
  13. package/dist/native/darwin-arm64/wand-render +0 -0
  14. package/dist/native/darwin-arm64/wand-render.sha256 +1 -0
  15. package/dist/native/darwin-arm64/wand-render.version +1 -0
  16. package/dist/native/darwin-arm64/wand-structured-renderd +0 -0
  17. package/dist/native/darwin-arm64/wand-structured-renderd.sha256 +1 -0
  18. package/dist/native/darwin-arm64/wand-structured-renderd.version +1 -0
  19. package/dist/native/darwin-x64/wand-render +0 -0
  20. package/dist/native/darwin-x64/wand-render.sha256 +1 -0
  21. package/dist/native/darwin-x64/wand-render.version +1 -0
  22. package/dist/native/darwin-x64/wand-structured-renderd +0 -0
  23. package/dist/native/darwin-x64/wand-structured-renderd.sha256 +1 -0
  24. package/dist/native/darwin-x64/wand-structured-renderd.version +1 -0
  25. package/dist/native/linux-arm64/wand-render +0 -0
  26. package/dist/native/linux-arm64/wand-render.sha256 +1 -0
  27. package/dist/native/linux-arm64/wand-render.version +1 -0
  28. package/dist/native/linux-arm64/wand-structured-renderd +0 -0
  29. package/dist/native/linux-arm64/wand-structured-renderd.sha256 +1 -0
  30. package/dist/native/linux-arm64/wand-structured-renderd.version +1 -0
  31. package/dist/native/linux-x64/wand-render +0 -0
  32. package/dist/native/linux-x64/wand-render.sha256 +1 -0
  33. package/dist/native/linux-x64/wand-render.version +1 -0
  34. package/dist/native/linux-x64/wand-structured-renderd +0 -0
  35. package/dist/native/linux-x64/wand-structured-renderd.sha256 +1 -0
  36. package/dist/native/linux-x64/wand-structured-renderd.version +1 -0
  37. package/dist/process-manager.d.ts +12 -1
  38. package/dist/process-manager.js +88 -7
  39. package/dist/pty-terminal-state.d.ts +17 -0
  40. package/dist/pty-terminal-state.js +51 -1
  41. package/dist/render-binary.d.ts +61 -0
  42. package/dist/render-binary.js +204 -0
  43. package/dist/render-daemon-client.d.ts +202 -0
  44. package/dist/render-daemon-client.js +1164 -0
  45. package/dist/render-host.d.ts +88 -0
  46. package/dist/render-host.js +440 -0
  47. package/dist/render-protocol.d.ts +128 -0
  48. package/dist/render-protocol.js +99 -0
  49. package/dist/render-structured-client.d.ts +80 -0
  50. package/dist/render-structured-client.js +513 -0
  51. package/dist/render-structured-host.d.ts +31 -0
  52. package/dist/render-structured-host.js +218 -0
  53. package/dist/render-structured-protocol.d.ts +101 -0
  54. package/dist/render-structured-protocol.js +35 -0
  55. package/dist/server-session-routes.js +114 -12
  56. package/dist/server-task-routes.js +55 -6
  57. package/dist/server-update-routes.d.ts +2 -0
  58. package/dist/server-update-routes.js +44 -0
  59. package/dist/server.js +43 -13
  60. package/dist/session-ai-context.d.ts +1 -1
  61. package/dist/session-ai-context.js +15 -4
  62. package/dist/session-logger.d.ts +2 -0
  63. package/dist/session-logger.js +44 -1
  64. package/dist/session-transport.js +1 -1
  65. package/dist/storage.d.ts +2 -1
  66. package/dist/storage.js +14 -5
  67. package/dist/structured-client-protocol.d.ts +3 -1
  68. package/dist/structured-client-protocol.js +85 -25
  69. package/dist/structured-content.d.ts +20 -3
  70. package/dist/structured-content.js +80 -1
  71. package/dist/structured-exec-host.js +7 -1
  72. package/dist/structured-exec-pump.js +6 -2
  73. package/dist/structured-grok-adapter.js +22 -0
  74. package/dist/structured-pi-adapter.js +18 -2
  75. package/dist/structured-provider-common.d.ts +11 -9
  76. package/dist/structured-provider-common.js +60 -18
  77. package/dist/structured-session-manager.d.ts +2 -0
  78. package/dist/structured-session-manager.js +27 -3
  79. package/dist/task-types.d.ts +4 -1
  80. package/dist/terminal-daemon-client.d.ts +9 -2
  81. package/dist/terminal-daemon-client.js +119 -46
  82. package/dist/terminal-daemon-server.js +47 -8
  83. package/dist/terminal-host.d.ts +6 -0
  84. package/dist/terminal-host.js +3 -0
  85. package/dist/tui/commands.js +183 -10
  86. package/dist/tui/ipc-server.js +12 -0
  87. package/dist/types.d.ts +30 -10
  88. package/dist/unix-socket-keepalive.d.ts +3 -0
  89. package/dist/unix-socket-keepalive.js +94 -0
  90. package/dist/wand-task-sync.js +2 -1
  91. package/dist/web-ui/content/scripts.js +79 -73
  92. package/dist/web-ui/content/styles.css +1 -1
  93. package/dist/web-ui/content/tailwind.css +21 -0
  94. package/dist/web-ui/embedded-assets.js +2 -2
  95. package/dist/web-ui/thinking-efforts.d.ts +24 -0
  96. package/dist/web-ui/thinking-efforts.js +81 -0
  97. package/dist/ws-broadcast.d.ts +1 -1
  98. package/dist/ws-broadcast.js +28 -9
  99. package/package.json +8 -3
  100. package/scripts/install-render-binary.js +499 -0
  101. package/scripts/stage-render-binaries.js +626 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 思考档位下拉。
3
+ *
4
+ * 旧的 off/standard/deep/max 继续表示「不覆盖 / 各 CLI 的低、中、高档」,
5
+ * CLI 新报出来的档位用 `provider:level` 存,避免和旧的 max 撞车。
6
+ */
7
+ export interface CliThinkingEffort {
8
+ effort: string;
9
+ description?: string;
10
+ }
11
+ export interface ThinkingChoice {
12
+ id: string;
13
+ /** CLI 原生档位名,例如 low / xhigh。off 档的 label 是 auto。 */
14
+ label: string;
15
+ hint: string;
16
+ }
17
+ /** 能和旧四档对上的原生档位继续用旧 id,其余写成 `provider:level`。 */
18
+ export declare function thinkingChoiceId(provider: string, native: string): string;
19
+ export declare function compactThinkingLabel(native: string): string;
20
+ /**
21
+ * 用 CLI 报出的档位生成下拉。完全没有档位时返回 null,调用方继续用旧的四档兜底。
22
+ * 模型明确只支持 off 时只保留「不覆盖」。原生 off 不重复列出。
23
+ */
24
+ export declare function dynamicThinkingChoices(provider: string, efforts: readonly CliThinkingEffort[], defaultEffort?: string): ThinkingChoice[] | null;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * 思考档位下拉。
3
+ *
4
+ * 旧的 off/standard/deep/max 继续表示「不覆盖 / 各 CLI 的低、中、高档」,
5
+ * CLI 新报出来的档位用 `provider:level` 存,避免和旧的 max 撞车。
6
+ */
7
+ const LEGACY_NATIVE = {
8
+ claude: { standard: "low", deep: "medium", max: "max" },
9
+ codex: { standard: "low", deep: "medium", max: "xhigh" },
10
+ opencode: { standard: "low", deep: "high", max: "max" },
11
+ grok: { standard: "low", deep: "high", max: "xhigh" },
12
+ qoder: { standard: "low", deep: "high", max: "max" },
13
+ pi: { standard: "low", deep: "high", max: "max" },
14
+ };
15
+ const COMPACT_LABELS = {
16
+ auto: "自动",
17
+ none: "关闭",
18
+ minimal: "最低",
19
+ low: "低",
20
+ medium: "中",
21
+ high: "高",
22
+ xhigh: "超高",
23
+ max: "极高",
24
+ ultra: "极限",
25
+ ultracode: "极限代码",
26
+ };
27
+ /** 能和旧四档对上的原生档位继续用旧 id,其余写成 `provider:level`。 */
28
+ export function thinkingChoiceId(provider, native) {
29
+ const legacy = LEGACY_NATIVE[provider];
30
+ if (legacy?.standard === native)
31
+ return "standard";
32
+ if (legacy?.deep === native)
33
+ return "deep";
34
+ if (legacy?.max === native)
35
+ return "max";
36
+ return `${provider}:${native}`;
37
+ }
38
+ export function compactThinkingLabel(native) {
39
+ return COMPACT_LABELS[native] ?? native;
40
+ }
41
+ /**
42
+ * 用 CLI 报出的档位生成下拉。完全没有档位时返回 null,调用方继续用旧的四档兜底。
43
+ * 模型明确只支持 off 时只保留「不覆盖」。原生 off 不重复列出。
44
+ */
45
+ export function dynamicThinkingChoices(provider, efforts, defaultEffort) {
46
+ const reported = efforts
47
+ .map((level) => level.effort.trim().toLowerCase())
48
+ .filter((effort) => /^[a-z][a-z0-9_-]{0,31}$/.test(effort));
49
+ if (!reported.length)
50
+ return null;
51
+ const natives = efforts
52
+ .map((level) => ({
53
+ effort: level.effort.trim().toLowerCase(),
54
+ description: level.description?.trim() || "",
55
+ }))
56
+ .filter((level) => /^[a-z][a-z0-9_-]{0,31}$/.test(level.effort) && level.effort !== "off");
57
+ if (!natives.length) {
58
+ return [{
59
+ id: "off",
60
+ label: "auto",
61
+ hint: "这个模型不能调思考深度",
62
+ }];
63
+ }
64
+ const hint = defaultEffort
65
+ ? `使用模型默认档位(${defaultEffort})`
66
+ : "使用模型默认档位";
67
+ const choices = [{ id: "off", label: "auto", hint }];
68
+ const seen = new Set(["off"]);
69
+ for (const level of natives) {
70
+ const id = thinkingChoiceId(provider, level.effort);
71
+ if (seen.has(id))
72
+ continue;
73
+ seen.add(id);
74
+ choices.push({
75
+ id,
76
+ label: level.effort,
77
+ hint: level.description || level.effort,
78
+ });
79
+ }
80
+ return choices;
81
+ }
@@ -11,7 +11,7 @@ export type { ProcessEvent } from "./types.js";
11
11
  export interface WsSessionPort {
12
12
  getSession(id: string): SessionSnapshot | null;
13
13
  getTerminalState?(id: string): PtyTerminalSnapshot | null;
14
- sendPtyInput?(id: string, input: string, shortcutKey?: string, userInput?: boolean): void;
14
+ sendPtyInput?(id: string, input: string, shortcutKey?: string, userInput?: boolean): void | Promise<void>;
15
15
  resizePty?(id: string, cols: number, rows: number): void;
16
16
  }
17
17
  export declare class WsBroadcastManager {
@@ -185,7 +185,10 @@ export class WsBroadcastManager {
185
185
  if (!client.ptySubscriptions.has(msg.sessionId) || msg.data.length > MAX_PTY_INPUT_CHARS)
186
186
  return;
187
187
  try {
188
- this.port?.sendPtyInput?.(msg.sessionId, msg.data, typeof msg.shortcutKey === "string" ? msg.shortcutKey : undefined, msg.userInput !== false);
188
+ const delivery = this.port?.sendPtyInput?.(msg.sessionId, msg.data, typeof msg.shortcutKey === "string" ? msg.shortcutKey : undefined, msg.userInput !== false);
189
+ if (delivery) {
190
+ void delivery.catch((error) => this.sendPtyError(client, msg.sessionId, error));
191
+ }
189
192
  }
190
193
  catch (error) {
191
194
  this.sendPtyError(client, msg.sessionId, error);
@@ -263,6 +266,15 @@ export class WsBroadcastManager {
263
266
  emitEvent(event) {
264
267
  if (this.disposed)
265
268
  return;
269
+ if (event.type === "resync") {
270
+ this.flushOutput(event.sessionId);
271
+ for (const client of this.clients) {
272
+ if (client.ptySubscriptions.has(event.sessionId)) {
273
+ this.queueResyncNotice(client, event.sessionId, "render_replay_gap");
274
+ }
275
+ }
276
+ return;
277
+ }
266
278
  // Debounce output events to reduce flicker during rapid streaming
267
279
  if (event.type === "output") {
268
280
  const existing = this.outputDebounceCache.get(event.sessionId);
@@ -332,20 +344,27 @@ export class WsBroadcastManager {
332
344
  * and the first incremental update.
333
345
  */
334
346
  sendInit(client, sessionId, snapshot, resync) {
335
- // 块级窗口客户端(iOS)只下发最近 blockBudget 个块;其余走 turn 级窗口。
347
+ // 块级窗口客户端(Web/iOS)只下发最近 blockBudget 个块;其余走 turn 级窗口。
336
348
  // 两种都附 offset/total,更早的客户端按需翻页。
337
- const windowed = this.windowForClient(client, snapshot.messages);
349
+ const windowed = this.windowForClient(client, sessionId, snapshot.messages);
338
350
  const seq = (client.outputSeqBySession.get(sessionId) ?? 0) + 1;
339
351
  client.outputSeqBySession.set(sessionId, seq);
340
352
  client.pendingResyncSessions.delete(sessionId);
353
+ const terminalState = (snapshot.sessionKind ?? "pty") === "pty"
354
+ ? this.port?.getTerminalState?.(sessionId) ?? undefined
355
+ : undefined;
341
356
  client.ws.send(JSON.stringify({
342
357
  type: "init",
343
358
  sessionId,
344
359
  seq,
345
360
  ...(resync ? { resync: true } : {}),
346
361
  data: {
347
- ...toSessionDetailDTO(snapshot, { output: snapshot.output, ...windowed }),
348
- terminalState: this.port?.getTerminalState?.(sessionId) ?? undefined,
362
+ ...toSessionDetailDTO(snapshot, {
363
+ output: snapshot.output,
364
+ outputLimit: terminalState ? 16_000 : undefined,
365
+ ...windowed,
366
+ }),
367
+ terminalState,
349
368
  },
350
369
  }));
351
370
  }
@@ -353,11 +372,11 @@ export class WsBroadcastManager {
353
372
  * 按客户端偏好窗口化一段完整 messages:opted-in 的块级窗口(iOS)会附带
354
373
  * leadingBlockOffset/leadingBlockTotal;否则 turn 级窗口(字段与改动前一致)。
355
374
  */
356
- windowForClient(client, messages) {
375
+ windowForClient(client, sessionId, messages) {
357
376
  if (!messages) {
358
377
  return { messages: undefined, messageOffset: 0, messageTotal: 0 };
359
378
  }
360
- messages = enrichStructuredMessages(messages);
379
+ messages = enrichStructuredMessages(messages, sessionId);
361
380
  if (client.blockBudget && client.blockBudget > 0) {
362
381
  const w = blockWindowMessagesForTransport(messages, this.getCardDefaults(), client.blockBudget);
363
382
  return {
@@ -377,7 +396,7 @@ export class WsBroadcastManager {
377
396
  // 非增量事件若带完整 messages(结构化 output/ended 快照、PTY 非流式 chat 快照),
378
397
  // 在这个统一出口窗口化——避免逐个 emit 点各自处理、也防止超大帧撑爆移动端 WS。
379
398
  // 增量事件只带 lastMessage,不含 messages 数组,不受影响。
380
- // 块级窗口客户端(iOS)需按各自预算切,所以这里改为「按客户端」窗口化;
399
+ // 块级窗口客户端(Web/iOS)需按各自预算切,所以这里改为「按客户端」窗口化;
381
400
  // turn 级(Web/Android)的结果跨客户端一致,缓存一次复用,避免重复计算。
382
401
  const boundedData = boundSessionEventData(event.data);
383
402
  const boundedEvent = boundedData === event.data ? event : { ...event, data: boundedData };
@@ -397,7 +416,7 @@ export class WsBroadcastManager {
397
416
  if (client.blockBudget && client.blockBudget > 0) {
398
417
  return {
399
418
  ...boundedEvent,
400
- data: { ...data, ...this.windowForClient(client, rawMessages) },
419
+ data: { ...data, ...this.windowForClient(client, event.sessionId, rawMessages) },
401
420
  };
402
421
  }
403
422
  if (!turnWindowedEvent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "4.72.2",
3
+ "version": "4.75.0-beta.g1d477a2",
4
4
  "description": "A web console for Claude Code, Codex, OpenCode, and other local CLI tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,13 +13,18 @@
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
- "browser-extension"
16
+ "browser-extension",
17
+ "scripts/install-render-binary.js",
18
+ "scripts/stage-render-binaries.js"
17
19
  ],
18
20
  "preferGlobal": true,
19
21
  "scripts": {
20
22
  "generate:web-assets": "node scripts/generate-web-assets.js",
21
- "build": "rm -rf dist && node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/check-bundle-budget.js && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
23
+ "build": "rm -rf dist && node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/check-bundle-budget.js && (npm run build:render-bin || echo '[wand] WARNING: build:render-bin failed; dist/native/ has no wand-render (run: npm run build:render-bin)' >&2) && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
22
24
  "build:copy-content": "cp -r src/web-ui/content dist/web-ui/ && node scripts/minify-dist-content.js",
25
+ "build:render-bin": "node scripts/stage-render-binaries.js --all",
26
+ "build:render-native": "cargo build --release --manifest-path render/Cargo.toml -p wand-renderd",
27
+ "build:structured-render-native": "cargo build --release --manifest-path render/Cargo.toml -p wand-structured-renderd",
23
28
  "dev": "node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-browser.js --development && npm run generate:web-assets && tsx src/cli.ts web",
24
29
  "check": "node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p tsconfig.react.json",
25
30
  "test": "node --test --import tsx tests/*.test.ts",