@proxysoul/soulforge 1.6.3 → 1.7.2

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.
@@ -24204,6 +24204,8 @@ class RepoMap {
24204
24204
  );
24205
24205
  CREATE INDEX IF NOT EXISTS idx_refs_file ON refs(file_id);
24206
24206
  CREATE INDEX IF NOT EXISTS idx_refs_name ON refs(name);
24207
+ CREATE INDEX IF NOT EXISTS idx_refs_source ON refs(source_file_id);
24208
+ CREATE INDEX IF NOT EXISTS idx_refs_import ON refs(import_source);
24207
24209
  `);
24208
24210
  try {
24209
24211
  this.db.run("ALTER TABLE refs ADD COLUMN source_file_id INTEGER REFERENCES files(id) ON DELETE CASCADE");
@@ -24423,13 +24425,16 @@ class RepoMap {
24423
24425
  });
24424
24426
  }
24425
24427
  const stale = [...existingFiles.keys()].filter((p2) => !currentPaths.has(p2));
24426
- if (stale.length > 0) {
24428
+ const staleRatio = existingFiles.size > 0 ? stale.length / existingFiles.size : 0;
24429
+ if (stale.length > 0 && staleRatio < 0.8) {
24427
24430
  const deleteFile = this.db.prepare("DELETE FROM files WHERE path = ?");
24428
24431
  const tx = this.db.transaction(() => {
24429
24432
  for (const p2 of stale)
24430
24433
  deleteFile.run(p2);
24431
24434
  });
24432
24435
  tx();
24436
+ } else if (stale.length > 0) {
24437
+ this.onError?.(`Skipped removing ${String(stale.length)} files \u2014 looks like a file listing error (${String(Math.round(staleRatio * 100))}% stale). Use /repo-map \u2192 [X] clear to force.`);
24433
24438
  }
24434
24439
  if (toIndex.length > 0) {
24435
24440
  this.onProgress?.(0, toIndex.length);
@@ -24453,7 +24458,10 @@ class RepoMap {
24453
24458
  }
24454
24459
  this.onProgress?.(toIndex.length, toIndex.length);
24455
24460
  }
24456
- if (toIndex.length > 0 || stale.length > 0) {
24461
+ const edgeCount = this.db.query("SELECT COUNT(*) as c FROM edges").get()?.c ?? 0;
24462
+ const fileCount = this.db.query("SELECT COUNT(*) as c FROM files").get()?.c ?? 0;
24463
+ const needsPostIndexing = toIndex.length > 0 || stale.length > 0 || fileCount > 0 && edgeCount === 0;
24464
+ if (needsPostIndexing) {
24457
24465
  this.onProgress?.(-1, -1);
24458
24466
  await tick();
24459
24467
  await this.resolveUnresolvedRefs();
@@ -24466,6 +24474,7 @@ class RepoMap {
24466
24474
  this.onProgress?.(-3, -3);
24467
24475
  await tick();
24468
24476
  await this.buildEdges();
24477
+ this.onProgress?.(-4, -4);
24469
24478
  this.linkTestFiles();
24470
24479
  this.rescueOrphans();
24471
24480
  this.onProgress?.(-4, -4);
@@ -25088,6 +25097,8 @@ class RepoMap {
25088
25097
  addEdge(row.source_file_id, row.target_file_id, Math.sqrt(row.ref_count) * 3, 3);
25089
25098
  if (i4 % 500 === 499)
25090
25099
  await tick();
25100
+ if (i4 % 2000 === 0)
25101
+ this.onProgress?.(-3, -3);
25091
25102
  }
25092
25103
  const refDfMap = new Map;
25093
25104
  const dfRows = this.db.query("SELECT name, COUNT(DISTINCT file_id) AS ref_df FROM refs GROUP BY name").all();
@@ -25118,20 +25129,26 @@ class RepoMap {
25118
25129
  addEdge(row.source_file_id, row.target_file_id, w3, 1);
25119
25130
  if (i4 % 500 === 499)
25120
25131
  await tick();
25132
+ if (i4 % 2000 === 0)
25133
+ this.onProgress?.(-3, -3);
25121
25134
  }
25135
+ this.onProgress?.(-3, -3);
25122
25136
  await tick();
25137
+ const uniqueExportNames = new Set;
25138
+ const exportNameCounts = this.db.query("SELECT name, COUNT(DISTINCT file_id) as fc FROM symbols WHERE is_exported = 1 GROUP BY name HAVING fc = 1").all();
25139
+ for (const row of exportNameCounts)
25140
+ uniqueExportNames.add(row.name);
25123
25141
  const inferredRows = this.db.query(`SELECT r.file_id AS source_file_id, s.file_id AS target_file_id,
