@kb-labs/devkit 1.0.0 → 1.2.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/.github/workflow-templates/deploy.yml +28 -0
- package/.github/workflow-templates/docker-build.yml +25 -0
- package/.github/workflows/deploy-reusable.yml +110 -0
- package/.github/workflows/docker-build-reusable.yml +110 -0
- package/README.md +186 -34
- package/bin/devkit-architecture.mjs +14 -32
- package/bin/devkit-build-order.mjs +2 -30
- package/bin/devkit-check-build-readiness.mjs +14 -24
- package/bin/devkit-check-commands.mjs +9 -25
- package/bin/devkit-check-deprecated.mjs +24 -39
- package/bin/devkit-check-duplicates.mjs +3 -34
- package/bin/devkit-check-exports.mjs +3 -34
- package/bin/devkit-check-imports.mjs +3 -34
- package/bin/devkit-check-paths.mjs +9 -32
- package/bin/devkit-check-structure.mjs +3 -34
- package/bin/devkit-check-types.mjs +8 -31
- package/bin/devkit-fix-deps.mjs +3 -33
- package/bin/devkit-health.mjs +13 -35
- package/bin/devkit-stats.mjs +3 -31
- package/bin/devkit-types-audit.mjs +13 -34
- package/bin/devkit-types-order.mjs +8 -29
- package/bin/devkit-validate-naming.mjs +9 -35
- package/bin/devkit-visualize.mjs +3 -34
- package/bin/lib/find-packages.mjs +77 -0
- package/eslint/node.js +3 -1
- package/eslint/plugin.js +51 -0
- package/eslint/react.js +2 -1
- package/package.json +29 -24
- package/sync/index.mjs +27 -3
- package/tsconfig/dist/tsconfig.tools.tsbuildinfo +1 -1
- package/tsconfig/node.json +2 -1
- package/tsup/bin.js +5 -0
- package/tsup/dual.js +5 -0
- package/tsup/node.js +41 -3
- package/tsup/react-lib.js +6 -1
- package/tsup/sdk.js +5 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Deploy
|
|
2
|
+
|
|
3
|
+
# Deploys all services to VPS via docker compose
|
|
4
|
+
# Triggered manually with a specific image tag
|
|
5
|
+
#
|
|
6
|
+
# Prerequisites:
|
|
7
|
+
# Add secrets in GitHub → Settings → Secrets → Actions:
|
|
8
|
+
# VPS_HOST - server IP or hostname
|
|
9
|
+
# VPS_USER - SSH username (e.g. deploy)
|
|
10
|
+
# VPS_SSH_KEY - SSH private key
|
|
11
|
+
|
|
12
|
+
on:
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
tag:
|
|
16
|
+
description: Image tag to deploy (e.g. release-1.0.0)
|
|
17
|
+
required: true
|
|
18
|
+
type: string
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
call:
|
|
22
|
+
uses: KirillBaranov/kb-labs-devkit/.github/workflows/deploy-reusable.yml@main
|
|
23
|
+
with:
|
|
24
|
+
image-tag: ${{ inputs.tag }}
|
|
25
|
+
compose-file: docker-compose.production.yml
|
|
26
|
+
deploy-dir: /opt/kb-labs
|
|
27
|
+
health-check-url: http://localhost:5050/api/v1/health
|
|
28
|
+
secrets: inherit
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Docker Build
|
|
2
|
+
|
|
3
|
+
# Builds and pushes Docker image to ghcr.io
|
|
4
|
+
#
|
|
5
|
+
# Flow:
|
|
6
|
+
# rc branch → build image tagged rc-<sha> (for testing)
|
|
7
|
+
# release tag → build image tagged release-x.y.z + latest (for deploy)
|
|
8
|
+
#
|
|
9
|
+
# Configure:
|
|
10
|
+
# - Set image-name to your service name (e.g. kb-labs-rest-api)
|
|
11
|
+
# - Set dockerfile path if not at repo root
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [rc]
|
|
16
|
+
tags: ['release-*']
|
|
17
|
+
workflow_dispatch: {}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
call:
|
|
21
|
+
uses: KirillBaranov/kb-labs-devkit/.github/workflows/docker-build-reusable.yml@main
|
|
22
|
+
with:
|
|
23
|
+
image-name: kb-labs-my-service # TODO: change to your service name
|
|
24
|
+
dockerfile: Dockerfile
|
|
25
|
+
context: .
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: reusable-deploy
|
|
2
|
+
|
|
3
|
+
# Reusable workflow: deploy to VPS via SSH + docker compose
|
|
4
|
+
#
|
|
5
|
+
# Usage in orchestrator repo (e.g. kb-labs root):
|
|
6
|
+
# jobs:
|
|
7
|
+
# call:
|
|
8
|
+
# uses: KirillBaranov/kb-labs-devkit/.github/workflows/deploy-reusable.yml@main
|
|
9
|
+
# with:
|
|
10
|
+
# image-tag: release-1.0.0
|
|
11
|
+
# compose-file: docker-compose.production.yml
|
|
12
|
+
# secrets: inherit
|
|
13
|
+
#
|
|
14
|
+
# Required secrets in calling repo:
|
|
15
|
+
# VPS_HOST, VPS_USER, VPS_SSH_KEY
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
workflow_call:
|
|
19
|
+
inputs:
|
|
20
|
+
image-tag:
|
|
21
|
+
description: Docker image tag to deploy (e.g. release-1.0.0)
|
|
22
|
+
required: true
|
|
23
|
+
type: string
|
|
24
|
+
compose-file:
|
|
25
|
+
description: Path to docker-compose file on VPS
|
|
26
|
+
required: false
|
|
27
|
+
default: docker-compose.production.yml
|
|
28
|
+
type: string
|
|
29
|
+
deploy-dir:
|
|
30
|
+
description: Working directory on VPS
|
|
31
|
+
required: false
|
|
32
|
+
default: /opt/kb-labs
|
|
33
|
+
type: string
|
|
34
|
+
registry:
|
|
35
|
+
description: Container registry host
|
|
36
|
+
required: false
|
|
37
|
+
default: ghcr.io
|
|
38
|
+
type: string
|
|
39
|
+
health-check-url:
|
|
40
|
+
description: URL to check after deploy (e.g. http://localhost:5050/api/v1/health)
|
|
41
|
+
required: false
|
|
42
|
+
default: ''
|
|
43
|
+
type: string
|
|
44
|
+
health-check-wait:
|
|
45
|
+
description: Seconds to wait before health check
|
|
46
|
+
required: false
|
|
47
|
+
default: '15'
|
|
48
|
+
type: string
|
|
49
|
+
secrets:
|
|
50
|
+
VPS_HOST:
|
|
51
|
+
required: true
|
|
52
|
+
VPS_USER:
|
|
53
|
+
required: true
|
|
54
|
+
VPS_SSH_KEY:
|
|
55
|
+
required: true
|
|
56
|
+
|
|
57
|
+
jobs:
|
|
58
|
+
deploy:
|
|
59
|
+
name: Deploy to VPS
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
environment: production
|
|
62
|
+
|
|
63
|
+
steps:
|
|
64
|
+
- name: Deploy via SSH
|
|
65
|
+
uses: appleboy/ssh-action@v1
|
|
66
|
+
env:
|
|
67
|
+
DEPLOY_TAG: ${{ inputs.image-tag }}
|
|
68
|
+
DEPLOY_REGISTRY: ${{ inputs.registry }}/${{ github.repository_owner }}
|
|
69
|
+
with:
|
|
70
|
+
host: ${{ secrets.VPS_HOST }}
|
|
71
|
+
username: ${{ secrets.VPS_USER }}
|
|
72
|
+
key: ${{ secrets.VPS_SSH_KEY }}
|
|
73
|
+
envs: DEPLOY_TAG,DEPLOY_REGISTRY
|
|
74
|
+
script: |
|
|
75
|
+
set -euo pipefail
|
|
76
|
+
cd ${{ inputs.deploy-dir }}
|
|
77
|
+
|
|
78
|
+
echo "→ Deploying tag: $DEPLOY_TAG"
|
|
79
|
+
echo "→ Registry: $DEPLOY_REGISTRY"
|
|
80
|
+
|
|
81
|
+
# Save current tag for rollback
|
|
82
|
+
[ -f .current-tag ] && cp .current-tag .previous-tag
|
|
83
|
+
echo "$DEPLOY_TAG" > .current-tag
|
|
84
|
+
|
|
85
|
+
# Pull new images
|
|
86
|
+
TAG="$DEPLOY_TAG" REGISTRY="$DEPLOY_REGISTRY" \
|
|
87
|
+
docker compose -f ${{ inputs.compose-file }} pull
|
|
88
|
+
|
|
89
|
+
# Rolling update
|
|
90
|
+
TAG="$DEPLOY_TAG" REGISTRY="$DEPLOY_REGISTRY" \
|
|
91
|
+
docker compose -f ${{ inputs.compose-file }} up -d --remove-orphans
|
|
92
|
+
|
|
93
|
+
echo "→ Containers started, waiting ${{ inputs.health-check-wait }}s..."
|
|
94
|
+
sleep ${{ inputs.health-check-wait }}
|
|
95
|
+
|
|
96
|
+
# Show status
|
|
97
|
+
docker compose -f ${{ inputs.compose-file }} ps
|
|
98
|
+
|
|
99
|
+
# Health check (if URL provided)
|
|
100
|
+
if [ -n "${{ inputs.health-check-url }}" ]; then
|
|
101
|
+
echo "→ Health check: ${{ inputs.health-check-url }}"
|
|
102
|
+
wget -qO- "${{ inputs.health-check-url }}" \
|
|
103
|
+
&& echo "✓ Health check passed" \
|
|
104
|
+
|| { echo "✗ Health check failed!"; exit 1; }
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Cleanup old images
|
|
108
|
+
docker image prune -f > /dev/null 2>&1 || true
|
|
109
|
+
|
|
110
|
+
echo "✓ Deploy complete: $DEPLOY_TAG"
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: reusable-docker-build
|
|
2
|
+
|
|
3
|
+
# Reusable workflow: build Docker image and push to ghcr.io
|
|
4
|
+
#
|
|
5
|
+
# Usage in consumer repo:
|
|
6
|
+
# jobs:
|
|
7
|
+
# call:
|
|
8
|
+
# uses: KirillBaranov/kb-labs-devkit/.github/workflows/docker-build-reusable.yml@main
|
|
9
|
+
# with:
|
|
10
|
+
# image-name: kb-labs-rest-api
|
|
11
|
+
# dockerfile: Dockerfile
|
|
12
|
+
# secrets: inherit
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
workflow_call:
|
|
16
|
+
inputs:
|
|
17
|
+
image-name:
|
|
18
|
+
description: Docker image name (e.g. kb-labs-rest-api)
|
|
19
|
+
required: true
|
|
20
|
+
type: string
|
|
21
|
+
dockerfile:
|
|
22
|
+
description: Path to Dockerfile (relative to context)
|
|
23
|
+
required: false
|
|
24
|
+
default: Dockerfile
|
|
25
|
+
type: string
|
|
26
|
+
context:
|
|
27
|
+
description: Docker build context (default is repo root)
|
|
28
|
+
required: false
|
|
29
|
+
default: .
|
|
30
|
+
type: string
|
|
31
|
+
build-args:
|
|
32
|
+
description: Build args as multiline string (KEY=VALUE per line)
|
|
33
|
+
required: false
|
|
34
|
+
default: ''
|
|
35
|
+
type: string
|
|
36
|
+
platforms:
|
|
37
|
+
description: Target platforms (e.g. linux/amd64,linux/arm64)
|
|
38
|
+
required: false
|
|
39
|
+
default: linux/amd64
|
|
40
|
+
type: string
|
|
41
|
+
registry:
|
|
42
|
+
description: Container registry host
|
|
43
|
+
required: false
|
|
44
|
+
default: ghcr.io
|
|
45
|
+
type: string
|
|
46
|
+
outputs:
|
|
47
|
+
image-tag:
|
|
48
|
+
description: Full image tag that was pushed
|
|
49
|
+
value: ${{ jobs.build.outputs.image-tag }}
|
|
50
|
+
short-sha:
|
|
51
|
+
description: Short commit SHA used as tag
|
|
52
|
+
value: ${{ jobs.build.outputs.short-sha }}
|
|
53
|
+
|
|
54
|
+
jobs:
|
|
55
|
+
build:
|
|
56
|
+
name: Build & Push
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
permissions:
|
|
59
|
+
contents: read
|
|
60
|
+
packages: write
|
|
61
|
+
|
|
62
|
+
outputs:
|
|
63
|
+
image-tag: ${{ steps.meta.outputs.version }}
|
|
64
|
+
short-sha: ${{ steps.sha.outputs.short }}
|
|
65
|
+
|
|
66
|
+
steps:
|
|
67
|
+
- name: Checkout
|
|
68
|
+
uses: actions/checkout@v4
|
|
69
|
+
with:
|
|
70
|
+
submodules: recursive
|
|
71
|
+
|
|
72
|
+
- name: Get short SHA
|
|
73
|
+
id: sha
|
|
74
|
+
run: echo "short=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
|
|
75
|
+
|
|
76
|
+
- name: Log in to Container Registry
|
|
77
|
+
uses: docker/login-action@v3
|
|
78
|
+
with:
|
|
79
|
+
registry: ${{ inputs.registry }}
|
|
80
|
+
username: ${{ github.actor }}
|
|
81
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
82
|
+
|
|
83
|
+
- name: Set up Docker Buildx
|
|
84
|
+
uses: docker/setup-buildx-action@v3
|
|
85
|
+
|
|
86
|
+
- name: Docker metadata
|
|
87
|
+
id: meta
|
|
88
|
+
uses: docker/metadata-action@v5
|
|
89
|
+
with:
|
|
90
|
+
images: ${{ inputs.registry }}/${{ github.repository_owner }}/${{ inputs.image-name }}
|
|
91
|
+
tags: |
|
|
92
|
+
# rc branch → rc-<sha>
|
|
93
|
+
type=raw,value=rc-${{ steps.sha.outputs.short }},enable=${{ github.ref == 'refs/heads/rc' }}
|
|
94
|
+
# release tag → release-1.0.0
|
|
95
|
+
type=raw,value=${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/release-') }}
|
|
96
|
+
# always tag latest on release
|
|
97
|
+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/release-') }}
|
|
98
|
+
|
|
99
|
+
- name: Build and push
|
|
100
|
+
uses: docker/build-push-action@v6
|
|
101
|
+
with:
|
|
102
|
+
context: ${{ inputs.context }}
|
|
103
|
+
file: ${{ inputs.dockerfile }}
|
|
104
|
+
platforms: ${{ inputs.platforms }}
|
|
105
|
+
push: true
|
|
106
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
107
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
108
|
+
build-args: ${{ inputs.build-args }}
|
|
109
|
+
cache-from: type=gha,scope=${{ inputs.image-name }}
|
|
110
|
+
cache-to: type=gha,mode=max,scope=${{ inputs.image-name }}
|
package/README.md
CHANGED
|
@@ -990,6 +990,143 @@ To generate `tsup.external.json` manually (if needed):
|
|
|
990
990
|
npx kb-devkit-tsup-external --generate
|
|
991
991
|
```
|
|
992
992
|
|
|
993
|
+
### QA History Tracker
|
|
994
|
+
|
|
995
|
+
Track QA metrics over time and detect regressions:
|
|
996
|
+
|
|
997
|
+
```bash
|
|
998
|
+
npx kb-devkit-qa-history save # Save current QA results with git context
|
|
999
|
+
npx kb-devkit-qa-history show # Show last 20 runs
|
|
1000
|
+
npx kb-devkit-qa-history trends # Show quality trends over time
|
|
1001
|
+
npx kb-devkit-qa-history regressions # Detect new failures since last save
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
**Root commands:**
|
|
1005
|
+
```bash
|
|
1006
|
+
pnpm qa:save # Save current QA state
|
|
1007
|
+
pnpm qa:history # Show history
|
|
1008
|
+
pnpm qa:trends # Show trends
|
|
1009
|
+
pnpm qa:regressions # Detect regressions (exits 1 on regression)
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
### Core Gate
|
|
1013
|
+
|
|
1014
|
+
Check if the 6 core platform monorepos meet zero-failure quality requirements. Reads from the last `pnpm qa` run — no recompilation:
|
|
1015
|
+
|
|
1016
|
+
```bash
|
|
1017
|
+
npx kb-devkit-core-gate # Gate check (exits 1 if core is broken)
|
|
1018
|
+
npx kb-devkit-core-gate --verbose # Show failing packages
|
|
1019
|
+
npx kb-devkit-core-gate --json # JSON output
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
**Core monorepos checked:** `kb-labs-cli`, `kb-labs-core`, `kb-labs-shared`, `kb-labs-sdk`, `kb-labs-rest-api`, `kb-labs-plugin`
|
|
1023
|
+
|
|
1024
|
+
**Requirements:** build → zero failures, types → zero errors, lint → zero errors
|
|
1025
|
+
|
|
1026
|
+
**Typical flow:**
|
|
1027
|
+
```bash
|
|
1028
|
+
pnpm qa # Run checks
|
|
1029
|
+
pnpm core:gate # Inspect core result
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
### Architecture Audit
|
|
1033
|
+
|
|
1034
|
+
Analyze monorepo architecture and detect structural issues:
|
|
1035
|
+
|
|
1036
|
+
```bash
|
|
1037
|
+
npx kb-devkit-architecture # Full audit (JSON + HTML graph + markdown report)
|
|
1038
|
+
npx kb-devkit-architecture --json # AI-readable JSON output
|
|
1039
|
+
npx kb-devkit-architecture --md # Markdown report only
|
|
1040
|
+
npx kb-devkit-architecture --trends # Compare with previous runs
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
**Detects 10 anomaly types** (scored by severity):
|
|
1044
|
+
- Circular dependencies (100), Layer violations (90), God packages (80)
|
|
1045
|
+
- Unstable core (75), Bidirectional dependencies (70)
|
|
1046
|
+
- Large packages >10K LOC (60), Orphan packages (60)
|
|
1047
|
+
- Many dependencies >10 (50), Deep chains >7 (50), Missing docs (40)
|
|
1048
|
+
|
|
1049
|
+
### Freshness Tracker
|
|
1050
|
+
|
|
1051
|
+
Detect stale packages — when package A uses an old build of dependency B:
|
|
1052
|
+
|
|
1053
|
+
```bash
|
|
1054
|
+
npx kb-devkit-freshness # Default table output
|
|
1055
|
+
npx kb-devkit-freshness --json # JSON for AI agents
|
|
1056
|
+
npx kb-devkit-freshness --only-stale # Show only stale packages
|
|
1057
|
+
npx kb-devkit-freshness --suggest-rebuild # Show rebuild order
|
|
1058
|
+
npx kb-devkit-freshness --package=cli-core # Single package analysis
|
|
1059
|
+
npx kb-devkit-freshness --age-days=30 # Packages not built in 30+ days
|
|
1060
|
+
npx kb-devkit-freshness --high-impact=5 # Packages affecting 5+ others
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
### Config Checker
|
|
1064
|
+
|
|
1065
|
+
Check all packages for configuration drift from standard DevKit templates:
|
|
1066
|
+
|
|
1067
|
+
```bash
|
|
1068
|
+
npx kb-devkit-check-configs # Check all packages
|
|
1069
|
+
npx kb-devkit-check-configs --fix # Auto-fix with backup
|
|
1070
|
+
npx kb-devkit-check-configs --package=cli-core # Check specific package
|
|
1071
|
+
npx kb-devkit-check-configs --ci # CI mode (fail on drift)
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
**What it validates:**
|
|
1075
|
+
- Missing or modified config files vs standard templates
|
|
1076
|
+
- `tsup.config.ts` structure (nodePreset usage, `dts: true`, etc.)
|
|
1077
|
+
- Duplicate external/ignores declarations
|
|
1078
|
+
|
|
1079
|
+
### Scripts Checker
|
|
1080
|
+
|
|
1081
|
+
Validate that all packages have required scripts and devDependencies:
|
|
1082
|
+
|
|
1083
|
+
```bash
|
|
1084
|
+
npx kb-devkit-check-scripts # Check all packages
|
|
1085
|
+
npx kb-devkit-check-scripts --fix # Auto-add missing scripts
|
|
1086
|
+
npx kb-devkit-check-scripts --package=cli-core # Check specific package
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
**Required scripts validated:** `clean`, `build`, `dev`, `lint`, `lint:fix`, `type-check`, `test`, `test:watch`
|
|
1090
|
+
|
|
1091
|
+
### Deprecated Code Checker
|
|
1092
|
+
|
|
1093
|
+
Find all `@deprecated` markers in the codebase with context:
|
|
1094
|
+
|
|
1095
|
+
```bash
|
|
1096
|
+
npx kb-devkit-check-deprecated # Check all packages
|
|
1097
|
+
npx kb-devkit-check-deprecated --package cli-core # Check specific package
|
|
1098
|
+
npx kb-devkit-check-deprecated --json # JSON output
|
|
1099
|
+
npx kb-devkit-check-deprecated --stats # Statistics only
|
|
1100
|
+
npx kb-devkit-check-deprecated --verbose # Full context
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
**Finds:** JSDoc `@deprecated` tags, TypeScript `@deprecated` patterns, inline `// @deprecated` comments.
|
|
1104
|
+
|
|
1105
|
+
### Build Readiness Checker
|
|
1106
|
+
|
|
1107
|
+
Analyze whether packages can be successfully bundled (useful before creating standalone executables):
|
|
1108
|
+
|
|
1109
|
+
```bash
|
|
1110
|
+
npx kb-devkit-check-build-readiness
|
|
1111
|
+
npx kb-devkit-check-build-readiness --package @kb-labs/cli-bin
|
|
1112
|
+
npx kb-devkit-check-build-readiness --fix
|
|
1113
|
+
```
|
|
1114
|
+
|
|
1115
|
+
**Checks:** missing packages in imports, broken import paths, dependency chains that would fail bundling.
|
|
1116
|
+
|
|
1117
|
+
### Config Migrator
|
|
1118
|
+
|
|
1119
|
+
Mass migration to standardize all package configurations to current DevKit templates:
|
|
1120
|
+
|
|
1121
|
+
```bash
|
|
1122
|
+
npx kb-devkit-migrate-configs # Dry run (preview only)
|
|
1123
|
+
npx kb-devkit-migrate-configs --apply # Apply changes
|
|
1124
|
+
npx kb-devkit-migrate-configs --package=cli-core # Migrate specific package
|
|
1125
|
+
npx kb-devkit-migrate-configs --force # Skip confirmation prompts
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
Creates backups before applying changes and generates a migration report.
|
|
1129
|
+
|
|
993
1130
|
## ✨ Features
|
|
994
1131
|
|
|
995
1132
|
- **TypeScript**: Ready-to-use `tsconfig` for libraries, Node services, and CLIs
|
|
@@ -1493,48 +1630,63 @@ jobs:
|
|
|
1493
1630
|
|
|
1494
1631
|
## 📦 Complete Tools Summary
|
|
1495
1632
|
|
|
1496
|
-
DevKit provides **
|
|
1497
|
-
|
|
1498
|
-
### Analysis Tools (
|
|
1499
|
-
1. **Import Checker** -
|
|
1500
|
-
2. **Export Checker** -
|
|
1501
|
-
3. **Duplicate Checker** -
|
|
1502
|
-
4. **Structure Checker** -
|
|
1503
|
-
5. **Naming Validator** -
|
|
1504
|
-
6. **Path Validator** -
|
|
1505
|
-
7. **TypeScript Types Audit** - Deep type safety
|
|
1506
|
-
8. **Visualizer** -
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1633
|
+
DevKit provides **29 tools** for monorepo management and quality assurance:
|
|
1634
|
+
|
|
1635
|
+
### Analysis Tools (12)
|
|
1636
|
+
1. **Import Checker** (`kb-devkit-check-imports`) - Broken imports, unused deps, circular deps
|
|
1637
|
+
2. **Export Checker** (`kb-devkit-check-exports`) - Unused exports and dead code
|
|
1638
|
+
3. **Duplicate Checker** (`kb-devkit-check-duplicates`) - Duplicate dependencies
|
|
1639
|
+
4. **Structure Checker** (`kb-devkit-check-structure`) - Package structure validation
|
|
1640
|
+
5. **Naming Validator** (`kb-devkit-validate-naming`) - Pyramid Rule naming convention
|
|
1641
|
+
6. **Path Validator** (`kb-devkit-check-paths`) - Workspace deps, exports, bin paths
|
|
1642
|
+
7. **TypeScript Types Audit** (`kb-devkit-types-audit`) - Deep type safety across monorepo
|
|
1643
|
+
8. **Visualizer** (`kb-devkit-visualize`) - Dependency graphs and stats
|
|
1644
|
+
9. **Architecture Audit** (`kb-devkit-architecture`) - Structural anomalies, layer violations
|
|
1645
|
+
10. **Deprecated Checker** (`kb-devkit-check-deprecated`) - Find `@deprecated` markers
|
|
1646
|
+
11. **Build Readiness** (`kb-devkit-check-build-readiness`) - Pre-bundle dependency analysis
|
|
1647
|
+
12. **Config Checker** (`kb-devkit-check-configs`) - Drift from standard templates
|
|
1648
|
+
|
|
1649
|
+
### Automation Tools (11)
|
|
1650
|
+
1. **QA Runner** (`kb-devkit-qa`) - ⚡ Incremental builds + lint + types + tests
|
|
1651
|
+
2. **QA History** (`kb-devkit-qa-history`) - Track metrics over time, detect regressions
|
|
1652
|
+
3. **Core Gate** (`kb-devkit-core-gate`) - Zero-failure gate for 6 core monorepos
|
|
1653
|
+
4. **Quick Statistics** (`kb-devkit-stats`) - Health scores and metrics
|
|
1654
|
+
5. **Dependency Auto-Fixer** (`kb-devkit-fix-deps`) - Auto-fix dependency issues
|
|
1655
|
+
6. **CI Combo Tool** (`kb-devkit-ci`) - All static checks in one command
|
|
1656
|
+
7. **Build Order Calculator** (`kb-devkit-build-order`) - Correct build order with layers
|
|
1657
|
+
8. **Types Order Calculator** (`kb-devkit-types-order`) - Types generation order
|
|
1658
|
+
9. **Command Health Checker** (`kb-devkit-check-commands`) - Verify all CLI commands work
|
|
1659
|
+
10. **TypeScript Types Checker** (`kb-devkit-check-types`) - Ensure packages generate types
|
|
1660
|
+
11. **Scripts Checker** (`kb-devkit-check-scripts`) - Validate required package scripts
|
|
1661
|
+
|
|
1662
|
+
### Infrastructure Tools (6)
|
|
1663
|
+
1. **Repository Sync** (`kb-devkit-sync`) - Sync DevKit assets across projects
|
|
1664
|
+
2. **Path Aliases Generator** (`kb-devkit-paths`) - Generate workspace path aliases
|
|
1665
|
+
3. **Tsup External Generator** (`kb-devkit-tsup-external`) - Generate external deps list
|
|
1666
|
+
4. **Freshness Tracker** (`kb-devkit-freshness`) - Detect stale packages in dep chains
|
|
1667
|
+
5. **Config Migrator** (`kb-devkit-migrate-configs`) - Mass migrate configs to current templates
|
|
1668
|
+
6. **Health Check** (`kb-devkit-health`) - Comprehensive health check with grade A–F
|
|
1522
1669
|
|
|
1523
1670
|
### Quick Access
|
|
1524
1671
|
```bash
|
|
1525
1672
|
# Quality Assurance (recommended)
|
|
1526
|
-
npx kb-devkit-qa
|
|
1527
|
-
npx kb-devkit-
|
|
1673
|
+
npx kb-devkit-qa # ⚡ Incremental builds (~20s)
|
|
1674
|
+
npx kb-devkit-qa-history regressions # Detect regressions
|
|
1675
|
+
npx kb-devkit-core-gate # Zero-failure gate for core
|
|
1676
|
+
npx kb-devkit-ci # All static checks
|
|
1528
1677
|
|
|
1529
1678
|
# Analysis
|
|
1530
|
-
npx kb-devkit-check-imports
|
|
1531
|
-
npx kb-devkit-check-exports
|
|
1532
|
-
npx kb-devkit-types-audit
|
|
1679
|
+
npx kb-devkit-check-imports # Imports
|
|
1680
|
+
npx kb-devkit-check-exports # Exports
|
|
1681
|
+
npx kb-devkit-types-audit # Type safety
|
|
1682
|
+
npx kb-devkit-architecture --md # Architecture report
|
|
1683
|
+
npx kb-devkit-freshness --only-stale # Stale packages
|
|
1533
1684
|
|
|
1534
1685
|
# Automation
|
|
1535
|
-
npx kb-devkit-fix-deps --dry-run
|
|
1536
|
-
npx kb-devkit-build-order --layers
|
|
1537
|
-
npx kb-devkit-stats --health
|
|
1686
|
+
npx kb-devkit-fix-deps --dry-run # Fix dependencies
|
|
1687
|
+
npx kb-devkit-build-order --layers # Build order
|
|
1688
|
+
npx kb-devkit-stats --health # Health score
|
|
1689
|
+
npx kb-devkit-check-configs # Config drift
|
|
1538
1690
|
```
|
|
1539
1691
|
|
|
1540
1692
|
## License
|
|
@@ -42,6 +42,9 @@ import fs from 'node:fs';
|
|
|
42
42
|
import path from 'node:path';
|
|
43
43
|
import { fileURLToPath } from 'node:url';
|
|
44
44
|
|
|
45
|
+
// Shared package discovery — supports both flat and categorized layouts
|
|
46
|
+
import { findPackages } from './lib/find-packages.mjs';
|
|
47
|
+
|
|
45
48
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
46
49
|
|
|
47
50
|
// ANSI colors
|
|
@@ -80,38 +83,13 @@ const options = {
|
|
|
80
83
|
// ============================
|
|
81
84
|
|
|
82
85
|
/**
|
|
83
|
-
*
|
|
86
|
+
* Extract repo name from a package.json path.
|
|
87
|
+
* Handles both flat (kb-labs-core/packages/...) and categorized (platform/kb-labs-core/packages/...) layouts.
|
|
84
88
|
*/
|
|
85
|
-
function
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
for (const entry of entries) {
|
|
90
|
-
if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
|
|
91
|
-
|
|
92
|
-
const repoPath = path.join(rootDir, entry.name);
|
|
93
|
-
const packagesDir = path.join(repoPath, 'packages');
|
|
94
|
-
|
|
95
|
-
if (!fs.existsSync(packagesDir)) {continue;}
|
|
96
|
-
|
|
97
|
-
const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
|
|
98
|
-
|
|
99
|
-
for (const pkgDir of packageDirs) {
|
|
100
|
-
if (!pkgDir.isDirectory()) {continue;}
|
|
101
|
-
|
|
102
|
-
const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
|
|
103
|
-
|
|
104
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
105
|
-
packages.push({
|
|
106
|
-
path: packageJsonPath,
|
|
107
|
-
dir: path.join(packagesDir, pkgDir.name),
|
|
108
|
-
repository: entry.name,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return packages;
|
|
89
|
+
function extractRepoFromPath(pkgPath) {
|
|
90
|
+
const parts = pkgPath.split(path.sep);
|
|
91
|
+
const repo = parts.find((p) => p.startsWith('kb-labs-'));
|
|
92
|
+
return repo || 'unknown';
|
|
115
93
|
}
|
|
116
94
|
|
|
117
95
|
/**
|
|
@@ -1074,7 +1052,11 @@ async function main() {
|
|
|
1074
1052
|
}
|
|
1075
1053
|
|
|
1076
1054
|
// Phase 1: Data Collection
|
|
1077
|
-
const packages = findPackages(rootDir)
|
|
1055
|
+
const packages = findPackages(rootDir).map((pkgPath) => ({
|
|
1056
|
+
path: pkgPath,
|
|
1057
|
+
dir: path.dirname(pkgPath),
|
|
1058
|
+
repository: extractRepoFromPath(pkgPath),
|
|
1059
|
+
}));
|
|
1078
1060
|
|
|
1079
1061
|
if (packages.length === 0) {
|
|
1080
1062
|
log('⚠️ No KB Labs packages found', 'yellow');
|
|
@@ -49,36 +49,8 @@ const options = {
|
|
|
49
49
|
package: args.find((arg) => arg.startsWith('--package='))?.split('=')[1],
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
*/
|
|
55
|
-
function findPackages(rootDir) {
|
|
56
|
-
const packages = [];
|
|
57
|
-
const entries = fs.readdirSync(rootDir, { withFileTypes: true });
|
|
58
|
-
|
|
59
|
-
for (const entry of entries) {
|
|
60
|
-
if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
|
|
61
|
-
|
|
62
|
-
const repoPath = path.join(rootDir, entry.name);
|
|
63
|
-
const packagesDir = path.join(repoPath, 'packages');
|
|
64
|
-
|
|
65
|
-
if (!fs.existsSync(packagesDir)) {continue;}
|
|
66
|
-
|
|
67
|
-
const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
|
|
68
|
-
|
|
69
|
-
for (const pkgDir of packageDirs) {
|
|
70
|
-
if (!pkgDir.isDirectory()) {continue;}
|
|
71
|
-
|
|
72
|
-
const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
|
|
73
|
-
|
|
74
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
75
|
-
packages.push(packageJsonPath);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return packages;
|
|
81
|
-
}
|
|
52
|
+
// Shared package discovery — supports both flat and categorized layouts
|
|
53
|
+
import { findPackages } from './lib/find-packages.mjs';
|
|
82
54
|
|
|
83
55
|
/**
|
|
84
56
|
* Build dependency graph
|
|
@@ -22,6 +22,9 @@ import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
|
22
22
|
import { join, dirname } from 'path';
|
|
23
23
|
import { fileURLToPath } from 'url';
|
|
24
24
|
|
|
25
|
+
// Shared package discovery — supports both flat and categorized layouts
|
|
26
|
+
import { findPackages } from './lib/find-packages.mjs';
|
|
27
|
+
|
|
25
28
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
26
29
|
const rootDir = join(__dirname, '../..');
|
|
27
30
|
|
|
@@ -34,31 +37,18 @@ console.log('🔍 KB Labs Build Readiness Checker\n');
|
|
|
34
37
|
|
|
35
38
|
// Step 1: Find all workspace packages
|
|
36
39
|
function findWorkspacePackages() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
50
|
-
packages.push({
|
|
51
|
-
name: pkgJson.name,
|
|
52
|
-
path: join(packagesDir, pkg),
|
|
53
|
-
pkgJson,
|
|
54
|
-
});
|
|
55
|
-
} catch (e) {
|
|
56
|
-
// Skip invalid package.json
|
|
57
|
-
}
|
|
40
|
+
return findPackages(rootDir).map((pkgJsonPath) => {
|
|
41
|
+
try {
|
|
42
|
+
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
43
|
+
return {
|
|
44
|
+
name: pkgJson.name,
|
|
45
|
+
path: dirname(pkgJsonPath),
|
|
46
|
+
pkgJson,
|
|
47
|
+
};
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return null;
|
|
58
50
|
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return packages;
|
|
51
|
+
}).filter(Boolean);
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
// Step 2: Get import checker results
|