@staff0rd/assist 0.284.1 → 0.285.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 +4 -0
  2. package/dist/index.js +390 -65
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -253,6 +253,10 @@ The first backlog command in a repository that still has a local `.assist/backlo
253
253
 
254
254
  Web sessions are owned by a long-lived daemon process, not the web server: the server is a thin client that relays WebSocket traffic to the daemon over a local IPC socket (unix domain socket at `~/.assist/daemon/daemon.sock`; named pipe `\\.\pipe\assist-sessions-daemon` on Windows). Restarting the web server leaves sessions running with scrollback intact. The daemon logs to `~/.assist/daemon/daemon.log` (timestamped lines tagged with the daemon's pid, including why it spawned and which sessions it restored) and auto-exits once no sessions remain and no client has been connected for 60 seconds (it is respawned on demand by the web server). Daemon spawning is arbitrated by an `O_EXCL` lockfile so racing clients start at most one daemon; sessions are only restored after the daemon owns the IPC socket, and a daemon that loses ownership of `daemon.pid` shuts down its sessions and exits rather than running orphaned.
255
255
 
256
+ Set `sessions.windowsProjectsRoot` in config to the Windows `.claude/projects` directory as seen from WSL (e.g. `/mnt/c/Users/<user>/.claude/projects`) to surface Windows-host repos in the selector. Their transcripts are discovered alongside local ones and tagged as windows-origin (the project name is derived with Windows path rules so `C:\…` cwds name correctly).
257
+
258
+ Selecting a windows-origin repo (cwd like `C:\…`) from the WSL UI runs an interactive session natively on Windows: the WSL daemon launches a second assist daemon on the Windows host on demand via interop (`cmd.exe /c start "" assist daemon run`), connects to it over TCP (the WSL daemon cannot reach the Windows named pipe directly), and proxies create/resume and I/O to the Windows daemon's native PTY. Windows sessions appear in the same list as local ones (their ids are namespaced internally to avoid collisions) with live output, scrollback, and resume. The TCP connection performs a version handshake on connect; a mismatch is logged (auto-healing comes later). A native Windows daemon listens for the WSL bridge on `sessions.windowsDaemonPort` (default `51764`); the WSL daemon dials `sessions.windowsDaemonHost` (default `127.0.0.1`, which works under WSL2 mirrored networking — NAT-mode setups should set it to the Windows host IP).
259
+
256
260
  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.
257
261
  - `assist next [id] [--once]` - Alias for `backlog next [id]`; `--once` exits after the first completed item run instead of prompting for another
258
262
  - `assist draft [description] [--once]` (alias: `feat`) - Launch Claude in `/draft` mode, chain into next on `/next` signal; an optional `description` is forwarded as `/draft <description>`; `--once` exits when the done signal arrives after the initial draft completes
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.284.1",
9
+ version: "0.285.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -275,6 +275,14 @@ var assistConfigSchema = z2.strictObject({
275
275
  screenshot: z2.strictObject({
276
276
  outputDir: z2.string().default("./screenshots")
277
277
  }).default({ outputDir: "./screenshots" }),
278
+ sessions: z2.strictObject({
279
+ // why: Windows .claude/projects root as seen from WSL (e.g. /mnt/c/Users/<user>/.claude/projects); when set its transcripts are discovered and tagged windows-origin
280
+ windowsProjectsRoot: z2.string().optional(),
281
+ // 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.
282
+ windowsDaemonHost: z2.string().optional(),
283
+ // why: TCP port the native Windows daemon listens on for the WSL bridge; defaults to 51764
284
+ windowsDaemonPort: z2.number().optional()
285
+ }).optional(),
278
286
  backlog: z2.strictObject({
279
287
  databaseUrl: z2.string().optional()
280
288
  }).default({}),
@@ -12069,10 +12077,10 @@ async function getAccessToken(apiKey) {
12069
12077
  }
12070
12078
  });
12071
12079
  if (!response.ok) {
12072
- const errorText = await response.text();
12080
+ const errorText2 = await response.text();
12073
12081
  throw new Error(
12074
12082
  `Failed to get access token: ${response.status} ${response.statusText}
