fix(mcp): drop dead ESLint selector + suppress redundant grammar warning

Two minor PR #1383 review findings:

1. eslint.config.mjs: removed Selector 3 (`Property[key.name='write'].properties:has(...)`).
   `.properties` is not a valid attribute on a Property node in the ESTree
   AST, so the :has clause never matched — dead code. Selector 4 covers
   the canonical `const { write } = process.stdout` shape; tightened its
   comment to make that explicit.

2. cli/mcp.ts: removed the unconditional warnMissingOptionalGrammars call
   at MCP startup. The analyze path already emits this warning at index
   time with relevantExtensions filtered to the repo's actual file types,
   and a repo can only be served by MCP after analyze has run. Repeating
   the warning unconditionally on every MCP session was pure noise on
   machines whose indexed repos don't use .dart/.proto.
This commit is contained in:
Gergo Magyar 2026-05-07 08:09:15 +01:00
parent af1968f0fe
commit ca617552b0
2 changed files with 16 additions and 17 deletions

View file

@ -99,12 +99,11 @@ export default [
'Direct process.stdout.write is forbidden in MCP-reachable code. Route diagnostics through console.error or process.stderr.write — the MCP stdio transport owns stdout for JSON-RPC frames.',
},
{
selector:
"VariableDeclarator > ObjectPattern > Property[key.name='write'].properties:has(MemberExpression[object.name='process'][property.name='stdout'])",
message:
'Destructuring write off process.stdout is forbidden in MCP-reachable code — bypasses the sentinel. Use process.stderr.write for diagnostics.',
},
{
// Catches the canonical destructuring shape:
// const { write } = process.stdout;
// (and any other ObjectPattern destructure rooted at process.stdout)
// which would otherwise capture a reference to the original write
// and bypass the sentinel.
selector:
"VariableDeclarator[init.type='MemberExpression'][init.object.name='process'][init.property.name='stdout'] > ObjectPattern",
message:

View file

@ -43,18 +43,18 @@ export const mcpCommand = async () => {
// Now safe to dynamically import the heavy backend modules. Anything
// they emit to stdout during evaluation will route through the sentinel.
const [{ startMCPServer }, { LocalBackend }, { warnMissingOptionalGrammars }] = await Promise.all(
[
import('../mcp/server.js'),
import('../mcp/local/local-backend.js'),
import('./optional-grammars.js'),
],
);
const [{ startMCPServer }, { LocalBackend }] = await Promise.all([
import('../mcp/server.js'),
import('../mcp/local/local-backend.js'),
]);
// Surface missing optional grammars at startup so users learn why
// .dart/.proto files won't be parsed instead of silently getting a
// degraded index.
warnMissingOptionalGrammars({ context: 'mcp' });
// Note: missing-optional-grammar warnings are emitted by `gitnexus analyze`
// (with `relevantExtensions` filtered to the repo's actual file types) at
// index time. A repo can only be served by MCP after it has been analyzed,
// so the user has already been warned through the path that knows whether
// the repo even contains .dart/.proto files. Repeating an unconditional
// warning at every MCP startup would be pure noise on machines whose
// indexed repos don't use those grammars.
// Initialize multi-repo backend from registry.
// The server starts even with 0 repos — tools call refreshRepos() lazily,