@threadbase-sh/streamer 1.46.0 → 1.46.1

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/cli.cjs CHANGED
@@ -145919,6 +145919,27 @@ var ConversationWatcher = class {
145919
145919
  * Watch a directory of conversation JSONL files. Fires
145920
145920
  * onConversationChanged for any add/change/unlink event so the caller
145921
145921
  * can mark the cache dirty without scanning everything immediately.
145922
+ *
145923
+ * **This costs one OS watch handle per file under `directory`, not one per
145924
+ * directory.** chokidar recurses the tree and registers a separate fs.watch
145925
+ * per entry, because a directory watch alone does not report writes to files
145926
+ * inside it — and per-file `change` events are exactly what the caller needs
145927
+ * (they drive poke()'s tail self-heal and the external-tail attach). So the
145928
+ * handle count tracks the size of the conversation corpus on disk, not the
145929
+ * number of live sessions, and it does not shrink until transcripts are
145930
+ * deleted. `ignoreInitial` suppresses the startup *events*, not the walk.
145931
+ *
145932
+ * Measured 2026-08-09 on the live macOS instance: 2131 open .jsonl fds
145933
+ * against 2133 files under the watched roots — 1:1, ~88% of all fds on the
145934
+ * process, at 2.0% of that box's 122 880 per-process ceiling. Comfortable
145935
+ * there. **Linux is the tight one**: these are inotify watches billed to the
145936
+ * per-user `max_user_watches`, which can be 8192 and is shared with every
145937
+ * other watcher the user runs. Exhaustion surfaces as ENOSPC on the `error`
145938
+ * event — which is why server.ts wires onError rather than leaving it unset.
145939
+ *
145940
+ * Before trading handles for a bound here, note the regression it invites: a
145941
+ * conversation excluded from the walk (by age or by an LRU cap) is one whose
145942
+ * external appends produce no event at all, and that failure is silent.
145922
145943
  */
145923
145944
  watchDirectory(directory) {
145924
145945
  if (this.directories.has(directory)) return;
@@ -148480,6 +148501,13 @@ var StreamerServer = class {
148480
148501
  event: "cache.invalidate_on_unlink"
148481
148502
  });
148482
148503
  this.cacheMonitor?.recordUnlink(filePath);
148504
+ },
148505
+ onError: (filePath, err) => {
148506
+ const enospc = err.code === "ENOSPC";
148507
+ this.log.error(
148508
+ enospc ? `Watcher hit the OS watch-handle limit on ${filePath} \u2014 raise fs.inotify.max_user_watches (Linux) or the process fd limit; conversation discovery and live tails are degraded until then` : `Watcher error on ${filePath}: ${err.message}`,
148509
+ { filePath, err, event: enospc ? "watcher.limit_exhausted" : "watcher.error" }
148510
+ );
148483
148511
  }
148484
148512
  });
148485
148513
  this.ptyManager = new LiveSessionManager({