12075
- ${errorText}`
12083
+ ${errorText2}`
12076
12084
  );
12077
12085
  }
12078
12086
  const tokenData = await response.json();
@@ -18100,11 +18108,11 @@ function toSessionInfo({
18100
18108
  }
18101
18109
 
18102
18110
  // src/commands/sessions/daemon/broadcastSessions.ts
18103
- function broadcastSessions(sessions, clients) {
18111
+ function broadcastSessions(sessions, clients, windowsSessions = []) {
18104
18112
  persistLiveSessions(sessions);
18105
18113
  broadcast(clients, {
18106
18114
  type: "sessions",
18107
- sessions: [...sessions.values()].map(toSessionInfo)
18115
+ sessions: [...sessions.values()].map(toSessionInfo).concat(windowsSessions)
18108
18116
  });
18109
18117
  }
18110
18118
 
@@ -18228,9 +18236,10 @@ function replayScrollback(sessions, client) {
18228
18236
  }
18229
18237
 
18230
18238
  // src/commands/sessions/daemon/greetClient.ts
18231
- function greetClient(client, sessions, list4) {
18239
+ function greetClient(client, sessions, list4, windowsProxy) {
18232
18240
  sendTo(client, { type: "sessions", sessions: list4() });
18233
18241
  replayScrollback(sessions, client);
18242
+ windowsProxy.replayScrollback(client);
18234
18243
  }
18235
18244
 
18236
18245
  // src/commands/sessions/daemon/shouldAutoDismiss.ts
@@ -18470,6 +18479,308 @@ function shutdownSessions(sessions) {
18470
18479
  }
18471
18480
  }
18472
18481
 
18482
+ // src/commands/sessions/daemon/connectToWindowsDaemon.ts
18483
+ import * as net2 from "net";
18484
+
18485
+ // src/commands/sessions/daemon/windowsDaemonPort.ts
18486
+ var DEFAULT_PORT = 51764;
18487
+ var DEFAULT_HOST = "127.0.0.1";
18488
+ function windowsDaemonPort() {
18489
+ return loadConfig().sessions?.windowsDaemonPort ?? DEFAULT_PORT;
18490
+ }
18491
+ function windowsDaemonHost() {
18492
+ return loadConfig().sessions?.windowsDaemonHost ?? DEFAULT_HOST;
18493
+ }
18494
+
18495
+ // src/commands/sessions/daemon/connectToWindowsDaemon.ts
18496
+ function connectToWindowsDaemon() {
18497
+ return new Promise((resolve16, reject) => {
18498
+ const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
18499
+ socket.once("connect", () => resolve16(socket));
18500
+ socket.once("error", reject);
18501
+ });
18502
+ }
18503
+ async function isWindowsDaemonRunning() {
18504
+ try {
18505
+ (await connectToWindowsDaemon()).destroy();
18506
+ return true;
18507
+ } catch {
18508
+ return false;
18509
+ }
18510
+ }
18511
+
18512
+ // src/commands/sessions/daemon/ensureWindowsDaemonRunning.ts
18513
+ import { spawn as spawn10 } from "child_process";
18514
+ var SPAWN_TIMEOUT_MS2 = 3e4;
18515
+ var RETRY_DELAY_MS2 = 300;
18516
+ async function ensureWindowsDaemonRunning() {
18517
+ if (await isWindowsDaemonRunning()) return;
18518
+ launchWindowsDaemon();
18519
+ await waitForWindowsDaemon();
18520
+ }
18521
+ function launchWindowsDaemon() {
18522
+ const child = spawn10(
18523
+ "cmd.exe",
18524
+ ["/c", "start", "", "assist", "daemon", "run"],
18525
+ { detached: true, stdio: "ignore" }
18526
+ );
18527
+ child.on(
18528
+ "error",
18529
+ (e) => daemonLog(`failed to launch windows daemon: ${e.message}`)
18530
+ );
18531
+ child.unref();
18532
+ }
18533
+ async function waitForWindowsDaemon() {
18534
+ const deadline = Date.now() + SPAWN_TIMEOUT_MS2;
18535
+ while (Date.now() < deadline) {
18536
+ await delay2(RETRY_DELAY_MS2);
18537
+ if (await isWindowsDaemonRunning()) return;
18538
+ }
18539
+ throw new Error(
18540
+ "Windows daemon did not start; is assist installed on the Windows host?"
18541
+ );
18542
+ }
18543
+ function delay2(ms) {
18544
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
18545
+ }
18546
+
18547
+ // src/commands/sessions/daemon/buildHello.ts
18548
+ var ASSIST_VERSION = package_default.version;
18549
+ function buildHello() {
18550
+ return { type: "hello", version: ASSIST_VERSION };
18551
+ }
18552
+ function isHello(msg) {
18553
+ return msg.type === "hello" && typeof msg.version === "string";
18554
+ }
18555
+ function versionsMatch(a, b) {
18556
+ return a === b;
18557
+ }
18558
+
18559
+ // src/commands/sessions/daemon/toWindowsSessionId.ts
18560
+ var PREFIX = "w-";
18561
+ function toWindowsSessionId(id) {
18562
+ return `${PREFIX}${id}`;
18563
+ }
18564
+ function isWindowsSessionId(id) {
18565
+ return id.startsWith(PREFIX);
18566
+ }
18567
+ function stripWindowsSessionId(id) {
18568
+ return id.startsWith(PREFIX) ? id.slice(PREFIX.length) : id;
18569
+ }
18570
+
18571
+ // src/commands/sessions/daemon/WindowsProxyState.ts
18572
+ var MAX_SCROLLBACK2 = 256 * 1024;
18573
+ function createState(broadcast2, onSessionsChanged) {
18574
+ return {
18575
+ windowsSessions: [],
18576
+ scrollback: /* @__PURE__ */ new Map(),
18577
+ pendingCreators: [],
18578
+ broadcast: broadcast2,
18579
+ onSessionsChanged
18580
+ };
18581
+ }
18582
+ function resetState(state) {
18583
+ state.windowsSessions = [];
18584
+ state.scrollback.clear();
18585
+ state.pendingCreators = [];
18586
+ }
18587
+ function replayScrollback2(state, client) {
18588
+ for (const [sessionId, data] of state.scrollback)
18589
+ if (data) sendTo(client, { type: "output", sessionId, data });
18590
+ }
18591
+ function appendScrollback2(state, sessionId, data) {
18592
+ const next3 = (state.scrollback.get(sessionId) ?? "") + data;
18593
+ state.scrollback.set(
18594
+ sessionId,
18595
+ next3.length > MAX_SCROLLBACK2 ? next3.slice(-MAX_SCROLLBACK2) : next3
18596
+ );
18597
+ }
18598
+
18599
+ // src/commands/sessions/daemon/handleInbound.ts
18600
+ function handleInbound(state, line) {
18601
+ let msg;
18602
+ try {
18603
+ msg = JSON.parse(line);
18604
+ } catch {
18605
+ return;
18606
+ }
18607
+ inbound[msg.type]?.(state, msg);
18608
+ }
18609
+ var inbound = {
18610
+ hello: (_state, msg) => handleHello(msg),
18611
+ created: handleCreated,
18612
+ sessions: handleSessions,
18613
+ output: handleOutput,
18614
+ clear: relayWithSessionId,
18615
+ error: (state, msg) => state.broadcast(msg)
18616
+ };
18617
+ function handleHello(msg) {
18618
+ if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION))
18619
+ daemonLog(
18620
+ `windows daemon version mismatch: ${msg.version} (wsl ${ASSIST_VERSION})`
18621
+ );
18622
+ }
18623
+ function handleCreated(state, msg) {
18624
+ const client = state.pendingCreators.shift();
18625
+ if (client) sendTo(client, { type: "created", sessionId: nsId(msg) });
18626
+ }
18627
+ function handleSessions(state, msg) {
18628
+ state.windowsSessions = msg.sessions.map((s) => ({
18629
+ ...s,
18630
+ id: toWindowsSessionId(s.id)
18631
+ }));
18632
+ const live = new Set(state.windowsSessions.map((s) => s.id));
18633
+ for (const id of state.scrollback.keys())
18634
+ if (!live.has(id)) state.scrollback.delete(id);
18635
+ state.onSessionsChanged();
18636
+ }
18637
+ function handleOutput(state, msg) {
18638
+ const sessionId = nsId(msg);
18639
+ const data = msg.data;
18640
+ appendScrollback2(state, sessionId, data);
18641
+ state.broadcast({ type: "output", sessionId, data });
18642
+ }
18643
+ function relayWithSessionId(state, msg) {
18644
+ state.broadcast({ ...msg, sessionId: nsId(msg) });
18645
+ }
18646
+ function nsId(msg) {
18647
+ return toWindowsSessionId(msg.sessionId);
18648
+ }
18649
+
18650
+ // src/commands/sessions/daemon/isWindowsCwd.ts
18651
+ function isWindowsCwd(cwd) {
18652
+ return /^[A-Za-z]:[\\/]/.test(cwd);
18653
+ }
18654
+ function shouldProxyToWindows(cwd) {
18655
+ return detectPlatform() === "wsl" && isWindowsCwd(cwd);
18656
+ }
18657
+
18658
+ // src/commands/sessions/daemon/WindowsConnection.ts
18659
+ import { createInterface as createInterface5 } from "readline";
18660
+ var WindowsConnection = class {
18661
+ constructor(deps2) {
18662
+ this.deps = deps2;
18663
+ }
18664
+ connection = null;
18665
+ socket = null;
18666
+ ensure() {
18667
+ if (this.connection) return this.connection;
18668
+ const connection = this.open();
18669
+ this.connection = connection;
18670
+ connection.catch(() => {
18671
+ if (this.connection === connection) this.connection = null;
18672
+ });
18673
+ return connection;
18674
+ }
18675
+ write(msg) {
18676
+ this.socket?.write(`${JSON.stringify(msg)}
18677
+ `);
18678
+ }
18679
+ trySend(msg) {
18680
+ if (!this.socket?.writable) return false;
18681
+ this.write(msg);
18682
+ return true;
18683
+ }
18684
+ dispose() {
18685
+ this.socket?.destroy();
18686
+ this.reset();
18687
+ }
18688
+ async open() {
18689
+ const socket = await this.deps.connect();
18690
+ this.socket = socket;
18691
+ const lines = createInterface5({ input: socket });
18692
+ lines.on("error", () => {
18693
+ });
18694
+ lines.on("line", (line) => this.deps.onLine(line));
18695
+ socket.on("error", () => {
18696
+ });
18697
+ socket.on("close", () => {
18698
+ this.reset();
18699
+ this.deps.onClose();
18700
+ });
18701
+ this.write(buildHello());
18702
+ return socket;
18703
+ }
18704
+ reset() {
18705
+ this.socket = null;
18706
+ this.connection = null;
18707
+ }
18708
+ };
18709
+
18710
+ // src/commands/sessions/daemon/WindowsProxy.ts
18711
+ var WindowsProxy = class {
18712
+ state;
18713
+ conn;
18714
+ constructor(clients, onSessionsChanged, connect3 = defaultConnect) {
18715
+ this.state = createState(
18716
+ (msg) => broadcast(clients, msg),
18717
+ onSessionsChanged
18718
+ );
18719
+ this.conn = new WindowsConnection({
18720
+ connect: connect3,
18721
+ onLine: (line) => handleInbound(this.state, line),
18722
+ onClose: () => this.handleClose()
18723
+ });
18724
+ }
18725
+ sessions() {
18726
+ return this.state.windowsSessions;
18727
+ }
18728
+ replayScrollback(client) {
18729
+ replayScrollback2(this.state, client);
18730
+ }
18731
+ // Returns true when the message targets Windows: a create/resume in a
18732
+ // windows-origin cwd is forwarded, as is I/O for a namespaced session id.
18733
+ route(client, data) {
18734
+ if (isWindowsCreate(data)) {
18735
+ void this.forwardCreate(client, data);
18736
+ return true;
18737
+ }
18738
+ if (isWindowsIo(data)) {
18739
+ const sessionId = stripWindowsSessionId(data.sessionId);
18740
+ this.conn.trySend({ ...data, sessionId });
18741
+ return true;
18742
+ }
18743
+ return false;
18744
+ }
18745
+ dispose() {
18746
+ this.conn.dispose();
18747
+ }
18748
+ async forwardCreate(client, data) {
18749
+ try {
18750
+ await this.conn.ensure();
18751
+ this.state.pendingCreators.push(client);
18752
+ this.conn.write(data);
18753
+ } catch (e) {
18754
+ sendTo(client, {
18755
+ type: "error",
18756
+ message: `Windows session unavailable: ${errorText(e)}`
18757
+ });
18758
+ }
18759
+ }
18760
+ handleClose() {
18761
+ for (const client of this.state.pendingCreators)
18762
+ sendTo(client, {
18763
+ type: "error",
18764
+ message: "Windows daemon connection closed"
18765
+ });
18766
+ resetState(this.state);
18767
+ this.state.onSessionsChanged();
18768
+ }
18769
+ };
18770
+ function isWindowsCreate(data) {
18771
+ return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
18772
+ }
18773
+ function isWindowsIo(data) {
18774
+ return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
18775
+ }
18776
+ async function defaultConnect() {
18777
+ await ensureWindowsDaemonRunning();
18778
+ return connectToWindowsDaemon();
18779
+ }
18780
+ function errorText(e) {
18781
+ return e instanceof Error ? e.message : String(e);
18782
+ }
18783
+
18473
18784
  // src/commands/sessions/daemon/watchClaudeSessionId.ts
