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

Function planFrontload

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

Source from the content-addressed store, hash-verified

798 * 3. **nothing indexed reachable** → do nothing (the agent's own tools apply).
799 */
800export function planFrontload(cwd: string, prompt: string): FrontloadPlan {
801 const none: FrontloadPlan = { exploreRoot: null, nudgeProjects: [], viaSubScan: false };
802
803 // 1. up-walk — nearest indexed ancestor (incl. cwd). Cheap; covers the common
804 // single-project case without a down-scan.
805 let dir = path.resolve(cwd);
806 for (let i = 0; i < 6; i++) {
807 if (isInitialized(dir)) return { exploreRoot: dir, nudgeProjects: [], viaSubScan: false };
808 const parent = path.dirname(dir);
809 if (parent === dir) break;
810 dir = parent;
811 }
812
813 // 2. down-scan — only from something that looks like a workspace root, so a
814 // non-project cwd (e.g. $HOME) is a cheap no-op, not a deep crawl.
815 const base = path.resolve(cwd);
816 if (!looksLikeProjectRoot(base)) return none;
817 const subs = findIndexedSubprojectRoots(base);
818 if (subs.length === 0) return none;
819 if (subs.length === 1) return { exploreRoot: subs[0]!, nudgeProjects: [], viaSubScan: true };
820
821 // Several indexed sub-projects — pick the one the prompt points at, if any.
822 const p = prompt.toLowerCase();
823 let best: { root: string; score: number; relLen: number } | null = null;
824 for (const s of subs) {
825 const rel = path.relative(base, s);
826 const relLc = rel.split(path.sep).join('/').toLowerCase();
827 const name = path.basename(s).toLowerCase();
828 let score = 0;
829 if (relLc && p.includes(relLc)) score = 10; // "packages/api"
830 else if (name.length >= 3 && new RegExp(`\\b${escapeRegExp(name)}\\b`).test(p)) score = 5; // "api"
831 if (score > 0 && (!best || score > best.score || (score === best.score && rel.length < best.relLen))) {
832 best = { root: s, score, relLen: rel.length };
833 }
834 }
835 if (best) {
836 return { exploreRoot: best.root, nudgeProjects: subs.filter((s) => s !== best!.root), viaSubScan: true };
837 }
838 // No clear match — nudge the full list rather than front-load a guess.
839 return { exploreRoot: null, nudgeProjects: subs, viaSubScan: true };
840}
841
842/**
843 * Contents of `.codegraph/.gitignore`. A single wildcard ignore keeps every

Callers 3

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