@co0ontty/wand 1.21.4 → 1.21.5

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.
@@ -35,7 +35,6 @@ export class WsBroadcastManager {
35
35
  backpressurePaused: false,
36
36
  lastOutputBySession: new Map(),
37
37
  outputSeqBySession: new Map(),
38
- droppedSinceLast: false,
39
38
  pendingResyncSessions: new Set(),
40
39
  };
41
40
  this.clients.add(client);
@@ -51,21 +50,7 @@ export class WsBroadcastManager {
51
50
  if (msg.type === "subscribe" && msg.sessionId) {
52
51
  const snapshot = getSession(msg.sessionId);
53
52
  if (snapshot) {
54
- const truncatedMessages = snapshot.messages
55
- ? truncateMessagesForTransport(snapshot.messages, this.getCardDefaults())
56
- : undefined;
57
- // Reset the per-client sequence counter for this session so the
58
- // client can detect missed output events between init and the
59
- // first incremental update.
60
- const initSeq = (client.outputSeqBySession.get(msg.sessionId) ?? 0) + 1;
61
- client.outputSeqBySession.set(msg.sessionId, initSeq);
62
- client.pendingResyncSessions.delete(msg.sessionId);
63
- ws.send(JSON.stringify({
64
- type: "init",
65
- sessionId: msg.sessionId,
66
- seq: initSeq,
67
- data: { ...snapshot, messages: truncatedMessages, output: snapshot.output },
68
- }));
53
+ this.sendInit(client, msg.sessionId, snapshot, false);
69
54
  }
70
55
  else {
71
56
  ws.send(JSON.stringify({
@@ -76,23 +61,9 @@ export class WsBroadcastManager {
76
61
  }
77
62
  }
78
63
  else if (msg.type === "resync" && msg.sessionId) {
79
- // Client noticed a gap and asks for a fresh snapshot.
80
64
  const snapshot = getSession(msg.sessionId);
81
- if (snapshot) {
82
- const truncatedMessages = snapshot.messages
83
- ? truncateMessagesForTransport(snapshot.messages, this.getCardDefaults())
84
- : undefined;
85
- const seq = (client.outputSeqBySession.get(msg.sessionId) ?? 0) + 1;
86
- client.outputSeqBySession.set(msg.sessionId, seq);
87
- client.pendingResyncSessions.delete(msg.sessionId);
88
- ws.send(JSON.stringify({
89
- type: "init",
90
- sessionId: msg.sessionId,
91
- seq,
92
- resync: true,
93
- data: { ...snapshot, messages: truncatedMessages, output: snapshot.output },
94
- }));
95
- }
65
+ if (snapshot)
66
+ this.sendInit(client, msg.sessionId, snapshot, true);
96
67
  }
97
68
  }
98
69
  catch {
@@ -145,6 +116,26 @@ export class WsBroadcastManager {
145
116
  }
146
117
  }
147
118
  // ── Internal ──
119
+ /**
120
+ * Send an init/resync snapshot to a single client. Bumps the per-session
121
+ * sequence counter so the client can detect gaps between the init payload
122
+ * and the first incremental update.
123
+ */
124
+ sendInit(client, sessionId, snapshot, resync) {
125
+ const truncatedMessages = snapshot.messages
126
+ ? truncateMessagesForTransport(snapshot.messages, this.getCardDefaults())
127
+ : undefined;
128
+ const seq = (client.outputSeqBySession.get(sessionId) ?? 0) + 1;
129
+ client.outputSeqBySession.set(sessionId, seq);
130
+ client.pendingResyncSessions.delete(sessionId);
131
+ client.ws.send(JSON.stringify({
132
+ type: "init",
133
+ sessionId,
134
+ seq,
135
+ ...(resync ? { resync: true } : {}),
136
+ data: { ...snapshot, messages: truncatedMessages, output: snapshot.output },
137
+ }));
138
+ }
148
139
  broadcast(event) {
149
140
  for (const client of this.clients) {
150
141
  if (client.ws.readyState !== WebSocket.OPEN)
@@ -162,17 +153,13 @@ export class WsBroadcastManager {
162
153
  // request a fresh snapshot once it sees the resync hint.
163
154
  if (client.sendQueue.length >= MAX_QUEUE_SIZE) {
164
155
  client.backpressurePaused = true;
165
- if (event.type === "output") {
156
+ if (event.type === "output")
166
157
  client.pendingResyncSessions.add(event.sessionId);
167
- client.droppedSinceLast = true;
168
- }
169
158
  continue;
170
159
  }
171
160
  if (client.backpressurePaused) {
172
- if (event.type === "output") {
161
+ if (event.type === "output")
173
162
  client.pendingResyncSessions.add(event.sessionId);
174
- client.droppedSinceLast = true;
175
- }
176
163
  continue;
177
164
  }
178
165
  // If we owed this session a resync notice, prepend it now that the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.21.4",
3
+ "version": "1.21.5",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,6 +33,7 @@
33
33
  "node": ">=22.5.0"
34
34
  },
35
35
  "dependencies": {
36
+ "@anthropic-ai/claude-agent-sdk": "^0.2.138",
36
37
  "@types/compression": "^1.8.1",
37
38
  "@types/cookie": "^0.6.0",
38
39
  "@types/multer": "^2.1.0",