@av-pi-studio/server 0.0.43 → 0.0.44

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 (39) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/daemon/bootstrap.d.ts.map +1 -1
  3. package/dist/daemon/bootstrap.js +30 -10
  4. package/dist/daemon/bootstrap.js.map +1 -1
  5. package/dist/daemon/dev-bootstrap.d.ts.map +1 -1
  6. package/dist/daemon/dev-bootstrap.js +19 -9
  7. package/dist/daemon/dev-bootstrap.js.map +1 -1
  8. package/dist/files/file-watch-rpc.d.ts +29 -0
  9. package/dist/files/file-watch-rpc.d.ts.map +1 -0
  10. package/dist/files/file-watch-rpc.js +54 -0
  11. package/dist/files/file-watch-rpc.js.map +1 -0
  12. package/dist/files/file-watch-service.d.ts +47 -0
  13. package/dist/files/file-watch-service.d.ts.map +1 -0
  14. package/dist/files/file-watch-service.js +169 -0
  15. package/dist/files/file-watch-service.js.map +1 -0
  16. package/dist/files/index.d.ts +1 -0
  17. package/dist/files/index.d.ts.map +1 -1
  18. package/dist/files/index.js +1 -0
  19. package/dist/files/index.js.map +1 -1
  20. package/dist/files/limits.d.ts +13 -0
  21. package/dist/files/limits.d.ts.map +1 -0
  22. package/dist/files/limits.js +13 -0
  23. package/dist/files/limits.js.map +1 -0
  24. package/dist/projects/git-checkout-rpc.d.ts +4 -0
  25. package/dist/projects/git-checkout-rpc.d.ts.map +1 -1
  26. package/dist/projects/git-checkout-rpc.js +3 -12
  27. package/dist/projects/git-checkout-rpc.js.map +1 -1
  28. package/dist/projects/workspace-git-service.d.ts +7 -2
  29. package/dist/projects/workspace-git-service.d.ts.map +1 -1
  30. package/dist/projects/workspace-git-service.js.map +1 -1
  31. package/dist/ws/session-subscriptions.d.ts +33 -0
  32. package/dist/ws/session-subscriptions.d.ts.map +1 -0
  33. package/dist/ws/session-subscriptions.js +69 -0
  34. package/dist/ws/session-subscriptions.js.map +1 -0
  35. package/dist/ws/ws-server.d.ts +5 -0
  36. package/dist/ws/ws-server.d.ts.map +1 -1
  37. package/dist/ws/ws-server.js +6 -0
  38. package/dist/ws/ws-server.js.map +1 -1
  39. package/package.json +4 -4
