mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-27 07:23:43 +08:00
fix(mcp,extraction): exit a daemon whose install changed; never store a grammar-load failure (#2335, #2336) (#2346)
* fix(mcp,extraction): a daemon whose install changed exits; grammar-load failures are never stored (#2335, #2336) A daemon that outlived an upgrade loaded grammars lazily from an install that no longer existed, and stored every file its watcher re-indexed as a zero-node row under the file's new content hash: no hash-based sync ever revisited those rows, and `codegraph status` called the index up to date. - The daemon checks its own package.json every 30 s (CODEGRAPH_DAEMON_INSTALL_CHECK_MS, 0 turns it off) and exits once the file is gone or carries another version, so the next session starts a daemon from the current install. - A result whose grammar failed to load (`parser_error`) is never stored: the file keeps its previous data and the next sync or index retries it, and a row an older engine stored that way is re-indexed even though its hash matches. The tag-based CFML path reports a missing grammar with the same code. - A launcher whose own install was deleted no longer crashes on the spawn error of the daemon it tried to start. - `codegraph status` and `status --json` (filesNeedingReindex, filesWithParseErrors) report indexed files whose symbols are missing although their content is current (#2336), and `files --json` carries each file's recorded errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(mcp): a session whose own install changed never claims the writer lock (#2335) A daemon now exits once its install is upgraded or removed, and nobody holds the writer slot for a successor at that point. Its sessions run the same replaced code and serve themselves in-process the moment it goes; one that found the slot free claimed it as its writer even though its engine could not load (a real npm upgrade: "Cannot find module './sqlite-adapter'"), and so kept a daemon from the current install from starting. Such a session now falls back read-only and says to restart it. Also adds the CHANGELOG entries for the install check and grammar-load failures (#2335) and for the status report (#2336). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
511d86e94d
commit
dea076fd1e
+48
-1
@@ -1056,6 +1056,33 @@ program
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The `status` warnings for indexed files whose symbols are missing although
|
||||
* their content is current (#2335, #2336): one line per group, saying what is
|
||||
* wrong, what to do, and naming up to three of the files.
|
||||
*/
|
||||
function describeFilesMissingSymbols(health: { needsReindex: string[]; parseErrors: string[] }): string[] {
|
||||
const dash = getGlyphs().dash;
|
||||
const sample = (paths: string[]): string =>
|
||||
paths.slice(0, 3).join(', ') + (paths.length > 3 ? ` (+${formatNumber(paths.length - 3)} more)` : '');
|
||||
const lines: string[] = [];
|
||||
const reindex = health.needsReindex.length;
|
||||
if (reindex > 0) {
|
||||
lines.push(
|
||||
`${formatNumber(reindex)} ${reindex === 1 ? 'file is missing its' : 'files are missing their'} symbols ${dash} ` +
|
||||
`run "codegraph sync" to re-index ${reindex === 1 ? 'it' : 'them'}: ${sample(health.needsReindex)}`
|
||||
);
|
||||
}
|
||||
const unparsed = health.parseErrors.length;
|
||||
if (unparsed > 0) {
|
||||
lines.push(
|
||||
`${formatNumber(unparsed)} ${unparsed === 1 ? 'file could not be parsed, so its symbols are' : 'files could not be parsed, so their symbols are'} ` +
|
||||
`missing: ${sample(health.parseErrors)} ${dash} "codegraph files --json" shows the errors`
|
||||
);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* codegraph status [path]
|
||||
*/
|
||||
@@ -1103,6 +1130,9 @@ program
|
||||
// Zero on a healthy index; non-zero at rest means a resolution pass was
|
||||
// interrupted, so some files' call edges are missing (#1187).
|
||||
const pendingRefs = cg.getPendingReferenceCount();
|
||||
// Files whose content is current but whose symbols are missing — the
|
||||
// content-hash check behind "up to date" cannot see them (#2336).
|
||||
const health = cg.getIndexHealth();
|
||||
|
||||
// JSON output mode
|
||||
if (options.json) {
|
||||
@@ -1143,6 +1173,12 @@ program
|
||||
// interrupted resolution pass left edges missing; the next
|
||||
// sync sweeps them (#1187).
|
||||
pendingRefs,
|
||||
// Files stored without their symbols (e.g. while their grammar
|
||||
// could not load, #2335); the next sync re-indexes them.
|
||||
filesNeedingReindex: health.needsReindex.length,
|
||||
// Files with a recorded parse error and no symbols from it
|
||||
// (#2336); unchanged until the file or the parser changes.
|
||||
filesWithParseErrors: health.parseErrors.length,
|
||||
},
|
||||
}));
|
||||
cg.destroy();
|
||||
@@ -1235,7 +1271,10 @@ program
|
||||
console.log(` Removed: ${changes.removed.length} files`);
|
||||
}
|
||||
info('Run "codegraph sync" to update the index');
|
||||
} else {
|
||||
}
|
||||
const missingSymbols = describeFilesMissingSymbols(health);
|
||||
for (const line of missingSymbols) warn(line);
|
||||
if (totalChanges === 0 && missingSymbols.length === 0) {
|
||||
success('Index is up to date');
|
||||
}
|
||||
console.log();
|
||||
@@ -1751,6 +1790,14 @@ program
|
||||
language: f.language,
|
||||
nodeCount: f.nodeCount,
|
||||
size: f.size,
|
||||
// What extraction recorded for the file — a parse error, a skip
|
||||
// reason — so a health check needn't read the database (#2336).
|
||||
errors: (f.errors ?? []).map((e) => ({
|
||||
severity: e.severity,
|
||||
code: e.code,
|
||||
message: e.message,
|
||||
line: e.line,
|
||||
})),
|
||||
}));
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
cg.destroy();
|
||||
|
||||
Reference in New Issue
Block a user