@threadbase-sh/streamer 1.67.0 → 1.67.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/index.cjs CHANGED
@@ -8684,6 +8684,64 @@ var ConversationHandlers = class {
8684
8684
  }
8685
8685
  return null;
8686
8686
  }
8687
+ /**
8688
+ * Resolve a conversation id to a JSONL path, in order of authority.
8689
+ *
8690
+ * `findJsonlPath` alone answers 64.0% of this machine's 961 conversations and
8691
+ * 0 of 343 Codex ones — it reconstructs `<projectsDir>/<dir>/<uuid>.jsonl`,
8692
+ * which is Claude Code's layout, and a Codex rollout is
8693
+ * `rollout-<ts>-<uuid>.jsonl` under a date path, so that walk cannot match one
8694
+ * by construction. The ladder below answers 99.7%, leaving only the three
8695
+ * whose file is genuinely gone.
8696
+ */
8697
+ async locateJsonlPath(uuid, lookupId) {
8698
+ const live = this.deps.findLiveSessionFilePath(uuid) ?? this.deps.findLiveSessionFilePath(lookupId);
8699
+ if (live) return live;
8700
+ const cached3 = this.cache?.getMetaById(lookupId)?.filePath;
8701
+ if (cached3 && await this.isJsonlPathFor(cached3, lookupId)) return cached3;
8702
+ return this.findJsonlPath(lookupId);
8703
+ }
8704
+ /**
8705
+ * Does `filePath` actually hold the conversation `requestedId` names?
8706
+ *
8707
+ * The filename settles it for both providers: Claude writes `<uuid>.jsonl`
8708
+ * (or `agent-<agentId>.jsonl`), Codex writes `rollout-<ts>-<uuid>.jsonl`.
8709
+ * Only when the name says nothing do we open the file — and there the naive
8710
+ * rule is wrong, because **a Claude subagent transcript carries the PARENT's
8711
+ * `sessionId`**. Matching on `sessionId` alone therefore verifies exactly the
8712
+ * file this check exists to reject, so a sidechain is refused outright unless
8713
+ * it was asked for by its own `agent-<agentId>` name, which the filename
8714
+ * branch above already covers.
8715
+ */
8716
+ async isJsonlPathFor(filePath, requestedId) {
8717
+ if (!(0, import_fs13.existsSync)(filePath)) return false;
8718
+ const stem = (0, import_path13.basename)(filePath).replace(/\.jsonl$/, "");
8719
+ if (stem === requestedId || stem.includes(requestedId)) return true;
8720
+ const first = await this.readFirstJsonlEntry(filePath);
8721
+ if (!first || first.isSidechain === true) return false;
8722
+ return first.sessionId === requestedId;
8723
+ }
8724
+ /** First parseable JSONL line, for identity checks. Null on an empty or unreadable file. */
8725
+ async readFirstJsonlEntry(filePath) {
8726
+ return new Promise((resolve2) => {
8727
+ const rl = (0, import_readline.createInterface)({ input: (0, import_fs13.createReadStream)(filePath), crlfDelay: Infinity });
8728
+ let done = false;
8729
+ rl.on("line", (line) => {
8730
+ if (done) return;
8731
+ try {
8732
+ const entry = JSON.parse(line);
8733
+ done = true;
8734
+ rl.close();
8735
+ resolve2(entry);
8736
+ } catch {
8737
+ }
8738
+ });
8739
+ rl.on("close", () => {
8740
+ if (!done) resolve2(null);
8741
+ });
8742
+ rl.on("error", () => resolve2(null));
8743
+ });
8744
+ }
8687
8745
  async readCwdFromJsonl(filePath) {
8688
8746
  return new Promise((resolve2) => {
8689
8747
  const rl = (0, import_readline.createInterface)({ input: (0, import_fs13.createReadStream)(filePath), crlfDelay: Infinity });
@@ -8709,7 +8767,7 @@ var ConversationHandlers = class {
8709
8767
  async findConversationByUuid(uuid) {
8710
8768
  const lookupId = this.deps.resolveConversationLookupId(uuid);
8711
8769
  if (!this.scannerManager.ready && !this.scanProfiles) {
8712
- const filePath2 = this.findJsonlPath(lookupId) ?? this.deps.findLiveSessionFilePath(uuid) ?? this.deps.findLiveSessionFilePath(lookupId);
8770
+ const filePath2 = await this.locateJsonlPath(uuid, lookupId);
8713
8771
  if (filePath2) {
8714
8772
  const account = this.cache?.getMetaById(lookupId)?.account ?? void 0;
8715
8773
  const coldScanner = this.scannerManager.current ?? this.scannerManager.newScanner();
@@ -8761,7 +8819,7 @@ var ConversationHandlers = class {
8761
8819
  return fromIndex;
8762
8820
  }
8763
8821
  if (this.scanProfiles) return null;
8764
- const filePath = this.findJsonlPath(lookupId) ?? this.deps.findLiveSessionFilePath(uuid) ?? this.deps.findLiveSessionFilePath(lookupId);
8822
+ const filePath = await this.locateJsonlPath(uuid, lookupId);
8765
8823
  if (!filePath) return null;
8766
8824
  if (this.scannerManager.ready) {
8767
8825
  const account = this.cache?.getMetaById(lookupId)?.account ?? void 0;