import { inspectDrift, pruneDeadInstalls, readManifest, tildify } from "@designpaca/core"; import { getVersion } from "../skill.ts"; import { bad, dim, heading, info, ok, table, warn } from "../ui.ts"; export async function runDoctor(): Promise { const version = await getVersion(); const pruned = await pruneDeadInstalls(); const manifest = await readManifest(); console.log(heading("designpaca 진단")); console.log( table([ ["CLI 버전", version], ["Node", process.version], ["설치 기록", `${manifest.installs.length}건`], ]), ); if (pruned > 0) console.log(info(`사라진 설치 기록 ${pruned}건을 정리했다`)); if (manifest.installs.length === 0) { console.log(warn("아직 설치된 곳이 없습니다. `npx designpaca install` 로 설치하실 수 있습니다.")); return 0; } let problems = 0; for (const rec of manifest.installs) { const drift = await inspectDrift(rec); const missing = drift.files.filter((f) => f.status === "missing"); const modified = drift.files.filter((f) => f.status === "modified"); console.log(heading(`${rec.target} (${rec.scope})`)); console.log( table([ ["위치", tildify(rec.root)], ["버전", rec.version === version ? rec.version : `${rec.version} → ${version} 업데이트 가능`], ["파일", `${rec.files.length}개`], ]), ); if (rec.version !== version) problems++; if (missing.length > 0) { problems++; console.log(bad(`파일 ${missing.length}개가 보이지 않습니다 — \`designpaca update --force\` 로 복구하실 수 있습니다`)); for (const m of missing.slice(0, 5)) console.log(dim(` ${tildify(m.path)}`)); } if (modified.length > 0) { console.log(warn(`직접 수정한 파일 ${modified.length}개 — 업데이트가 이 파일들을 건너뛴다`)); for (const m of modified.slice(0, 5)) console.log(dim(` ${tildify(m.path)}`)); } if (missing.length === 0 && modified.length === 0 && rec.version === version) { console.log(ok("정상")); } } return problems > 0 ? 1 : 0; }