@coderule/mcp 1.6.2 → 1.6.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/mcp-cli.cjs CHANGED
@@ -1061,6 +1061,11 @@ async function walkDirectory(current, opts, stats) {
1061
1061
  stats.skipped += 1;
1062
1062
  continue;
1063
1063
  }
1064
+ if (stat.size === 0) {
1065
+ stats.skipped += 1;
1066
+ dirLogger.debug({ relPath }, "Skipping zero-length file");
1067
+ continue;
1068
+ }
1064
1069
  const target = dirent.isSymbolicLink() ? await readSymlinkTarget(absPath, dirLogger) : null;
1065
1070
  const state = opts.filesRepo.upsertFromStat({
1066
1071
  relPath,
@@ -1579,6 +1584,13 @@ var ServiceRunner = class {
1579
1584
  this.runtime.logger.debug({ relPath }, "Watcher event ignored by rules");
1580
1585
  return;
1581
1586
  }
1587
+ if (fileStats.size === 0) {
1588
+ this.runtime.logger.debug(
1589
+ { relPath },
1590
+ "Watcher skipping zero-length file"
1591
+ );
1592
+ return;
1593
+ }
1582
1594
  const isSymlink = fileStats.isSymbolicLink();
1583
1595
  const target = isSymlink ? await readSymlinkTarget2(absPath) : null;
1584
1596
  const state = this.runtime.filesRepo.upsertFromStat({
@@ -1717,7 +1729,7 @@ var ServiceRunner = class {
1717
1729
  }
1718
1730
  };
1719
1731
  var HASH_STATES = ["clean", "dirty", "hashing", "missing"];
1720
- function collectIndexingStatus(runtime, runner) {
1732
+ async function collectIndexingStatus(runtime, runner) {
1721
1733
  const byState = {};
1722
1734
  for (const state of HASH_STATES) {
1723
1735
  byState[state] = runtime.filesRepo.countByState(state);
@@ -1730,6 +1742,20 @@ function collectIndexingStatus(runtime, runner) {
1730
1742
  done: queue.countByStatus(qulite.JobStatus.Done),
1731
1743
  failed: queue.countByStatus(qulite.JobStatus.Failed)
1732
1744
  };
1745
+ const latestSnapshot = runtime.snapshotsRepo.getLatest() ?? null;
1746
+ let serverStatus = null;
1747
+ if (latestSnapshot) {
1748
+ try {
1749
+ serverStatus = await runtime.clients.sync.checkSnapshotStatus(
1750
+ latestSnapshot.snapshot_hash
1751
+ );
1752
+ } catch (error) {
1753
+ runtime.logger.warn(
1754
+ { err: error, snapshotHash: latestSnapshot.snapshot_hash },
1755
+ "Failed to fetch server snapshot status"
1756
+ );
1757
+ }
1758
+ }
1733
1759
  return {
1734
1760
  timestamp: Date.now(),
1735
1761
  root: {
@@ -1740,7 +1766,8 @@ function collectIndexingStatus(runtime, runner) {
1740
1766
  total,
1741
1767
  byState
1742
1768
  },
1743
- latestSnapshot: runtime.snapshotsRepo.getLatest() ?? null,
1769
+ latestSnapshot,
1770
+ serverStatus,
1744
1771
  queue: queueCounts,
1745
1772
  service: runner.getServiceStateSnapshot()
1746
1773
  };
@@ -1777,6 +1804,60 @@ function formatStatus(status) {
1777
1804
  lines.push(
1778
1805
  ` Created: ${new Date(status.latestSnapshot.created_at).toISOString()}`
1779
1806
  );
1807
+ if (status.serverStatus) {
1808
+ lines.push(` Server Status: ${status.serverStatus.status}`);
1809
+ if (status.serverStatus.status === "READY" && status.serverStatus.timing) {
1810
+ lines.push("");
1811
+ lines.push(" Indexing Performance:");
1812
+ const timing = status.serverStatus.timing;
1813
+ if (timing.pass1 !== void 0) {
1814
+ lines.push(
1815
+ ` Pass 1 (File Discovery): ${formatDuration(timing.pass1)}`
1816
+ );
1817
+ }
1818
+ if (timing.gap !== void 0) {
1819
+ lines.push(` Gap (Waiting): ${formatDuration(timing.gap)}`);
1820
+ }
1821
+ if (timing.pass2 !== void 0) {
1822
+ lines.push(
1823
+ ` Pass 2 (Cross-Reference): ${formatDuration(timing.pass2)}`
1824
+ );
1825
+ }
1826
+ if (timing.pass2db !== void 0) {
1827
+ lines.push(
1828
+ ` Pass 2 DB Operations: ${formatDuration(timing.pass2db)}`
1829
+ );
1830
+ }
1831
+ const totalTime = (timing.pass1 ?? 0) + (timing.gap ?? 0) + (timing.pass2 ?? 0);
1832
+ if (totalTime > 0) {
1833
+ lines.push(` Total Time: ${formatDuration(totalTime)}`);
1834
+ }
1835
+ lines.push("");
1836
+ lines.push(" Indexing Summary:");
1837
+ if (timing.total_files !== void 0) {
1838
+ lines.push(
1839
+ ` Files Indexed: ${timing.total_files.toLocaleString()}`
1840
+ );
1841
+ }
1842
+ if (timing.total_chunks !== void 0) {
1843
+ lines.push(
1844
+ ` Chunks Created: ${timing.total_chunks.toLocaleString()}`
1845
+ );
1846
+ }
1847
+ if (timing.total_classes !== void 0) {
1848
+ lines.push(
1849
+ ` Classes Found: ${timing.total_classes.toLocaleString()}`
1850
+ );
1851
+ }
1852
+ if (timing.total_methods !== void 0) {
1853
+ lines.push(
1854
+ ` Methods Found: ${timing.total_methods.toLocaleString()}`
1855
+ );
1856
+ }
1857
+ } else if (status.serverStatus.message) {
1858
+ lines.push(` Message: ${status.serverStatus.message}`);
1859
+ }
1860
+ }
1780
1861
  } else {
1781
1862
  lines.push("Latest Snapshot: None");
1782
1863
  }
@@ -1802,6 +1883,19 @@ function formatBytes(bytes) {
1802
1883
  const i = Math.floor(Math.log(bytes) / Math.log(k));
1803
1884
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${units[i]}`;
1804
1885
  }
1886
+ function formatDuration(seconds) {
1887
+ if (seconds < 1e-3) return "<1ms";
1888
+ if (seconds < 1) return `${(seconds * 1e3).toFixed(0)}ms`;
1889
+ if (seconds < 60) return `${seconds.toFixed(2)}s`;
1890
+ const minutes = Math.floor(seconds / 60);
1891
+ const remainingSeconds = seconds % 60;
1892
+ if (minutes < 60) {
1893
+ return `${minutes}m ${remainingSeconds.toFixed(1)}s`;
1894
+ }
1895
+ const hours = Math.floor(minutes / 60);
1896
+ const remainingMinutes = minutes % 60;
1897
+ return `${hours}h ${remainingMinutes}m ${remainingSeconds.toFixed(0)}s`;
1898
+ }
1805
1899
 
1806
1900
  // src/mcp/server.ts
1807
1901
  var SERVER_NAME = "coderule-scanner-mcp";
@@ -1854,7 +1948,7 @@ function createMcpServer({
1854
1948
  inputSchema: {}
1855
1949
  },
1856
1950
  async () => {
1857
- const status = collectIndexingStatus(runtime, runner);
1951
+ const status = await collectIndexingStatus(runtime, runner);
1858
1952
  const text = formatStatus(status);
1859
1953
  return {
1860
1954
  content: [{ type: "text", text }]
@@ -1879,7 +1973,9 @@ function createMcpServer({
1879
1973
  const deadline = Date.now() + runtime.config.maxQueryWaitMs;
1880
1974
  const latest = await waitForLocalSnapshot(deadline);
1881
1975
  if (!latest) {
1882
- const statusText = formatStatus(collectIndexingStatus(runtime, runner));
1976
+ const statusText = formatStatus(
1977
+ await collectIndexingStatus(runtime, runner)
1978
+ );
1883
1979
  const text = `We are not ready....
1884
1980
  ${statusText}`;
1885
1981
  return { content: [{ type: "text", text }] };
@@ -1889,7 +1985,9 @@ ${statusText}`;
1889
1985
  deadline
1890
1986
  );
1891
1987
  if (!readyHash) {
1892
- const statusText = formatStatus(collectIndexingStatus(runtime, runner));
1988
+ const statusText = formatStatus(
1989
+ await collectIndexingStatus(runtime, runner)
1990
+ );
1893
1991
  const text = `We are not ready....
1894
1992
  ${statusText}`;
1895
1993
  return { content: [{ type: "text", text }] };