feat(mcp): extract buildFocusManifestValidation into @loopover/engine for offline loopover_validate_config - #6305
Conversation
… for offline loopover_validate_config Move the focus-manifest validation-result builder into @loopover/engine and leave a re-export shim at src/services/focus-manifest-validation.ts, so the local loopover_validate_config MCP tool computes the result in-process instead of proxying to POST /v1/validate/focus-manifest. The unknownTopLevelWarnings helper it depends on co-moves into the engine (single source of truth shared with the self-host config linter). Bump packages/loopover-mcp's @loopover/engine dependency to ^3.0.0 so it tracks the workspace engine, mirroring packages/loopover-miner. Remote server behavior is unchanged via the shim. Closes JSONbored#6269
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Caution 🛑 LoopOver review result - fixes requiredReview updated: 2026-07-16 00:48:44 UTC
Review summary Nits — 6 non-blocking
CI checks failing
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.
|
|
LoopOver is closing this pull request on the maintainer's behalf (CI is failing (validate, validate-code)). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
Summary
buildFocusManifestValidation(the focus-manifest validation-result builder) out ofsrc/services/focus-manifest-validation.tsinto@loopover/engine(packages/loopover-engine/src/focus-manifest-validation.ts), leaving a thin re-export shim at the originalsrc/path so the remote server (src/api/routes.ts,src/mcp/server.ts) keeps importing it unchanged.loopover_validate_confignow computes the result in-process via the engine instead ofapiPost("/v1/validate/focus-manifest", …), so a user running the local MCP server can validate a.loopover.ymlfully offline. Verified identical output to the remote route.Closes #6269
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coverage— the extraction + the twosrc/files it touches are at 100% patch coverage (statements/branches/functions/lines) under the existingfocus-manifest-validationandselfhost-config-lintsuites; no new uncovered lines/branches. (The unrelatedsqlite3-backed and miner-discover suites fail only in this sandbox for lack of a localsqlite3binary — identical failures on a clean checkout ofmain.)npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run engine-parity:drift-check,test:engine-parity,manifest:drift-check,docs:drift-check,command-reference:check,selfhost:env-reference:checknpm audit --audit-level=moderate(0 vulnerabilities)test/unit/focus-manifest-validation.test.ts(13 cases) andtest/unit/selfhost-config-lint.test.ts(20 cases) exercise every branch of the moved code against its new location and continue to pass.If any required check was skipped, explain why:
ui:lint/ui:typecheck/ui:buildare unaffected — this PR touches noapps/**UI code (no UI surface).Safety
maintainerNotes.loopover_validate_confighandler now returns the byte-identical result the remotePOST /v1/validate/focus-manifestroute produces.UI Evidenceneeded).Notes
unknownTopLevelWarningsco-moves with the builder (required, not scope-creep).buildFocusManifestValidationdepends onunknownTopLevelWarnings, which lived insrc/selfhost/config-lint.ts; the engine cannot import fromsrc/, so that helper (plus itsTOP_LEVEL_FIELDSallowlist and theisOversize/topLevelObjectOrNullprimitives) moves into the engine module as the single source of truth.config-lint.tsnow imports them back — no duplicate implementation, and its recognized-field report keeps sharing the same allowlist so the two surfaces cannot drift (the class of miss feat(config): add .gittensory.yml surface to enable/scope repo-doc generation #3002/Add "experimental" to config-lint.ts's TOP_LEVEL_FIELDS allowlist #5281 fixed).@loopover/enginedependency bump inpackages/loopover-mcp. The local MCP package pinned@loopover/engine@^1.0.0(a published copy that predates this function), so it could not consume the extracted symbol. Bumped to^3.0.0to track the workspace engine — mirroringpackages/loopover-miner, which already declares^3.0.0and consumes workspace-only 3.x engine exports the same way.package-lock.jsonis regenerated accordingly (the stale nested@loopover/engine@1.0.0is dropped in favor of the workspace link).buildFocusManifestValidationfromsrc/services/focus-manifest-validation.ts, now resolving through the shim to the engine.