MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / planFrontload

Function planFrontload

src/directory.ts:602–642  ·  view source on GitHub ↗
(cwd: string, prompt: string)

Source from the content-addressed store, hash-verified

600 * 3. **nothing indexed reachable** → do nothing (the agent's own tools apply).
601 */
602export function planFrontload(cwd: string, prompt: string): FrontloadPlan {
603 const none: FrontloadPlan = { exploreRoot: null, nudgeProjects: [], viaSubScan: false };
604
605 // 1. up-walk — nearest indexed ancestor (incl. cwd). Cheap; covers the common
606 // single-project case without a down-scan.
607 let dir = path.resolve(cwd);
608 for (let i = 0; i < 6; i++) {
609 if (isInitialized(dir)) return { exploreRoot: dir, nudgeProjects: [], viaSubScan: false };
610 const parent = path.dirname(dir);
611 if (parent === dir) break;
612 dir = parent;
613 }
614
615 // 2. down-scan — only from something that looks like a workspace root, so a
616 // non-project cwd (e.g. $HOME) is a cheap no-op, not a deep crawl.
617 const base = path.resolve(cwd);
618 if (!looksLikeProjectRoot(base)) return none;
619 const subs = findIndexedSubprojectRoots(base);
620 if (subs.length === 0) return none;
621 if (subs.length === 1) return { exploreRoot: subs[0]!, nudgeProjects: [], viaSubScan: true };
622
623 // Several indexed sub-projects — pick the one the prompt points at, if any.
624 const p = prompt.toLowerCase();
625 let best: { root: string; score: number; relLen: number } | null = null;
626 for (const s of subs) {
627 const rel = path.relative(base, s);
628 const relLc = rel.split(path.sep).join('/').toLowerCase();
629 const name = path.basename(s).toLowerCase();
630 let score = 0;
631 if (relLc && p.includes(relLc)) score = 10; // "packages/api"
632 else if (name.length >= 3 && new RegExp(`\\b${escapeRegExp(name)}\\b`).test(p)) score = 5; // "api"
633 if (score > 0 && (!best || score > best.score || (score === best.score && rel.length < best.relLen))) {
634 best = { root: s, score, relLen: rel.length };
635 }
636 }
637 if (best) {
638 return { exploreRoot: best.root, nudgeProjects: subs.filter((s) => s !== best!.root), viaSubScan: true };
639 }
640 // No clear match — nudge the full list rather than front-load a guess.
641 return { exploreRoot: null, nudgeProjects: subs, viaSubScan: true };
642}
643
644/**
645 * Contents of `.codegraph/.gitignore`. A single wildcard ignore keeps every

Callers 2

mainFunction · 0.90

Calls 6

isInitializedFunction · 0.85
looksLikeProjectRootFunction · 0.85
escapeRegExpFunction · 0.70
resolveMethod · 0.65
joinMethod · 0.45

Tested by

no test coverage detected