@kb-labs/quality-entry 2.14.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.
Files changed (74) hide show
  1. package/README.md +120 -0
  2. package/dist/cli/commands/build-order.d.ts +16 -0
  3. package/dist/cli/commands/build-order.js +113 -0
  4. package/dist/cli/commands/build-order.js.map +1 -0
  5. package/dist/cli/commands/check-builds.d.ts +10 -0
  6. package/dist/cli/commands/check-builds.js +93 -0
  7. package/dist/cli/commands/check-builds.js.map +1 -0
  8. package/dist/cli/commands/check-tests.d.ts +10 -0
  9. package/dist/cli/commands/check-tests.js +114 -0
  10. package/dist/cli/commands/check-tests.js.map +1 -0
  11. package/dist/cli/commands/check-types.d.ts +10 -0
  12. package/dist/cli/commands/check-types.js +108 -0
  13. package/dist/cli/commands/check-types.js.map +1 -0
  14. package/dist/cli/commands/cycles.d.ts +17 -0
  15. package/dist/cli/commands/cycles.js +85 -0
  16. package/dist/cli/commands/cycles.js.map +1 -0
  17. package/dist/cli/commands/dead-code.d.ts +10 -0
  18. package/dist/cli/commands/dead-code.js +217 -0
  19. package/dist/cli/commands/dead-code.js.map +1 -0
  20. package/dist/cli/commands/fix-deps.d.ts +28 -0
  21. package/dist/cli/commands/fix-deps.js +389 -0
  22. package/dist/cli/commands/fix-deps.js.map +1 -0
  23. package/dist/cli/commands/flags.d.ts +344 -0
  24. package/dist/cli/commands/flags.js +298 -0
  25. package/dist/cli/commands/flags.js.map +1 -0
  26. package/dist/cli/commands/health.d.ts +10 -0
  27. package/dist/cli/commands/health.js +210 -0
  28. package/dist/cli/commands/health.js.map +1 -0
  29. package/dist/cli/commands/index.d.ts +14 -0
  30. package/dist/cli/commands/index.js +1747 -0
  31. package/dist/cli/commands/index.js.map +1 -0
  32. package/dist/cli/commands/stats.d.ts +10 -0
  33. package/dist/cli/commands/stats.js +282 -0
  34. package/dist/cli/commands/stats.js.map +1 -0
  35. package/dist/cli/commands/visualize.d.ts +26 -0
  36. package/dist/cli/commands/visualize.js +210 -0
  37. package/dist/cli/commands/visualize.js.map +1 -0
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.js +666 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/manifest.d.ts +168 -0
  42. package/dist/manifest.js +666 -0
  43. package/dist/manifest.js.map +1 -0
  44. package/dist/rest/handlers/build-order-handler.d.ts +17 -0
  45. package/dist/rest/handlers/build-order-handler.js +28 -0
  46. package/dist/rest/handlers/build-order-handler.js.map +1 -0
  47. package/dist/rest/handlers/builds-handler.d.ts +12 -0
  48. package/dist/rest/handlers/builds-handler.js +17 -0
  49. package/dist/rest/handlers/builds-handler.js.map +1 -0
  50. package/dist/rest/handlers/cycles-handler.d.ts +13 -0
  51. package/dist/rest/handlers/cycles-handler.js +23 -0
  52. package/dist/rest/handlers/cycles-handler.js.map +1 -0
  53. package/dist/rest/handlers/dependencies-handler.d.ts +14 -0
  54. package/dist/rest/handlers/dependencies-handler.js +19 -0
  55. package/dist/rest/handlers/dependencies-handler.js.map +1 -0
  56. package/dist/rest/handlers/graph-handler.d.ts +30 -0
  57. package/dist/rest/handlers/graph-handler.js +155 -0
  58. package/dist/rest/handlers/graph-handler.js.map +1 -0
  59. package/dist/rest/handlers/health-handler.d.ts +15 -0
  60. package/dist/rest/handlers/health-handler.js +19 -0
  61. package/dist/rest/handlers/health-handler.js.map +1 -0
  62. package/dist/rest/handlers/stale-handler.d.ts +30 -0
  63. package/dist/rest/handlers/stale-handler.js +20 -0
  64. package/dist/rest/handlers/stale-handler.js.map +1 -0
  65. package/dist/rest/handlers/stats-handler.d.ts +16 -0
  66. package/dist/rest/handlers/stats-handler.js +29 -0
  67. package/dist/rest/handlers/stats-handler.js.map +1 -0
  68. package/dist/rest/handlers/tests-handler.d.ts +14 -0
  69. package/dist/rest/handlers/tests-handler.js +19 -0
  70. package/dist/rest/handlers/tests-handler.js.map +1 -0
  71. package/dist/rest/handlers/types-handler.d.ts +12 -0
  72. package/dist/rest/handlers/types-handler.js +17 -0
  73. package/dist/rest/handlers/types-handler.js.map +1 -0
  74. package/package.json +98 -0
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # @kb-labs/plugin-template-cli
2
+
3
+ Reference CLI/REST/Studio plugin package for KB Labs Plugin Template.
4
+
5
+ ## Vision & Purpose
6
+
7
+ **@kb-labs/plugin-template-cli** is the canonical example plugin package used by `@kb-labs/plugin-template`.
8
+ It shows how to implement a plugin that exposes:
9
+
10
+ - a **CLI command** (Hello),
11
+ - a **REST handler**, and
12
+ - a **Studio widget**,
13
+
14
+ all driven by a single manifest and contracts package.
15
+
16
+ ## Package Status
17
+
18
+ - **Version**: 0.1.0
19
+ - **Stage**: Stable (template)
20
+ - **Status**: Reference Implementation ✅
21
+
22
+ ## Architecture
23
+
24
+ ### High-Level Overview
25
+
26
+ ```
27
+ plugin-cli
28
+
29
+ ├──► contracts (from @kb-labs/plugin-template-contracts)
30
+ ├──► shared (constants/helpers)
31
+ ├──► domain (Greeting entity and invariants)
32
+ ├──► application (use-cases: create greeting, etc.)
33
+ ├──► cli (Hello command wiring)
34
+ ├──► rest (Hello REST handler + schema)
35
+ └──► studio (Hello Studio widget)
36
+ ```
37
+
38
+ ### Key Components
39
+
40
+ - `src/domain/`: `Greeting` entity and domain rules
41
+ - `src/application/`: use-cases that orchestrate domain logic
42
+ - `src/cli/commands/hello/*`: CLI command implementation
43
+ - `src/rest/handlers/hello-handler.ts`: REST handler bound to manifest
44
+ - `src/studio/widgets/hello-widget.tsx`: Studio widget implementation
45
+ - `src/manifest.v2.ts`: Plugin manifest v2 (CLI/REST/Studio wiring)
46
+
47
+ ## Features
48
+
49
+ - **Single-source manifest** for CLI/REST/Studio surfaces
50
+ - **Layered architecture** (shared → domain → application → interface)
51
+ - **Type-safe contracts** via `@kb-labs/plugin-template-contracts`
52
+ - **Hello-world flow** demonstrating end-to-end plugin wiring
53
+
54
+ ## Exports
55
+
56
+ From `src/index.ts`:
57
+
58
+ - `manifest`: Plugin Manifest V2
59
+ - All public surfaces:
60
+ - CLI command exports
61
+ - domain/application/shared re-exports
62
+
63
+ ## Dependencies
64
+
65
+ ### Runtime
66
+
67
+ - `@kb-labs/setup-operations`: reusable setup operations
68
+ - `@kb-labs/plugin-manifest`: manifest types and helpers
69
+ - `@kb-labs/plugin-template-contracts`: public contracts for this template plugin
70
+ - `@kb-labs/shared-cli-ui`: shared CLI UI helpers
71
+ - `react`, `react-dom`, `zod`
72
+
73
+ ### Development
74
+
75
+ - `@kb-labs/devkit`: shared TS/ESLint/Vitest/TSUP presets
76
+ - `typescript`, `tsup`, `vitest`, `rimraf`
77
+
78
+ ## Scripts
79
+
80
+ From `kb-labs-plugin-template` repo root:
81
+
82
+ ```bash
83
+ pnpm install
84
+ pnpm --filter @kb-labs/plugin-template-cli build
85
+ pnpm --filter @kb-labs/plugin-template-cli test
86
+ ```
87
+
88
+ To run sandboxes, see the root `README.md` (`pnpm sandbox:cli`, `sandbox:rest`, `sandbox:studio`).
89
+
90
+ ## Command Implementation
91
+
92
+ This template demonstrates **three different approaches** to implementing CLI commands:
93
+
94
+ 1. **High-level wrapper (`defineCommand`)** - Recommended for most cases
95
+ 2. **Low-level atomic tools** - For maximum control
96
+ 3. **Hybrid approach** - Combining both
97
+
98
+ See [`COMMAND_IMPLEMENTATION_GUIDE.md`](./COMMAND_IMPLEMENTATION_GUIDE.md) for detailed explanations and examples.
99
+
100
+ ### Quick Start
101
+
102
+ The `template:hello` command in `src/cli/commands/hello/run.ts` shows all three approaches with working code examples. The default implementation uses Approach 1 (`defineCommand`), which provides:
103
+
104
+ - ✅ Zero-boilerplate flag validation
105
+ - ✅ Automatic analytics integration
106
+ - ✅ Structured logging
107
+ - ✅ Error handling
108
+ - ✅ Timing tracking
109
+ - ✅ JSON output mode
110
+
111
+ ## Customising for Your Plugin
112
+
113
+ When using this as a starting point:
114
+
115
+ - Rename the package in `package.json` (e.g. `@kb-labs/my-plugin-cli`)
116
+ - Update manifest IDs and the contracts package
117
+ - Replace the Hello flow with your own domain, use-cases, and surfaces
118
+ - Choose the command implementation approach that fits your needs (see `COMMAND_IMPLEMENTATION_GUIDE.md`)
119
+
120
+
@@ -0,0 +1,16 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { TopologicalSortResult } from '@kb-labs/quality-core/graph';
3
+
4
+ type BuildOrderFlags = {
5
+ package?: string;
6
+ layers?: boolean;
7
+ script?: boolean;
8
+ json?: boolean;
9
+ argv?: string[];
10
+ };
11
+ type BuildOrderInput = BuildOrderFlags & {
12
+ argv?: string[];
13
+ };
14
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, BuildOrderInput, TopologicalSortResult>;
15
+
16
+ export { _default as default };
@@ -0,0 +1,113 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { buildDependencyGraph, getBuildOrderForPackage, topologicalSort } from '@kb-labs/quality-core/graph';
3
+
4
+ // src/cli/commands/build-order.ts
5
+ var build_order_default = defineCommand({
6
+ id: "quality:build-order",
7
+ description: "Calculate build order using topological sort",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const { ui } = ctx;
11
+ const flags = input.flags ?? input;
12
+ const graph = buildDependencyGraph(ctx.cwd);
13
+ let result;
14
+ if (flags.package) {
15
+ result = getBuildOrderForPackage(graph, flags.package);
16
+ } else {
17
+ result = topologicalSort(graph);
18
+ }
19
+ if (result.circular.length > 0) {
20
+ ui?.error?.(
21
+ `Found ${result.circular.length} circular dependencies. Build order cannot be determined.`
22
+ );
23
+ outputCircularDependencies(result.circular, ui);
24
+ return { exitCode: 1, result };
25
+ }
26
+ outputBuildOrder(result, flags, ui);
27
+ return { exitCode: 0, result };
28
+ }
29
+ }
30
+ });
31
+ function outputBuildOrder(result, flags, ui) {
32
+ if (flags.json) {
33
+ ui?.json?.(result);
34
+ return;
35
+ }
36
+ if (flags.script) {
37
+ ui?.write?.("#!/bin/bash");
38
+ ui?.write?.("# Generated build script");
39
+ ui?.write?.("set -e");
40
+ ui?.write?.("");
41
+ for (let i = 0; i < result.layers.length; i++) {
42
+ const layer = result.layers[i];
43
+ if (!layer) {
44
+ continue;
45
+ }
46
+ ui?.write?.(`# Layer ${i + 1} (${layer.length} packages)`);
47
+ for (const pkg of layer) {
48
+ ui?.write?.(`pnpm --filter "${pkg}" run build`);
49
+ }
50
+ ui?.write?.("");
51
+ }
52
+ return;
53
+ }
54
+ const sections = [];
55
+ if (flags.layers) {
56
+ const layerItems = [];
57
+ for (let i = 0; i < result.layers.length; i++) {
58
+ const layer = result.layers[i];
59
+ if (!layer) {
60
+ continue;
61
+ }
62
+ layerItems.push(`Layer ${i + 1}: ${layer.length} packages (can build in parallel)`);
63
+ for (const pkg of layer) {
64
+ layerItems.push(` \u2022 ${pkg}`);
65
+ }
66
+ layerItems.push("");
67
+ }
68
+ sections.push({ header: "Build Layers", items: layerItems });
69
+ } else {
70
+ const orderItems = result.sorted.map((pkg, idx) => `${idx + 1}. ${pkg}`);
71
+ sections.push({ header: "Build Order", items: orderItems });
72
+ }
73
+ sections.push({
74
+ header: "Summary",
75
+ items: [
76
+ `Total packages: ${result.sorted.length}`,
77
+ `Build layers: ${result.layers.length}`,
78
+ `Circular dependencies: ${result.circular.length}`
79
+ ]
80
+ });
81
+ const title = flags.package ? `\u{1F4E6} Build Order for ${flags.package}` : "\u{1F4E6} Monorepo Build Order";
82
+ ui?.success?.("Build order calculated successfully", {
83
+ title,
84
+ sections
85
+ });
86
+ }
87
+ function outputCircularDependencies(cycles, ui) {
88
+ const sections = [];
89
+ for (let i = 0; i < cycles.length; i++) {
90
+ const cycle = cycles[i];
91
+ if (!cycle) {
92
+ continue;
93
+ }
94
+ sections.push({
95
+ header: `Cycle ${i + 1}`,
96
+ items: cycle.map((pkg, idx) => {
97
+ if (idx === cycle.length - 1) {
98
+ const firstPkg = cycle[0];
99
+ return ` ${pkg} \u2192 ${firstPkg ?? "?"} (circular!)`;
100
+ }
101
+ return ` ${pkg} \u2192`;
102
+ })
103
+ });
104
+ }
105
+ ui?.error?.("Circular dependencies detected", {
106
+ title: "\u26A0\uFE0F Circular Dependencies",
107
+ sections
108
+ });
109
+ }
110
+
111
+ export { build_order_default as default };
112
+ //# sourceMappingURL=build-order.js.map
113
+ //# sourceMappingURL=build-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/build-order.ts"],"names":[],"mappings":"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","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 } 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 come in input.flags object (not auto-merged)\n const flags = (input as any).flags ?? 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: any, ui: any) {\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: any) {\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"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { BuildCheckResult } from '@kb-labs/quality-contracts';
3
+ import { CheckBuildsFlags } from './flags.js';
4
+
5
+ type CheckBuildsInput = CheckBuildsFlags & {
6
+ argv?: string[];
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CheckBuildsInput, BuildCheckResult>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,93 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { CACHE_KEYS } from '@kb-labs/quality-contracts';
3
+ import { checkBuilds } from '@kb-labs/quality-core/builds';
4
+
5
+ // src/cli/commands/check-builds.ts
6
+ var check_builds_default = defineCommand({
7
+ id: "quality:check-builds",
8
+ description: "Check build status across monorepo",
9
+ handler: {
10
+ async execute(ctx, input) {
11
+ const { ui, platform } = ctx;
12
+ const flags = input.flags ?? input;
13
+ const cacheKey = `${CACHE_KEYS.BUILDS}:${flags.package || "all"}`;
14
+ if (!flags.refresh) {
15
+ const cached = await platform.cache.get(cacheKey);
16
+ if (cached) {
17
+ outputBuildCheck({ ...cached, cached: true }, flags, ui);
18
+ return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };
19
+ }
20
+ }
21
+ const result = await checkBuilds(ctx.cwd, {
22
+ packageFilter: flags.package,
23
+ timeout: flags.timeout ? Number(flags.timeout) : 3e4
24
+ });
25
+ await platform.cache.set(cacheKey, result, 10 * 60 * 1e3);
26
+ await platform.analytics.track("quality:check-builds", {
27
+ totalPackages: result.totalPackages,
28
+ passing: result.passing,
29
+ failing: result.failing,
30
+ staleBuilds: result.staleBuilds.length,
31
+ duration: result.duration,
32
+ packageSpecific: !!flags.package
33
+ });
34
+ outputBuildCheck({ ...result, cached: false }, flags, ui);
35
+ return {
36
+ exitCode: result.failing > 0 ? 1 : 0,
37
+ result
38
+ };
39
+ }
40
+ }
41
+ });
42
+ function outputBuildCheck(result, flags, ui) {
43
+ if (flags.json) {
44
+ ui?.json?.(result);
45
+ return;
46
+ }
47
+ const sections = [];
48
+ const statusIcon = result.failing === 0 ? "\u2705" : "\u274C";
49
+ const statusText = result.failing === 0 ? "All builds passing" : "Build failures detected";
50
+ const statusItems = [
51
+ `${statusIcon} ${statusText}`,
52
+ `Passing: ${result.passing} package(s)`,
53
+ result.failing > 0 ? `Failing: ${result.failing} package(s)` : null
54
+ ].filter(Boolean);
55
+ sections.push({ header: "Build Status", items: statusItems });
56
+ if (result.failures.length > 0) {
57
+ const failureItems = [];
58
+ for (const failure of result.failures.slice(0, 5)) {
59
+ failureItems.push(`\u2022 ${failure.package}`);
60
+ const firstLine = failure.error.split("\n")[0];
61
+ failureItems.push(` ${firstLine?.substring(0, 80) || "Build failed"}`);
62
+ }
63
+ if (result.failures.length > 5) {
64
+ failureItems.push(`... and ${result.failures.length - 5} more failures`);
65
+ }
66
+ sections.push({ header: "\u274C Failed Packages", items: failureItems });
67
+ }
68
+ if (result.staleBuilds.length > 0) {
69
+ const staleItems = result.staleBuilds.slice(0, 5).map((s) => `\u2022 ${s.package}`);
70
+ if (result.staleBuilds.length > 5) {
71
+ staleItems.push(`... and ${result.staleBuilds.length - 5} more`);
72
+ }
73
+ sections.push({
74
+ header: "\u26A0\uFE0F Stale Builds (dist/ older than src/)",
75
+ items: staleItems
76
+ });
77
+ }
78
+ const summaryItems = [
79
+ `Total packages: ${result.totalPackages}`,
80
+ `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
81
+ result.cached ? "\u{1F4BE} Cached (use --refresh to recheck)" : "\u{1F504} Fresh check"
82
+ ];
83
+ sections.push({ header: "Summary", items: summaryItems });
84
+ const title = result.failing === 0 ? "\u2705 All Builds Passing" : `\u274C ${result.failing} Build Failure(s) Detected`;
85
+ ui?.success?.("Build check completed", {
86
+ title,
87
+ sections
88
+ });
89
+ }
90
+
91
+ export { check_builds_default as default };
92
+ //# sourceMappingURL=check-builds.js.map
93
+ //# sourceMappingURL=check-builds.js.map
@@ -0,0 +1 @@
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 come in input.flags object (not auto-merged)\n const flags = (input as any).flags ?? 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: any,\n ui: any\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"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { TestRunResult } from '@kb-labs/quality-contracts';
3
+ import { CheckTestsFlags } from './flags.js';
4
+
5
+ type CheckTestsInput = CheckTestsFlags & {
6
+ argv?: string[];
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CheckTestsInput, TestRunResult>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,114 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { runTests } from '@kb-labs/quality-core/tests';
3
+ import { CACHE_KEYS } from '@kb-labs/quality-contracts';
4
+
5
+ // src/cli/commands/check-tests.ts
6
+ var check_tests_default = defineCommand({
7
+ id: "quality:check-tests",
8
+ description: "Run tests and track coverage across monorepo",
9
+ handler: {
10
+ async execute(ctx, input) {
11
+ const { ui, platform } = ctx;
12
+ const flags = input.flags ?? input;
13
+ const cacheKey = `${CACHE_KEYS.TESTS}:${flags.package || "all"}`;
14
+ if (!flags.refresh) {
15
+ const cached = await platform.cache.get(cacheKey);
16
+ if (cached) {
17
+ outputTestResults({ ...cached, cached: true }, flags, ui);
18
+ return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };
19
+ }
20
+ }
21
+ const result = await runTests(ctx.cwd, {
22
+ packageFilter: flags.package,
23
+ timeout: flags.timeout ? Number(flags.timeout) : 6e4,
24
+ withCoverage: flags["with-coverage"],
25
+ coverageOnly: flags["coverage-only"]
26
+ });
27
+ await platform.cache.set(cacheKey, result, 5 * 60 * 1e3);
28
+ await platform.analytics.track("quality:check-tests", {
29
+ packageFilter: flags.package || "all",
30
+ totalPackages: result.totalPackages,
31
+ passing: result.passing,
32
+ failing: result.failing,
33
+ withCoverage: flags["with-coverage"],
34
+ cached: false
35
+ });
36
+ outputTestResults({ ...result, cached: false }, flags, ui);
37
+ return {
38
+ exitCode: result.failing > 0 ? 1 : 0,
39
+ result,
40
+ meta: { cached: false }
41
+ };
42
+ }
43
+ }
44
+ });
45
+ function outputTestResults(result, flags, ui) {
46
+ if (flags.json) {
47
+ ui?.json?.(result);
48
+ return;
49
+ }
50
+ const sections = [];
51
+ const statusIcon = result.failing === 0 ? "\u2705" : "\u274C";
52
+ const statusText = result.failing === 0 ? "All tests passing" : "Test failures detected";
53
+ const statusItems = [
54
+ `${statusIcon} ${statusText}`,
55
+ `Total packages: ${result.totalPackages}`,
56
+ `Passing: ${result.passing}`,
57
+ result.failing > 0 ? `Failing: ${result.failing}` : null,
58
+ result.skipped > 0 ? `Skipped: ${result.skipped} (no test script)` : null
59
+ ].filter(Boolean);
60
+ sections.push({ header: "Test Status", items: statusItems });
61
+ if (result.summary.totalTests > 0) {
62
+ const summaryItems2 = [
63
+ `Total tests: ${result.summary.totalTests}`,
64
+ `Passed: ${result.summary.passedTests}`,
65
+ result.summary.failedTests > 0 ? `Failed: ${result.summary.failedTests}` : null
66
+ ].filter(Boolean);
67
+ sections.push({ header: "Test Summary", items: summaryItems2 });
68
+ }
69
+ if (result.failures.length > 0) {
70
+ const failureItems = [];
71
+ for (const failure of result.failures.slice(0, 5)) {
72
+ failureItems.push(`\u274C ${failure.package}`);
73
+ if (failure.failedTests && failure.totalTests) {
74
+ failureItems.push(` ${failure.failedTests}/${failure.totalTests} tests failed`);
75
+ }
76
+ const firstLine = failure.error.split("\n")[0];
77
+ failureItems.push(` ${firstLine?.substring(0, 80) || "Test failed"}`);
78
+ }
79
+ if (result.failures.length > 5) {
80
+ failureItems.push(`... and ${result.failures.length - 5} more failures`);
81
+ }
82
+ sections.push({ header: "Failed Packages", items: failureItems });
83
+ }
84
+ if (result.coverage.packages.length > 0) {
85
+ const coverageItems = [];
86
+ coverageItems.push(`Average coverage: ${result.coverage.avgCoverage.toFixed(1)}%`);
87
+ coverageItems.push("");
88
+ const topPackages = result.coverage.packages.sort((a, b) => b.lines - a.lines).slice(0, 5);
89
+ for (const pkg of topPackages) {
90
+ coverageItems.push(`${pkg.name}`);
91
+ coverageItems.push(
92
+ ` Lines: ${pkg.lines.toFixed(1)}% | Statements: ${pkg.statements.toFixed(1)}% | Functions: ${pkg.functions.toFixed(1)}% | Branches: ${pkg.branches.toFixed(1)}%`
93
+ );
94
+ }
95
+ if (result.coverage.packages.length > 5) {
96
+ coverageItems.push(`... and ${result.coverage.packages.length - 5} more packages`);
97
+ }
98
+ sections.push({ header: "Coverage", items: coverageItems });
99
+ }
100
+ const summaryItems = [
101
+ `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
102
+ result.cached ? "\u{1F4BE} Cached (use --refresh to re-run)" : "\u{1F504} Fresh run"
103
+ ];
104
+ sections.push({ header: "Summary", items: summaryItems });
105
+ const title = result.failing === 0 ? "\u2705 All Tests Passed" : `\u274C ${result.failing} Package(s) with Test Failures`;
106
+ ui?.success?.("Test run completed", {
107
+ title,
108
+ sections
109
+ });
110
+ }
111
+
112
+ export { check_tests_default as default };
113
+ //# sourceMappingURL=check-tests.js.map
114
+ //# sourceMappingURL=check-tests.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,10 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { TypeAnalysisResult } from '@kb-labs/quality-contracts';
3
+ import { CheckTypesFlags } from './flags.js';
4
+
5
+ type CheckTypesInput = CheckTypesFlags & {
6
+ argv?: string[];
7
+ };
8
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CheckTypesInput, TypeAnalysisResult>;
9
+
10
+ export { _default as default };
@@ -0,0 +1,108 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { analyzeTypes } from '@kb-labs/quality-core/types';
3
+ import { CACHE_KEYS } from '@kb-labs/quality-contracts';
4
+
5
+ // src/cli/commands/check-types.ts
6
+ var check_types_default = defineCommand({
7
+ id: "quality:check-types",
8
+ description: "Analyze TypeScript type safety across monorepo",
9
+ handler: {
10
+ async execute(ctx, input) {
11
+ const { ui, platform } = ctx;
12
+ const flags = input.flags ?? input;
13
+ const cacheKey = `${CACHE_KEYS.TYPE_ANALYSIS}:${flags.package || "all"}`;
14
+ if (!flags.refresh) {
15
+ const cached = await platform.cache.get(cacheKey);
16
+ if (cached) {
17
+ outputTypeAnalysis({ ...cached, cached: true }, flags, ui);
18
+ return { exitCode: cached.totalErrors > 0 ? 1 : 0, result: cached };
19
+ }
20
+ }
21
+ const result = await analyzeTypes(ctx.cwd, {
22
+ packageFilter: flags.package,
23
+ errorsOnly: flags["errors-only"]
24
+ });
25
+ await platform.cache.set(cacheKey, result, 10 * 60 * 1e3);
26
+ await platform.analytics.track("quality:check-types", {
27
+ packageFilter: flags.package || "all",
28
+ totalPackages: result.totalPackages,
29
+ totalErrors: result.totalErrors,
30
+ avgCoverage: result.avgCoverage,
31
+ cached: false
32
+ });
33
+ outputTypeAnalysis({ ...result, cached: false }, flags, ui);
34
+ return {
35
+ exitCode: result.totalErrors > 0 ? 1 : 0,
36
+ result,
37
+ meta: { cached: false }
38
+ };
39
+ }
40
+ }
41
+ });
42
+ function outputTypeAnalysis(result, flags, ui) {
43
+ if (flags.json) {
44
+ ui?.json?.(result);
45
+ return;
46
+ }
47
+ const errorsOnly = flags["errors-only"] || false;
48
+ const sections = [];
49
+ const statusIcon = result.totalErrors === 0 ? "\u2705" : "\u274C";
50
+ const statusText = result.totalErrors === 0 ? "All packages passed type checks" : "Type errors detected";
51
+ const statusItems = [
52
+ `${statusIcon} ${statusText}`,
53
+ `Analyzed: ${result.totalPackages} package(s)`,
54
+ `Errors: ${result.totalErrors}`,
55
+ `Warnings: ${result.totalWarnings}`,
56
+ `Avg Coverage: ${result.avgCoverage.toFixed(1)}%`
57
+ ];
58
+ sections.push({ header: "Type Safety Status", items: statusItems });
59
+ if (result.packagesWithErrors > 0) {
60
+ const errorItems = [];
61
+ const packagesToShow = result.packages.filter((pkg) => !errorsOnly || pkg.errors > 0).slice(0, 10);
62
+ for (const pkg of packagesToShow) {
63
+ const status = pkg.errors > 0 ? "\u274C" : "\u2705";
64
+ errorItems.push(`${status} ${pkg.name}`);
65
+ const details = [
66
+ pkg.errors > 0 ? `${pkg.errors} error(s)` : null,
67
+ pkg.warnings > 0 ? `${pkg.warnings} warning(s)` : null,
68
+ `${pkg.coverage.toFixed(1)}% coverage`,
69
+ pkg.anyCount > 0 ? `${pkg.anyCount} any` : null,
70
+ pkg.tsIgnoreCount > 0 ? `${pkg.tsIgnoreCount} @ts-ignore` : null
71
+ ].filter(Boolean).join(", ");
72
+ errorItems.push(` ${details}`);
73
+ }
74
+ if (result.packages.length > 10) {
75
+ errorItems.push(`... and ${result.packages.length - 10} more packages`);
76
+ }
77
+ sections.push({
78
+ header: `Packages with Type Errors (${result.packagesWithErrors})`,
79
+ items: errorItems
80
+ });
81
+ }
82
+ const excellent = result.packages.filter((p) => p.coverage >= 90).length;
83
+ const good = result.packages.filter((p) => p.coverage >= 70 && p.coverage < 90).length;
84
+ const poor = result.packages.filter((p) => p.coverage < 70).length;
85
+ if (result.packages.length > 0) {
86
+ const coverageItems = [
87
+ `\u2705 Excellent (\u226590%): ${excellent} package(s)`,
88
+ `\u26A0\uFE0F Good (70-90%): ${good} package(s)`,
89
+ poor > 0 ? `\u274C Poor (<70%): ${poor} package(s)` : null
90
+ ].filter(Boolean);
91
+ sections.push({ header: "Type Coverage Distribution", items: coverageItems });
92
+ }
93
+ const summaryItems = [
94
+ `Total packages: ${result.totalPackages}`,
95
+ `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
96
+ result.cached ? "\u{1F4BE} Cached (use --refresh to recheck)" : "\u{1F504} Fresh analysis"
97
+ ];
98
+ sections.push({ header: "Summary", items: summaryItems });
99
+ const title = result.totalErrors === 0 ? "\u2705 All Type Checks Passed" : `\u274C ${result.packagesWithErrors} Package(s) with Type Errors`;
100
+ ui?.success?.("Type analysis completed", {
101
+ title,
102
+ sections
103
+ });
104
+ }
105
+
106
+ export { check_types_default as default };
107
+ //# sourceMappingURL=check-types.js.map
108
+ //# sourceMappingURL=check-types.js.map