@sickr/replay 0.9.0-beta.2 → 0.9.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.
Files changed (2) hide show
  1. package/dist/live.js +31 -1
  2. package/package.json +3 -2
package/dist/live.js CHANGED
@@ -183,9 +183,12 @@ async function sessionLoop(creds, urlid, opts) {
183
183
  tailTimer = setInterval(() => pumpNewLines(ws, offsets, opts), 500);
184
184
  });
185
185
  ws.addEventListener('message', (ev) => {
186
+ const raw = decodeWsPayload(ev.data);
187
+ if (opts.verbose)
188
+ process.stderr.write(`sickr: ws recv (${raw.length}b): ${raw.slice(0, 120)}\n`);
186
189
  let m;
187
190
  try {
188
- m = JSON.parse(typeof ev.data === 'string' ? ev.data : '{}');
191
+ m = JSON.parse(raw);
189
192
  }
190
193
  catch {
191
194
  return;
@@ -256,6 +259,33 @@ function pumpNewLines(ws, offsets, opts) {
256
259
  }
257
260
  writeOffsets(offsets);
258
261
  }
262
+ /** Decode a WebSocket `MessageEvent.data` payload into a UTF-8 string.
263
+ * The browser WebSocket gives strings for text frames; the Node `ws`
264
+ * package gives Buffers; some shims give ArrayBuffer/Uint8Array. Reading
265
+ * any of those as `typeof === 'string'` silently produces empty JSON,
266
+ * which dropped steer messages on the CLI side in 0.9.0-beta.2 (#bug6).
267
+ * Always run inbound frames through this. Exported for test coverage. */
268
+ export function decodeWsPayload(data) {
269
+ if (typeof data === 'string')
270
+ return data;
271
+ if (data == null)
272
+ return '';
273
+ // Buffer / Uint8Array / ArrayBuffer all expose toString — but ArrayBuffer's
274
+ // default toString returns "[object ArrayBuffer]", so coerce via Uint8Array.
275
+ if (data instanceof ArrayBuffer)
276
+ return Buffer.from(new Uint8Array(data)).toString('utf8');
277
+ if (ArrayBuffer.isView(data))
278
+ return Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('utf8');
279
+ if (typeof data.toString === 'function') {
280
+ try {
281
+ return data.toString('utf8');
282
+ }
283
+ catch {
284
+ return '';
285
+ }
286
+ }
287
+ return '';
288
+ }
259
289
  function isAlive(pid) {
260
290
  try {
261
291
  process.kill(pid, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sickr/replay",
3
- "version": "0.9.0-beta.2",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "npx @sickr/replay — local Claude Code audit + one-click share. The free wedge into SICKR.",
6
6
  "bin": { "replay": "dist/cli.js", "sickr": "dist/cli.js" },
@@ -9,7 +9,8 @@
9
9
  "scripts": {
10
10
  "build": "tsc",
11
11
  "test": "vitest run",
12
- "dev": "tsc -w"
12
+ "dev": "tsc -w",
13
+ "prepublishOnly": "npm run build && npm test && node scripts/pre-publish-check.mjs"
13
14
  },
14
15
  "engines": { "node": ">=20" },
15
16
  "license": "UNLICENSED",