@@ -0,0 +1,169 @@
1
+ import { statSync, watch as fsWatch } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { basename, dirname, join } from "node:path";
4
+ /**
5
+ * The daemon's first real filesystem watcher (architecture/websocket-protocol.md § push/
6
+ * subscription families; features/file-explorer-transfer.md § listings, § file preview). Backs
7
+ * both the molecule viewer's live reload (task-007) and the live file tree (task-008) via a single
8
+ * `subscribe(path, listener)` primitive that watches one file OR one directory.
9
+ *
10
+ * Every daemon-*initiated* mutation already refreshes and pushes correctly today (every mutating
11
+ * git RPC calls `WorkspaceGitService.refresh(cwd)` itself, and `checkout_refresh_request` covers
12
+ * the client's own post-tool guess). What was missing — and what this class exists for — is a
13
+ * change the daemon did **not** itself perform: an external editor, a shell command, a build step,
14
+ * or `git` run inside a pi-studio terminal. Those produce no `refresh()` call and, before this,
15
+ * no push at all.
16
+ */
17
+ /** Per-subscription debounce: collapses a write+rename burst into one push (chosen above
18
+ * `TerminalManager`'s latency-driven 4 ms and safely below `files-changed.ts`'s 500 ms client
19
+ * debounce so daemon pushes never race the client's own post-tool invalidation). */
20
+ export const FILE_WATCH_COALESCE_MS = 150;
21
+ export class FileWatchService {
22
+ coalesceMs;
23
+ logger;
24
+ dirs = new Map();
25
+ constructor(options = {}) {
26
+ this.coalesceMs = options.coalesceMs ?? FILE_WATCH_COALESCE_MS;
27
+ this.logger = options.logger;
28
+ }
29
+ /**
30
+ * Watch one file OR one directory. Fires whenever the target changes; for a directory that
31
+ * includes children being created, deleted, renamed, or modified. Returns an unsubscribe
32
+ * function that is always safe to call, even for a path that could not be watched.
33
+ */
34
+ subscribe(rawPath, listener) {
35
+ // Resolve `~` server-side before anything else (root `AGENTS.md` invariant 7), mirroring
36
+ // `bootstrap.ts`'s own `path.startsWith("~") ? join(homedir(), path.slice(1)) : path`
37
+ // expansion — duplicated inline per that file's own convention (already duplicated verbatim
38
+ // across `bootstrap.ts` and `dev-bootstrap.ts`) rather than factored into a shared helper.
39
+ const resolved = rawPath.startsWith("~") ? join(homedir(), rawPath.slice(1)) : rawPath;
40
+ const isDirectory = statSafe(resolved)?.isDirectory() ?? false;
41
+ // A file target (including one that does not exist yet) watches its *parent* directory and
42
+ // filters by basename — never a direct file handle. Editors and agents commonly save via
43
+ // write-temp + atomic rename, which replaces the inode; a watcher bound to the original file
44
+ // stops firing after the first such save, which this deliberately avoids.
45
+ const dirPath = isDirectory ? resolved : dirname(resolved);
46
+ const basenameFilter = isDirectory ? null : basename(resolved);
47
+ const dirWatch = this.ensureDirWatch(dirPath);
48
+ if (!dirWatch)
49
+ return () => { };
50
+ const sub = { basenameFilter, listener, timer: undefined };
51
+ dirWatch.subs.add(sub);
52
+ let released = false;
53
+ return () => {
54
+ if (released)
55
+ return;
56
+ released = true;
57
+ clearTimeout(sub.timer);
58
+ dirWatch.subs.delete(sub);
59
+ this.releaseDirWatch(dirPath);
60
+ };
61
+ }
62
+ /** Stop every watcher (daemon shutdown). */
63
+ close() {
64
+ for (const dirPath of this.dirs.keys())
65
+ this.teardownDirWatch(dirPath);
66
+ }
67
+ /** Test-only observability seam: number of distinct directories currently holding a live
68
+ * `fs.watch` handle. Not part of the public contract — exists so tests can assert a handle is
69
+ * actually released once its last subscriber leaves, not merely that pushes stop. */
70
+ get watchedDirectoryCount() {
71
+ return this.dirs.size;
72
+ }
73
+ // ─── Internals ───────────────────────────────────────────────────────────
74
+ ensureDirWatch(dirPath) {
75
+ const existing = this.dirs.get(dirPath);
76
+ if (existing) {
77
+ existing.refCount++;
78
+ return existing;
79
+ }
80
+ let watcher;
81
+ try {
82
+ watcher = fsWatch(dirPath, { persistent: false }, (_eventType, filename) => {
83
+ this.onEvent(dirPath, filename ? filename.toString() : null);
84
+ });
85
+ }
86
+ catch (err) {
87
+ this.logger?.debug({ dirPath, err: err.message }, "file-watch: cannot watch directory");
88
+ return undefined;
89
+ }
90
+ const dirWatch = { watcher, subs: new Set(), refCount: 1 };
91
+ watcher.on("error", (err) => {
92
+ this.logger?.warn({ dirPath, err: err?.message ?? String(err) }, "file-watch: watcher error — emitting a final notification and dropping");
93
+ const subsSnapshot = [...dirWatch.subs];
94
+ this.teardownDirWatch(dirPath);
95
+ // One final notification per subscriber so the client refetches and observes e.g. a
96
+ // deletion of the watched directory itself, bypassing the coalescing window entirely
97
+ // since the watcher is already gone and nothing would flush a pending timer.
98
+ for (const sub of subsSnapshot)
99
+ fireSafely(sub.listener);
100
+ });
101
+ this.dirs.set(dirPath, dirWatch);
102
+ return dirWatch;
103
+ }
104
+ releaseDirWatch(dirPath) {
105
+ const dirWatch = this.dirs.get(dirPath);
106
+ if (!dirWatch)
107
+ return; // Already torn down (e.g. by a watcher error).
108
+ dirWatch.refCount--;
109
+ if (dirWatch.refCount <= 0)
110
+ this.teardownDirWatch(dirPath);
111
+ }
112
+ teardownDirWatch(dirPath) {
113
+ const dirWatch = this.dirs.get(dirPath);
114
+ if (!dirWatch)
115
+ return;
116
+ this.dirs.delete(dirPath);
117
+ for (const sub of dirWatch.subs)
118
+ clearTimeout(sub.timer);
119
+ try {
120
+ dirWatch.watcher.close();
121
+ }
122
+ catch {
123
+ // Already closed.
124
+ }
125
+ }
126
+ onEvent(dirPath, filename) {
127
+ const dirWatch = this.dirs.get(dirPath);
128
+ if (!dirWatch)
129
+ return;
130
+ for (const sub of dirWatch.subs) {
131
+ // `filename` can be null on some platforms for some events — treat that as "something
132
+ // changed, notify everyone" rather than guessing, matching the deliberate platform-portable
133
+ // "every event means refetch" design (no per-event-type logic).
134
+ if (sub.basenameFilter === null || filename === null || filename === sub.basenameFilter) {
135
+ this.scheduleFire(sub);
136
+ }
137
+ }
138
+ }
139
+ scheduleFire(sub) {
140
+ if (sub.timer)
141
+ return; // A burst inside the coalescing window collapses to one push.
142
+ sub.timer = setTimeout(() => {
143
+ sub.timer = undefined;
144
+ fireSafely(sub.listener);
145
+ }, this.coalesceMs);
146
+ }
147
+ }
148
+ /** Stats the path, or `undefined` for a nonexistent/unreadable one — treated by `subscribe()` as
149
+ * a file target (see there) rather than a hard failure. */
150
+ function statSafe(path) {
151
+ try {
152
+ return statSync(path);
153
+ }
154
+ catch {
155
+ return undefined;
156
+ }
157
+ }
158
+ /** Runs a listener inside try/catch so one throwing subscriber cannot break another subscriber's
159
+ * delivery, the watcher's own event callback, or (via an uncaught `fs.watch` callback exception)
160
+ * the process. Mirrors `SessionSubscriptions`'s `disposeSafely`. */
161
+ function fireSafely(listener) {
162
+ try {
163
+ listener();
164
+ }
165
+ catch {
166
+ // Intentionally swallowed.
167
+ }
168
+ }
169
+ //# sourceMappingURL=file-watch-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watch-service.js","sourceRoot":"","sources":["../../src/files/file-watch-service.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export * from "./file-explorer.js";
2
2
  export * from "./download-token-store.js";
