@kb-labs/quality-entry 2.89.0 → 2.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/build-order.js +1 -1
- package/dist/cli/commands/build-order.js.map +1 -1
- package/dist/cli/commands/check-builds.js +1 -1
- package/dist/cli/commands/check-builds.js.map +1 -1
- package/dist/cli/commands/check-tests.js +1 -1
- package/dist/cli/commands/check-tests.js.map +1 -1
- package/dist/cli/commands/check-types.js +1 -1
- package/dist/cli/commands/check-types.js.map +1 -1
- package/dist/cli/commands/cycles.js +1 -1
- package/dist/cli/commands/cycles.js.map +1 -1
- package/dist/cli/commands/dead-code.js +3 -3
- package/dist/cli/commands/dead-code.js.map +1 -1
- package/dist/cli/commands/fix-deps.js +1 -1
- package/dist/cli/commands/fix-deps.js.map +1 -1
- package/dist/cli/commands/flags.d.ts +87 -11
- package/dist/cli/commands/flags.js.map +1 -1
- package/dist/cli/commands/health.js +1 -1
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/index.js +13 -13
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/stats.js +1 -1
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/visualize.js +2 -2
- package/dist/cli/commands/visualize.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/widgets/mf-manifest.json +5 -5
- package/dist/widgets/mf-stats.json +5 -5
- package/dist/widgets/remoteEntry.js +2 -2
- package/dist/widgets/remoteEntry.js.map +1 -1
- package/package.json +7 -7
|
@@ -8,7 +8,7 @@ var build_order_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const graph = buildDependencyGraph(ctx.cwd);
|
|
13
13
|
let result;
|
|
14
14
|
if (flags.package) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/build-order.ts"],"names":[],"mappings":";;;;AA8BA,IAAO,sBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,qBAAA;AAAA,EACJ,WAAA,EAAa,8CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA0D;AAC5F,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AAGf,MAAA,MAAM,KAAA,GAAS,
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/build-order.ts"],"names":[],"mappings":";;;;AA8BA,IAAO,sBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,qBAAA;AAAA,EACJ,WAAA,EAAa,8CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA0D;AAC5F,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AAGf,MAAA,MAAM,KAAA,GAAS,OAAA,IAAW,KAAA,IAAS,OAAQ,KAAA,CAA8B,KAAA,KAAU,QAAA,IAAa,KAAA,CAA8B,KAAA,KAAU,IAAA,GACnI,KAAA,CAAqC,KAAA,GACtC,KAAA;AAGJ,MAAA,MAAM,KAAA,GAAQ,oBAAA,CAAqB,GAAA,CAAI,GAAG,CAAA;AAG1C,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,MAAA,GAAS,uBAAA,CAAwB,KAAA,EAAO,KAAA,CAAM,OAAO,CAAA;AAAA,MACvD,CAAA,MAAO;AACL,QAAA,MAAA,GAAS,gBAAgB,KAAK,CAAA;AAAA,MAChC;AAGA,MAAA,IAAI,MAAA,CAAO,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC9B,QAAA,EAAA,EAAI,KAAA;AAAA,UACF,CAAA,MAAA,EAAS,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,yDAAA;AAAA,SACjC;AACA,QAAA,0BAAA,CAA2B,MAAA,CAAO,UAAU,EAAE,CAAA;AAC9C,QAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,MAAA,EAAO;AAAA,MAC/B;AAGA,MAAA,gBAAA,CAAiB,MAAA,EAAQ,OAAO,EAAE,CAAA;AAElC,MAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,MAAA,EAAO;AAAA,IAC/B;AAAA;AAEJ,CAAC;AAKD,SAAS,gBAAA,CAAiB,MAAA,EAA+B,KAAA,EAAwB,EAAA,EAA0B;AACzG,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,EAAA,EAAI,OAAO,MAAM,CAAA;AACjB,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,MAAM,MAAA,EAAQ;AAEhB,IAAA,EAAA,EAAI,QAAQ,aAAa,CAAA;AACzB,IAAA,EAAA,EAAI,QAAQ,0BAA0B,CAAA;AACtC,IAAA,EAAA,EAAI,QAAQ,QAAQ,CAAA;AACpB,IAAA,EAAA,EAAI,QAAQ,EAAE,CAAA;AAEd,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAC7C,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA;AAC7B,MAAA,IAAI,CAAC,KAAA,EAAO;AAAC,QAAA;AAAA,MAAS;AACtB,MAAA,EAAA,EAAI,QAAQ,CAAA,QAAA,EAAW,CAAA,GAAI,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,MAAM,CAAA,UAAA,CAAY,CAAA;AACzD,MAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,QAAA,EAAA,EAAI,KAAA,GAAQ,CAAA,eAAA,EAAkB,GAAG,CAAA,WAAA,CAAa,CAAA;AAAA,MAChD;AACA,MAAA,EAAA,EAAI,QAAQ,EAAE,CAAA;AAAA,IAChB;AACA,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,WAAuD,EAAC;AAE9D,EAAA,IAAI,MAAM,MAAA,EAAQ;AAEhB,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAC7C,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA;AAC7B,MAAA,IAAI,CAAC,KAAA,EAAO;AAAC,QAAA;AAAA,MAAS;AACtB,MAAA,UAAA,CAAW,KAAK,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,MAAM,CAAA,iCAAA,CAAmC,CAAA;AAClF,MAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,QAAA,UAAA,CAAW,IAAA,CAAK,CAAA,SAAA,EAAO,GAAG,CAAA,CAAE,CAAA;AAAA,MAC9B;AACA,MAAA,UAAA,CAAW,KAAK,EAAE,CAAA;AAAA,IACpB;AACA,IAAA,QAAA,CAAS,KAAK,EAAE,MAAA,EAAQ,cAAA,EAAgB,KAAA,EAAO,YAAY,CAAA;AAAA,EAC7D,CAAA,MAAO;AAEL,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAC,GAAA,EAAK,GAAA,KAAQ,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AACvE,IAAA,QAAA,CAAS,KAAK,EAAE,MAAA,EAAQ,aAAA,EAAe,KAAA,EAAO,YAAY,CAAA;AAAA,EAC5D;AAGA,EAAA,QAAA,CAAS,IAAA,CAAK;AAAA,IACZ,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO;AAAA,MACL,CAAA,gBAAA,EAAmB,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,MACvC,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,MACrC,CAAA,uBAAA,EAA0B,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA;AAAA;AAClD,GACD,CAAA;AAED,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,GAChB,CAAA,0BAAA,EAAsB,KAAA,CAAM,OAAO,CAAA,CAAA,GACnC,gCAAA;AAEJ,EAAA,EAAA,EAAI,UAAU,qCAAA,EAAuC;AAAA,IACnD,KAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AAKA,SAAS,0BAAA,CAA2B,QAAoB,EAAA,EAA0B;AAChF,EAAA,MAAM,WAAuD,EAAC;AAE9D,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AACtB,IAAA,IAAI,CAAC,KAAA,EAAO;AAAC,MAAA;AAAA,IAAS;AACtB,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,MAAA,EAAQ,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,CAAA;AAAA,MACtB,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,KAAK,GAAA,KAAQ;AAC7B,QAAA,IAAI,GAAA,KAAQ,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC5B,UAAA,MAAM,QAAA,GAAW,MAAM,CAAC,CAAA;AACxB,UAAA,OAAO,CAAA,EAAA,EAAK,GAAG,CAAA,QAAA,EAAM,QAAA,IAAY,GAAG,CAAA,YAAA,CAAA;AAAA,QACtC;AACA,QAAA,OAAO,KAAK,GAAG,CAAA,OAAA,CAAA;AAAA,MACjB,CAAC;AAAA,KACF,CAAA;AAAA,EACH;AAEA,EAAA,EAAA,EAAI,QAAQ,gCAAA,EAAkC;AAAA,IAC5C,KAAA,EAAO,oCAAA;AAAA,IACP;AAAA,GACD,CAAA;AACH","file":"build-order.js","sourcesContent":["/**\n * quality:build-order - Calculate build order and dependency layers\n *\n * Uses topological sort to determine correct build order.\n * Shows build layers where each layer can build in parallel.\n */\n\nimport { defineCommand, type PluginContextV3, type UIFacade } from '@kb-labs/sdk';\nimport {\n buildDependencyGraph,\n topologicalSort,\n getBuildOrderForPackage,\n type TopologicalSortResult,\n} from '@kb-labs/quality-core/graph';\n\ntype BuildOrderFlags = {\n package?: string;\n layers?: boolean;\n script?: boolean;\n json?: boolean;\n argv?: string[];\n};\n\ntype BuildOrderInput = BuildOrderFlags & { argv?: string[] };\n\ntype BuildOrderCommandResult = {\n exitCode: number;\n result?: TopologicalSortResult;\n};\n\nexport default defineCommand({\n id: 'quality:build-order',\n description: 'Calculate build order using topological sort',\n\n handler: {\n async execute(ctx: PluginContextV3, input: BuildOrderInput): Promise<BuildOrderCommandResult> {\n const { ui } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: BuildOrderInput }).flags\n : input;\n\n // Build dependency graph\n const graph = buildDependencyGraph(ctx.cwd);\n\n // Calculate build order\n let result: TopologicalSortResult;\n if (flags.package) {\n result = getBuildOrderForPackage(graph, flags.package);\n } else {\n result = topologicalSort(graph);\n }\n\n // Check for circular dependencies\n if (result.circular.length > 0) {\n ui?.error?.(\n `Found ${result.circular.length} circular dependencies. Build order cannot be determined.`\n );\n outputCircularDependencies(result.circular, ui);\n return { exitCode: 1, result };\n }\n\n // Output results\n outputBuildOrder(result, flags, ui);\n\n return { exitCode: 0, result };\n },\n },\n});\n\n/**\n * Output build order results\n */\nfunction outputBuildOrder(result: TopologicalSortResult, flags: BuildOrderFlags, ui: UIFacade | undefined) {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n if (flags.script) {\n // Output as shell script\n ui?.write?.('#!/bin/bash');\n ui?.write?.('# Generated build script');\n ui?.write?.('set -e');\n ui?.write?.('');\n\n for (let i = 0; i < result.layers.length; i++) {\n const layer = result.layers[i];\n if (!layer) {continue;}\n ui?.write?.(`# Layer ${i + 1} (${layer.length} packages)`);\n for (const pkg of layer) {\n ui?.write?.(`pnpm --filter \"${pkg}\" run build`);\n }\n ui?.write?.('');\n }\n return;\n }\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n if (flags.layers) {\n // Show build layers\n const layerItems: string[] = [];\n for (let i = 0; i < result.layers.length; i++) {\n const layer = result.layers[i];\n if (!layer) {continue;}\n layerItems.push(`Layer ${i + 1}: ${layer.length} packages (can build in parallel)`);\n for (const pkg of layer) {\n layerItems.push(` • ${pkg}`);\n }\n layerItems.push('');\n }\n sections.push({ header: 'Build Layers', items: layerItems });\n } else {\n // Show sequential order\n const orderItems = result.sorted.map((pkg, idx) => `${idx + 1}. ${pkg}`);\n sections.push({ header: 'Build Order', items: orderItems });\n }\n\n // Summary\n sections.push({\n header: 'Summary',\n items: [\n `Total packages: ${result.sorted.length}`,\n `Build layers: ${result.layers.length}`,\n `Circular dependencies: ${result.circular.length}`,\n ],\n });\n\n const title = flags.package\n ? `📦 Build Order for ${flags.package}`\n : '📦 Monorepo Build Order';\n\n ui?.success?.('Build order calculated successfully', {\n title,\n sections,\n });\n}\n\n/**\n * Output circular dependencies\n */\nfunction outputCircularDependencies(cycles: string[][], ui: UIFacade | undefined) {\n const sections: Array<{ header: string; items: string[] }> = [];\n\n for (let i = 0; i < cycles.length; i++) {\n const cycle = cycles[i];\n if (!cycle) {continue;}\n sections.push({\n header: `Cycle ${i + 1}`,\n items: cycle.map((pkg, idx) => {\n if (idx === cycle.length - 1) {\n const firstPkg = cycle[0];\n return ` ${pkg} → ${firstPkg ?? '?'} (circular!)`;\n }\n return ` ${pkg} →`;\n }),\n });\n }\n\n ui?.error?.('Circular dependencies detected', {\n title: '⚠️ Circular Dependencies',\n sections,\n });\n}\n"]}
|
|
@@ -9,7 +9,7 @@ var check_builds_default = defineCommand({
|
|
|
9
9
|
handler: {
|
|
10
10
|
async execute(ctx, input) {
|
|
11
11
|
const { ui, platform } = ctx;
|
|
12
|
-
const flags = input.flags
|
|
12
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
13
13
|
const cacheKey = `${CACHE_KEYS.BUILDS}:${flags.package || "all"}`;
|
|
14
14
|
if (!flags.refresh) {
|
|
15
15
|
const cached = await platform.cache.get(cacheKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/check-builds.ts"],"names":[],"mappings":";;;;;AAwBA,IAAO,uBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,sBAAA;AAAA,EACJ,WAAA,EAAa,oCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACmC;AACnC,MAAA,MAAM,EAAE,EAAA,EAAI,QAAA,EAAS,GAAI,GAAA;AAGzB,MAAA,MAAM,KAAA,GAAS,
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/check-builds.ts"],"names":[],"mappings":"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","file":"check-builds.js","sourcesContent":["/**\n * quality:check-builds - Check build status across monorepo\n *\n * Analyzes build status including:\n * - Build failures with error messages\n * - Stale builds (dist/ older than src/)\n * - Build duration tracking\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { BuildCheckResult } from '@kb-labs/quality-contracts';\nimport { CACHE_KEYS } from '@kb-labs/quality-contracts';\nimport { checkBuilds } from '@kb-labs/quality-core/builds';\nimport type { CheckBuildsFlags } from './flags.js';\n\n// Input type with backward compatibility\ntype CheckBuildsInput = CheckBuildsFlags & { argv?: string[] };\n\ntype CheckBuildsCommandResult = {\n exitCode: number;\n result?: BuildCheckResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:check-builds',\n description: 'Check build status across monorepo',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: CheckBuildsInput\n ): Promise<CheckBuildsCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: CheckBuildsInput }).flags\n : input;\n\n // Check cache unless refresh requested\n const cacheKey = `${CACHE_KEYS.BUILDS}:${flags.package || 'all'}`;\n\n if (!flags.refresh) {\n const cached = await platform.cache.get<BuildCheckResult>(cacheKey);\n if (cached) {\n outputBuildCheck({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run build check\n const result = await checkBuilds(ctx.cwd, {\n packageFilter: flags.package,\n timeout: flags.timeout ? Number(flags.timeout) : 30000,\n });\n\n // Cache results for 10 minutes\n await platform.cache.set(cacheKey, result, 10 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:check-builds', {\n totalPackages: result.totalPackages,\n passing: result.passing,\n failing: result.failing,\n staleBuilds: result.staleBuilds.length,\n duration: result.duration,\n packageSpecific: !!flags.package,\n });\n\n // Output results\n outputBuildCheck({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.failing > 0 ? 1 : 0,\n result,\n };\n },\n },\n});\n\n/**\n * Output build check results\n */\nfunction outputBuildCheck(\n result: BuildCheckResult & { cached?: boolean },\n flags: Record<string, unknown>,\n ui: PluginContextV3['ui']\n) {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Status section\n const statusIcon = result.failing === 0 ? '✅' : '❌';\n const statusText = result.failing === 0 ? 'All builds passing' : 'Build failures detected';\n const statusItems = [\n `${statusIcon} ${statusText}`,\n `Passing: ${result.passing} package(s)`,\n result.failing > 0 ? `Failing: ${result.failing} package(s)` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Build Status', items: statusItems });\n\n // Failed packages\n if (result.failures.length > 0) {\n const failureItems: string[] = [];\n for (const failure of result.failures.slice(0, 5)) {\n failureItems.push(`• ${failure.package}`);\n // Show first line of error\n const firstLine = failure.error.split('\\n')[0];\n failureItems.push(` ${firstLine?.substring(0, 80) || 'Build failed'}`);\n }\n\n if (result.failures.length > 5) {\n failureItems.push(`... and ${result.failures.length - 5} more failures`);\n }\n\n sections.push({ header: '❌ Failed Packages', items: failureItems });\n }\n\n // Stale builds\n if (result.staleBuilds.length > 0) {\n const staleItems = result.staleBuilds.slice(0, 5).map((s) => `• ${s.package}`);\n\n if (result.staleBuilds.length > 5) {\n staleItems.push(`... and ${result.staleBuilds.length - 5} more`);\n }\n\n sections.push({\n header: '⚠️ Stale Builds (dist/ older than src/)',\n items: staleItems,\n });\n }\n\n // Summary\n const summaryItems = [\n `Total packages: ${result.totalPackages}`,\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '💾 Cached (use --refresh to recheck)' : '🔄 Fresh check',\n ];\n\n sections.push({ header: 'Summary', items: summaryItems });\n\n const title =\n result.failing === 0\n ? '✅ All Builds Passing'\n : `❌ ${result.failing} Build Failure(s) Detected`;\n\n ui?.success?.('Build check completed', {\n title,\n sections,\n });\n}\n"]}
|
|
@@ -9,7 +9,7 @@ var check_tests_default = defineCommand({
|
|
|
9
9
|
handler: {
|
|
10
10
|
async execute(ctx, input) {
|
|
11
11
|
const { ui, platform } = ctx;
|
|
12
|
-
const flags = input.flags
|
|
12
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
13
13
|
const cacheKey = `${CACHE_KEYS.TESTS}:${flags.package || "all"}`;
|
|
14
14
|
if (!flags.refresh) {
|
|
15
15
|
const cached = await platform.cache.get(cacheKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/check-tests.ts"],"names":["summaryItems"],"mappings":"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","file":"check-tests.js","sourcesContent":["/**\n * quality:check-tests - Test execution and coverage tracking\n *\n * Runs tests across monorepo packages and collects coverage statistics.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { runTests } from '@kb-labs/quality-core/tests';\nimport { CACHE_KEYS, type TestRunResult } from '@kb-labs/quality-contracts';\nimport { type CheckTestsFlags } from './flags.js';\n\n// Input type with backward compatibility\ntype CheckTestsInput = CheckTestsFlags & { argv?: string[] };\n\ntype CheckTestsCommandResult = {\n exitCode: number;\n result?: TestRunResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:check-tests',\n description: 'Run tests and track coverage across monorepo',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: CheckTestsInput\n ): Promise<CheckTestsCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags come in input.flags object (not auto-merged)\n const flags = (input as any).flags ?? input;\n\n const cacheKey = `${CACHE_KEYS.TESTS}:${flags.package || 'all'}`;\n\n // Check cache unless refresh requested\n if (!flags.refresh) {\n const cached = await platform.cache.get<TestRunResult>(cacheKey);\n if (cached) {\n outputTestResults({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run tests\n const result = await runTests(ctx.cwd, {\n packageFilter: flags.package,\n timeout: flags.timeout ? Number(flags.timeout) : 60000,\n withCoverage: flags['with-coverage'],\n coverageOnly: flags['coverage-only'],\n });\n\n // Cache result (5 min TTL - tests are slower)\n await platform.cache.set(cacheKey, result, 5 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:check-tests', {\n packageFilter: flags.package || 'all',\n totalPackages: result.totalPackages,\n passing: result.passing,\n failing: result.failing,\n withCoverage: flags['with-coverage'],\n cached: false,\n });\n\n // Output results\n outputTestResults({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.failing > 0 ? 1 : 0,\n result,\n meta: { cached: false },\n };\n },\n },\n});\n\n/**\n * Output test results\n */\nfunction outputTestResults(\n result: TestRunResult & { cached: boolean },\n flags: CheckTestsInput,\n ui: any\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Status section\n const statusIcon = result.failing === 0 ? '✅' : '❌';\n const statusText = result.failing === 0 ? 'All tests passing' : 'Test failures detected';\n const statusItems = [\n `${statusIcon} ${statusText}`,\n `Total packages: ${result.totalPackages}`,\n `Passing: ${result.passing}`,\n result.failing > 0 ? `Failing: ${result.failing}` : null,\n result.skipped > 0 ? `Skipped: ${result.skipped} (no test script)` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Test Status', items: statusItems });\n\n // Test summary\n if (result.summary.totalTests > 0) {\n const summaryItems = [\n `Total tests: ${result.summary.totalTests}`,\n `Passed: ${result.summary.passedTests}`,\n result.summary.failedTests > 0 ? `Failed: ${result.summary.failedTests}` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Test Summary', items: summaryItems });\n }\n\n // Failed packages\n if (result.failures.length > 0) {\n const failureItems: string[] = [];\n for (const failure of result.failures.slice(0, 5)) {\n failureItems.push(`❌ ${failure.package}`);\n if (failure.failedTests && failure.totalTests) {\n failureItems.push(` ${failure.failedTests}/${failure.totalTests} tests failed`);\n }\n // Show first line of error\n const firstLine = failure.error.split('\\n')[0];\n failureItems.push(` ${firstLine?.substring(0, 80) || 'Test failed'}`);\n }\n\n if (result.failures.length > 5) {\n failureItems.push(`... and ${result.failures.length - 5} more failures`);\n }\n\n sections.push({ header: 'Failed Packages', items: failureItems });\n }\n\n // Coverage section (if available)\n if (result.coverage.packages.length > 0) {\n const coverageItems: string[] = [];\n coverageItems.push(`Average coverage: ${result.coverage.avgCoverage.toFixed(1)}%`);\n coverageItems.push('');\n\n const topPackages = result.coverage.packages\n .sort((a, b) => b.lines - a.lines)\n .slice(0, 5);\n\n for (const pkg of topPackages) {\n coverageItems.push(`${pkg.name}`);\n coverageItems.push(\n ` Lines: ${pkg.lines.toFixed(1)}% | Statements: ${pkg.statements.toFixed(1)}% | Functions: ${pkg.functions.toFixed(1)}% | Branches: ${pkg.branches.toFixed(1)}%`\n );\n }\n\n if (result.coverage.packages.length > 5) {\n coverageItems.push(`... and ${result.coverage.packages.length - 5} more packages`);\n }\n\n sections.push({ header: 'Coverage', items: coverageItems });\n }\n\n // Summary\n const summaryItems = [\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '💾 Cached (use --refresh to re-run)' : '🔄 Fresh run',\n ];\n\n sections.push({ header: 'Summary', items: summaryItems });\n\n const title =\n result.failing === 0\n ? '✅ All Tests Passed'\n : `❌ ${result.failing} Package(s) with Test Failures`;\n\n ui?.success?.('Test run completed', {\n title,\n sections,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/check-tests.ts"],"names":["summaryItems"],"mappings":"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","file":"check-tests.js","sourcesContent":["/**\n * quality:check-tests - Test execution and coverage tracking\n *\n * Runs tests across monorepo packages and collects coverage statistics.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { runTests } from '@kb-labs/quality-core/tests';\nimport { CACHE_KEYS, type TestRunResult } from '@kb-labs/quality-contracts';\nimport { type CheckTestsFlags } from './flags.js';\n\n// Input type with backward compatibility\ntype CheckTestsInput = CheckTestsFlags & { argv?: string[] };\n\ntype CheckTestsCommandResult = {\n exitCode: number;\n result?: TestRunResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:check-tests',\n description: 'Run tests and track coverage across monorepo',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: CheckTestsInput\n ): Promise<CheckTestsCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: CheckTestsInput }).flags\n : input;\n\n const cacheKey = `${CACHE_KEYS.TESTS}:${flags.package || 'all'}`;\n\n // Check cache unless refresh requested\n if (!flags.refresh) {\n const cached = await platform.cache.get<TestRunResult>(cacheKey);\n if (cached) {\n outputTestResults({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run tests\n const result = await runTests(ctx.cwd, {\n packageFilter: flags.package,\n timeout: flags.timeout ? Number(flags.timeout) : 60000,\n withCoverage: flags['with-coverage'],\n coverageOnly: flags['coverage-only'],\n });\n\n // Cache result (5 min TTL - tests are slower)\n await platform.cache.set(cacheKey, result, 5 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:check-tests', {\n packageFilter: flags.package || 'all',\n totalPackages: result.totalPackages,\n passing: result.passing,\n failing: result.failing,\n withCoverage: flags['with-coverage'],\n cached: false,\n });\n\n // Output results\n outputTestResults({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.failing > 0 ? 1 : 0,\n result,\n meta: { cached: false },\n };\n },\n },\n});\n\n/**\n * Output test results\n */\nfunction outputTestResults(\n result: TestRunResult & { cached: boolean },\n flags: CheckTestsInput,\n ui: PluginContextV3['ui']\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Status section\n const statusIcon = result.failing === 0 ? '✅' : '❌';\n const statusText = result.failing === 0 ? 'All tests passing' : 'Test failures detected';\n const statusItems = [\n `${statusIcon} ${statusText}`,\n `Total packages: ${result.totalPackages}`,\n `Passing: ${result.passing}`,\n result.failing > 0 ? `Failing: ${result.failing}` : null,\n result.skipped > 0 ? `Skipped: ${result.skipped} (no test script)` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Test Status', items: statusItems });\n\n // Test summary\n if (result.summary.totalTests > 0) {\n const summaryItems = [\n `Total tests: ${result.summary.totalTests}`,\n `Passed: ${result.summary.passedTests}`,\n result.summary.failedTests > 0 ? `Failed: ${result.summary.failedTests}` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Test Summary', items: summaryItems });\n }\n\n // Failed packages\n if (result.failures.length > 0) {\n const failureItems: string[] = [];\n for (const failure of result.failures.slice(0, 5)) {\n failureItems.push(`❌ ${failure.package}`);\n if (failure.failedTests && failure.totalTests) {\n failureItems.push(` ${failure.failedTests}/${failure.totalTests} tests failed`);\n }\n // Show first line of error\n const firstLine = failure.error.split('\\n')[0];\n failureItems.push(` ${firstLine?.substring(0, 80) || 'Test failed'}`);\n }\n\n if (result.failures.length > 5) {\n failureItems.push(`... and ${result.failures.length - 5} more failures`);\n }\n\n sections.push({ header: 'Failed Packages', items: failureItems });\n }\n\n // Coverage section (if available)\n if (result.coverage.packages.length > 0) {\n const coverageItems: string[] = [];\n coverageItems.push(`Average coverage: ${result.coverage.avgCoverage.toFixed(1)}%`);\n coverageItems.push('');\n\n const topPackages = result.coverage.packages\n .sort((a, b) => b.lines - a.lines)\n .slice(0, 5);\n\n for (const pkg of topPackages) {\n coverageItems.push(`${pkg.name}`);\n coverageItems.push(\n ` Lines: ${pkg.lines.toFixed(1)}% | Statements: ${pkg.statements.toFixed(1)}% | Functions: ${pkg.functions.toFixed(1)}% | Branches: ${pkg.branches.toFixed(1)}%`\n );\n }\n\n if (result.coverage.packages.length > 5) {\n coverageItems.push(`... and ${result.coverage.packages.length - 5} more packages`);\n }\n\n sections.push({ header: 'Coverage', items: coverageItems });\n }\n\n // Summary\n const summaryItems = [\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '💾 Cached (use --refresh to re-run)' : '🔄 Fresh run',\n ];\n\n sections.push({ header: 'Summary', items: summaryItems });\n\n const title =\n result.failing === 0\n ? '✅ All Tests Passed'\n : `❌ ${result.failing} Package(s) with Test Failures`;\n\n ui?.success?.('Test run completed', {\n title,\n sections,\n });\n}\n"]}
|
|
@@ -9,7 +9,7 @@ var check_types_default = defineCommand({
|
|
|
9
9
|
handler: {
|
|
10
10
|
async execute(ctx, input) {
|
|
11
11
|
const { ui, platform } = ctx;
|
|
12
|
-
const flags = input.flags
|
|
12
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
13
13
|
const cacheKey = `${CACHE_KEYS.TYPE_ANALYSIS}:${flags.package || "all"}`;
|
|
14
14
|
if (!flags.refresh) {
|
|
15
15
|
const cached = await platform.cache.get(cacheKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/check-types.ts"],"names":[],"mappings":"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","file":"check-types.js","sourcesContent":["/**\n * quality:check-types - TypeScript type safety analysis\n *\n * Analyzes TypeScript type errors, warnings, and coverage across monorepo.\n * Uses TypeScript Compiler API for semantic analysis.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { analyzeTypes } from '@kb-labs/quality-core/types';\nimport { CACHE_KEYS, type TypeAnalysisResult } from '@kb-labs/quality-contracts';\nimport { type CheckTypesFlags } from './flags.js';\n\n// Input type with backward compatibility\ntype CheckTypesInput = CheckTypesFlags & { argv?: string[] };\n\ntype CheckTypesCommandResult = {\n exitCode: number;\n result?: TypeAnalysisResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:check-types',\n description: 'Analyze TypeScript type safety across monorepo',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: CheckTypesInput\n ): Promise<CheckTypesCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags come in input.flags object (not auto-merged)\n const flags = (input as any).flags ?? input;\n\n const cacheKey = `${CACHE_KEYS.TYPE_ANALYSIS}:${flags.package || 'all'}`;\n\n // Check cache unless refresh requested\n if (!flags.refresh) {\n const cached = await platform.cache.get<TypeAnalysisResult>(cacheKey);\n if (cached) {\n outputTypeAnalysis({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.totalErrors > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run type analysis\n const result = await analyzeTypes(ctx.cwd, {\n packageFilter: flags.package,\n errorsOnly: flags['errors-only'],\n });\n\n // Cache result (10 min TTL)\n await platform.cache.set(cacheKey, result, 10 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:check-types', {\n packageFilter: flags.package || 'all',\n totalPackages: result.totalPackages,\n totalErrors: result.totalErrors,\n avgCoverage: result.avgCoverage,\n cached: false,\n });\n\n // Output results\n outputTypeAnalysis({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.totalErrors > 0 ? 1 : 0,\n result,\n meta: { cached: false },\n };\n },\n },\n});\n\n/**\n * Output type analysis results\n */\nfunction outputTypeAnalysis(\n result: TypeAnalysisResult & { cached: boolean },\n flags: CheckTypesInput,\n ui: any\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const errorsOnly = flags['errors-only'] || false;\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Status section\n const statusIcon = result.totalErrors === 0 ? '✅' : '❌';\n const statusText =\n result.totalErrors === 0 ? 'All packages passed type checks' : 'Type errors detected';\n const statusItems = [\n `${statusIcon} ${statusText}`,\n `Analyzed: ${result.totalPackages} package(s)`,\n `Errors: ${result.totalErrors}`,\n `Warnings: ${result.totalWarnings}`,\n `Avg Coverage: ${result.avgCoverage.toFixed(1)}%`,\n ];\n\n sections.push({ header: 'Type Safety Status', items: statusItems });\n\n // Packages with errors\n if (result.packagesWithErrors > 0) {\n const errorItems: string[] = [];\n const packagesToShow = result.packages\n .filter((pkg) => !errorsOnly || pkg.errors > 0)\n .slice(0, 10);\n\n for (const pkg of packagesToShow) {\n const status = pkg.errors > 0 ? '❌' : '✅';\n errorItems.push(`${status} ${pkg.name}`);\n\n const details = [\n pkg.errors > 0 ? `${pkg.errors} error(s)` : null,\n pkg.warnings > 0 ? `${pkg.warnings} warning(s)` : null,\n `${pkg.coverage.toFixed(1)}% coverage`,\n pkg.anyCount > 0 ? `${pkg.anyCount} any` : null,\n pkg.tsIgnoreCount > 0 ? `${pkg.tsIgnoreCount} @ts-ignore` : null,\n ]\n .filter(Boolean)\n .join(', ');\n\n errorItems.push(` ${details}`);\n }\n\n if (result.packages.length > 10) {\n errorItems.push(`... and ${result.packages.length - 10} more packages`);\n }\n\n sections.push({\n header: `Packages with Type Errors (${result.packagesWithErrors})`,\n items: errorItems,\n });\n }\n\n // Coverage distribution\n const excellent = result.packages.filter((p) => p.coverage >= 90).length;\n const good = result.packages.filter((p) => p.coverage >= 70 && p.coverage < 90).length;\n const poor = result.packages.filter((p) => p.coverage < 70).length;\n\n if (result.packages.length > 0) {\n const coverageItems = [\n `✅ Excellent (≥90%): ${excellent} package(s)`,\n `⚠️ Good (70-90%): ${good} package(s)`,\n poor > 0 ? `❌ Poor (<70%): ${poor} package(s)` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Type Coverage Distribution', items: coverageItems });\n }\n\n // Summary\n const summaryItems = [\n `Total packages: ${result.totalPackages}`,\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '💾 Cached (use --refresh to recheck)' : '🔄 Fresh analysis',\n ];\n\n sections.push({ header: 'Summary', items: summaryItems });\n\n const title =\n result.totalErrors === 0\n ? '✅ All Type Checks Passed'\n : `❌ ${result.packagesWithErrors} Package(s) with Type Errors`;\n\n ui?.success?.('Type analysis completed', {\n title,\n sections,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/check-types.ts"],"names":[],"mappings":"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","file":"check-types.js","sourcesContent":["/**\n * quality:check-types - TypeScript type safety analysis\n *\n * Analyzes TypeScript type errors, warnings, and coverage across monorepo.\n * Uses TypeScript Compiler API for semantic analysis.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { analyzeTypes } from '@kb-labs/quality-core/types';\nimport { CACHE_KEYS, type TypeAnalysisResult } from '@kb-labs/quality-contracts';\nimport { type CheckTypesFlags } from './flags.js';\n\n// Input type with backward compatibility\ntype CheckTypesInput = CheckTypesFlags & { argv?: string[] };\n\ntype CheckTypesCommandResult = {\n exitCode: number;\n result?: TypeAnalysisResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:check-types',\n description: 'Analyze TypeScript type safety across monorepo',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: CheckTypesInput\n ): Promise<CheckTypesCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: CheckTypesInput }).flags\n : input;\n\n const cacheKey = `${CACHE_KEYS.TYPE_ANALYSIS}:${flags.package || 'all'}`;\n\n // Check cache unless refresh requested\n if (!flags.refresh) {\n const cached = await platform.cache.get<TypeAnalysisResult>(cacheKey);\n if (cached) {\n outputTypeAnalysis({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.totalErrors > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run type analysis\n const result = await analyzeTypes(ctx.cwd, {\n packageFilter: flags.package,\n errorsOnly: flags['errors-only'],\n });\n\n // Cache result (10 min TTL)\n await platform.cache.set(cacheKey, result, 10 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:check-types', {\n packageFilter: flags.package || 'all',\n totalPackages: result.totalPackages,\n totalErrors: result.totalErrors,\n avgCoverage: result.avgCoverage,\n cached: false,\n });\n\n // Output results\n outputTypeAnalysis({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.totalErrors > 0 ? 1 : 0,\n result,\n meta: { cached: false },\n };\n },\n },\n});\n\n/**\n * Output type analysis results\n */\nfunction outputTypeAnalysis(\n result: TypeAnalysisResult & { cached: boolean },\n flags: CheckTypesInput,\n ui: PluginContextV3['ui']\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const errorsOnly = flags['errors-only'] || false;\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Status section\n const statusIcon = result.totalErrors === 0 ? '✅' : '❌';\n const statusText =\n result.totalErrors === 0 ? 'All packages passed type checks' : 'Type errors detected';\n const statusItems = [\n `${statusIcon} ${statusText}`,\n `Analyzed: ${result.totalPackages} package(s)`,\n `Errors: ${result.totalErrors}`,\n `Warnings: ${result.totalWarnings}`,\n `Avg Coverage: ${result.avgCoverage.toFixed(1)}%`,\n ];\n\n sections.push({ header: 'Type Safety Status', items: statusItems });\n\n // Packages with errors\n if (result.packagesWithErrors > 0) {\n const errorItems: string[] = [];\n const packagesToShow = result.packages\n .filter((pkg) => !errorsOnly || pkg.errors > 0)\n .slice(0, 10);\n\n for (const pkg of packagesToShow) {\n const status = pkg.errors > 0 ? '❌' : '✅';\n errorItems.push(`${status} ${pkg.name}`);\n\n const details = [\n pkg.errors > 0 ? `${pkg.errors} error(s)` : null,\n pkg.warnings > 0 ? `${pkg.warnings} warning(s)` : null,\n `${pkg.coverage.toFixed(1)}% coverage`,\n pkg.anyCount > 0 ? `${pkg.anyCount} any` : null,\n pkg.tsIgnoreCount > 0 ? `${pkg.tsIgnoreCount} @ts-ignore` : null,\n ]\n .filter(Boolean)\n .join(', ');\n\n errorItems.push(` ${details}`);\n }\n\n if (result.packages.length > 10) {\n errorItems.push(`... and ${result.packages.length - 10} more packages`);\n }\n\n sections.push({\n header: `Packages with Type Errors (${result.packagesWithErrors})`,\n items: errorItems,\n });\n }\n\n // Coverage distribution\n const excellent = result.packages.filter((p) => p.coverage >= 90).length;\n const good = result.packages.filter((p) => p.coverage >= 70 && p.coverage < 90).length;\n const poor = result.packages.filter((p) => p.coverage < 70).length;\n\n if (result.packages.length > 0) {\n const coverageItems = [\n `✅ Excellent (≥90%): ${excellent} package(s)`,\n `⚠️ Good (70-90%): ${good} package(s)`,\n poor > 0 ? `❌ Poor (<70%): ${poor} package(s)` : null,\n ].filter(Boolean) as string[];\n\n sections.push({ header: 'Type Coverage Distribution', items: coverageItems });\n }\n\n // Summary\n const summaryItems = [\n `Total packages: ${result.totalPackages}`,\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '💾 Cached (use --refresh to recheck)' : '🔄 Fresh analysis',\n ];\n\n sections.push({ header: 'Summary', items: summaryItems });\n\n const title =\n result.totalErrors === 0\n ? '✅ All Type Checks Passed'\n : `❌ ${result.packagesWithErrors} Package(s) with Type Errors`;\n\n ui?.success?.('Type analysis completed', {\n title,\n sections,\n });\n}\n"]}
|
|
@@ -8,7 +8,7 @@ var cycles_default = defineCommand({
|
|
|
8
8
|
handler: {
|
|
9
9
|
async execute(ctx, input) {
|
|
10
10
|
const { ui } = ctx;
|
|
11
|
-
const flags = input.flags
|
|
11
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
12
12
|
const graph = buildDependencyGraph(ctx.cwd);
|
|
13
13
|
const cycles = findCircularDependencies(graph);
|
|
14
14
|
outputCycles(cycles, flags, ui);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/cycles.ts"],"names":[],"mappings":";;;;AAwBA,IAAO,iBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,gBAAA;AAAA,EACJ,WAAA,EAAa,0CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkD;AACpF,MAAA,MAAM,EAAE,IAAG,GAAI,GAAA;AAGf,MAAA,MAAM,KAAA,GAAS,
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/cycles.ts"],"names":[],"mappings":"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","file":"cycles.js","sourcesContent":["/**\n * quality:cycles - Detect circular dependencies\n *\n * Uses DFS to find all circular dependency chains in the monorepo.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport {\n buildDependencyGraph,\n findCircularDependencies,\n} from '@kb-labs/quality-core/graph';\n\ntype CyclesFlags = {\n json?: boolean;\n argv?: string[];\n};\n\ntype CyclesInput = CyclesFlags & { argv?: string[] };\n\ntype CyclesCommandResult = {\n exitCode: number;\n cycles?: string[][];\n};\n\nexport default defineCommand({\n id: 'quality:cycles',\n description: 'Detect circular dependencies in monorepo',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CyclesInput): Promise<CyclesCommandResult> {\n const { ui } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: CyclesInput }).flags\n : input;\n\n // Build dependency graph\n const graph = buildDependencyGraph(ctx.cwd);\n\n // Find circular dependencies\n const cycles = findCircularDependencies(graph);\n\n // Output results\n outputCycles(cycles, flags, ui);\n\n return {\n exitCode: cycles.length > 0 ? 1 : 0,\n cycles,\n };\n },\n },\n});\n\n/**\n * Output circular dependencies\n */\nfunction outputCycles(cycles: string[][], flags: Record<string, unknown>, ui: PluginContextV3['ui']) {\n if (flags.json) {\n ui?.json?.({ cycles, count: cycles.length });\n return;\n }\n\n if (cycles.length === 0) {\n ui?.success?.('No circular dependencies found', {\n title: '✅ Circular Dependencies Check',\n sections: [\n {\n header: 'Result',\n items: ['✅ No circular dependencies detected'],\n },\n ],\n });\n return;\n }\n\n // Build sections\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Summary\n sections.push({\n header: 'Summary',\n items: [\n `⚠️ Found ${cycles.length} circular dependency chain(s)`,\n 'These must be broken to enable clean builds',\n ],\n });\n\n // Show each cycle\n for (let i = 0; i < cycles.length; i++) {\n const cycle = cycles[i];\n if (!cycle) {continue;}\n const cycleItems: string[] = [];\n\n for (let j = 0; j < cycle.length; j++) {\n const pkg = cycle[j];\n if (j === cycle.length - 1) {\n cycleItems.push(` ${j + 1}. ${pkg}`);\n const firstPkg = cycle[0];\n cycleItems.push(` ${j + 2}. ${firstPkg ?? '?'} ⬅ circular!`);\n } else {\n cycleItems.push(` ${j + 1}. ${pkg}`);\n }\n }\n\n sections.push({\n header: `Cycle ${i + 1} (${cycle.length} packages)`,\n items: cycleItems,\n });\n }\n\n // Recommendations\n sections.push({\n header: 'Recommendations',\n items: [\n '1. Extract shared code into a new package',\n '2. Move one dependency to devDependencies',\n '3. Refactor to remove bidirectional dependencies',\n '4. Use dependency injection patterns',\n ],\n });\n\n ui?.error?.('Circular dependencies detected', {\n title: `⚠️ Circular Dependencies Detected (${cycles.length})`,\n sections,\n });\n}\n"]}
|
|
@@ -9,7 +9,7 @@ var dead_code_default = defineCommand({
|
|
|
9
9
|
handler: {
|
|
10
10
|
async execute(ctx, input) {
|
|
11
11
|
const { ui, platform } = ctx;
|
|
12
|
-
const flags = input.flags
|
|
12
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
13
13
|
if (flags["list-backups"]) {
|
|
14
14
|
const backups = listBackups(ctx.cwd);
|
|
15
15
|
if (flags.json) {
|
|
@@ -33,9 +33,9 @@ var dead_code_default = defineCommand({
|
|
|
33
33
|
return { exitCode: 0 };
|
|
34
34
|
} catch (err) {
|
|
35
35
|
if (flags.json) {
|
|
36
|
-
ui?.json?.({ error: err.message });
|
|
36
|
+
ui?.json?.({ error: err instanceof Error ? err.message : String(err) });
|
|
37
37
|
} else {
|
|
38
|
-
ui?.error?.(err.message);
|
|
38
|
+
ui?.error?.(err instanceof Error ? err.message : String(err));
|
|
39
39
|
}
|
|
40
40
|
return { exitCode: 1 };
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/dead-code.ts"],"names":["result"],"mappings":"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","file":"dead-code.js","sourcesContent":["/**\n * quality:dead-code - Detect and optionally remove dead source files\n *\n * Uses reachability analysis: builds import graph, walks from entry points,\n * files not reachable are dead. Zero false positives by design.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { DeadCodeResult, DeadCodeRemovalResult, DeadCodeBackupManifest } from '@kb-labs/quality-contracts';\nimport { CACHE_KEYS } from '@kb-labs/quality-contracts';\nimport {\n scanDeadFiles,\n removeDeadFiles,\n restoreFromBackup,\n listBackups,\n} from '@kb-labs/quality-core/dead-code';\nimport type { DeadCodeFlags } from './flags.js';\n\ntype DeadCodeInput = DeadCodeFlags & { argv?: string[] };\n\ntype DeadCodeCommandResult = {\n exitCode: number;\n result?: DeadCodeResult | DeadCodeRemovalResult | DeadCodeBackupManifest[];\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:dead-code',\n description: 'Detect and optionally remove dead (unreachable) source files',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: DeadCodeInput,\n ): Promise<DeadCodeCommandResult> {\n const { ui, platform } = ctx;\n const flags = (input as any).flags ?? input;\n\n // --- Sub-operations ---\n\n // List backups\n if (flags['list-backups']) {\n const backups = listBackups(ctx.cwd);\n if (flags.json) {\n ui?.json?.(backups);\n } else {\n outputBackupList(backups, ui);\n }\n return { exitCode: 0, result: backups };\n }\n\n // Restore from backup\n if (flags.restore) {\n try {\n const result = await restoreFromBackup(ctx.cwd, flags.restore);\n if (flags.json) {\n ui?.json?.(result);\n } else {\n ui?.success?.(`Restored ${result.restoredFiles} file(s) from backup ${flags.restore}`, {});\n if (result.restoredExports > 0) {\n ui?.info?.(`Note: ${result.restoredExports} package.json export(s) were cleaned. You may need to rebuild.`);\n }\n }\n return { exitCode: 0 };\n } catch (err: any) {\n if (flags.json) {\n ui?.json?.({ error: err.message });\n } else {\n ui?.error?.(err.message);\n }\n return { exitCode: 1 };\n }\n }\n\n // --- Main scan flow ---\n\n // Check cache\n const cacheKey = `${CACHE_KEYS.DEAD_CODE}:${flags.package || 'all'}`;\n if (!flags.refresh && !flags['auto-remove']) {\n const cached = await platform.cache.get<DeadCodeResult>(cacheKey);\n if (cached) {\n outputDeadCodeReport({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.summary.totalDead > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run scan\n const result = await scanDeadFiles(ctx.cwd, {\n packageFilter: flags.package,\n verbose: flags.verbose,\n });\n\n // Cache results for 5 minutes\n await platform.cache.set(cacheKey, result, 5 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:dead-code', {\n totalPackages: result.summary.totalPackages,\n totalFiles: result.summary.totalFiles,\n totalDead: result.summary.totalDead,\n totalDeadBytes: result.summary.totalDeadBytes,\n duration: result.duration,\n autoRemove: !!flags['auto-remove'],\n dryRun: !!flags['dry-run'],\n });\n\n // Auto-remove flow\n if (flags['auto-remove']) {\n if (result.summary.totalDead === 0) {\n if (flags.json) {\n ui?.json?.({ message: 'No dead files found', ...result });\n } else {\n ui?.success?.('No dead files found. Nothing to remove.', {});\n }\n return { exitCode: 0, result };\n }\n\n const removalResult = await removeDeadFiles(ctx.cwd, result, {\n dryRun: flags['dry-run'],\n });\n\n if (flags.json) {\n ui?.json?.(removalResult);\n } else {\n outputRemovalReport(removalResult, flags, ui);\n }\n\n return { exitCode: 0, result: removalResult };\n }\n\n // Output scan results\n outputDeadCodeReport({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.summary.totalDead > 0 ? 1 : 0,\n result,\n };\n },\n },\n});\n\n// --- Output helpers ---\n\nfunction outputDeadCodeReport(\n result: DeadCodeResult & { cached?: boolean },\n flags: any,\n ui: any,\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Per-package results (only packages with dead files)\n const packagesWithDead = result.packages.filter(p => p.deadFiles.length > 0);\n\n if (packagesWithDead.length > 0) {\n const items: string[] = [];\n for (const pkg of packagesWithDead) {\n items.push(`${pkg.packageName} (${pkg.deadFiles.length} dead file${pkg.deadFiles.length === 1 ? '' : 's'})`);\n for (const dead of pkg.deadFiles.slice(0, 5)) {\n const sizeKb = (dead.sizeBytes / 1024).toFixed(1);\n items.push(` ${dead.relativePath} (${sizeKb} KB)`);\n }\n if (pkg.deadFiles.length > 5) {\n items.push(` ... and ${pkg.deadFiles.length - 5} more`);\n }\n }\n sections.push({ header: 'Dead Files', items });\n }\n\n // Verbose: show entry points\n if (flags.verbose) {\n for (const pkg of result.packages) {\n if (pkg.entryPoints.length > 0) {\n const items = pkg.entryPoints.slice(0, 10).map(ep => ` ${ep}`);\n if (pkg.entryPoints.length > 10) {\n items.push(` ... and ${pkg.entryPoints.length - 10} more`);\n }\n sections.push({ header: `Entry Points: ${pkg.packageName}`, items });\n }\n }\n }\n\n // Warnings\n const allWarnings = result.packages.flatMap(p => p.warnings);\n if (allWarnings.length > 0) {\n sections.push({\n header: 'Warnings',\n items: allWarnings.slice(0, 10),\n });\n }\n\n // Summary\n const totalDeadKb = (result.summary.totalDeadBytes / 1024).toFixed(1);\n const summaryItems = [\n `Packages scanned: ${result.summary.totalPackages}`,\n `Total source files: ${result.summary.totalFiles}`,\n `Alive files: ${result.summary.totalAlive}`,\n `Dead files: ${result.summary.totalDead}`,\n result.summary.totalDead > 0 ? `Dead code size: ${totalDeadKb} KB` : null,\n result.summary.emptyDirectories.length > 0\n ? `Empty directories: ${result.summary.emptyDirectories.length}`\n : null,\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '(cached — use --refresh to rescan)' : null,\n ].filter(Boolean) as string[];\n sections.push({ header: 'Summary', items: summaryItems });\n\n // Recommendations\n if (result.summary.totalDead > 0) {\n sections.push({\n header: 'Next Steps',\n items: [\n 'Run with --auto-remove --dry-run to preview removal',\n 'Run with --auto-remove to remove and create backup',\n 'Run with --verbose to see entry points',\n ],\n });\n }\n\n const title =\n result.summary.totalDead === 0\n ? 'No dead files found'\n : `${result.summary.totalDead} dead file(s) found`;\n\n ui?.success?.('Dead code analysis completed', { title, sections });\n}\n\nfunction outputRemovalReport(\n result: DeadCodeRemovalResult,\n flags: any,\n ui: any,\n): void {\n const isDryRun = flags['dry-run'];\n const prefix = isDryRun ? '[DRY RUN] Would' : 'Successfully';\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n const items = [\n `${prefix} remove ${result.filesRemoved} file(s)`,\n `${prefix} free ${(result.bytesRemoved / 1024).toFixed(1)} KB`,\n ];\n\n if (result.emptyDirsRemoved > 0) {\n items.push(`${prefix} remove ${result.emptyDirsRemoved} empty director${result.emptyDirsRemoved === 1 ? 'y' : 'ies'}`);\n }\n if (result.exportsCleanedUp > 0) {\n items.push(`${prefix} clean ${result.exportsCleanedUp} package.json export(s)`);\n }\n\n sections.push({ header: isDryRun ? 'Preview' : 'Removal Complete', items });\n\n if (!isDryRun) {\n sections.push({\n header: 'Backup',\n items: [\n `Backup ID: ${result.backupId}`,\n `To restore: pnpm kb quality:dead-code --restore ${result.backupId}`,\n ],\n });\n }\n\n // Show removed files\n const fileItems: string[] = [];\n for (const file of result.manifest.removedFiles.slice(0, 10)) {\n const sizeKb = (file.sizeBytes / 1024).toFixed(1);\n fileItems.push(`${file.backupPath} (${sizeKb} KB)`);\n }\n if (result.manifest.removedFiles.length > 10) {\n fileItems.push(`... and ${result.manifest.removedFiles.length - 10} more`);\n }\n sections.push({ header: 'Files', items: fileItems });\n\n const title = isDryRun\n ? `[DRY RUN] Would remove ${result.filesRemoved} file(s)`\n : `Removed ${result.filesRemoved} file(s)`;\n\n ui?.success?.(title, { title, sections });\n}\n\nfunction outputBackupList(\n backups: DeadCodeBackupManifest[],\n ui: any,\n): void {\n if (backups.length === 0) {\n ui?.info?.('No backups found.');\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n for (const backup of backups) {\n const date = new Date(backup.createdAt).toLocaleString();\n const items = [\n `Date: ${date}`,\n `Git: ${backup.gitBranch} @ ${backup.gitSha.slice(0, 8)}`,\n `Files: ${backup.totalFilesRemoved}`,\n `Size: ${(backup.totalBytesRemoved / 1024).toFixed(1)} KB`,\n `Restore: pnpm kb quality:dead-code --restore ${backup.id}`,\n ];\n sections.push({ header: `Backup: ${backup.id}`, items });\n }\n\n ui?.success?.(`${backups.length} backup(s) found`, {\n title: 'Dead Code Backups',\n sections,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/dead-code.ts"],"names":["result"],"mappings":"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","file":"dead-code.js","sourcesContent":["/**\n * quality:dead-code - Detect and optionally remove dead source files\n *\n * Uses reachability analysis: builds import graph, walks from entry points,\n * files not reachable are dead. Zero false positives by design.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { UIFacade } from '@kb-labs/sdk';\nimport type { DeadCodeResult, DeadCodeRemovalResult, DeadCodeBackupManifest } from '@kb-labs/quality-contracts';\nimport { CACHE_KEYS } from '@kb-labs/quality-contracts';\nimport {\n scanDeadFiles,\n removeDeadFiles,\n restoreFromBackup,\n listBackups,\n} from '@kb-labs/quality-core/dead-code';\nimport type { DeadCodeFlags } from './flags.js';\n\ntype DeadCodeInput = DeadCodeFlags & { argv?: string[] };\n\ntype DeadCodeCommandResult = {\n exitCode: number;\n result?: DeadCodeResult | DeadCodeRemovalResult | DeadCodeBackupManifest[];\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:dead-code',\n description: 'Detect and optionally remove dead (unreachable) source files',\n\n handler: {\n async execute(\n ctx: PluginContextV3,\n input: DeadCodeInput,\n ): Promise<DeadCodeCommandResult> {\n const { ui, platform } = ctx;\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: DeadCodeInput }).flags\n : input;\n\n // --- Sub-operations ---\n\n // List backups\n if (flags['list-backups']) {\n const backups = listBackups(ctx.cwd);\n if (flags.json) {\n ui?.json?.(backups);\n } else {\n outputBackupList(backups, ui);\n }\n return { exitCode: 0, result: backups };\n }\n\n // Restore from backup\n if (flags.restore) {\n try {\n const result = await restoreFromBackup(ctx.cwd, flags.restore);\n if (flags.json) {\n ui?.json?.(result);\n } else {\n ui?.success?.(`Restored ${result.restoredFiles} file(s) from backup ${flags.restore}`, {});\n if (result.restoredExports > 0) {\n ui?.info?.(`Note: ${result.restoredExports} package.json export(s) were cleaned. You may need to rebuild.`);\n }\n }\n return { exitCode: 0 };\n } catch (err: unknown) {\n if (flags.json) {\n ui?.json?.({ error: err instanceof Error ? err.message : String(err) });\n } else {\n ui?.error?.(err instanceof Error ? err.message : String(err));\n }\n return { exitCode: 1 };\n }\n }\n\n // --- Main scan flow ---\n\n // Check cache\n const cacheKey = `${CACHE_KEYS.DEAD_CODE}:${flags.package || 'all'}`;\n if (!flags.refresh && !flags['auto-remove']) {\n const cached = await platform.cache.get<DeadCodeResult>(cacheKey);\n if (cached) {\n outputDeadCodeReport({ ...cached, cached: true }, flags, ui);\n return { exitCode: cached.summary.totalDead > 0 ? 1 : 0, result: cached };\n }\n }\n\n // Run scan\n const result = await scanDeadFiles(ctx.cwd, {\n packageFilter: flags.package,\n verbose: flags.verbose,\n });\n\n // Cache results for 5 minutes\n await platform.cache.set(cacheKey, result, 5 * 60 * 1000);\n\n // Track analytics\n await platform.analytics.track('quality:dead-code', {\n totalPackages: result.summary.totalPackages,\n totalFiles: result.summary.totalFiles,\n totalDead: result.summary.totalDead,\n totalDeadBytes: result.summary.totalDeadBytes,\n duration: result.duration,\n autoRemove: !!flags['auto-remove'],\n dryRun: !!flags['dry-run'],\n });\n\n // Auto-remove flow\n if (flags['auto-remove']) {\n if (result.summary.totalDead === 0) {\n if (flags.json) {\n ui?.json?.({ message: 'No dead files found', ...result });\n } else {\n ui?.success?.('No dead files found. Nothing to remove.', {});\n }\n return { exitCode: 0, result };\n }\n\n const removalResult = await removeDeadFiles(ctx.cwd, result, {\n dryRun: flags['dry-run'],\n });\n\n if (flags.json) {\n ui?.json?.(removalResult);\n } else {\n outputRemovalReport(removalResult, flags, ui);\n }\n\n return { exitCode: 0, result: removalResult };\n }\n\n // Output scan results\n outputDeadCodeReport({ ...result, cached: false }, flags, ui);\n\n return {\n exitCode: result.summary.totalDead > 0 ? 1 : 0,\n result,\n };\n },\n },\n});\n\n// --- Output helpers ---\n\nfunction outputDeadCodeReport(\n result: DeadCodeResult & { cached?: boolean },\n flags: DeadCodeFlags,\n ui: UIFacade | undefined,\n): void {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Per-package results (only packages with dead files)\n const packagesWithDead = result.packages.filter(p => p.deadFiles.length > 0);\n\n if (packagesWithDead.length > 0) {\n const items: string[] = [];\n for (const pkg of packagesWithDead) {\n items.push(`${pkg.packageName} (${pkg.deadFiles.length} dead file${pkg.deadFiles.length === 1 ? '' : 's'})`);\n for (const dead of pkg.deadFiles.slice(0, 5)) {\n const sizeKb = (dead.sizeBytes / 1024).toFixed(1);\n items.push(` ${dead.relativePath} (${sizeKb} KB)`);\n }\n if (pkg.deadFiles.length > 5) {\n items.push(` ... and ${pkg.deadFiles.length - 5} more`);\n }\n }\n sections.push({ header: 'Dead Files', items });\n }\n\n // Verbose: show entry points\n if (flags.verbose) {\n for (const pkg of result.packages) {\n if (pkg.entryPoints.length > 0) {\n const items = pkg.entryPoints.slice(0, 10).map(ep => ` ${ep}`);\n if (pkg.entryPoints.length > 10) {\n items.push(` ... and ${pkg.entryPoints.length - 10} more`);\n }\n sections.push({ header: `Entry Points: ${pkg.packageName}`, items });\n }\n }\n }\n\n // Warnings\n const allWarnings = result.packages.flatMap(p => p.warnings);\n if (allWarnings.length > 0) {\n sections.push({\n header: 'Warnings',\n items: allWarnings.slice(0, 10),\n });\n }\n\n // Summary\n const totalDeadKb = (result.summary.totalDeadBytes / 1024).toFixed(1);\n const summaryItems = [\n `Packages scanned: ${result.summary.totalPackages}`,\n `Total source files: ${result.summary.totalFiles}`,\n `Alive files: ${result.summary.totalAlive}`,\n `Dead files: ${result.summary.totalDead}`,\n result.summary.totalDead > 0 ? `Dead code size: ${totalDeadKb} KB` : null,\n result.summary.emptyDirectories.length > 0\n ? `Empty directories: ${result.summary.emptyDirectories.length}`\n : null,\n `Duration: ${(result.duration / 1000).toFixed(1)}s`,\n result.cached ? '(cached — use --refresh to rescan)' : null,\n ].filter(Boolean) as string[];\n sections.push({ header: 'Summary', items: summaryItems });\n\n // Recommendations\n if (result.summary.totalDead > 0) {\n sections.push({\n header: 'Next Steps',\n items: [\n 'Run with --auto-remove --dry-run to preview removal',\n 'Run with --auto-remove to remove and create backup',\n 'Run with --verbose to see entry points',\n ],\n });\n }\n\n const title =\n result.summary.totalDead === 0\n ? 'No dead files found'\n : `${result.summary.totalDead} dead file(s) found`;\n\n ui?.success?.('Dead code analysis completed', { title, sections });\n}\n\nfunction outputRemovalReport(\n result: DeadCodeRemovalResult,\n flags: DeadCodeFlags,\n ui: UIFacade | undefined,\n): void {\n const isDryRun = flags['dry-run'];\n const prefix = isDryRun ? '[DRY RUN] Would' : 'Successfully';\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n const items = [\n `${prefix} remove ${result.filesRemoved} file(s)`,\n `${prefix} free ${(result.bytesRemoved / 1024).toFixed(1)} KB`,\n ];\n\n if (result.emptyDirsRemoved > 0) {\n items.push(`${prefix} remove ${result.emptyDirsRemoved} empty director${result.emptyDirsRemoved === 1 ? 'y' : 'ies'}`);\n }\n if (result.exportsCleanedUp > 0) {\n items.push(`${prefix} clean ${result.exportsCleanedUp} package.json export(s)`);\n }\n\n sections.push({ header: isDryRun ? 'Preview' : 'Removal Complete', items });\n\n if (!isDryRun) {\n sections.push({\n header: 'Backup',\n items: [\n `Backup ID: ${result.backupId}`,\n `To restore: pnpm kb quality:dead-code --restore ${result.backupId}`,\n ],\n });\n }\n\n // Show removed files\n const fileItems: string[] = [];\n for (const file of result.manifest.removedFiles.slice(0, 10)) {\n const sizeKb = (file.sizeBytes / 1024).toFixed(1);\n fileItems.push(`${file.backupPath} (${sizeKb} KB)`);\n }\n if (result.manifest.removedFiles.length > 10) {\n fileItems.push(`... and ${result.manifest.removedFiles.length - 10} more`);\n }\n sections.push({ header: 'Files', items: fileItems });\n\n const title = isDryRun\n ? `[DRY RUN] Would remove ${result.filesRemoved} file(s)`\n : `Removed ${result.filesRemoved} file(s)`;\n\n ui?.success?.(title, { title, sections });\n}\n\nfunction outputBackupList(\n backups: DeadCodeBackupManifest[],\n ui: UIFacade | undefined,\n): void {\n if (backups.length === 0) {\n ui?.info?.('No backups found.');\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n for (const backup of backups) {\n const date = new Date(backup.createdAt).toLocaleString();\n const items = [\n `Date: ${date}`,\n `Git: ${backup.gitBranch} @ ${backup.gitSha.slice(0, 8)}`,\n `Files: ${backup.totalFilesRemoved}`,\n `Size: ${(backup.totalBytesRemoved / 1024).toFixed(1)} KB`,\n `Restore: pnpm kb quality:dead-code --restore ${backup.id}`,\n ];\n sections.push({ header: `Backup: ${backup.id}`, items });\n }\n\n ui?.success?.(`${backups.length} backup(s) found`, {\n title: 'Dead Code Backups',\n sections,\n });\n}\n"]}
|
|
@@ -9,7 +9,7 @@ var fix_deps_default = defineCommand({
|
|
|
9
9
|
handler: {
|
|
10
10
|
async execute(ctx, input) {
|
|
11
11
|
const { ui, platform } = ctx;
|
|
12
|
-
const flags = input.flags
|
|
12
|
+
const flags = "flags" in input && typeof input.flags === "object" && input.flags !== null ? input.flags : input;
|
|
13
13
|
const dryRun = flags["dry-run"] ?? false;
|
|
14
14
|
const removeUnused = flags["remove-unused"] || flags.all;
|
|
15
15
|
const addMissing = flags["add-missing"] || flags.all;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/fix-deps.ts"],"names":[],"mappings":"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","file":"fix-deps.js","sourcesContent":["/**\n * quality:fix-deps - Dependency auto-fixer\n *\n * Automatically fixes dependency issues:\n * - Remove unused dependencies\n * - Add missing workspace dependencies\n * - Align duplicate dependency versions\n *\n * Supports --dry-run for previewing changes without applying\n */\n\nimport { defineCommand, type PluginContextV3, useLoader } from '@kb-labs/sdk';\nimport type { FixDepsFlags } from './flags.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n// Input type with backward compatibility\ntype FixDepsInput = FixDepsFlags & { argv?: string[] };\n\ninterface FixResult {\n packagesScanned: number;\n removedDeps: Array<{ package: string; dep: string }>;\n addedDeps: Array<{ package: string; dep: string; version: string }>;\n alignedDeps: Array<{ dep: string; from: string; to: string; packages: string[] }>;\n dryRun: boolean;\n}\n\ntype FixDepsCommandResult = {\n exitCode: number;\n result?: FixResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:fix-deps',\n description: 'Auto-fix dependency issues',\n\n handler: {\n async execute(ctx: PluginContextV3, input: FixDepsInput): Promise<FixDepsCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags come in input.flags object (not auto-merged)\n const flags = (input as any).flags ?? input;\n\n const dryRun = flags['dry-run'] ?? false;\n const removeUnused = flags['remove-unused'] || flags.all;\n const addMissing = flags['add-missing'] || flags.all;\n const alignVersions = flags['align-versions'] || flags.all;\n const showStats = flags.stats;\n\n // If stats requested, show dependency statistics\n if (showStats) {\n const stats = await getDependencyStats(ctx.cwd);\n outputStats(stats, flags, ui);\n return { exitCode: 0 };\n }\n\n // If no fix flags specified, show error\n if (!removeUnused && !addMissing && !alignVersions) {\n ui?.error?.('No fix options specified. Use --remove-unused, --add-missing, --align-versions, or --all');\n return { exitCode: 1 };\n }\n\n const loader = useLoader('Scanning packages...');\n loader.start();\n\n const result: FixResult = {\n packagesScanned: 0,\n removedDeps: [],\n addedDeps: [],\n alignedDeps: [],\n dryRun,\n };\n\n const packages = findPackages(ctx.cwd);\n result.packagesScanned = packages.length;\n\n loader.update({ text: `Scanned ${packages.length} packages` });\n\n // 1. Align versions first (if requested)\n if (alignVersions) {\n loader.update({ text: 'Analyzing duplicate dependencies...' });\n const aligned = await alignDuplicateVersions(packages, dryRun);\n result.alignedDeps = aligned;\n }\n\n // 2. Add missing workspace dependencies\n if (addMissing) {\n loader.update({ text: 'Checking for missing workspace dependencies...' });\n const added = await addMissingWorkspaceDeps(packages, dryRun);\n result.addedDeps = added;\n }\n\n // 3. Remove unused dependencies\n if (removeUnused) {\n loader.update({ text: 'Checking for unused dependencies...' });\n const removed = await removeUnusedDeps(packages, dryRun);\n result.removedDeps = removed;\n }\n\n loader.succeed('Dependency analysis completed');\n\n // Track analytics\n await platform.analytics.track('quality:fix-deps', {\n dryRun,\n packagesScanned: result.packagesScanned,\n removedCount: result.removedDeps.length,\n addedCount: result.addedDeps.length,\n alignedCount: result.alignedDeps.length,\n });\n\n // Output results\n outputResults(result, flags, ui);\n\n return {\n exitCode: 0,\n result,\n };\n },\n },\n});\n\n/**\n * Find all packages in the monorepo\n */\nfunction findPackages(rootDir: string): Array<{ name: string; path: string; json: any }> {\n const packages: Array<{ name: string; path: string; json: any }> = [];\n\n if (!fs.existsSync(rootDir)) {\n return packages;\n }\n\n const entries = fs.readdirSync(rootDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}\n\n const repoPath = path.join(rootDir, entry.name);\n const packagesDir = path.join(repoPath, 'packages');\n\n if (!fs.existsSync(packagesDir)) {continue;}\n\n const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });\n\n for (const pkgDir of packageDirs) {\n if (!pkgDir.isDirectory()) {continue;}\n\n const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');\n\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n packages.push({\n name: packageJson.name || pkgDir.name,\n path: packageJsonPath,\n json: packageJson,\n });\n }\n }\n }\n\n return packages;\n}\n\n/**\n * Get dependency statistics\n */\nasync function getDependencyStats(rootDir: string): Promise<any> {\n const packages = findPackages(rootDir);\n const allDeps = new Map<string, Set<string>>();\n\n for (const pkg of packages) {\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const [dep, version] of Object.entries(deps)) {\n if (!allDeps.has(dep)) {\n allDeps.set(dep, new Set());\n }\n allDeps.get(dep)!.add(version as string);\n }\n }\n\n const duplicates = Array.from(allDeps.entries())\n .filter(([_, versions]) => versions.size > 1)\n .filter(([dep]) => !dep.startsWith('@kb-labs/'));\n\n const topUsed = Array.from(allDeps.entries())\n .map(([name, versions]) => ({ name, count: versions.size > 1 ? versions.size : 1 }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return {\n totalPackages: packages.length,\n totalDeps: allDeps.size,\n duplicates: duplicates.length,\n topUsed,\n };\n}\n\n/**\n * Align duplicate dependency versions to most common version\n */\nasync function alignDuplicateVersions(\n packages: Array<{ name: string; path: string; json: any }>,\n dryRun: boolean\n): Promise<Array<{ dep: string; from: string; to: string; packages: string[] }>> {\n const aligned: Array<{ dep: string; from: string; to: string; packages: string[] }> = [];\n\n // Find all dependencies and their versions\n const depVersions = new Map<string, Map<string, Set<string>>>();\n\n for (const pkg of packages) {\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const [dep, version] of Object.entries(deps)) {\n if (dep.startsWith('@kb-labs/')) {continue;} // Skip workspace deps\n\n if (!depVersions.has(dep)) {\n depVersions.set(dep, new Map());\n }\n\n const versions = depVersions.get(dep)!;\n if (!versions.has(version as string)) {\n versions.set(version as string, new Set());\n }\n versions.get(version as string)!.add(pkg.name);\n }\n }\n\n // Find duplicates and determine most common version\n for (const [dep, versions] of depVersions.entries()) {\n if (versions.size <= 1) {continue;}\n\n // Find most common version\n const versionCounts = Array.from(versions.entries()).map(([ver, pkgs]) => ({\n version: ver,\n count: pkgs.size,\n packages: Array.from(pkgs),\n }));\n\n versionCounts.sort((a, b) => b.count - a.count);\n const targetVersion = versionCounts[0]?.version;\n if (!targetVersion) {continue;}\n\n // Align all packages to target version\n for (const { version, packages: pkgNames } of versionCounts.slice(1)) {\n aligned.push({\n dep,\n from: version,\n to: targetVersion,\n packages: pkgNames,\n });\n\n if (!dryRun) {\n // Apply changes to package.json files\n for (const pkgName of pkgNames) {\n const pkg = packages.find(p => p.name === pkgName);\n if (!pkg) {continue;}\n\n if (pkg.json.dependencies?.[dep]) {\n pkg.json.dependencies[dep] = targetVersion;\n }\n if (pkg.json.devDependencies?.[dep]) {\n pkg.json.devDependencies[dep] = targetVersion;\n }\n\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return aligned;\n}\n\n/**\n * Add missing workspace dependencies\n */\nasync function addMissingWorkspaceDeps(\n packages: Array<{ name: string; path: string; json: any }>,\n dryRun: boolean\n): Promise<Array<{ package: string; dep: string; version: string }>> {\n const added: Array<{ package: string; dep: string; version: string }> = [];\n\n // Build map of workspace packages\n const workspacePackages = new Map<string, string>();\n for (const pkg of packages) {\n if (pkg.name.startsWith('@kb-labs/')) {\n workspacePackages.set(pkg.name, 'workspace:*');\n }\n }\n\n // Check each package for missing workspace deps\n for (const pkg of packages) {\n const packageDir = path.dirname(pkg.path);\n const srcDir = path.join(packageDir, 'src');\n\n if (!fs.existsSync(srcDir)) {continue;}\n\n // Scan imports\n const imports = scanImports(srcDir);\n const currentDeps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const imp of imports) {\n if (imp.startsWith('@kb-labs/') && workspacePackages.has(imp) && !currentDeps[imp]) {\n added.push({\n package: pkg.name,\n dep: imp,\n version: 'workspace:*',\n });\n\n if (!dryRun) {\n if (!pkg.json.dependencies) {\n pkg.json.dependencies = {};\n }\n pkg.json.dependencies[imp] = 'workspace:*';\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return added;\n}\n\n/**\n * Remove unused dependencies\n */\nasync function removeUnusedDeps(\n packages: Array<{ name: string; path: string; json: any }>,\n dryRun: boolean\n): Promise<Array<{ package: string; dep: string }>> {\n const removed: Array<{ package: string; dep: string }> = [];\n\n for (const pkg of packages) {\n const packageDir = path.dirname(pkg.path);\n const srcDir = path.join(packageDir, 'src');\n\n if (!fs.existsSync(srcDir)) {continue;}\n\n // Scan imports\n const imports = new Set(scanImports(srcDir));\n\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const dep of Object.keys(deps)) {\n // Skip protected dependencies\n if (isProtectedDep(dep)) {continue;}\n\n // Check if dependency is used\n if (!imports.has(dep)) {\n removed.push({\n package: pkg.name,\n dep,\n });\n\n if (!dryRun) {\n delete pkg.json.dependencies?.[dep];\n delete pkg.json.devDependencies?.[dep];\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return removed;\n}\n\n/**\n * Scan directory for imports\n */\nfunction scanImports(dir: string): string[] {\n const imports: string[] = [];\n\n function walk(currentDir: string) {\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n\n if (entry.isDirectory()) {\n walk(fullPath);\n } else if (entry.isFile() && /\\.(ts|tsx|js|jsx)$/.test(entry.name)) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n\n // Match import statements\n const importRegex = /(?:import|require)\\s*\\(?['\"]([^'\"]+)['\"]\\)?/g;\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const imp = match[1];\n if (!imp) {continue;}\n // Extract package name (handle scoped packages)\n const pkgName = imp.startsWith('@') ? imp.split('/').slice(0, 2).join('/') : imp.split('/')[0];\n if (pkgName) {\n imports.push(pkgName);\n }\n }\n }\n }\n }\n\n walk(dir);\n return Array.from(new Set(imports));\n}\n\n/**\n * Check if dependency is protected (build tools, etc.)\n */\nfunction isProtectedDep(dep: string): boolean {\n const protectedDeps = [\n 'typescript',\n 'tsup',\n 'esbuild',\n 'vite',\n 'rollup',\n 'rimraf',\n 'vitest',\n 'jest',\n 'playwright',\n 'eslint',\n 'prettier',\n ];\n\n return protectedDeps.some(p => dep === p || dep.startsWith(`${p}-`) || dep.startsWith(`@${p}/`));\n}\n\n/**\n * Output dependency statistics\n */\nfunction outputStats(stats: any, flags: any, ui: any) {\n if (flags.json) {\n ui?.json?.(stats);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n sections.push({\n header: 'Overview',\n items: [\n `Total Packages: ${stats.totalPackages}`,\n `Total Dependencies: ${stats.totalDeps}`,\n `Duplicate Versions: ${stats.duplicates}`,\n ],\n });\n\n if (stats.topUsed.length > 0) {\n sections.push({\n header: 'Top 10 Most Used',\n items: stats.topUsed.map((d: any) => `${d.name} (${d.count} packages)`),\n });\n }\n\n ui?.success?.('Dependency statistics', {\n title: '📊 Dependency Statistics',\n sections,\n });\n}\n\n/**\n * Output fix results\n */\nfunction outputResults(result: FixResult, flags: any, ui: any) {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Summary\n const summaryItems = [\n `Packages Scanned: ${result.packagesScanned}`,\n `Mode: ${result.dryRun ? '🔍 Dry Run (no changes applied)' : '✅ Changes Applied'}`,\n ];\n sections.push({ header: 'Summary', items: summaryItems });\n\n // Aligned dependencies\n if (result.alignedDeps.length > 0) {\n const alignedItems = result.alignedDeps.map(\n a => `${a.dep}: ${a.from} → ${a.to} (${a.packages.length} packages)`\n );\n sections.push({ header: 'Aligned Versions', items: alignedItems.slice(0, 10) });\n if (result.alignedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.alignedDeps.length - 10} more`);\n }\n }\n }\n\n // Added dependencies\n if (result.addedDeps.length > 0) {\n const addedItems = result.addedDeps.map(a => `${a.package}: +${a.dep}`);\n sections.push({ header: 'Added Dependencies', items: addedItems.slice(0, 10) });\n if (result.addedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.addedDeps.length - 10} more`);\n }\n }\n }\n\n // Removed dependencies\n if (result.removedDeps.length > 0) {\n const removedItems = result.removedDeps.map(r => `${r.package}: -${r.dep}`);\n sections.push({ header: 'Removed Dependencies', items: removedItems.slice(0, 10) });\n if (result.removedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.removedDeps.length - 10} more`);\n }\n }\n }\n\n // No changes\n if (\n result.alignedDeps.length === 0 &&\n result.addedDeps.length === 0 &&\n result.removedDeps.length === 0\n ) {\n sections.push({ header: 'Result', items: ['✅ No issues found!'] });\n }\n\n // Next steps for dry run\n if (result.dryRun && (result.alignedDeps.length > 0 || result.addedDeps.length > 0 || result.removedDeps.length > 0)) {\n sections.push({\n header: 'Next Steps',\n items: ['Remove --dry-run flag to apply changes', 'Run `pnpm install` after applying changes'],\n });\n }\n\n const title = result.dryRun ? '🔍 Dependency Fix Preview' : '✅ Dependency Fix Complete';\n\n ui?.success?.('Dependency fix completed', {\n title,\n sections,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/fix-deps.ts"],"names":[],"mappings":"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","file":"fix-deps.js","sourcesContent":["/**\n * quality:fix-deps - Dependency auto-fixer\n *\n * Automatically fixes dependency issues:\n * - Remove unused dependencies\n * - Add missing workspace dependencies\n * - Align duplicate dependency versions\n *\n * Supports --dry-run for previewing changes without applying\n */\n\nimport { defineCommand, type PluginContextV3, useLoader } from '@kb-labs/sdk';\nimport type { UIFacade } from '@kb-labs/sdk';\nimport type { FixDepsFlags } from './flags.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n// Input type with backward compatibility\ntype FixDepsInput = FixDepsFlags & { argv?: string[] };\n\n/** Minimal package.json structure used by fix-deps */\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\n/** Parsed package entry */\ninterface PackageEntry {\n name: string;\n path: string;\n json: PackageJson;\n}\n\ninterface FixResult {\n packagesScanned: number;\n removedDeps: Array<{ package: string; dep: string }>;\n addedDeps: Array<{ package: string; dep: string; version: string }>;\n alignedDeps: Array<{ dep: string; from: string; to: string; packages: string[] }>;\n dryRun: boolean;\n}\n\ntype FixDepsCommandResult = {\n exitCode: number;\n result?: FixResult;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'quality:fix-deps',\n description: 'Auto-fix dependency issues',\n\n handler: {\n async execute(ctx: PluginContextV3, input: FixDepsInput): Promise<FixDepsCommandResult> {\n const { ui, platform } = ctx;\n\n // V3: Flags may come wrapped in input.flags or passed directly\n const flags = ('flags' in input && typeof (input as { flags?: unknown }).flags === 'object' && (input as { flags?: unknown }).flags !== null)\n ? (input as { flags: FixDepsInput }).flags\n : input;\n\n const dryRun = flags['dry-run'] ?? false;\n const removeUnused = flags['remove-unused'] || flags.all;\n const addMissing = flags['add-missing'] || flags.all;\n const alignVersions = flags['align-versions'] || flags.all;\n const showStats = flags.stats;\n\n // If stats requested, show dependency statistics\n if (showStats) {\n const stats = await getDependencyStats(ctx.cwd);\n outputStats(stats, flags, ui);\n return { exitCode: 0 };\n }\n\n // If no fix flags specified, show error\n if (!removeUnused && !addMissing && !alignVersions) {\n ui?.error?.('No fix options specified. Use --remove-unused, --add-missing, --align-versions, or --all');\n return { exitCode: 1 };\n }\n\n const loader = useLoader('Scanning packages...');\n loader.start();\n\n const result: FixResult = {\n packagesScanned: 0,\n removedDeps: [],\n addedDeps: [],\n alignedDeps: [],\n dryRun,\n };\n\n const packages = findPackages(ctx.cwd);\n result.packagesScanned = packages.length;\n\n loader.update({ text: `Scanned ${packages.length} packages` });\n\n // 1. Align versions first (if requested)\n if (alignVersions) {\n loader.update({ text: 'Analyzing duplicate dependencies...' });\n const aligned = await alignDuplicateVersions(packages, dryRun);\n result.alignedDeps = aligned;\n }\n\n // 2. Add missing workspace dependencies\n if (addMissing) {\n loader.update({ text: 'Checking for missing workspace dependencies...' });\n const added = await addMissingWorkspaceDeps(packages, dryRun);\n result.addedDeps = added;\n }\n\n // 3. Remove unused dependencies\n if (removeUnused) {\n loader.update({ text: 'Checking for unused dependencies...' });\n const removed = await removeUnusedDeps(packages, dryRun);\n result.removedDeps = removed;\n }\n\n loader.succeed('Dependency analysis completed');\n\n // Track analytics\n await platform.analytics.track('quality:fix-deps', {\n dryRun,\n packagesScanned: result.packagesScanned,\n removedCount: result.removedDeps.length,\n addedCount: result.addedDeps.length,\n alignedCount: result.alignedDeps.length,\n });\n\n // Output results\n outputResults(result, flags, ui);\n\n return {\n exitCode: 0,\n result,\n };\n },\n },\n});\n\n/**\n * Find all packages in the monorepo\n */\nfunction findPackages(rootDir: string): PackageEntry[] {\n const packages: PackageEntry[] = [];\n\n if (!fs.existsSync(rootDir)) {\n return packages;\n }\n\n const entries = fs.readdirSync(rootDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}\n\n const repoPath = path.join(rootDir, entry.name);\n const packagesDir = path.join(repoPath, 'packages');\n\n if (!fs.existsSync(packagesDir)) {continue;}\n\n const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });\n\n for (const pkgDir of packageDirs) {\n if (!pkgDir.isDirectory()) {continue;}\n\n const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');\n\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n packages.push({\n name: packageJson.name || pkgDir.name,\n path: packageJsonPath,\n json: packageJson,\n });\n }\n }\n }\n\n return packages;\n}\n\n/**\n * Get dependency statistics\n */\ninterface DependencyStats {\n totalPackages: number;\n totalDeps: number;\n duplicates: number;\n topUsed: Array<{ name: string; count: number }>;\n}\n\nasync function getDependencyStats(rootDir: string): Promise<DependencyStats> {\n const packages = findPackages(rootDir);\n const allDeps = new Map<string, Set<string>>();\n\n for (const pkg of packages) {\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const [dep, version] of Object.entries(deps)) {\n if (!allDeps.has(dep)) {\n allDeps.set(dep, new Set());\n }\n allDeps.get(dep)!.add(version as string);\n }\n }\n\n const duplicates = Array.from(allDeps.entries())\n .filter(([_, versions]) => versions.size > 1)\n .filter(([dep]) => !dep.startsWith('@kb-labs/'));\n\n const topUsed = Array.from(allDeps.entries())\n .map(([name, versions]) => ({ name, count: versions.size > 1 ? versions.size : 1 }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return {\n totalPackages: packages.length,\n totalDeps: allDeps.size,\n duplicates: duplicates.length,\n topUsed,\n };\n}\n\n/**\n * Align duplicate dependency versions to most common version\n */\nasync function alignDuplicateVersions(\n packages: PackageEntry[],\n dryRun: boolean\n): Promise<Array<{ dep: string; from: string; to: string; packages: string[] }>> {\n const aligned: Array<{ dep: string; from: string; to: string; packages: string[] }> = [];\n\n // Find all dependencies and their versions\n const depVersions = new Map<string, Map<string, Set<string>>>();\n\n for (const pkg of packages) {\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const [dep, version] of Object.entries(deps)) {\n if (dep.startsWith('@kb-labs/')) {continue;} // Skip workspace deps\n\n if (!depVersions.has(dep)) {\n depVersions.set(dep, new Map());\n }\n\n const versions = depVersions.get(dep)!;\n if (!versions.has(version as string)) {\n versions.set(version as string, new Set());\n }\n versions.get(version as string)!.add(pkg.name);\n }\n }\n\n // Find duplicates and determine most common version\n for (const [dep, versions] of depVersions.entries()) {\n if (versions.size <= 1) {continue;}\n\n // Find most common version\n const versionCounts = Array.from(versions.entries()).map(([ver, pkgs]) => ({\n version: ver,\n count: pkgs.size,\n packages: Array.from(pkgs),\n }));\n\n versionCounts.sort((a, b) => b.count - a.count);\n const targetVersion = versionCounts[0]?.version;\n if (!targetVersion) {continue;}\n\n // Align all packages to target version\n for (const { version, packages: pkgNames } of versionCounts.slice(1)) {\n aligned.push({\n dep,\n from: version,\n to: targetVersion,\n packages: pkgNames,\n });\n\n if (!dryRun) {\n // Apply changes to package.json files\n for (const pkgName of pkgNames) {\n const pkg = packages.find(p => p.name === pkgName);\n if (!pkg) {continue;}\n\n if (pkg.json.dependencies?.[dep]) {\n pkg.json.dependencies[dep] = targetVersion;\n }\n if (pkg.json.devDependencies?.[dep]) {\n pkg.json.devDependencies[dep] = targetVersion;\n }\n\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return aligned;\n}\n\n/**\n * Add missing workspace dependencies\n */\nasync function addMissingWorkspaceDeps(\n packages: PackageEntry[],\n dryRun: boolean\n): Promise<Array<{ package: string; dep: string; version: string }>> {\n const added: Array<{ package: string; dep: string; version: string }> = [];\n\n // Build map of workspace packages\n const workspacePackages = new Map<string, string>();\n for (const pkg of packages) {\n if (pkg.name.startsWith('@kb-labs/')) {\n workspacePackages.set(pkg.name, 'workspace:*');\n }\n }\n\n // Check each package for missing workspace deps\n for (const pkg of packages) {\n const packageDir = path.dirname(pkg.path);\n const srcDir = path.join(packageDir, 'src');\n\n if (!fs.existsSync(srcDir)) {continue;}\n\n // Scan imports\n const imports = scanImports(srcDir);\n const currentDeps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const imp of imports) {\n if (imp.startsWith('@kb-labs/') && workspacePackages.has(imp) && !currentDeps[imp]) {\n added.push({\n package: pkg.name,\n dep: imp,\n version: 'workspace:*',\n });\n\n if (!dryRun) {\n if (!pkg.json.dependencies) {\n pkg.json.dependencies = {};\n }\n pkg.json.dependencies[imp] = 'workspace:*';\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return added;\n}\n\n/**\n * Remove unused dependencies\n */\nasync function removeUnusedDeps(\n packages: PackageEntry[],\n dryRun: boolean\n): Promise<Array<{ package: string; dep: string }>> {\n const removed: Array<{ package: string; dep: string }> = [];\n\n for (const pkg of packages) {\n const packageDir = path.dirname(pkg.path);\n const srcDir = path.join(packageDir, 'src');\n\n if (!fs.existsSync(srcDir)) {continue;}\n\n // Scan imports\n const imports = new Set(scanImports(srcDir));\n\n const deps = {\n ...pkg.json.dependencies,\n ...pkg.json.devDependencies,\n };\n\n for (const dep of Object.keys(deps)) {\n // Skip protected dependencies\n if (isProtectedDep(dep)) {continue;}\n\n // Check if dependency is used\n if (!imports.has(dep)) {\n removed.push({\n package: pkg.name,\n dep,\n });\n\n if (!dryRun) {\n delete pkg.json.dependencies?.[dep];\n delete pkg.json.devDependencies?.[dep];\n fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + '\\n');\n }\n }\n }\n }\n\n return removed;\n}\n\n/**\n * Scan directory for imports\n */\nfunction scanImports(dir: string): string[] {\n const imports: string[] = [];\n\n function walk(currentDir: string) {\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n\n if (entry.isDirectory()) {\n walk(fullPath);\n } else if (entry.isFile() && /\\.(ts|tsx|js|jsx)$/.test(entry.name)) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n\n // Match import statements\n const importRegex = /(?:import|require)\\s*\\(?['\"]([^'\"]+)['\"]\\)?/g;\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const imp = match[1];\n if (!imp) {continue;}\n // Extract package name (handle scoped packages)\n const pkgName = imp.startsWith('@') ? imp.split('/').slice(0, 2).join('/') : imp.split('/')[0];\n if (pkgName) {\n imports.push(pkgName);\n }\n }\n }\n }\n }\n\n walk(dir);\n return Array.from(new Set(imports));\n}\n\n/**\n * Check if dependency is protected (build tools, etc.)\n */\nfunction isProtectedDep(dep: string): boolean {\n const protectedDeps = [\n 'typescript',\n 'tsup',\n 'esbuild',\n 'vite',\n 'rollup',\n 'rimraf',\n 'vitest',\n 'jest',\n 'playwright',\n 'eslint',\n 'prettier',\n ];\n\n return protectedDeps.some(p => dep === p || dep.startsWith(`${p}-`) || dep.startsWith(`@${p}/`));\n}\n\n/**\n * Output dependency statistics\n */\nfunction outputStats(stats: DependencyStats, flags: FixDepsFlags, ui: UIFacade | undefined) {\n if (flags.json) {\n ui?.json?.(stats);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n sections.push({\n header: 'Overview',\n items: [\n `Total Packages: ${stats.totalPackages}`,\n `Total Dependencies: ${stats.totalDeps}`,\n `Duplicate Versions: ${stats.duplicates}`,\n ],\n });\n\n if (stats.topUsed.length > 0) {\n sections.push({\n header: 'Top 10 Most Used',\n items: stats.topUsed.map((d) => `${d.name} (${d.count} packages)`),\n });\n }\n\n ui?.success?.('Dependency statistics', {\n title: '📊 Dependency Statistics',\n sections,\n });\n}\n\n/**\n * Output fix results\n */\nfunction outputResults(result: FixResult, flags: FixDepsFlags, ui: UIFacade | undefined) {\n if (flags.json) {\n ui?.json?.(result);\n return;\n }\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n // Summary\n const summaryItems = [\n `Packages Scanned: ${result.packagesScanned}`,\n `Mode: ${result.dryRun ? '🔍 Dry Run (no changes applied)' : '✅ Changes Applied'}`,\n ];\n sections.push({ header: 'Summary', items: summaryItems });\n\n // Aligned dependencies\n if (result.alignedDeps.length > 0) {\n const alignedItems = result.alignedDeps.map(\n a => `${a.dep}: ${a.from} → ${a.to} (${a.packages.length} packages)`\n );\n sections.push({ header: 'Aligned Versions', items: alignedItems.slice(0, 10) });\n if (result.alignedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.alignedDeps.length - 10} more`);\n }\n }\n }\n\n // Added dependencies\n if (result.addedDeps.length > 0) {\n const addedItems = result.addedDeps.map(a => `${a.package}: +${a.dep}`);\n sections.push({ header: 'Added Dependencies', items: addedItems.slice(0, 10) });\n if (result.addedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.addedDeps.length - 10} more`);\n }\n }\n }\n\n // Removed dependencies\n if (result.removedDeps.length > 0) {\n const removedItems = result.removedDeps.map(r => `${r.package}: -${r.dep}`);\n sections.push({ header: 'Removed Dependencies', items: removedItems.slice(0, 10) });\n if (result.removedDeps.length > 10) {\n const lastSection = sections[sections.length - 1];\n if (lastSection) {\n lastSection.items.push(`... and ${result.removedDeps.length - 10} more`);\n }\n }\n }\n\n // No changes\n if (\n result.alignedDeps.length === 0 &&\n result.addedDeps.length === 0 &&\n result.removedDeps.length === 0\n ) {\n sections.push({ header: 'Result', items: ['✅ No issues found!'] });\n }\n\n // Next steps for dry run\n if (result.dryRun && (result.alignedDeps.length > 0 || result.addedDeps.length > 0 || result.removedDeps.length > 0)) {\n sections.push({\n header: 'Next Steps',\n items: ['Remove --dry-run flag to apply changes', 'Run `pnpm install` after applying changes'],\n });\n }\n\n const title = result.dryRun ? '🔍 Dependency Fix Preview' : '✅ Dependency Fix Complete';\n\n ui?.success?.('Dependency fix completed', {\n title,\n sections,\n });\n}\n"]}
|