@staff0rd/assist 0.326.0 → 0.327.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 (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +66 -38
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -277,6 +277,7 @@ From WSL, the selector can also surface and drive Windows-host repos (requires `
277
277
 
278
278
  - `sessions.windowsProjectsRoot` — the Windows `.claude/projects` directory as seen from WSL (e.g. `/mnt/c/Users/<user>/.claude/projects`); enables discovery of Windows-host repos, tagged with a `Windows` badge. Selecting one launches a native assist daemon on Windows and runs an interactive session there.
279
279
  - `sessions.windowsDaemonHost` / `sessions.windowsDaemonPort` — where the WSL daemon reaches the native Windows daemon (defaults `127.0.0.1` / `51764`; set the host to the Windows IP on WSL2 NAT-mode networking).
280
+ - `sessions.windowsVersionCheck` — how the WSL↔Windows daemon handshake reacts to a protocol-version mismatch: `block` (default) refuses creates and auto-heals the host, `warn` logs and proceeds anyway, `off` skips the check. Use `warn`/`off` to keep working across an unfixable version gap.
280
281
 
281
282
  When iterating on assist itself: web server changes only need the `assist sessions` process restarted — sessions survive. Daemon/session-core changes need `assist daemon restart` to load the new code; this kills the PTYs, then claude sessions — including assist sessions that wrap claude, like `assist draft` — are auto-respawned via `claude --resume` with scrollback starting fresh, while run sessions (and assist sessions whose claude sessionId was never discovered) reappear as not-restored tiles that can be retried.
282
283
 
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.326.0",
9
+ version: "0.327.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -285,7 +285,8 @@ var assistConfigSchema = z2.strictObject({
285
285
  // why: host the WSL daemon dials to reach the native Windows daemon over TCP (WSL can't use the Windows named pipe); defaults to 127.0.0.1 (WSL2 mirrored networking). NAT-mode users set the Windows host IP.
286
286
  windowsDaemonHost: z2.string().optional(),
287
287
  // why: TCP port the native Windows daemon listens on for the WSL bridge; defaults to 51764
288
- windowsDaemonPort: z2.number().optional()
288
+ windowsDaemonPort: z2.number().optional(),
289
+ windowsVersionCheck: z2.enum(["block", "warn", "off"]).default("block")
289
290
  }).optional(),
290
291
  database: z2.strictObject({
291
292
  url: z2.string().optional()
@@ -6654,8 +6655,10 @@ async function connect2() {
6654
6655
  await ensureDaemonRunning("web log stream");
6655
6656
  const socket = await connectToDaemon();
6656
6657
  wire(socket);
6657
- socket.write(`${JSON.stringify({ type: "subscribe-logs" })}
6658
- `);
6658
+ socket.write(
6659
+ `${JSON.stringify({ type: "subscribe-logs", replay: false })}
6660
+ `
6661
+ );
6659
6662
  } catch {
6660
6663
  scheduleReconnect();
6661
6664
  }
@@ -20579,9 +20582,11 @@ var ClientHub = class extends Set {
20579
20582
  sendTo(client, { type: "limits", rateLimits: this.latestLimits });
20580
20583
  }
20581
20584
  }
20582
- subscribeLogs(client) {
20583
- for (const line of recentDaemonLogLines()) {
20584
- sendTo(client, { type: "log", line });
20585
+ subscribeLogs(client, replay = true) {
20586
+ if (replay) {
20587
+ for (const line of recentDaemonLogLines()) {
20588
+ sendTo(client, { type: "log", line });
20589
+ }
20585
20590
  }
20586
20591
  this.logSubscribers.add(client);
20587
20592
  }
@@ -21338,18 +21343,6 @@ function stripOutboundSessionId(data) {
21338
21343
  return { ...data, sessionId: stripWindowsSessionId(data.sessionId) };
21339
21344
  }
21340
21345
 
21341
- // src/commands/sessions/daemon/buildHello.ts
21342
- var ASSIST_VERSION = package_default.version;
21343
- function buildHello() {
21344
- return { type: "hello", version: ASSIST_VERSION };
21345
- }
21346
- function isHello(msg) {
21347
- return msg.type === "hello" && typeof msg.version === "string";
21348
- }
21349
- function versionsMatch(a, b) {
21350
- return a === b;
21351
- }
21352
-
21353
21346
  // src/commands/sessions/daemon/WindowsProxyState.ts
21354
21347
  var MAX_SCROLLBACK2 = 256 * 1024;
21355
21348
  var DEFAULT_CREATE_TIMEOUT_MS = 5e3;
@@ -21395,6 +21388,59 @@ function appendScrollback2(state, sessionId, data) {
21395
21388
  );
21396
21389
  }
21397
21390
 
21391
+ // src/commands/sessions/daemon/handleSessions.ts
21392
+ function handleSessions(state, msg) {
21393
+ state.windowsSessions = msg.sessions.map((s) => ({
21394
+ ...s,
21395
+ id: toWindowsSessionId(s.id)
21396
+ }));
21397
+ const live = new Set(state.windowsSessions.map((s) => s.id));
21398
+ for (const id2 of state.scrollback.keys())
21399
+ if (!live.has(id2)) state.scrollback.delete(id2);
21400
+ state.onSessionsChanged();
21401
+ }
21402
+
21403
+ // src/commands/sessions/daemon/buildHello.ts
21404
+ var ASSIST_VERSION = package_default.version;
21405
+ var PROTOCOL_VERSION = 1;
21406
+ function buildHello() {
21407
+ return { type: "hello", version: ASSIST_VERSION, protocol: PROTOCOL_VERSION };
21408
+ }
21409
+ function isHello(msg) {
21410
+ return msg.type === "hello" && typeof msg.version === "string" && (msg.protocol === void 0 || typeof msg.protocol === "number");
21411
+ }
21412
+ function helloCompatible(msg) {
21413
+ if (typeof msg.protocol === "number")
21414
+ return msg.protocol === PROTOCOL_VERSION;
21415
+ return msg.version === ASSIST_VERSION;
21416
+ }
21417
+
21418
+ // src/commands/sessions/daemon/windowsVersionCheck.ts
21419
+ function windowsVersionCheck() {
21420
+ return loadConfig().sessions?.windowsVersionCheck ?? "block";
21421
+ }
21422
+
21423
+ // src/commands/sessions/daemon/handleHello.ts
21424
+ function handleHello(state, msg) {
21425
+ if (!isHello(msg) || helloCompatible(msg)) return;
21426
+ const mode = windowsVersionCheck();
21427
+ const detail = `protocol ${msg.protocol ?? "legacy"} version ${msg.version} (wsl protocol ${PROTOCOL_VERSION} version ${ASSIST_VERSION})`;
21428
+ if (mode === "off") {
21429
+ daemonLog(
21430
+ `windows daemon protocol mismatch: ${detail}; check disabled (sessions.windowsVersionCheck=off), proceeding`
21431
+ );
21432
+ return;
21433
+ }
21434
+ if (mode === "warn") {
21435
+ daemonLog(
21436
+ `windows daemon protocol mismatch: ${detail}; proceeding with warning (sessions.windowsVersionCheck=warn)`
21437
+ );
21438
+ return;
21439
+ }
21440
+ daemonLog(`windows daemon protocol mismatch: ${detail}`);
21441
+ state.onVersionMismatch(msg.version);
21442
+ }
21443
+
21398
21444
  // src/commands/sessions/daemon/handleInbound.ts
21399
21445
  function handleInbound(state, line) {
21400
21446
  let msg;
@@ -21420,14 +21466,6 @@ var inbound = {
21420
21466
  state.broadcast(msg);
21421
21467
  }
21422
21468
  };
21423
- function handleHello(state, msg) {
21424
- if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION)) {
21425
- daemonLog(
21426
- `windows daemon version mismatch: ${msg.version} (wsl ${ASSIST_VERSION})`
21427
- );
21428
- state.onVersionMismatch(msg.version);
21429
- }
21430
- }
21431
21469
  function handleCreated(state, msg) {
21432
21470
  daemonLog(`windows daemon: created session ${nsId(msg)}`);
21433
21471
  const client = takePendingCreator(state);
@@ -21439,16 +21477,6 @@ function handleCreated(state, msg) {
21439
21477
  });
21440
21478
  else daemonLog("windows daemon: created with no pending creator (dropped)");
21441
21479
  }
21442
- function handleSessions(state, msg) {
21443
- state.windowsSessions = msg.sessions.map((s) => ({
21444
- ...s,
21445
- id: toWindowsSessionId(s.id)
21446
- }));
21447
- const live = new Set(state.windowsSessions.map((s) => s.id));
21448
- for (const id2 of state.scrollback.keys())
21449
- if (!live.has(id2)) state.scrollback.delete(id2);
21450
- state.onSessionsChanged();
21451
- }
21452
21480
  function handleOutput(state, msg) {
21453
21481
  const sessionId = nsId(msg);
21454
21482
  const data = msg.data;
@@ -22198,7 +22226,7 @@ function routed(local) {
22198
22226
  }
22199
22227
  var messageHandlers = {
22200
22228
  ping: (client) => sendTo(client, { type: "pong", pid: process.pid }),
22201
- "subscribe-logs": (client, m) => m.clients.subscribeLogs(client),
22229
+ "subscribe-logs": (client, m, d) => m.clients.subscribeLogs(client, d.replay !== false),
22202
22230
  hello: (client) => sendTo(client, buildHello()),
22203
22231
  create: creator(
22204
22232
  true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.326.0",
3
+ "version": "0.327.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {