@co0ontty/wand 1.63.1 → 1.64.0

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.
@@ -5,7 +5,7 @@
5
5
  import { WebSocket } from "ws";
6
6
  import { EventEmitter } from "node:events";
7
7
  import { readSessionCookie, validateSession } from "./auth.js";
8
- import { truncateMessagesForTransport } from "./message-truncator.js";
8
+ import { windowMessagesForTransport } from "./message-truncator.js";
9
9
  // ── Constants ──
10
10
  const MAX_QUEUE_SIZE = 500;
11
11
  const OUTPUT_DEBOUNCE_MS = 16;
@@ -222,9 +222,10 @@ export class WsBroadcastManager {
222
222
  * and the first incremental update.
223
223
  */
224
224
  sendInit(client, sessionId, snapshot, resync) {
225
- const truncatedMessages = snapshot.messages
226
- ? truncateMessagesForTransport(snapshot.messages, this.getCardDefaults())
227
- : undefined;
225
+ // 只下发最近 MESSAGE_WINDOW_SIZE 条 turn,附 offset/total;更早的客户端按需翻页。
226
+ const windowed = snapshot.messages
227
+ ? windowMessagesForTransport(snapshot.messages, this.getCardDefaults())
228
+ : { messages: undefined, messageOffset: 0, messageTotal: 0 };
228
229
  const seq = (client.outputSeqBySession.get(sessionId) ?? 0) + 1;
229
230
  client.outputSeqBySession.set(sessionId, seq);
230
231
  client.pendingResyncSessions.delete(sessionId);
@@ -233,10 +234,32 @@ export class WsBroadcastManager {
233
234
  sessionId,
234
235
  seq,
235
236
  ...(resync ? { resync: true } : {}),
236
- data: { ...snapshot, messages: truncatedMessages, output: snapshot.output },
237
+ data: {
238
+ ...snapshot,
239
+ messages: windowed.messages,
240
+ messageOffset: windowed.messageOffset,
241
+ messageTotal: windowed.messageTotal,
242
+ output: snapshot.output,
243
+ },
237
244
  }));
238
245
  }
239
246
  broadcast(event) {
247
+ // 非增量事件若带完整 messages(结构化 output/ended 快照、PTY 非流式 chat 快照),
248
+ // 在这个统一出口窗口化——避免逐个 emit 点各自处理、也防止超大帧撑爆移动端 WS。
249
+ // 增量事件只带 lastMessage,不含 messages 数组,不受影响。
250
+ const data = event.data;
251
+ if (data && !data.incremental && Array.isArray(data.messages)) {
252
+ const windowed = windowMessagesForTransport(data.messages, this.getCardDefaults());
253
+ event = {
254
+ ...event,
255
+ data: {
256
+ ...data,
257
+ messages: windowed.messages,
258
+ messageOffset: windowed.messageOffset,
259
+ messageTotal: windowed.messageTotal,
260
+ },
261
+ };
262
+ }
240
263
  for (const client of this.clients) {
241
264
  if (client.ws.readyState !== WebSocket.OPEN)
242
265
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.63.1",
3
+ "version": "1.64.0",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {