@staff0rd/assist 0.297.4 → 0.298.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.
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.297.4",
9
+ version: "0.298.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -18412,6 +18412,44 @@ function daemonLog(message) {
18412
18412
  console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
18413
18413
  }
18414
18414
 
18415
+ // src/commands/sessions/daemon/loadActiveSelection.ts
18416
+ import { z as z5 } from "zod";
18417
+ var ACTIVE_FILE = "active.json";
18418
+ var activeSelectionSchema = z5.record(z5.string(), z5.string());
18419
+ function loadActiveSelection() {
18420
+ const parsed = activeSelectionSchema.safeParse(
18421
+ loadJson(ACTIVE_FILE)
18422
+ );
18423
+ return parsed.success ? parsed.data : {};
18424
+ }
18425
+ function saveActiveSelection(active) {
18426
+ saveJson(ACTIVE_FILE, active);
18427
+ }
18428
+
18429
+ // src/commands/sessions/daemon/ActiveSelection.ts
18430
+ var ActiveSelection = class {
18431
+ // why: onChange triggers a broadcast only when the selection actually changes
18432
+ constructor(onChange) {
18433
+ this.onChange = onChange;
18434
+ }
18435
+ byRepo = /* @__PURE__ */ new Map();
18436
+ set(cwd, sessionId) {
18437
+ if (!cwd) return;
18438
+ this.byRepo.delete(cwd);
18439
+ this.byRepo.set(cwd, sessionId);
18440
+ saveActiveSelection(this.toJSON());
18441
+ this.onChange();
18442
+ }
18443
+ // why: on daemon restart, reload persisted selections but drop any whose session was not restored
18444
+ restore(isLive) {
18445
+ for (const [cwd, sessionId] of Object.entries(loadActiveSelection()))
18446
+ if (isLive(sessionId)) this.byRepo.set(cwd, sessionId);
18447
+ }
18448
+ toJSON() {
18449
+ return Object.fromEntries(this.byRepo);
18450
+ }
18451
+ };
18452
+
18415
18453
  // src/commands/sessions/daemon/broadcast.ts
18416
18454
  function sendTo(client, msg) {
18417
18455
  client.send(JSON.stringify(msg));
@@ -18424,17 +18462,17 @@ function broadcast(clients, msg) {
18424
18462
  }
18425
18463
 
18426
18464
  // src/commands/sessions/daemon/loadPersistedSessions.ts
18427
- import { z as z5 } from "zod";
18465
+ import { z as z6 } from "zod";
18428
18466
  var SESSIONS_FILE = "sessions.json";
18429
- var persistedSessionSchema = z5.object({
18430
- name: z5.string(),
18431
- commandType: z5.enum(["claude", "run", "assist"]),
18432
- cwd: z5.string(),
18433
- startedAt: z5.number(),
18434
- claudeSessionId: z5.string().optional(),
18435
- runName: z5.string().optional(),
18436
- runArgs: z5.array(z5.string()).optional(),
18437
- assistArgs: z5.array(z5.string()).optional(),
18467
+ var persistedSessionSchema = z6.object({
18468
+ name: z6.string(),
18469
+ commandType: z6.enum(["claude", "run", "assist"]),
18470
+ cwd: z6.string(),
18471
+ startedAt: z6.number(),
18472
+ claudeSessionId: z6.string().optional(),
18473
+ runName: z6.string().optional(),
18474
+ runArgs: z6.array(z6.string()).optional(),
18475
+ assistArgs: z6.array(z6.string()).optional(),
18438
18476
  activity: activitySchema.optional()
18439
18477
  });
18440
18478
  function loadPersistedSessions() {
@@ -18501,11 +18539,13 @@ function toSessionInfo({
18501
18539
  }
18502
18540
 
18503
18541
  // src/commands/sessions/daemon/broadcastSessions.ts
18504
- function broadcastSessions(sessions, clients, windowsSessions = []) {
18542
+ function broadcastSessions(sessions, clients, windowsSessions = [], active) {
18505
18543
  persistLiveSessions(sessions);
18544
+ const local = [...sessions.values()].map(toSessionInfo);
18506
18545
  broadcast(clients, {
18507
18546
  type: "sessions",
18508
- sessions: [...sessions.values()].map(toSessionInfo).concat(windowsSessions)
18547
+ sessions: local.concat(windowsSessions),
18548
+ active: active?.toJSON() ?? {}
18509
18549
  });
18510
18550
  }
18511
18551
 
@@ -18643,8 +18683,7 @@ function replayScrollback(sessions, client) {
18643
18683
  }
18644
18684
 
18645
18685
  // src/commands/sessions/daemon/greetClient.ts
18646
- function greetClient(client, sessions, list4, windowsProxy) {
18647
- sendTo(client, { type: "sessions", sessions: list4() });
18686
+ function greetClient(client, sessions, windowsProxy) {
18648
18687
  replayScrollback(sessions, client);
18649
18688
  windowsProxy.replayScrollback(client);
18650
18689
  void windowsProxy.discover();
@@ -19688,6 +19727,8 @@ var SessionManager = class {
19688
19727
  this.onIdleChange = onIdleChange;
19689
19728
  }
19690
19729
  sessions = /* @__PURE__ */ new Map();
19730
+ // why: dispatch calls active.set() on card click; broadcasts include active.toJSON()
19731
+ active = new ActiveSelection(() => this.notify());
19691
19732
  clients = new ClientHub();
19692
19733
  nextId = 1;
19693
19734
  shuttingDown = false;
@@ -19695,16 +19736,14 @@ var SessionManager = class {
19695
19736
  windowsProxy = new WindowsProxy(this.clients, () => this.notify());
19696
19737
  addClient(client) {
19697
19738
  this.clients.add(client);
19698
- this.onIdleChange?.(this.isIdle());
19699
- greetClient(client, this.sessions, this.listSessions, this.windowsProxy);
19739
+ this.notify();
19740
+ greetClient(client, this.sessions, this.windowsProxy);
19700
19741
  }
19701
19742
  removeClient(client) {
19702
19743
  this.clients.delete(client);
19703
19744
  this.onIdleChange?.(this.isIdle());
19704
19745
  }
19705
- isIdle() {
19706
- return this.sessions.size === 0 && this.clients.size === 0;
19707
- }
19746
+ isIdle = () => this.sessions.size === 0 && this.clients.size === 0;
19708
19747
  shutdown() {
19709
19748
  this.shuttingDown = true;
19710
19749
  shutdownSessions(this.sessions);
@@ -19772,7 +19811,7 @@ var SessionManager = class {
19772
19811
  notify = () => {
19773
19812
  if (this.shuttingDown) return;
19774
19813
  const windows = this.windowsProxy.sessions();
19775
- broadcastSessions(this.sessions, this.clients, windows);
19814
+ broadcastSessions(this.sessions, this.clients, windows, this.active);
19776
19815
  this.onIdleChange?.(this.isIdle());
19777
19816
  };
19778
19817
  };
@@ -19950,7 +19989,8 @@ var handlers = {
19950
19989
  ),
19951
19990
  "set-autoadvance": routed(
19952
19991
  (_client, m, d) => m.setAutoAdvance(d.sessionId, d.enabled)
19953
- )
19992
+ ),
19993
+ "set-active": (_client, m, d) => m.active.set(d.cwd, d.sessionId)
19954
19994
  };
19955
19995
  function dispatchMessage(client, manager, data) {
19956
19996
  handlers[data.type]?.(client, manager, data);
@@ -20021,6 +20061,8 @@ function onListening(manager, checkAutoExit) {
20021
20061
  });
20022
20062
  process.on("exit", cleanupOwnedFiles);
20023
20063
  const restored = manager.restore();
20064
+ const liveIds = new Set(manager.listSessions().map((s) => s.id));
20065
+ manager.active.restore((id2) => liveIds.has(id2));
20024
20066
  daemonLog(
20025
20067
  restored.length > 0 ? `restored ${restored.length} session(s): ${restored.join(", ")}` : "no persisted sessions to restore"
20026
20068
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.297.4",
3
+ "version": "0.298.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {