Bug Description
When running gbrain extract links --source fs, the command reports "Created 0 links" despite finding candidate links in the filesystem.
Root Cause
In src/commands/extract.ts, the extractLinksFromDir function builds slugs by stripping the .md extension without normalizing case:
// src/commands/extract.ts ~line 200
const allSlugs = files.map(f => f.relPath.replace('.md', ''));
However, in src/core/sync.ts, slugs are normalized using slugifySegment which applies toLowerCase():
// src/core/sync.ts ~line 211
function slugifySegment(segment: string): string {
return segment.toLowerCase().replace(/[^a-z0-9]+/g, '');
}
When addLinksBatch performs its JOIN on slug + source_id, the case mismatch causes all links to silently fail insertion:
- Extract provides:
synthesis/Synthesis
- Sync normalizes to:
synthesis/synthesis
- No match → 0 links created
Reproduction
# Register a source
gbrain sources add wiki --path /path/to/wiki
# Extract links — reports 0 created despite finding candidates
gbrain extract links --source fs --dir /path/to/wiki
# Output: "N candidate links found, 0 created"
Expected Behavior
All links that pass validation should be inserted into the database.
Fix
Replace the raw .replace('.md', '') slug construction in extractLinksFromDir with the existing pathToSlug normalization from sync.ts.
Environment
- OS: macOS (case-insensitive filesystem, but slug JOIN is case-sensitive)
- gbrain version: 0.24.0
Bug Description
When running
gbrain extract links --source fs, the command reports "Created 0 links" despite finding candidate links in the filesystem.Root Cause
In
src/commands/extract.ts, theextractLinksFromDirfunction builds slugs by stripping the.mdextension without normalizing case:However, in
src/core/sync.ts, slugs are normalized usingslugifySegmentwhich appliestoLowerCase():When
addLinksBatchperforms its JOIN onslug + source_id, the case mismatch causes all links to silently fail insertion:synthesis/Synthesissynthesis/synthesisReproduction
Expected Behavior
All links that pass validation should be inserted into the database.
Fix
Replace the raw
.replace('.md', '')slug construction inextractLinksFromDirwith the existingpathToSlugnormalization fromsync.ts.Environment