MCPcopy
hub / github.com/github/awesome-copilot / scanRepo

Function scanRepo

extensions/java-modernization-studio/scan.mjs:474–571  ·  view source on GitHub ↗
(repoPath, opts = {})

Source from the content-addressed store, hash-verified

472 * @param {{ includeGit?: boolean }} [opts]
473 */
474export async function scanRepo(repoPath, opts = {}) {
475 const includeGit = opts.includeGit !== false;
476 if (!repoPath || !(await isDirectory(repoPath))) {
477 return { ok: false, repoPath: repoPath || null, error: "repo path not available" };
478 }
479
480 // Modernization docs. Prefer the namespaced .appmod/ copies; the root-level
481 // files (plan.md / progress.md / summary.md) use very common filenames, so we
482 // trust them as workflow state only when the provenance gate below passes.
483 const [apPlan, apProgress, apSummary, rootPlan, rootProgress, rootSummary] = await Promise.all([
484 readText(join(repoPath, ".appmod", "plan.md")),
485 readText(join(repoPath, ".appmod", "progress.md")),
486 readText(join(repoPath, ".appmod", "summary.md")),
487 readText(join(repoPath, "plan.md")),
488 readText(join(repoPath, "progress.md")),
489 readText(join(repoPath, "summary.md")),
490 ]);
491
492 // Structured assessment report (written by the assessment step). Optional,
493 // and the strongest provenance signal that this repo is running the workflow.
494 let report = null;
495 const reportRaw = await readText(join(repoPath, ".appmod", "assessment.json"));
496 if (reportRaw) {
497 try {
498 report = normalizeReport(JSON.parse(reportRaw));
499 } catch {
500 report = null;
501 }
502 }
503
504 // Provenance gate. A .appmod/ artifact (assessment.json or a namespaced doc)
505 // means the modernization workflow is active in this repo, so the root docs
506 // are ours. Otherwise a root doc is trusted only if it carries the explicit
507 // <!-- appmod-cockpit --> marker. This stops an unrelated summary.md from
508 // flipping a foreign repo to "completed", or a stray plan.md from injecting
509 // fake steps into the progress/ordering/autopilot machinery.
510 const hasAppmodArtifact =
511 reportRaw != null || apPlan != null || apProgress != null || apSummary != null;
512 const trusted = (root) => hasAppmodArtifact || hasMarker(root);
513 const planMd = apPlan || (trusted(rootPlan) ? rootPlan : null);
514 const progressMd = apProgress || (trusted(rootProgress) ? rootProgress : null);
515 const summaryMd = apSummary || (trusted(rootSummary) ? rootSummary : null);
516
517 const assessment = await buildAssessment(repoPath);
518 const skills = await discoverSkills(repoPath);
519
520 const planSteps = parseSteps(planMd);
521 const progressSteps = parseSteps(progressMd);
522 // Tag each step with its canonical phase rank for ordering guidance.
523 for (const arr of [planSteps, progressSteps]) {
524 for (const st of arr) st.rank = phaseRankFromName(st.section);
525 }
526 // Progress is the source of truth for status; fall back to plan steps.
527 const steps = progressSteps.length ? progressSteps : planSteps;
528 const percent = percentDone(steps);
529 const ordering = computeOrdering(steps);
530 // Prefer an explicit "Validation"/"gates" section for gate status; fall back
531 // to scanning all steps when no such section exists.

Callers 3

extension.mjsFile · 0.90
buildStateFunction · 0.90
cockpit.test.mjsFile · 0.90

Calls 14

catalogWithRelevanceFunction · 0.90
isDirectoryFunction · 0.85
readTextFunction · 0.85
normalizeReportFunction · 0.85
trustedFunction · 0.85
buildAssessmentFunction · 0.85
discoverSkillsFunction · 0.85
parseStepsFunction · 0.85
phaseRankFromNameFunction · 0.85
percentDoneFunction · 0.85
computeOrderingFunction · 0.85
sectionStepsFunction · 0.85

Tested by

no test coverage detected