18474
18785
  import * as fs27 from "fs";
18475
18786
  import * as path48 from "path";
@@ -18753,10 +19064,12 @@ var SessionManager = class {
18753
19064
  clients = /* @__PURE__ */ new Set();
18754
19065
  nextId = 1;
18755
19066
  shuttingDown = false;
19067
+ // why: dispatch calls windowsProxy.route() to forward windows-origin sessions
19068
+ windowsProxy = new WindowsProxy(this.clients, () => this.notify());
18756
19069
  addClient(client) {
18757
19070
  this.clients.add(client);
18758
19071
  this.onIdleChange?.(this.isIdle());
18759
- greetClient(client, this.sessions, () => this.listSessions());
19072
+ greetClient(client, this.sessions, this.listSessions, this.windowsProxy);
18760
19073
  }
18761
19074
  removeClient(client) {
18762
19075
  this.clients.delete(client);
@@ -18825,22 +19138,24 @@ var SessionManager = class {
18825
19138
  setAutoAdvance(id, enabled) {
18826
19139
  if (setAutoAdvance(this.sessions, id, enabled)) this.notify();
18827
19140
  }
18828
- listSessions() {
18829
- return [...this.sessions.values()].map(toSessionInfo);
18830
- }
19141
+ listSessions = () => {
19142
+ const local = [...this.sessions.values()].map(toSessionInfo);
19143
+ return local.concat(this.windowsProxy.sessions());
19144
+ };
18831
19145
  notify = () => {
18832
19146
  if (this.shuttingDown) return;
18833
- broadcastSessions(this.sessions, this.clients);
19147
+ const windows = this.windowsProxy.sessions();
19148
+ broadcastSessions(this.sessions, this.clients, windows);
18834
19149
  this.onIdleChange?.(this.isIdle());
18835
19150
  };
18836
19151
  };
18837
19152
 
18838
19153
  // src/commands/sessions/daemon/startDaemonServer.ts
18839
19154
  import { unlinkSync as unlinkSync19 } from "fs";
18840
- import * as net2 from "net";
19155
+ import * as net3 from "net";
18841
19156
 
18842
19157
  // src/commands/sessions/daemon/handleConnection.ts
18843
- import { createInterface as createInterface5 } from "readline";
19158
+ import { createInterface as createInterface6 } from "readline";
18844
19159
 
18845
19160
  // src/commands/sessions/shared/parseTranscript.ts
18846
19161
  import * as fs28 from "fs";
@@ -18932,46 +19247,11 @@ function safeParse2(line) {
18932
19247
  }
18933
19248
 
18934
19249
  // src/commands/sessions/daemon/dispatchMessage.ts
18935
- function sendCreated(client, id) {
18936
- sendTo(client, { type: "created", sessionId: id });
18937
- }
18938
- function handleCreate(client, manager, data) {
18939
- sendCreated(
18940
- client,
18941
- manager.spawn(
18942
- data.prompt,
18943
- data.cwd
18944
- )
18945
- );
18946
- }
18947
- function handleCreateRun(client, manager, data) {
18948
- sendCreated(
18949
- client,
18950
- manager.spawnRun(
18951
- data.runName,
18952
- data.runArgs ?? [],
18953
- data.cwd
18954
- )
18955
- );
18956
- }
18957
- function handleCreateAssist(client, manager, data) {
18958
- sendCreated(
18959
- client,
18960
- manager.spawnAssist(
18961
- data.assistArgs ?? [],
18962
- data.cwd
18963
- )
18964
- );
18965
- }
18966
- function handleResume(client, manager, data) {
18967
- sendCreated(
18968
- client,
18969
- manager.resume(
18970
- data.sessionId,
18971
- data.cwd,
18972
- data.name
18973
- )
18974
- );
19250
+ function creator(spawn11) {
19251
+ return (client, m, d) => {
19252
+ if (m.windowsProxy.route(client, d)) return;
19253
+ sendTo(client, { type: "created", sessionId: spawn11(m, d) });
19254
+ };
18975
19255
  }
18976
19256
  function handleHistory(client) {
18977
19257
  discoverSessions().then(
@@ -18989,21 +19269,54 @@ function handleShutdown(client, manager) {
18989
19269
  sendTo(client, { type: "shutting-down" });
18990
19270
  setImmediate(() => process.exit(0));
18991
19271
  }
19272
+ function routed(local) {
19273
+ return (client, m, d) => {
19274
+ if (!m.windowsProxy.route(client, d)) local(client, m, d);
19275
+ };
19276
+ }
18992
19277
  var handlers = {
18993
19278
  ping: (client) => sendTo(client, { type: "pong", pid: process.pid }),
18994
- create: handleCreate,
18995
- "create-run": handleCreateRun,
18996
- "create-assist": handleCreateAssist,
18997
- resume: handleResume,
19279
+ hello: (client) => sendTo(client, buildHello()),
19280
+ create: creator(
19281
+ (m, d) => m.spawn(d.prompt, d.cwd)
19282
+ ),
19283
+ "create-run": creator(
19284
+ (m, d) => m.spawnRun(
19285
+ d.runName,
19286
+ d.runArgs ?? [],
19287
+ d.cwd
19288
+ )
19289
+ ),
19290
+ "create-assist": creator(
19291
+ (m, d) => m.spawnAssist(
19292
+ d.assistArgs ?? [],
19293
+ d.cwd
19294
+ )
19295
+ ),
19296
+ resume: creator(
19297
+ (m, d) => m.resume(
19298
+ d.sessionId,
19299
+ d.cwd,
19300
+ d.name
19301
+ )
19302
+ ),
18998
19303
  history: handleHistory,
18999
19304
  "fetch-transcript": handleFetchTranscript,
19000
19305
  shutdown: handleShutdown,
19001
- input: (_client, m, d) => m.writeToSession(d.sessionId, d.data),
19002
- resize: (_client, m, d) => m.resizeSession(d.sessionId, d.cols, d.rows),
19003
- retry: (_client, m, d) => m.retrySession(d.sessionId),
19004
- dismiss: (_client, m, d) => m.dismissSession(d.sessionId),
19005
- "set-autorun": (_client, m, d) => m.setAutoRun(d.sessionId, d.enabled),
19006
- "set-autoadvance": (_client, m, d) => m.setAutoAdvance(d.sessionId, d.enabled)
19306
+ input: routed(
19307
+ (_client, m, d) => m.writeToSession(d.sessionId, d.data)
19308
+ ),
19309
+ resize: routed(
19310
+ (_client, m, d) => m.resizeSession(d.sessionId, d.cols, d.rows)
19311
+ ),
19312
+ retry: routed((_client, m, d) => m.retrySession(d.sessionId)),
19313
+ dismiss: routed((_client, m, d) => m.dismissSession(d.sessionId)),
19314
+ "set-autorun": routed(
19315
+ (_client, m, d) => m.setAutoRun(d.sessionId, d.enabled)
19316
+ ),
19317
+ "set-autoadvance": routed(
19318
+ (_client, m, d) => m.setAutoAdvance(d.sessionId, d.enabled)
19319
+ )
19007
19320
  };
19008
19321
  function dispatchMessage(client, manager, data) {
19009
19322
  handlers[data.type]?.(client, manager, data);
@@ -19018,7 +19331,7 @@ function handleConnection(socket, manager) {
19018
19331
  }
19019
19332
  };
19020
19333
  manager.addClient(client);
19021
- const lines = createInterface5({ input: socket });
19334
+ const lines = createInterface6({ input: socket });
19022
19335
  lines.on("error", () => {
19023
19336
  });
19024
19337
  lines.on("line", (line) => {
@@ -19095,9 +19408,10 @@ function cleanupOwnedFiles() {
19095
19408
 
19096
19409
  // src/commands/sessions/daemon/startDaemonServer.ts
19097
19410
  function startDaemonServer(manager, checkAutoExit) {
19098
- const server = net2.createServer(
19411
+ const server = net3.createServer(
19099
19412
  (socket) => handleConnection(socket, manager)
19100
19413
  );
19414
+ if (process.platform === "win32") startWindowsBridge(manager);
19101
19415
  let retried = false;
19102
19416
  server.on("error", (e) => {
19103
19417
  if (e.code !== "EADDRINUSE" || retried) {
@@ -19109,6 +19423,17 @@ function startDaemonServer(manager, checkAutoExit) {
19109
19423
  });
19110
19424
  server.listen(daemonPaths.socket, () => onListening(manager, checkAutoExit));
19111
19425
  }
19426
+ function startWindowsBridge(manager) {
19427
+ const port = windowsDaemonPort();
19428
+ const bridge = net3.createServer(
19429
+ (socket) => handleConnection(socket, manager)
19430
+ );
19431
+ bridge.on(
19432
+ "error",
19433
+ (e) => daemonLog(`windows bridge error: ${e.message}`)
19434
+ );
19435
+ bridge.listen(port, () => daemonLog(`windows bridge listening on :${port}`));
19436
+ }
19112
19437
  async function recoverFromAddrInUse(server, manager, checkAutoExit) {
19113
19438
  if (await isDaemonRunning()) {
19114
19439
  daemonLog("another daemon owns the socket; exiting");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.284.1",
3
+ "version": "0.285.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {