@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.cjs CHANGED
@@ -1588,10 +1588,13 @@ async function discoverJsonlFilesGated(dirs, files, scannedDirs, options = {}) {
1588
1588
  const watermark = scannedDirs.get(projectDir);
1589
1589
  const canReuse = watermark !== void 0 && watermark.mtime_ms === dirStat.mtimeMs && watermark.has_nested === 0;
1590
1590
  if (canReuse) {
1591
- for (const row of files.activePathsByParentDir(projectDir)) {
1592
- results.push({ filePath: row.absolute_path, account: row.account });
1591
+ const known = files.activePathsByParentDir(projectDir);
1592
+ if (known.length > 0) {
1593
+ for (const row of known) {
1594
+ results.push({ filePath: row.absolute_path, account: row.account });
1595
+ }
1596
+ continue;
1593
1597
  }
1594
- continue;
1595
1598
  }
1596
1599
  const found = await discoverJsonlFiles([{ projectsDir: projectDir, account }]);
1597
1600
  const hasNested = found.some((f) => dirnameOf(f.filePath) !== projectDir);
@@ -1845,6 +1848,19 @@ var ConversationFilesRepo = class {
1845
1848
  const rows = this.db.prepare("SELECT absolute_path FROM conversation_files WHERE status != 'deleted'").all();
1846
1849
  return rows.map((r) => r.absolute_path);
1847
1850
  }
1851
+ // Active file paths belonging to any of the given accounts. Backs the
1852
+ // deletion-reconcile so a scan that covered only some accounts can't mark
1853
+ // another account's files deleted (they live in the same shared index.db but
1854
+ // a different profile owns them). Returns [] for an empty account list.
1855
+ activePathsByAccounts(accounts) {
1856
+ if (accounts.length === 0) return [];
1857
+ const placeholders = accounts.map(() => "?").join(", ");
1858
+ const rows = this.db.prepare(
1859
+ `SELECT absolute_path FROM conversation_files
1860
+ WHERE status != 'deleted' AND account IN (${placeholders})`
1861
+ ).all(...accounts);
1862
+ return rows.map((r) => r.absolute_path);
1863
+ }
1848
1864
  // Active files whose immediate parent is exactly parentDir (no nested
1849
1865
  // subdirectories). Backs the dir-mtime gate's reuse path: a project dir with
1850
1866
  // an unchanged mtime and no nested files can skip the glob entirely.
@@ -2217,8 +2233,15 @@ var PersistentEngine = class {
2217
2233
  scanned += batch.length;
2218
2234
  options.onProgress?.(scanned, discovered.length);
2219
2235
  }
2236
+ const coveredAccounts = /* @__PURE__ */ new Set();
2237
+ if (enabled.includes(CLAUDE_CODE_PROVIDER)) {
2238
+ for (const p of activeProfiles) coveredAccounts.add(p.id);
2239
+ }
2240
+ if (enabled.includes(CODEX_CLI_PROVIDER) && (options.codexRoots?.length ?? 0) > 0) {
2241
+ coveredAccounts.add("codex");
2242
+ }
2220
2243
  const seen = new Set(discovered.map((d) => d.filePath));
2221
- for (const path of this.files.allActivePaths()) {
2244
+ for (const path of this.files.activePathsByAccounts([...coveredAccounts])) {
2222
2245
  if (!seen.has(path)) this.markDeleted(path);
2223
2246
  }
2224
2247
  log.info({ scanned, indexed: this.conversations.count() }, "persistent: indexAll complete");