fix: Windows CRLF + MCP/CLI coexistence (doctor false-positives)#1190
Open
geormic12 wants to merge 2 commits into
Open
fix: Windows CRLF + MCP/CLI coexistence (doctor false-positives)#1190geormic12 wants to merge 2 commits into
geormic12 wants to merge 2 commits into
Conversation
`extractTriggers` used `/^---\n([\s\S]*?)\n---/` to capture the YAML
frontmatter block before scanning for a `triggers:` array. The literal `\n`
bytes don't match CRLF line endings, so on Windows the frontmatter match
failed before triggers were ever inspected, and every Windows-edited skill
got flagged as a `mece_gap` warning ("Skill 'X' has no triggers: field in
its SKILL.md frontmatter") even when the triggers were present.
Repro on a clean Windows clone: doctor --strict --json against a fresh
brain reported 39 of 42 skills as mece_gap warnings (every upstream skill
shipped with CRLF endings; only skills authored on the same machine via
gbrain skillify scaffold had LF endings and passed). After the fix:
0 mece_gap warnings, all 46 skills pass conformance, health_score 90 -> 100.
The single-character fix adds `\r?` before each `\n` in the outer match;
the inner triggers regex already tolerates `\r` because `\s` includes it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When `gbrain serve` is attached as an MCP server (the common Claude Code
configuration), PGLite's single-writer lock blocks `gbrain doctor` from
opening its own DB connection. The catch path at cli.ts surfaced this as
`connection [warn]: Could not connect to configured DB ...`, which is
noisy: co-existence with an attached MCP is expected behavior, the user
has DB-backed health available via `mcp__gbrain__get_health`, and the
warning fires on every CLI invocation while MCP is up.
Patch: in cli.ts, detect the lockfile (postmaster.pid in brain.pglite)
before calling runDoctor, pass an opts.lockHeldByMcp hint. In doctor.ts,
extend runDoctor's signature with the optional opts and demote the
connection check to status 'ok' with an info-prefixed message pointing
the user at the MCP-side health surface. The status type union stays
unchanged ('ok' | 'warn' | 'fail'); the info-prefix convention is already
used elsewhere in this file (see slug_fallback_audit).
Result: doctor --strict against a brain whose MCP is attached now reports
status 'healthy', score 100, instead of status 'warnings', score 95.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes for Windows users running gbrain alongside an attached MCP server (the common Claude Code configuration):
check-resolvable.ts—extractTriggersregex didn't tolerate CRLF line endings, so every Windows-edited skill got flagged asmece_gapeven when triggers were present. One-character fix (\n→\r?\n).doctor.ts+cli.ts—gbrain doctorreportsconnection [warn]: Could not connect to configured DBevery time it runs whilegbrain serveMCP holds the PGLite single-writer lock. Co-existence with MCP is expected, not an error. Patch detects the lockfile (postmaster.pid) and demotes toconnection [ok]: info: DB owned by another process ..., pointing the user atmcp__gbrain__get_healthfor DB-backed checks.Repro
On a clean Windows clone with an attached
gbrain serveMCP:```
$ gbrain doctor --strict --json
status: warnings
health_score: 90
resolver_health [warn]: 39 issue(s): 0 error(s), 39 warning(s)
(all 39 are mece_gap on upstream skills whose triggers: arrays ARE in
the frontmatter but get missed because of CRLF line endings)
skill_conformance [ok]: 46/46 skills pass
connection [warn]: Could not connect to configured DB ...
```
After both fixes:
```
$ gbrain doctor --strict --json
status: healthy
health_score: 100
resolver_health [ok]: 46 skills, all reachable
skill_conformance [ok]: 46/46 skills pass
connection [ok]: info: DB owned by another process (likely 'gbrain serve' MCP holding the PGLite single-writer lock). Filesystem checks ran; use 'mcp__gbrain__get_health' for DB-backed checks.
```
Why two commits
Each commit is independently revertable. Commit 1 is a one-character regex fix. Commit 2 extends
runDoctor's signature with an optional opts parameter (backward-compatible — only the catch-path caller passes it).Test plan
gbrain doctor --stricton Windows with attached MCP — clean outputgbrain doctor --stricton Windows without MCP — connection check behaves as beforeContext
Surfaced during a framework rewrite that's installing gbrain as the canonical knowledge layer on Windows. Documented in the issue at https://github.com/garrytan/gbrain/issues — happy to link if you'd like a separate report.
🤖 Generated with Claude Code