feat(mcp): compute loopover_lint_pr_text in-process from the shared engine - #6308
Conversation
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
…ngine
The local MCP server's loopover_lint_pr_text proxied over HTTP
(apiPost("/v1/lint/pr-text", …)) because buildPrTextLint lived in the
host-bound signals/engine.ts, which is excluded from @loopover/engine's tsc
emit and so never reached the published dist/.
Extract buildPrTextLint and its types into a self-contained, buildable
signals/pr-text-lint.ts that reuses the already-extracted shared rubric
(GENERIC_COMMIT_PATTERN/hasClearNoIssueRationale from slop.ts, tokenize from
predicted-gate-engine.ts) so there is one definition, not a mirror.
signals/engine.ts re-exports it, keeping the API route and remote MCP server
unchanged, and the engine barrel now exposes it.
Bump loopover-mcp's @loopover/engine dependency from ^1.0.0 (which resolved
the stale registry 1.0.0 predating this export) to ^3.0.0 so it links the
workspace engine like loopover-miner already does, then call buildPrTextLint
directly in the tool handler. A user running the local MCP server can now lint
PR text fully offline, matching the remote server's in-process behavior.
Closes JSONbored#6268
878f4f4 to
2edcb6e
Compare
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 01:10:25 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
…d engine (#6329) Make the local MCP server's loopover_check_slop_risk tool compute its result in-process from @loopover/engine, matching the remote server's existing in-process behavior, so slop-risk self-checks work fully offline instead of proxying over HTTP (apiPost("/v1/lint/slop-risk", …)). buildSlopAssessment's canonical logic already lives in packages/loopover-engine/src/signals/slop.ts, and both the remote MCP server (src/mcp/server.ts checkSlopRisk) and the API route (/v1/lint/slop-risk) call it directly. The only blocker for the local CLI was that @loopover/engine's exports map did not expose ./signals/slop. - Add a ./signals/slop entry to packages/loopover-engine/package.json's exports map, pointing at the same built module the barrel and the src/ re-export shim already consume. - Update loopover_check_slop_risk's handler to call buildSlopAssessment(input) directly and wrap it as { ...assessment, rubric: SLOP_RUBRIC_MARKDOWN } — byte-for-byte the shape the /v1/lint/slop-risk route returned, so the tool's documented output (slopRisk, band, findings, rubric) is unchanged, only computed locally. Refresh its description accordingly. - Leave the remote server, the API route, the slop-risk CLI subcommand, and the review-pr composition untouched, mirroring #6308's identical change for loopover_lint_pr_text. Closes #6267 Co-authored-by: nghetienhiep <13849419+nghetienhiep@users.noreply.github.com>
What
Make the local MCP server's
loopover_lint_pr_texttool compute its result in-process from@loopover/engine, matching the remote server's existing in-process behavior, so PR-text lint worksfully offline instead of proxying over HTTP (
apiPost("/v1/lint/pr-text", …)).Why
buildPrTextLint's canonical logic lived inpackages/loopover-engine/src/signals/engine.ts, which isexcluded from the engine package's
tscemit (it carries host-bound../../../../src/**imports), so itwas never in the published
dist/— the local package could not import it and fell back to an HTTP proxy.How
buildPrTextLint+ its types and private helpers into a new self-contained, buildable modulepackages/loopover-engine/src/signals/pr-text-lint.ts. It reuses the already-extracted shared rubric(
GENERIC_COMMIT_PATTERN/hasClearNoIssueRationalefromsignals/slop.ts,tokenizefromsignals/predicted-gate-engine.ts,hasValidationNote,sanitizePublicComment,nowIso) so there isone definition, not a hand-kept mirror.
signals/engine.tsnow re-exports from that module, so the API route and the remote MCP server keeptheir
../signals/engineimport path and behavior byte-for-byte unchanged.@loopover/engine).packages/loopover-mcp's@loopover/enginedependency from^1.0.0(stale — resolved theregistry
1.0.0, which predates this export) to^3.0.0, so it links the workspace engine exactly likepackages/loopover-mineralready does. Updated the tool handler to callbuildPrTextLint(input)directly and refreshed its description ("Computed in-process; … no API round-trip").
Testing
test/unit/mcp-lint-pr-text.test.ts: drives the real stdio server with an unreachableLOOPOVER_API_URL+ tight timeout, so any regression back to an HTTP proxy would fail — proving the toolruns fully offline.
test/unit/pr-text-lint.test.ts(via thesignals/enginere-export) covers the moved module at100% statements/branches/functions/lines.
npm run typecheck,npm run engine-parity:drift-check,npm run test:engine-parity, engine packagetests (566),
npm run build:mcp,npm run test:mcp-pack,npm run docs:drift-check,npm run command-reference:check,npm audit --audit-level=moderate— all green.Closes #6268