MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / isFileStaleOnDisk

Method isFileStaleOnDisk

src/mcp/tools.ts:1819–1852  ·  view source on GitHub ↗

* On-disk drift check for a single indexed file (issue #1474). The code * renderers slice CURRENT bytes at INDEXED line ranges; when the file * changed after its last index sync those ranges can point at a DIFFERENT * symbol's code — served under the requested name with `isError: false`.

(cg: CodeGraph, relPath: string, content?: string)

Source from the content-addressed store, hash-verified

1817 * would needlessly push the agent back to Read.
1818 */
1819 private isFileStaleOnDisk(cg: CodeGraph, relPath: string, content?: string): boolean {
1820 let root: string;
1821 try {
1822 root = cg.getProjectRoot();
1823 } catch {
1824 return false;
1825 }
1826 const key = `${root}\0${relPath}`;
1827 const now = Date.now();
1828 const hit = this.driftCache.get(key);
1829 if (hit && now - hit.at < ToolHandler.DRIFT_TTL_MS) return hit.stale;
1830 let stale = false;
1831 try {
1832 const rec = cg.getFile(relPath);
1833 const absPath = rec ? validatePathWithinRoot(root, relPath) : null;
1834 if (rec && absPath && existsSync(absPath)) {
1835 const st = statSync(absPath);
1836 // Same freshness test as the sync fast path (extraction/index.ts):
1837 // equal size + equal floored mtime ⇒ unchanged, no read needed.
1838 if (st.size !== rec.size || Math.floor(st.mtimeMs) !== Math.floor(rec.modifiedAt)) {
1839 const data = content ?? readFileSync(absPath, 'utf-8');
1840 // Must stay byte-identical to extraction's `hashContent` (sha256 over
1841 // the utf-8 string) — the identical-rewrite test in
1842 // mcp-stale-slice.test.ts pins the parity. Inlined (not imported)
1843 // to keep the extraction module off the MCP startup path.
1844 stale = createHash('sha256').update(data).digest('hex') !== rec.contentHash;
1845 }
1846 }
1847 } catch {
1848 stale = false;
1849 }
1850 this.driftCache.set(key, { at: now, stale });
1851 return stale;
1852 }
1853
1854 private withStalenessNotice(result: ToolResult, projectPath?: string): ToolResult {
1855 if (result.isError) return result;

Callers 2

handleExploreMethod · 0.95
renderNodeSectionMethod · 0.95

Calls 5

validatePathWithinRootFunction · 0.90
getFileMethod · 0.80
getProjectRootMethod · 0.65
getMethod · 0.65
setMethod · 0.45

Tested by

no test coverage detected