@threadbase-sh/scanner 0.9.2 → 0.9.4

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
@@ -1524,10 +1524,13 @@ async function discoverJsonlFilesGated(dirs, files, scannedDirs, options = {}) {
1524
1524
  const watermark = scannedDirs.get(projectDir);
1525
1525
  const canReuse = watermark !== void 0 && watermark.mtime_ms === dirStat.mtimeMs && watermark.has_nested === 0;
1526
1526
  if (canReuse) {
1527
- for (const row of files.activePathsByParentDir(projectDir)) {
1528
- results.push({ filePath: row.absolute_path, account: row.account });
1527
+ const known = files.activePathsByParentDir(projectDir);
1528
+ if (known.length > 0) {
1529
+ for (const row of known) {
1530
+ results.push({ filePath: row.absolute_path, account: row.account });
1531
+ }
1532
+ continue;
1529
1533
  }
1530
- continue;
1531
1534
  }
1532
1535
  const found = await discoverJsonlFiles([{ projectsDir: projectDir, account }]);
1533
1536
  const hasNested = found.some((f) => dirnameOf(f.filePath) !== projectDir);
@@ -1781,6 +1784,19 @@ var ConversationFilesRepo = class {
1781
1784
  const rows = this.db.prepare("SELECT absolute_path FROM conversation_files WHERE status != 'deleted'").all();
1782
1785
  return rows.map((r) => r.absolute_path);
1783
1786
  }
1787
+ // Active file paths belonging to any of the given accounts. Backs the
1788
+ // deletion-reconcile so a scan that covered only some accounts can't mark
1789
+ // another account's files deleted (they live in the same shared index.db but
1790
+ // a different profile owns them). Returns [] for an empty account list.
1791
+ activePathsByAccounts(accounts) {
1792
+ if (accounts.length === 0) return [];
1793
+ const placeholders = accounts.map(() => "?").join(", ");
1794
+ const rows = this.db.prepare(
1795
+ `SELECT absolute_path FROM conversation_files
1796
+ WHERE status != 'deleted' AND account IN (${placeholders})`
1797
+ ).all(...accounts);
1798
+ return rows.map((r) => r.absolute_path);
1799
+ }
1784
1800
  // Active files whose immediate parent is exactly parentDir (no nested
1785
1801
  // subdirectories). Backs the dir-mtime gate's reuse path: a project dir with
1786
1802
  // an unchanged mtime and no nested files can skip the glob entirely.
@@ -2153,8 +2169,15 @@ var PersistentEngine = class {
2153
2169
  scanned += batch.length;
2154
2170
  options.onProgress?.(scanned, discovered.length);
2155
2171
  }
2172
+ const coveredAccounts = /* @__PURE__ */ new Set();
2173
+ if (enabled.includes(CLAUDE_CODE_PROVIDER)) {
2174
+ for (const p of activeProfiles) coveredAccounts.add(p.id);
2175
+ }
2176
+ if (enabled.includes(CODEX_CLI_PROVIDER) && (options.codexRoots?.length ?? 0) > 0) {
2177
+ coveredAccounts.add("codex");
2178
+ }
2156
2179
  const seen = new Set(discovered.map((d) => d.filePath));
2157
- for (const path of this.files.allActivePaths()) {
2180
+ for (const path of this.files.activePathsByAccounts([...coveredAccounts])) {
2158
2181
  if (!seen.has(path)) this.markDeleted(path);
2159
2182
  }
2160
2183
  log.info({ scanned, indexed: this.conversations.count() }, "persistent: indexAll complete");