3
3
  export * from "./file-transfer.js";
4
+ export * from "./limits.js";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC"}
@@ -2,4 +2,5 @@
2
2
  export * from "./file-explorer.js";
3
3
  export * from "./download-token-store.js";
4
4
  export * from "./file-transfer.js";
5
+ export * from "./limits.js";
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The single source of truth for `file_read_request`'s inline-read ceiling (previously a
3
+ * `512 * 1024` literal duplicated verbatim across `bootstrap.ts` and `dev-bootstrap.ts`).
4
+ *
5
+ * Above this size, clients fall back to the chunked binary download path (`file-transfer.ts`),
6
+ * which is unbounded — so raising this number is a tradeoff between inline-read convenience and
7
+ * JSON round-trip cost (four-ish full-size copies: `JSON.stringify` → WS text frame → client
8
+ * `JSON.parse` → TanStack cache entry, doubled again over the relay's NaCl box), not a hard
9
+ * technical limit. 5 MiB covers essentially every real source file and most logs while keeping
10
+ * that round trip cheap.
11
+ */
12
+ export declare const MAX_INLINE_FILE_READ_BYTES: number;
13
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/files/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,QAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The single source of truth for `file_read_request`'s inline-read ceiling (previously a
3
+ * `512 * 1024` literal duplicated verbatim across `bootstrap.ts` and `dev-bootstrap.ts`).
4
+ *
5
+ * Above this size, clients fall back to the chunked binary download path (`file-transfer.ts`),
6
+ * which is unbounded — so raising this number is a tradeoff between inline-read convenience and
7
+ * JSON round-trip cost (four-ish full-size copies: `JSON.stringify` → WS text frame → client
8
+ * `JSON.parse` → TanStack cache entry, doubled again over the relay's NaCl box), not a hard
9
+ * technical limit. 5 MiB covers essentially every real source file and most logs while keeping
10
+ * that round trip cheap.
11
+ */
12
+ export const MAX_INLINE_FILE_READ_BYTES = 5 * 1024 * 1024;
13
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/files/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { HandlerRegistry } from "../ws/router.js";
2
+ import type { SessionSubscriptions } from "../ws/session-subscriptions.js";
2
3
  import { CheckoutDiffManager } from "./checkout-diff-manager.js";
3
4
  import { WorkspaceGitService } from "./workspace-git-service.js";
4
5
  /**
@@ -13,6 +14,9 @@ export interface GitCheckoutRpcDeps {
13
14
  diffManager: CheckoutDiffManager;
14
15
  /** Whether the daemon advertises `features.checkoutRefresh`. */
15
16
  checkoutRefreshEnabled: boolean;
17
+ /** Per-session subscription registry — disposes `checkout_status_subscribe`'s listener when the
18
+ * session's socket closes, not just on an explicit unsubscribe. */
19
+ subscriptions: SessionSubscriptions;
16
20
  }
17
21
  export declare function registerGitCheckoutHandlers(registry: HandlerRegistry, deps: GitCheckoutRpcDeps): void;
18
22
  //# sourceMappingURL=git-checkout-rpc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-checkout-rpc.d.ts","sourceRoot":"","sources":["../../src/projects/git-checkout-rpc.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,WAAW,EAAE,mBAAmB,CAAC;IACjC,gEAAgE;IAChE,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAuDN"}
1
+ {"version":3,"file":"git-checkout-rpc.d.ts","sourceRoot":"","sources":["../../src/projects/git-checkout-rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAoB,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,WAAW,EAAE,mBAAmB,CAAC;IACjC,gEAAgE;IAChE,sBAAsB,EAAE,OAAO,CAAC;IAChC;wEACoE;IACpE,aAAa,EAAE,oBAAoB,CAAC;CACrC;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAiDN"}
@@ -1,28 +1,22 @@
1
1
  import { CheckoutDiffManager } from "./checkout-diff-manager.js";
2
2
  import { WorkspaceGitService } from "./workspace-git-service.js";
3
3
  export function registerGitCheckoutHandlers(registry, deps) {
4
- const { gitService, diffManager } = deps;
5
- // Track per-session status unsubscribers so a session can stop watching.
6
- const statusUnsubs = new Map();
4
+ const { gitService, diffManager, subscriptions } = deps;
7
5
  registry.register("checkout_status_subscribe", (ctx) => {
8
6
  const cwd = String(ctx.message.cwd ?? "");
9
7
  const session = ctx.session;
10
- const key = `${sessionKey(session)}:${cwd}`;
11
- statusUnsubs.get(key)?.(); // replace an existing subscription for the same cwd
12
8
  const unsub = gitService.subscribe(cwd, (projection) => {
13
9
  session.send({
14
10
  type: "session",
15
11
  message: { type: "checkout_status_update", cwd, projection },
16
12
  });
17
13
  });
18
- statusUnsubs.set(key, unsub);
14
+ subscriptions.add(session, `checkout_status:${cwd}`, unsub);
19
15
  return { type: "checkout_status_subscribe_response", cwd, ok: true };
20
16
  });
21
17
  registry.register("checkout_status_unsubscribe", (ctx) => {
22
18
  const cwd = String(ctx.message.cwd ?? "");
23
- const key = `${sessionKey(ctx.session)}:${cwd}`;
24
- statusUnsubs.get(key)?.();
25
- statusUnsubs.delete(key);
19
+ subscriptions.remove(ctx.session, `checkout_status:${cwd}`);
26
20
  return { type: "checkout_status_unsubscribe_response", cwd, ok: true };
27
21
  });
28
22
  registry.register("checkout_diff_subscribe", async (ctx) => {
@@ -51,7 +45,4 @@ export function registerGitCheckoutHandlers(registry, deps) {
51
45
  });
52
46
  }
53
47
  }
54
- function sessionKey(session) {
55
- return session.id ?? String(session);
56
- }
57
48
  //# sourceMappingURL=git-checkout-rpc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-checkout-rpc.js","sourceRoot":"","sources":["../../src/projects/git-checkout-rpc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-checkout-rpc.js","sourceRoot":"","sources":["../../src/projects/git-checkout-rpc.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,13 @@ import { type GitRunner } from "./git-detect.js";
2
2
  import { type CheckoutStatusProjection } from "./status-projection.js";
3
3
  /**
4
4
  * Workspace git service: live status projections streamed as `checkout_status_update`
5
- * (features/git-checkout.md § Status & diff). Recomputation is change-driven (a filesystem watcher
6
- * calls `refresh()`), never polled. `CheckoutRefreshRequest` is gated by `features.checkoutRefresh`.
5
+ * (features/git-checkout.md § Status & diff). Recomputation is change-driven, never polled
6
+ * `refresh(cwd)` is called by `checkout_refresh_request`'s handler (the client's own post-tool
7
+ * debounce guess, `files-changed.ts`) and by every mutating git RPC (`git-operations.ts`, after
8
+ * commit/checkout/branch/merge/reset). `CheckoutRefreshRequest` is gated by
9
+ * `features.checkoutRefresh`. The daemon's `FileWatchService` (`files/file-watch-service.ts`) is a
10
+ * separate, `file_changed`-only push path for external filesystem changes — it does NOT call
11
+ * `refresh()` and does not affect git-status computation; see its own module header.
7
12
  */
8
13
  export type StatusListener = (projection: CheckoutStatusProjection) => void;
9
14
  export declare class WorkspaceGitService {
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-git-service.d.ts","sourceRoot":"","sources":["../../src/projects/workspace-git-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,KAAK,wBAAwB,EAAiB,MAAM,wBAAwB,CAAC;AAEtF;;;;GAIG;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,UAAU,EAAE,wBAAwB,KAAK,IAAI,CAAC;AAO5E,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IAEtD,YAA6B,SAAS,GAAE,SAA4B,EAAI;IAExE,sCAAsC;IACtC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAExD;IAED;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAe3D;IAED;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3C;YAEa,IAAI;CAMnB"}
1
+ {"version":3,"file":"workspace-git-service.d.ts","sourceRoot":"","sources":["../../src/projects/workspace-git-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,KAAK,wBAAwB,EAAiB,MAAM,wBAAwB,CAAC;AAEtF;;;;;;;;;GASG;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,UAAU,EAAE,wBAAwB,KAAK,IAAI,CAAC;AAO5E,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IAEtD,YAA6B,SAAS,GAAE,SAA4B,EAAI;IAExE,sCAAsC;IACtC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAExD;IAED;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAe3D;IAED;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3C;YAEa,IAAI;CAMnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-git-service.js","sourceRoot":"","sources":["../../src/projects/workspace-git-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAiC,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAetF,MAAM,OAAO,mBAAmB;IAGD,SAAS;IAFrB,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEtD,YAA6B,SAAS,GAAc,gBAAgB;yBAAvC,SAAS;IAAiC,CAAC;IAExE,sCAAsC;IACtC,SAAS,CAAC,GAAW;QACnB,OAAO,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,GAAW,EAAE,QAAwB;QAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,0DAA0D;QAC1D,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,CAAC;gBAAE,OAAO;YACf,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACvD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,UAAU,KAAK,KAAK,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;QACxB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS;YAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,QAAwB;QACtD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACnD,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"workspace-git-service.js","sourceRoot":"","sources":["../../src/projects/workspace-git-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAiC,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAoBtF,MAAM,OAAO,mBAAmB;IAGD,SAAS;IAFrB,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEtD,YAA6B,SAAS,GAAc,gBAAgB;yBAAvC,SAAS;IAAiC,CAAC;IAExE,sCAAsC;IACtC,SAAS,CAAC,GAAW;QACnB,OAAO,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,GAAW,EAAE,QAAwB;QAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,0DAA0D;QAC1D,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,CAAC;gBAAE,OAAO;YACf,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACvD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,UAAU,KAAK,KAAK,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;QACxB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS;YAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,QAAwB;QACtD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACnD,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { Session } from "./session.js";
2
+ /**
3
+ * Per-session push-subscription registry (architecture/websocket-protocol.md § session lifecycle,
4
+ * § push/subscription families). One place to hold every subscription a session has open —
5
+ * `checkout_status:<cwd>` today, `file_watch:<path>` from task-006 — and one hook
6
+ * (`disposeSession`) that releases all of them when the socket closes.
7
+ *
8
+ * Fixes a real leak: before this, `checkout_status_subscribe`'s `WorkspaceGitService` listener was
9
+ * only ever released by an explicit unsubscribe RPC or a same-key resubscribe — never by a dropped
10
+ * connection (`ws-server.ts`'s close handler had no hook to call into). A file-watch subscription
11
+ * (task-006) would inherit the same leak and additionally pin an OS-level `fs.watch` handle, so this
12
+ * is fixed first.
13
+ *
14
+ * Deliberately free of any domain knowledge (no cwd/path semantics) — callers namespace their own
15
+ * keys, which is what lets one registry serve multiple subscription families.
16
+ */
17
+ export declare class SessionSubscriptions {
18
+ private readonly bySession;
19
+ /** Register `unsub` under `key` for `session`, disposing any existing entry for that key first
20
+ * (preserves e.g. `checkout_status_subscribe`'s replace-on-resubscribe semantics). */
21
+ add(session: Session, key: string, unsub: () => void): void;
22
+ /** Snapshot of every key currently registered for `session` (empty array if none). Callers use
23
+ * this to enforce their own per-family limits — e.g. file-watch's per-session cap (task-006) —
24
+ * without this registry needing to know what a key "means"; a caller filters by its own key
25
+ * prefix (e.g. `key.startsWith("file_watch:")`). */
26
+ keysOf(session: Session): readonly string[];
27
+ /** Dispose and forget one key. Safe when absent. */
28
+ remove(session: Session, key: string): void;
29
+ /** Dispose every subscription this session holds. Safe to call twice — a second call finds
30
+ * nothing left to dispose. */
31
+ disposeSession(session: Session): void;
32
+ }
33
+ //# sourceMappingURL=session-subscriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-subscriptions.d.ts","sourceRoot":"","sources":["../../src/ws/session-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmD;IAE7E;2FACuF;IACvF,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAQ1D;IAED;;;yDAGqD;IACrD,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAG1C;IAED,oDAAoD;IACpD,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAM1C;IAED;mCAC+B;IAC/B,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAKrC;CACF"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Per-session push-subscription registry (architecture/websocket-protocol.md § session lifecycle,
3
+ * § push/subscription families). One place to hold every subscription a session has open —
4
+ * `checkout_status:<cwd>` today, `file_watch:<path>` from task-006 — and one hook
5
+ * (`disposeSession`) that releases all of them when the socket closes.
6
+ *
7
+ * Fixes a real leak: before this, `checkout_status_subscribe`'s `WorkspaceGitService` listener was
8
+ * only ever released by an explicit unsubscribe RPC or a same-key resubscribe — never by a dropped
9
+ * connection (`ws-server.ts`'s close handler had no hook to call into). A file-watch subscription
10
+ * (task-006) would inherit the same leak and additionally pin an OS-level `fs.watch` handle, so this
11
+ * is fixed first.
12
+ *
13
+ * Deliberately free of any domain knowledge (no cwd/path semantics) — callers namespace their own
14
+ * keys, which is what lets one registry serve multiple subscription families.
15
+ */
16
+ export class SessionSubscriptions {
17
+ bySession = new WeakMap();
18
+ /** Register `unsub` under `key` for `session`, disposing any existing entry for that key first
19
+ * (preserves e.g. `checkout_status_subscribe`'s replace-on-resubscribe semantics). */
20
+ add(session, key, unsub) {
21
+ let subs = this.bySession.get(session);
22
+ if (!subs) {
23
+ subs = new Map();
24
+ this.bySession.set(session, subs);
25
+ }
26
+ disposeSafely(subs.get(key));
27
+ subs.set(key, unsub);
28
+ }
29
+ /** Snapshot of every key currently registered for `session` (empty array if none). Callers use
30
+ * this to enforce their own per-family limits — e.g. file-watch's per-session cap (task-006) —
31
+ * without this registry needing to know what a key "means"; a caller filters by its own key
32
+ * prefix (e.g. `key.startsWith("file_watch:")`). */
33
+ keysOf(session) {
34
+ const subs = this.bySession.get(session);
35
+ return subs ? [...subs.keys()] : [];
36
+ }
37
+ /** Dispose and forget one key. Safe when absent. */
38
+ remove(session, key) {
39
+ const subs = this.bySession.get(session);
40
+ const unsub = subs?.get(key);
41
+ if (!unsub)
42
+ return;
43
+ subs?.delete(key);
44
+ disposeSafely(unsub);
45
+ }
46
+ /** Dispose every subscription this session holds. Safe to call twice — a second call finds
47
+ * nothing left to dispose. */
48
+ disposeSession(session) {
49
+ const subs = this.bySession.get(session);
50
+ if (!subs)
51
+ return;
52
+ for (const unsub of subs.values())
53
+ disposeSafely(unsub);
54
+ this.bySession.delete(session);
55
+ }
56
+ }
57
+ /** Runs `unsub` inside try/catch so one throwing disposer cannot strand its siblings. */
58
+ function disposeSafely(unsub) {
59
+ if (!unsub)
60
+ return;
61
+ try {
62
+ unsub();
63
+ }
64
+ catch {
65
+ // Intentionally swallowed — a subscription's own cleanup failing must never break another
66
+ // subscription's cleanup, socket teardown, or session bookkeeping.
67
+ }
68
+ }
69
+ //# sourceMappingURL=session-subscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-subscriptions.js","sourceRoot":"","sources":["../../src/ws/session-subscriptions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,oBAAoB;IACd,SAAS,GAAG,IAAI,OAAO,EAAoC,CAAC;IAE7E;2FACuF;IACvF,GAAG,CAAC,OAAgB,EAAE,GAAW,EAAE,KAAiB;QAClD,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvB,CAAC;IAED;;;yDAGqD;IACrD,MAAM,CAAC,OAAgB;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,oDAAoD;IACpD,MAAM,CAAC,OAAgB,EAAE,GAAW;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED;mCAC+B;IAC/B,cAAc,CAAC,OAAgB;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AAED,yFAAyF;AACzF,SAAS,aAAa,CAAC,KAA+B;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,IAAI,CAAC;QACH,KAAK,EAAE,CAAC;IACV,CAAC;IAAC,MAAM,CAAC;QACP,0FAA0F;QAC1F,mEAAmE;IACrE,CAAC;AACH,CAAC"}
@@ -30,6 +30,11 @@ export interface WebSocketServerDeps {
30
30
  capabilityStore?: CapabilityStore;
31
31
  /** Called once a session completes its handshake. */
32
32
  onSession?: (session: Session) => void;
33
+ /** Called when a session's socket closes — the hook a handler module uses to release
34
+ * per-session resources (subscriptions, watchers) it would otherwise leak forever on a
35
+ * dropped connection. A throwing callback never breaks socket teardown or `sessions`
36
+ * bookkeeping (guarded at the call site). */
37
+ onSessionClose?: (session: Session) => void;
33
38
  /** Called for every post-handshake frame. */
34
39
  onMessage?: (session: Session, frame: SessionFrame) => void;
35
40
  /** Operational logger: upgrade rejections (warn), handshake failures (warn), session close (info). */
@@ -1 +1 @@
1
- {"version":3,"file":"ws-server.d.ts","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAQvE,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,KAAK,eAAe,EAAiC,MAAM,uBAAuB,CAAC;AAC5F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AAEH,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;IACxD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5D,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAMD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,mBAAmB,GACxB,qBAAqB,CAwHvB"}
1
+ {"version":3,"file":"ws-server.d.ts","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAQvE,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,KAAK,eAAe,EAAiC,MAAM,uBAAuB,CAAC;AAC5F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AAEH,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;IACxD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;kDAG8C;IAC9C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,6CAA6C;IAC7C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5D,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAMD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,mBAAmB,GACxB,qBAAqB,CAgIvB"}
@@ -95,6 +95,12 @@ export function createWebSocketServer(httpServer, deps) {
95
95
  ws.on("close", (code) => {
96
96
  if (session) {
97
97
  sessions.delete(session);
98
+ try {
99
+ deps.onSessionClose?.(session);
100
+ }
101
+ catch (err) {
102
+ deps.logger?.warn({ err, clientId: session.clientId }, "onSessionClose callback threw; session teardown continues");
103
+ }
98
104
  deps.logger?.info({
99
105
  clientId: session.clientId,
100
106
  clientType: session.clientType,
@@ -1 +1 @@
1
- {"version":3,"file":"ws-server.js","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ws-server.js","sourceRoot":"","sources":["../../src/ws/ws-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@av-pi-studio/server",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -22,9 +22,9 @@
22
22
  "clean": "rm -rf dist *.tsbuildinfo"
23
23
  },
24
24
  "dependencies": {
25
- "@av-pi-studio/highlight": "^0.0.43",
26
- "@av-pi-studio/protocol": "^0.0.43",
27
- "@av-pi-studio/relay": "^0.0.43",
25
+ "@av-pi-studio/highlight": "^0.0.44",
26
+ "@av-pi-studio/protocol": "^0.0.44",
27
+ "@av-pi-studio/relay": "^0.0.44",
28
28
  "@earendil-works/pi-coding-agent": "^0.82.1",
29
29
  "@xterm/headless": "^6.0.0",
30
30
  "bcryptjs": "^3.0.3",