@kb-labs/devkit 1.0.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/.cursorrules +32 -0
- package/.github/CODEOWNERS +2 -0
- package/.github/actions/setup-node-pnpm/action.yml +47 -0
- package/.github/workflow-templates/ci.yml +13 -0
- package/.github/workflow-templates/drift-check.yml +10 -0
- package/.github/workflow-templates/profiles-validate.yml +16 -0
- package/.github/workflow-templates/release.yml +8 -0
- package/.github/workflows/ci-reusable.yml +131 -0
- package/.github/workflows/drift-check-reusable.yml +23 -0
- package/.github/workflows/fixtures.yml +74 -0
- package/.github/workflows/profiles-validate-reusable.yml +67 -0
- package/.github/workflows/release-reusable.yml +50 -0
- package/.vscode/settings.json +23 -0
- package/AGENTS.md +130 -0
- package/LICENSE +21 -0
- package/README.md +1542 -0
- package/agents/devkit-maintainer/context.globs +15 -0
- package/agents/devkit-maintainer/permissions.yml +17 -0
- package/agents/devkit-maintainer/prompt.md +28 -0
- package/agents/devkit-maintainer/runbook.md +31 -0
- package/agents/docs-crafter/prompt.md +24 -0
- package/agents/docs-crafter/runbook.md +18 -0
- package/agents/release-manager/context.globs +7 -0
- package/agents/release-manager/prompt.md +27 -0
- package/agents/release-manager/runbook.md +17 -0
- package/agents/test-generator/context.globs +7 -0
- package/agents/test-generator/prompt.md +27 -0
- package/agents/test-generator/runbook.md +18 -0
- package/bin/devkit-architecture.mjs +1225 -0
- package/bin/devkit-build-order.mjs +500 -0
- package/bin/devkit-check-build-readiness.mjs +222 -0
- package/bin/devkit-check-commands.mjs +394 -0
- package/bin/devkit-check-configs.mjs +461 -0
- package/bin/devkit-check-deprecated.mjs +532 -0
- package/bin/devkit-check-duplicates.mjs +431 -0
- package/bin/devkit-check-exports.mjs +561 -0
- package/bin/devkit-check-imports.mjs +712 -0
- package/bin/devkit-check-paths.mjs +670 -0
- package/bin/devkit-check-scripts.mjs +335 -0
- package/bin/devkit-check-structure.mjs +495 -0
- package/bin/devkit-check-types.mjs +450 -0
- package/bin/devkit-ci.mjs +261 -0
- package/bin/devkit-core-gate.mjs +225 -0
- package/bin/devkit-fix-deps.mjs +1169 -0
- package/bin/devkit-freshness.mjs +199 -0
- package/bin/devkit-health.mjs +489 -0
- package/bin/devkit-migrate-configs.mjs +370 -0
- package/bin/devkit-paths.mjs +192 -0
- package/bin/devkit-stats.mjs +453 -0
- package/bin/devkit-sync.mjs +12 -0
- package/bin/devkit-tsup-external.mjs +148 -0
- package/bin/devkit-types-audit.mjs +615 -0
- package/bin/devkit-types-order.mjs +637 -0
- package/bin/devkit-validate-naming.mjs +203 -0
- package/bin/devkit-visualize.mjs +452 -0
- package/bin/kb-devkit-qa-history.mjs +453 -0
- package/bin/kb-devkit-qa.mjs +915 -0
- package/eslint/node.js +134 -0
- package/eslint/react.js +260 -0
- package/package.json +186 -0
- package/prettier/index.json +10 -0
- package/sync/index.mjs +693 -0
- package/templates/configs/README.md +306 -0
- package/templates/configs/eslint.config.js +27 -0
- package/templates/configs/package.json.bin +25 -0
- package/templates/configs/package.json.lib +30 -0
- package/templates/configs/tsconfig.build.json +15 -0
- package/templates/configs/tsconfig.json +9 -0
- package/templates/configs/tsup.config.bin.ts +34 -0
- package/templates/configs/tsup.config.cli.ts +41 -0
- package/templates/configs/tsup.config.dual.ts +46 -0
- package/templates/configs/tsup.config.ts +36 -0
- package/templates/package-json/README.md +290 -0
- package/templates/package-json/package.json.bin.template +40 -0
- package/templates/package-json/package.json.template +45 -0
- package/tsconfig/base.json +21 -0
- package/tsconfig/cli.json +12 -0
- package/tsconfig/dist/__tests__/cache.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/cache.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/cache.spec.js +85 -0
- package/tsconfig/dist/__tests__/cache.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.js +153 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.js +99 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/kb-error.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/kb-error.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/kb-error.spec.js +190 -0
- package/tsconfig/dist/__tests__/kb-error.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.js +142 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.js +100 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/product-config.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/product-config.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/product-config.spec.js +298 -0
- package/tsconfig/dist/__tests__/product-config.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/runtime.spec.d.ts +2 -0
- package/tsconfig/dist/__tests__/runtime.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/runtime.spec.js +127 -0
- package/tsconfig/dist/__tests__/runtime.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.js +251 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/validate-config.spec.d.ts +2 -0
- package/tsconfig/dist/__tests__/validate-config.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/validate-config.spec.js +14 -0
- package/tsconfig/dist/__tests__/validate-config.spec.js.map +1 -0
- package/tsconfig/dist/api/init-workspace.d.ts +10 -0
- package/tsconfig/dist/api/init-workspace.d.ts.map +1 -0
- package/tsconfig/dist/api/init-workspace.js +191 -0
- package/tsconfig/dist/api/init-workspace.js.map +1 -0
- package/tsconfig/dist/api/product-config.d.ts +21 -0
- package/tsconfig/dist/api/product-config.d.ts.map +1 -0
- package/tsconfig/dist/api/product-config.js +192 -0
- package/tsconfig/dist/api/product-config.js.map +1 -0
- package/tsconfig/dist/api/read-config.d.ts +22 -0
- package/tsconfig/dist/api/read-config.d.ts.map +1 -0
- package/tsconfig/dist/api/read-config.js +105 -0
- package/tsconfig/dist/api/read-config.js.map +1 -0
- package/tsconfig/dist/api/upsert-lockfile.d.ts +10 -0
- package/tsconfig/dist/api/upsert-lockfile.d.ts.map +1 -0
- package/tsconfig/dist/api/upsert-lockfile.js +63 -0
- package/tsconfig/dist/api/upsert-lockfile.js.map +1 -0
- package/tsconfig/dist/cache/fs-cache.d.ts +38 -0
- package/tsconfig/dist/cache/fs-cache.d.ts.map +1 -0
- package/tsconfig/dist/cache/fs-cache.js +142 -0
- package/tsconfig/dist/cache/fs-cache.js.map +1 -0
- package/tsconfig/dist/errors/kb-error.d.ts +32 -0
- package/tsconfig/dist/errors/kb-error.d.ts.map +1 -0
- package/tsconfig/dist/errors/kb-error.js +54 -0
- package/tsconfig/dist/errors/kb-error.js.map +1 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.d.ts +2 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.d.ts.map +1 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.js +22 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.js.map +1 -0
- package/tsconfig/dist/fs/fs.d.ts +6 -0
- package/tsconfig/dist/fs/fs.d.ts.map +1 -0
- package/tsconfig/dist/fs/fs.js +12 -0
- package/tsconfig/dist/fs/fs.js.map +1 -0
- package/tsconfig/dist/fs/index.d.ts +2 -0
- package/tsconfig/dist/fs/index.d.ts.map +1 -0
- package/tsconfig/dist/fs/index.js +2 -0
- package/tsconfig/dist/fs/index.js.map +1 -0
- package/tsconfig/dist/hash/config-hash.d.ts +17 -0
- package/tsconfig/dist/hash/config-hash.d.ts.map +1 -0
- package/tsconfig/dist/hash/config-hash.js +55 -0
- package/tsconfig/dist/hash/config-hash.js.map +1 -0
- package/tsconfig/dist/index.d.ts +5 -0
- package/tsconfig/dist/index.d.ts.map +1 -0
- package/tsconfig/dist/index.js +5 -0
- package/tsconfig/dist/index.js.map +1 -0
- package/tsconfig/dist/lockfile/lockfile.d.ts +54 -0
- package/tsconfig/dist/lockfile/lockfile.d.ts.map +1 -0
- package/tsconfig/dist/lockfile/lockfile.js +141 -0
- package/tsconfig/dist/lockfile/lockfile.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.js +65 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.js +34 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.js +90 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.js.map +1 -0
- package/tsconfig/dist/logging/index.d.ts +6 -0
- package/tsconfig/dist/logging/index.d.ts.map +1 -0
- package/tsconfig/dist/logging/index.js +6 -0
- package/tsconfig/dist/logging/index.js.map +1 -0
- package/tsconfig/dist/logging/logger.d.ts +9 -0
- package/tsconfig/dist/logging/logger.d.ts.map +1 -0
- package/tsconfig/dist/logging/logger.js +101 -0
- package/tsconfig/dist/logging/logger.js.map +1 -0
- package/tsconfig/dist/logging/redaction.d.ts +7 -0
- package/tsconfig/dist/logging/redaction.d.ts.map +1 -0
- package/tsconfig/dist/logging/redaction.js +23 -0
- package/tsconfig/dist/logging/redaction.js.map +1 -0
- package/tsconfig/dist/logging/sinks/json.d.ts +4 -0
- package/tsconfig/dist/logging/sinks/json.d.ts.map +1 -0
- package/tsconfig/dist/logging/sinks/json.js +23 -0
- package/tsconfig/dist/logging/sinks/json.js.map +1 -0
- package/tsconfig/dist/logging/sinks/stdout.d.ts +3 -0
- package/tsconfig/dist/logging/sinks/stdout.d.ts.map +1 -0
- package/tsconfig/dist/logging/sinks/stdout.js +24 -0
- package/tsconfig/dist/logging/sinks/stdout.js.map +1 -0
- package/tsconfig/dist/logging/types/index.d.ts +2 -0
- package/tsconfig/dist/logging/types/index.d.ts.map +1 -0
- package/tsconfig/dist/logging/types/index.js +2 -0
- package/tsconfig/dist/logging/types/index.js.map +1 -0
- package/tsconfig/dist/logging/types/types.d.ts +37 -0
- package/tsconfig/dist/logging/types/types.d.ts.map +1 -0
- package/tsconfig/dist/logging/types/types.js +2 -0
- package/tsconfig/dist/logging/types/types.js.map +1 -0
- package/tsconfig/dist/merge/layered-merge.d.ts +16 -0
- package/tsconfig/dist/merge/layered-merge.d.ts.map +1 -0
- package/tsconfig/dist/merge/layered-merge.js +97 -0
- package/tsconfig/dist/merge/layered-merge.js.map +1 -0
- package/tsconfig/dist/preset/resolve-preset.d.ts +29 -0
- package/tsconfig/dist/preset/resolve-preset.d.ts.map +1 -0
- package/tsconfig/dist/preset/resolve-preset.js +104 -0
- package/tsconfig/dist/preset/resolve-preset.js.map +1 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.d.ts +2 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.d.ts.map +1 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.js +25 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.js.map +1 -0
- package/tsconfig/dist/repo/index.d.ts +2 -0
- package/tsconfig/dist/repo/index.d.ts.map +1 -0
- package/tsconfig/dist/repo/index.js +2 -0
- package/tsconfig/dist/repo/index.js.map +1 -0
- package/tsconfig/dist/repo/repo.d.ts +6 -0
- package/tsconfig/dist/repo/repo.d.ts.map +1 -0
- package/tsconfig/dist/repo/repo.js +25 -0
- package/tsconfig/dist/repo/repo.js.map +1 -0
- package/tsconfig/dist/runtime/index.d.ts +2 -0
- package/tsconfig/dist/runtime/index.d.ts.map +1 -0
- package/tsconfig/dist/runtime/index.js +2 -0
- package/tsconfig/dist/runtime/index.js.map +1 -0
- package/tsconfig/dist/runtime/runtime.d.ts +46 -0
- package/tsconfig/dist/runtime/runtime.d.ts.map +1 -0
- package/tsconfig/dist/runtime/runtime.js +126 -0
- package/tsconfig/dist/runtime/runtime.js.map +1 -0
- package/tsconfig/dist/tsconfig.tools.tsbuildinfo +1 -0
- package/tsconfig/dist/tsconfig.tsbuildinfo +1 -0
- package/tsconfig/dist/types/index.d.ts +2 -0
- package/tsconfig/dist/types/index.d.ts.map +1 -0
- package/tsconfig/dist/types/index.js +2 -0
- package/tsconfig/dist/types/index.js.map +1 -0
- package/tsconfig/dist/types/init.d.ts +34 -0
- package/tsconfig/dist/types/init.d.ts.map +1 -0
- package/tsconfig/dist/types/init.js +6 -0
- package/tsconfig/dist/types/init.js.map +1 -0
- package/tsconfig/dist/types/preset.d.ts +27 -0
- package/tsconfig/dist/types/preset.d.ts.map +1 -0
- package/tsconfig/dist/types/preset.js +6 -0
- package/tsconfig/dist/types/preset.js.map +1 -0
- package/tsconfig/dist/types/types.d.ts +6 -0
- package/tsconfig/dist/types/types.d.ts.map +1 -0
- package/tsconfig/dist/types/types.js +2 -0
- package/tsconfig/dist/types/types.js.map +1 -0
- package/tsconfig/dist/utils/__tests__/env.spec.d.ts +2 -0
- package/tsconfig/dist/utils/__tests__/env.spec.d.ts.map +1 -0
- package/tsconfig/dist/utils/__tests__/env.spec.js +33 -0
- package/tsconfig/dist/utils/__tests__/env.spec.js.map +1 -0
- package/tsconfig/dist/utils/env.d.ts +7 -0
- package/tsconfig/dist/utils/env.d.ts.map +1 -0
- package/tsconfig/dist/utils/env.js +25 -0
- package/tsconfig/dist/utils/env.js.map +1 -0
- package/tsconfig/dist/utils/fs-atomic.d.ts +15 -0
- package/tsconfig/dist/utils/fs-atomic.d.ts.map +1 -0
- package/tsconfig/dist/utils/fs-atomic.js +45 -0
- package/tsconfig/dist/utils/fs-atomic.js.map +1 -0
- package/tsconfig/dist/utils/index.d.ts +3 -0
- package/tsconfig/dist/utils/index.d.ts.map +1 -0
- package/tsconfig/dist/utils/index.js +3 -0
- package/tsconfig/dist/utils/index.js.map +1 -0
- package/tsconfig/dist/utils/paths.d.ts +21 -0
- package/tsconfig/dist/utils/paths.d.ts.map +1 -0
- package/tsconfig/dist/utils/paths.js +32 -0
- package/tsconfig/dist/utils/paths.js.map +1 -0
- package/tsconfig/dist/utils/product-normalize.d.ts +27 -0
- package/tsconfig/dist/utils/product-normalize.d.ts.map +1 -0
- package/tsconfig/dist/utils/product-normalize.js +45 -0
- package/tsconfig/dist/utils/product-normalize.js.map +1 -0
- package/tsconfig/dist/validation/validate-config.d.ts +7 -0
- package/tsconfig/dist/validation/validate-config.d.ts.map +1 -0
- package/tsconfig/dist/validation/validate-config.js +22 -0
- package/tsconfig/dist/validation/validate-config.js.map +1 -0
- package/tsconfig/lib.json +13 -0
- package/tsconfig/node.json +12 -0
- package/tsconfig/react-app.json +8 -0
- package/tsconfig/react-lib.json +8 -0
- package/tsconfig/test.json +15 -0
- package/tsup/bin.js +172 -0
- package/tsup/dual.js +155 -0
- package/tsup/external-sync.mjs +41 -0
- package/tsup/external.mjs +109 -0
- package/tsup/node.js +65 -0
- package/tsup/react-lib.js +18 -0
- package/tsup/sdk.js +118 -0
- package/vite/react-app.js +50 -0
- package/vitest/node.js +37 -0
- package/vitest/react.js +39 -0
- package/vitest/vitest-setup.ts +9 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* kb-devkit-check-configs
|
|
5
|
+
*
|
|
6
|
+
* Checks all packages for configuration drift from standard templates.
|
|
7
|
+
* Ensures consistency across the entire monorepo.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Detects missing or modified config files
|
|
11
|
+
* - Validates tsup.config.ts structure (nodePreset usage, dts: true, etc.)
|
|
12
|
+
* - Checks for duplicate external/ignores declarations
|
|
13
|
+
* - Auto-fix capability with backup
|
|
14
|
+
* - CI-friendly exit codes
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* npx kb-devkit-check-configs # Check all packages
|
|
18
|
+
* npx kb-devkit-check-configs --fix # Auto-fix issues
|
|
19
|
+
* npx kb-devkit-check-configs --package=cli-core # Check specific package
|
|
20
|
+
* npx kb-devkit-check-configs --ci # CI mode (fail on drift)
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { promises as fs } from 'node:fs';
|
|
24
|
+
import { join, dirname, resolve } from 'node:path';
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
import process from 'node:process';
|
|
27
|
+
import { glob } from 'glob';
|
|
28
|
+
import { createHash } from 'node:crypto';
|
|
29
|
+
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
31
|
+
const __dirname = dirname(__filename);
|
|
32
|
+
const DEVKIT_ROOT = resolve(__dirname, '..');
|
|
33
|
+
const TEMPLATES_DIR = resolve(DEVKIT_ROOT, 'templates/configs');
|
|
34
|
+
|
|
35
|
+
// ANSI colors
|
|
36
|
+
const colors = {
|
|
37
|
+
reset: '\x1b[0m',
|
|
38
|
+
bright: '\x1b[1m',
|
|
39
|
+
red: '\x1b[31m',
|
|
40
|
+
green: '\x1b[32m',
|
|
41
|
+
yellow: '\x1b[33m',
|
|
42
|
+
blue: '\x1b[34m',
|
|
43
|
+
cyan: '\x1b[36m',
|
|
44
|
+
gray: '\x1b[90m',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function color(c, text) {
|
|
48
|
+
return process.stdout.isTTY ? `${colors[c]}${text}${colors.reset}` : text;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function exists(path) {
|
|
52
|
+
try {
|
|
53
|
+
await fs.access(path);
|
|
54
|
+
return true;
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function sha256(content) {
|
|
61
|
+
return createHash('sha256').update(content).digest('hex');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function readJson(path) {
|
|
65
|
+
return JSON.parse(await fs.readFile(path, 'utf8'));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function findWorkspacePackages(root) {
|
|
69
|
+
const wsFile = join(root, 'pnpm-workspace.yaml');
|
|
70
|
+
if (!(await exists(wsFile))) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const pkgJsonPaths = await glob('**/package.json', {
|
|
75
|
+
cwd: root,
|
|
76
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/coverage/**'],
|
|
77
|
+
absolute: true,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const packages = [];
|
|
81
|
+
for (const pkgPath of pkgJsonPaths) {
|
|
82
|
+
try {
|
|
83
|
+
const pkg = await readJson(pkgPath);
|
|
84
|
+
if (pkg.name && pkg.name.startsWith('@kb-labs/')) {
|
|
85
|
+
packages.push({
|
|
86
|
+
name: pkg.name,
|
|
87
|
+
path: dirname(pkgPath),
|
|
88
|
+
pkg,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
} catch {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return packages;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const CONFIG_FILES = {
|
|
98
|
+
'tsup.config.ts': { required: true, template: 'tsup.config.ts' },
|
|
99
|
+
'eslint.config.js': { required: true, template: 'eslint.config.js' },
|
|
100
|
+
'tsconfig.json': { required: true, template: 'tsconfig.json' },
|
|
101
|
+
'tsconfig.build.json': { required: true, template: 'tsconfig.build.json' },
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
async function checkPackageConfig(pkg, opts) {
|
|
105
|
+
const issues = [];
|
|
106
|
+
const warnings = [];
|
|
107
|
+
|
|
108
|
+
// Check all required config files
|
|
109
|
+
for (const [filename, meta] of Object.entries(CONFIG_FILES)) {
|
|
110
|
+
const filePath = join(pkg.path, filename);
|
|
111
|
+
const templatePath = join(TEMPLATES_DIR, meta.template);
|
|
112
|
+
|
|
113
|
+
if (!(await exists(filePath))) {
|
|
114
|
+
if (meta.required) {
|
|
115
|
+
issues.push({
|
|
116
|
+
type: 'missing',
|
|
117
|
+
file: filename,
|
|
118
|
+
severity: 'error',
|
|
119
|
+
message: `Missing required config file: ${filename}`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
126
|
+
const templateContent = await fs.readFile(templatePath, 'utf8');
|
|
127
|
+
|
|
128
|
+
// For tsup.config.ts and eslint.config.js, do structural checks
|
|
129
|
+
if (filename === 'tsup.config.ts') {
|
|
130
|
+
await checkTsupConfig(content, filePath, issues, warnings);
|
|
131
|
+
} else if (filename === 'eslint.config.js') {
|
|
132
|
+
await checkEslintConfig(content, filePath, issues, warnings);
|
|
133
|
+
} else {
|
|
134
|
+
// For tsconfig files, check if they match template exactly (ignoring comments/whitespace)
|
|
135
|
+
const contentClean = content.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '').trim();
|
|
136
|
+
const templateClean = templateContent.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '').trim();
|
|
137
|
+
|
|
138
|
+
if (contentClean !== templateClean) {
|
|
139
|
+
issues.push({
|
|
140
|
+
type: 'drift',
|
|
141
|
+
file: filename,
|
|
142
|
+
severity: 'error',
|
|
143
|
+
message: `Config file differs from standard template`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { issues, warnings };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function checkTsupConfig(content, filePath, issues, warnings) {
|
|
153
|
+
// Check for any DevKit preset usage
|
|
154
|
+
const hasDevKitPreset =
|
|
155
|
+
content.includes('nodePreset') ||
|
|
156
|
+
content.includes('binPreset') ||
|
|
157
|
+
content.includes('reactPreset') ||
|
|
158
|
+
content.includes('reactLibPreset') ||
|
|
159
|
+
content.includes('reactAppPreset') ||
|
|
160
|
+
content.includes('sdkPreset') ||
|
|
161
|
+
content.includes('dualPreset') ||
|
|
162
|
+
content.includes("from '@kb-labs/devkit/tsup/"); // Generic DevKit import
|
|
163
|
+
|
|
164
|
+
if (!hasDevKitPreset) {
|
|
165
|
+
issues.push({
|
|
166
|
+
type: 'no-preset',
|
|
167
|
+
file: 'tsup.config.ts',
|
|
168
|
+
severity: 'error',
|
|
169
|
+
message: 'Not using any DevKit preset',
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Check for explicit dts: true
|
|
174
|
+
if (!content.includes('dts:')) {
|
|
175
|
+
warnings.push({
|
|
176
|
+
type: 'implicit-dts',
|
|
177
|
+
file: 'tsup.config.ts',
|
|
178
|
+
severity: 'warning',
|
|
179
|
+
message: 'Missing explicit dts: true',
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Check for dts: false (critical issue)
|
|
184
|
+
if (content.match(/dts:\s*false/)) {
|
|
185
|
+
issues.push({
|
|
186
|
+
type: 'dts-false',
|
|
187
|
+
file: 'tsup.config.ts',
|
|
188
|
+
severity: 'error',
|
|
189
|
+
message: 'Has dts: false - types not being generated!',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Check for duplicate external declarations
|
|
194
|
+
const externalMatch = content.match(/external:\s*\[([^\]]+)\]/s);
|
|
195
|
+
if (externalMatch) {
|
|
196
|
+
const externalContent = externalMatch[1];
|
|
197
|
+
// Check if declaring @kb-labs packages (already in preset)
|
|
198
|
+
if (externalContent.includes('@kb-labs/')) {
|
|
199
|
+
warnings.push({
|
|
200
|
+
type: 'redundant-external',
|
|
201
|
+
file: 'tsup.config.ts',
|
|
202
|
+
severity: 'warning',
|
|
203
|
+
message: 'Declares @kb-labs/* packages in external (already in nodePreset)',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Check for tsconfig: 'tsconfig.build.json'
|
|
209
|
+
if (!content.includes("tsconfig: 'tsconfig.build.json'") &&
|
|
210
|
+
!content.includes('tsconfig: "tsconfig.build.json"')) {
|
|
211
|
+
warnings.push({
|
|
212
|
+
type: 'wrong-tsconfig',
|
|
213
|
+
file: 'tsup.config.ts',
|
|
214
|
+
severity: 'warning',
|
|
215
|
+
message: 'Should use tsconfig: "tsconfig.build.json"',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function checkEslintConfig(content, filePath, issues, warnings) {
|
|
221
|
+
// Check for any DevKit preset usage (nodePreset or reactPreset)
|
|
222
|
+
const hasDevKitPreset =
|
|
223
|
+
content.includes('nodePreset') ||
|
|
224
|
+
content.includes('reactPreset');
|
|
225
|
+
|
|
226
|
+
if (!hasDevKitPreset) {
|
|
227
|
+
issues.push({
|
|
228
|
+
type: 'no-preset',
|
|
229
|
+
file: 'eslint.config.js',
|
|
230
|
+
severity: 'error',
|
|
231
|
+
message: 'Not using any DevKit preset (nodePreset/reactPreset)',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Check for duplicate ignores
|
|
236
|
+
const ignoresMatch = content.match(/ignores:\s*\[([^\]]+)\]/s);
|
|
237
|
+
if (ignoresMatch) {
|
|
238
|
+
const ignoresContent = ignoresMatch[1];
|
|
239
|
+
const redundantPatterns = [
|
|
240
|
+
'**/dist/**',
|
|
241
|
+
'**/coverage/**',
|
|
242
|
+
'**/node_modules/**',
|
|
243
|
+
'**/*.d.ts',
|
|
244
|
+
'**/scripts/**',
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
for (const pattern of redundantPatterns) {
|
|
248
|
+
if (ignoresContent.includes(pattern)) {
|
|
249
|
+
warnings.push({
|
|
250
|
+
type: 'redundant-ignore',
|
|
251
|
+
file: 'eslint.config.js',
|
|
252
|
+
severity: 'warning',
|
|
253
|
+
message: `Redundant ignore pattern: ${pattern} (already in preset)`,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function autoFix(pkg, issues, opts) {
|
|
261
|
+
const fixed = [];
|
|
262
|
+
|
|
263
|
+
for (const issue of issues) {
|
|
264
|
+
const filePath = join(pkg.path, issue.file);
|
|
265
|
+
|
|
266
|
+
if (issue.type === 'missing') {
|
|
267
|
+
// Copy template
|
|
268
|
+
const templatePath = join(TEMPLATES_DIR, CONFIG_FILES[issue.file].template);
|
|
269
|
+
await fs.copyFile(templatePath, filePath);
|
|
270
|
+
fixed.push({ issue, action: 'created from template' });
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (issue.type === 'dts-false') {
|
|
275
|
+
// Replace dts: false with dts: true
|
|
276
|
+
let content = await fs.readFile(filePath, 'utf8');
|
|
277
|
+
|
|
278
|
+
// Create backup
|
|
279
|
+
await fs.writeFile(`${filePath}.backup`, content);
|
|
280
|
+
|
|
281
|
+
content = content.replace(/dts:\s*false/, 'dts: true');
|
|
282
|
+
await fs.writeFile(filePath, content);
|
|
283
|
+
fixed.push({ issue, action: 'changed dts: false ā dts: true' });
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (issue.type === 'drift' && (issue.file === 'tsconfig.json' || issue.file === 'tsconfig.build.json')) {
|
|
288
|
+
// Replace with template
|
|
289
|
+
const templatePath = join(TEMPLATES_DIR, CONFIG_FILES[issue.file].template);
|
|
290
|
+
|
|
291
|
+
// Create backup
|
|
292
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
293
|
+
await fs.writeFile(`${filePath}.backup`, content);
|
|
294
|
+
|
|
295
|
+
await fs.copyFile(templatePath, filePath);
|
|
296
|
+
fixed.push({ issue, action: 'replaced with template (backup created)' });
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return fixed;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function parseArgs(argv) {
|
|
305
|
+
const flags = new Set();
|
|
306
|
+
const kv = new Map();
|
|
307
|
+
|
|
308
|
+
for (const arg of argv.slice(2)) {
|
|
309
|
+
if (arg.startsWith('--')) {
|
|
310
|
+
const [k, v] = arg.split('=', 2);
|
|
311
|
+
if (v === undefined) {
|
|
312
|
+
flags.add(k);
|
|
313
|
+
} else {
|
|
314
|
+
kv.set(k, v);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
help: flags.has('--help') || flags.has('-h'),
|
|
321
|
+
fix: flags.has('--fix'),
|
|
322
|
+
ci: flags.has('--ci'),
|
|
323
|
+
json: flags.has('--json'),
|
|
324
|
+
verbose: flags.has('--verbose'),
|
|
325
|
+
package: kv.get('--package'),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function printHelp() {
|
|
330
|
+
console.log(`
|
|
331
|
+
${color('bright', 'kb-devkit-check-configs')}
|
|
332
|
+
|
|
333
|
+
Check configuration files for drift from standard templates.
|
|
334
|
+
|
|
335
|
+
${color('blue', 'Usage:')}
|
|
336
|
+
npx kb-devkit-check-configs [options]
|
|
337
|
+
|
|
338
|
+
${color('blue', 'Options:')}
|
|
339
|
+
--help, -h Show this help
|
|
340
|
+
--fix Auto-fix issues (creates backups)
|
|
341
|
+
--ci CI mode (fail with exit code 1 on drift)
|
|
342
|
+
--package=NAME Check specific package only
|
|
343
|
+
--json Output JSON format
|
|
344
|
+
--verbose Verbose output
|
|
345
|
+
|
|
346
|
+
${color('blue', 'Examples:')}
|
|
347
|
+
npx kb-devkit-check-configs
|
|
348
|
+
npx kb-devkit-check-configs --fix
|
|
349
|
+
npx kb-devkit-check-configs --package=@kb-labs/core
|
|
350
|
+
npx kb-devkit-check-configs --ci
|
|
351
|
+
|
|
352
|
+
${color('blue', 'Checked Files:')}
|
|
353
|
+
ā tsup.config.ts - Build configuration
|
|
354
|
+
ā eslint.config.js - Linting rules
|
|
355
|
+
ā tsconfig.json - TypeScript IDE config
|
|
356
|
+
ā tsconfig.build.json - TypeScript build config
|
|
357
|
+
`);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function main() {
|
|
361
|
+
const opts = parseArgs(process.argv);
|
|
362
|
+
|
|
363
|
+
if (opts.help) {
|
|
364
|
+
printHelp();
|
|
365
|
+
process.exit(0);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
console.log(color('bright', '\nš KB Labs Configuration Drift Checker\n'));
|
|
369
|
+
|
|
370
|
+
const cwd = process.cwd();
|
|
371
|
+
let packages = await findWorkspacePackages(cwd);
|
|
372
|
+
|
|
373
|
+
if (opts.package) {
|
|
374
|
+
packages = packages.filter(p => p.name === opts.package);
|
|
375
|
+
if (packages.length === 0) {
|
|
376
|
+
console.error(color('red', `ā Package ${opts.package} not found`));
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
console.log(color('gray', `Found ${packages.length} package(s) to check\n`));
|
|
382
|
+
|
|
383
|
+
const results = [];
|
|
384
|
+
let totalIssues = 0;
|
|
385
|
+
let totalWarnings = 0;
|
|
386
|
+
let totalFixed = 0;
|
|
387
|
+
|
|
388
|
+
for (const pkg of packages) {
|
|
389
|
+
const { issues, warnings } = await checkPackageConfig(pkg, opts);
|
|
390
|
+
|
|
391
|
+
if (issues.length > 0 || warnings.length > 0) {
|
|
392
|
+
results.push({ pkg, issues, warnings });
|
|
393
|
+
totalIssues += issues.length;
|
|
394
|
+
totalWarnings += warnings.length;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (opts.fix && issues.length > 0) {
|
|
398
|
+
const fixed = await autoFix(pkg, issues, opts);
|
|
399
|
+
totalFixed += fixed.length;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Print results
|
|
404
|
+
if (totalIssues > 0) {
|
|
405
|
+
console.log(color('red', `š“ Issues: ${totalIssues} package(s) with errors\n`));
|
|
406
|
+
for (const { pkg, issues } of results) {
|
|
407
|
+
if (issues.length === 0) {continue;}
|
|
408
|
+
console.log(color('yellow', ` ${pkg.name}`));
|
|
409
|
+
for (const issue of issues) {
|
|
410
|
+
console.log(color('gray', ` ${issue.file}`));
|
|
411
|
+
console.log(color('red', ` āā ${issue.message}`));
|
|
412
|
+
}
|
|
413
|
+
console.log();
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (totalWarnings > 0) {
|
|
418
|
+
console.log(color('yellow', `ā ļø Warnings: ${totalWarnings} non-critical issues\n`));
|
|
419
|
+
if (opts.verbose) {
|
|
420
|
+
for (const { pkg, warnings } of results) {
|
|
421
|
+
if (warnings.length === 0) {continue;}
|
|
422
|
+
console.log(color('yellow', ` ${pkg.name}`));
|
|
423
|
+
for (const warning of warnings) {
|
|
424
|
+
console.log(color('gray', ` ${warning.file}`));
|
|
425
|
+
console.log(color('yellow', ` āā ${warning.message}`));
|
|
426
|
+
}
|
|
427
|
+
console.log();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (opts.fix && totalFixed > 0) {
|
|
433
|
+
console.log(color('green', `ā
Auto-fixed ${totalFixed} issue(s)`));
|
|
434
|
+
console.log(color('gray', ' Backups created with .backup extension\n'));
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (totalIssues === 0 && totalWarnings === 0) {
|
|
438
|
+
console.log(color('green', 'ā
All configurations are up to date!\n'));
|
|
439
|
+
} else if (!opts.fix) {
|
|
440
|
+
console.log(color('cyan', '\nš” Run with --fix to automatically fix issues\n'));
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Exit code
|
|
444
|
+
if (opts.ci && totalIssues > 0) {
|
|
445
|
+
process.exit(1);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (totalIssues > 0 && !opts.fix) {
|
|
449
|
+
process.exit(1);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
process.exit(0);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
main().catch(err => {
|
|
456
|
+
console.error(color('red', '\nā Error:'), err.message);
|
|
457
|
+
if (process.env.DEBUG) {
|
|
458
|
+
console.error(err.stack);
|
|
459
|
+
}
|
|
460
|
+
process.exit(1);
|
|
461
|
+
});
|