25124
- r.name, COUNT(*) AS ref_count,
25125
- (SELECT COUNT(DISTINCT s2.file_id) FROM symbols s2
25126
- WHERE s2.name = r.name AND s2.is_exported = 1) AS def_count
25142
+ r.name, COUNT(*) AS ref_count
25127
25143
  FROM refs r
25128
25144
  JOIN symbols s ON r.name = s.name AND s.is_exported = 1
25129
25145
  WHERE r.source_file_id IS NULL AND r.import_source IS NULL
25130
25146
  AND r.file_id != s.file_id
25131
- GROUP BY r.file_id, s.file_id, r.name
25132
- HAVING def_count = 1`).all();
25147
+ GROUP BY r.file_id, s.file_id, r.name`).all();
25133
25148
  for (let i4 = 0;i4 < inferredRows.length; i4++) {
25134
25149
  const row = inferredRows[i4];
25150
+ if (!uniqueExportNames.has(row.name))
25151
+ continue;
25135
25152
  const refDf = refDfMap.get(row.name) ?? 1;
25136
25153
  const idf = Math.log((totalFiles - refDf + 0.5) / (refDf + 0.5));
25137
25154
  if (idf <= 0)
@@ -25145,6 +25162,8 @@ class RepoMap {
25145
25162
  addEdge(row.source_file_id, row.target_file_id, w3, 1);
25146
25163
  if (i4 % 500 === 499)
25147
25164
  await tick();
25165
+ if (i4 % 2000 === 0)
25166
+ this.onProgress?.(-3, -3);
25148
25167
  }
25149
25168
  const cochangeRows = this.db.query("SELECT file_id_a, file_id_b, count FROM cochanges WHERE count >= 3").all();
25150
25169
  for (const row of cochangeRows) {
@@ -25201,6 +25220,8 @@ class RepoMap {
25201
25220
  try {
25202
25221
  tx();
25203
25222
  } catch {}
25223
+ if (i4 % 2000 === 0)
25224
+ this.onProgress?.(-3, -3);
25204
25225
  if (i4 + BATCH < entries.length)
25205
25226
  await tick();
25206
25227
  }
@@ -25544,6 +25565,7 @@ class RepoMap {
25544
25565
  }
25545
25566
  const pairCounts = new Map;
25546
25567
  const commits = logOutput.split("---COMMIT---").filter((s2) => s2.trim());
25568
+ const tick = () => new Promise((r4) => setTimeout(r4, 1));
25547
25569
  for (let ci = 0;ci < commits.length; ci++) {
25548
25570
  const commit = commits[ci];
25549
25571
  const files = commit.split(`
@@ -25558,8 +25580,10 @@ class RepoMap {
25558
25580
  pairCounts.set(key2, (pairCounts.get(key2) ?? 0) + 1);
25559
25581
  }
25560
25582
  }
25561
- if (ci % 50 === 0)
25583
+ if (ci % 50 === 0) {
25562
25584
  this.onProgress?.(-5, -5);
25585
+ await tick();
25586
+ }
25563
25587
  }
25564
25588
  if (pairCounts.size === 0)
25565
25589
  return;
@@ -272818,17 +272842,30 @@ ctx = createWorkerHandler(handlers, async (config) => {
272818
272842
  if (typeof config.maxFiles === "number" && config.maxFiles > 0) {
272819
272843
  repoMap.maxFiles = config.maxFiles;
272820
272844
  }
272845
+ let lastStats = repoMap.getStats();
272846
+ let lastDbSize = repoMap.dbSizeBytes();
272821
272847
  repoMap.onProgress = (indexed, total) => {
272822
272848
  const rm = repoMap;
272823
272849
  if (!rm)
272824
272850
  return;
272825
- const stats = rm.getStats();
272826
- const dbSize = rm.dbSizeBytes();
272851
+ if (indexed < 0) {
272852
+ ctx.emit("progress", {
272853
+ indexed,
272854
+ total,
272855
+ stats: lastStats,
272856
+ dbSize: lastDbSize
272857
+ });
272858
+ return;
272859
+ }
272860
+ try {
272861
+ lastStats = rm.getStats();
272862
+ lastDbSize = rm.dbSizeBytes();
272863
+ } catch {}
272827
272864
  ctx.emit("progress", {
272828
272865
  indexed,
272829
272866
  total,
272830
- stats,
272831
- dbSize
272867
+ stats: lastStats,
272868
+ dbSize: lastDbSize
272832
272869
  });
272833
272870
  };
272834
272871
  repoMap.onScanComplete = (success) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proxysoul/soulforge",
3
- "version": "1.6.3",
3
+ "version": "1.7.2",
4
4
  "description": "Graph-powered code intelligence — multi-agent coding with codebase-aware AI",
5
5
  "repository": {
6
6
  "type": "git",