MCPcopy
hub / github.com/colbymchenry/codegraph / planFrontload

Function planFrontload

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

Source from the content-addressed store, hash-verified

345 * 3. **nothing indexed reachable** → do nothing (the agent's own tools apply).
346 */
347export function planFrontload(cwd: string, prompt: string): FrontloadPlan {
348 const none: FrontloadPlan = { exploreRoot: null, nudgeProjects: [], viaSubScan: false };
349
350 // 1. up-walk — nearest indexed ancestor (incl. cwd). Cheap; covers the common
351 // single-project case without a down-scan.
352 let dir = path.resolve(cwd);
353 for (let i = 0; i < 6; i++) {
354 if (isInitialized(dir)) return { exploreRoot: dir, nudgeProjects: [], viaSubScan: false };
355 const parent = path.dirname(dir);
356 if (parent === dir) break;
357 dir = parent;
358 }
359
360 // 2. down-scan — only from something that looks like a workspace root, so a
361 // non-project cwd (e.g. $HOME) is a cheap no-op, not a deep crawl.
362 const base = path.resolve(cwd);
363 if (!looksLikeProjectRoot(base)) return none;
364 const subs = findIndexedSubprojectRoots(base);
365 if (subs.length === 0) return none;
366 if (subs.length === 1) return { exploreRoot: subs[0]!, nudgeProjects: [], viaSubScan: true };
367
368 // Several indexed sub-projects — pick the one the prompt points at, if any.
369 const p = prompt.toLowerCase();
370 let best: { root: string; score: number; relLen: number } | null = null;
371 for (const s of subs) {
372 const rel = path.relative(base, s);
373 const relLc = rel.split(path.sep).join('/').toLowerCase();
374 const name = path.basename(s).toLowerCase();
375 let score = 0;
376 if (relLc && p.includes(relLc)) score = 10; // "packages/api"
377 else if (name.length >= 3 && new RegExp(`\\b${escapeRegExp(name)}\\b`).test(p)) score = 5; // "api"
378 if (score > 0 && (!best || score > best.score || (score === best.score && rel.length < best.relLen))) {
379 best = { root: s, score, relLen: rel.length };
380 }
381 }
382 if (best) {
383 return { exploreRoot: best.root, nudgeProjects: subs.filter((s) => s !== best!.root), viaSubScan: true };
384 }
385 // No clear match — nudge the full list rather than front-load a guess.
386 return { exploreRoot: null, nudgeProjects: subs, viaSubScan: true };
387}
388
389/**
390 * Contents of `.codegraph/.gitignore`. A single wildcard ignore keeps every

Callers 2

mainFunction · 0.90

Calls 6

isInitializedFunction · 0.85
looksLikeProjectRootFunction · 0.85
resolveMethod · 0.80
joinMethod · 0.80
escapeRegExpFunction · 0.70

Tested by

no test coverage detected