@principal-ai/quality-lens-cli 0.1.1 → 0.1.3
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/README.md +33 -7
- package/dist/output/JsonFormatter.d.ts +6 -28
- package/dist/output/JsonFormatter.d.ts.map +1 -1
- package/dist/output/JsonFormatter.js +91 -0
- package/dist/output/JsonFormatter.js.map +1 -1
- package/dist/service/QualityLensService.d.ts.map +1 -1
- package/dist/service/QualityLensService.js +6 -0
- package/dist/service/QualityLensService.js.map +1 -1
- package/package.json +14 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Quality Lens CLI
|
|
2
2
|
|
|
3
|
-
A standalone CLI tool for running quality lenses (ESLint, Jest, TypeScript, Knip, Git) on codebases in CI/CD pipelines.
|
|
3
|
+
A standalone CLI tool for running quality lenses (ESLint, Jest, TypeScript, Knip, Git, Alexandria) on codebases in CI/CD pipelines.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -20,7 +20,7 @@ quality-lens run
|
|
|
20
20
|
quality-lens run /path/to/repo
|
|
21
21
|
|
|
22
22
|
# Run specific lenses only
|
|
23
|
-
quality-lens run --lenses eslint,jest,typescript
|
|
23
|
+
quality-lens run --lenses eslint,jest,typescript,alexandria
|
|
24
24
|
|
|
25
25
|
# Output to JSON file
|
|
26
26
|
quality-lens run --output results.json --format json
|
|
@@ -42,7 +42,7 @@ quality-lens list /path/to/repo
|
|
|
42
42
|
## Options
|
|
43
43
|
|
|
44
44
|
- `--output, -o`: Output file path for results (JSON format)
|
|
45
|
-
- `--lenses`: Comma-separated list of lenses to run (eslint,jest,typescript,knip,git)
|
|
45
|
+
- `--lenses`: Comma-separated list of lenses to run (eslint,jest,typescript,knip,git,alexandria)
|
|
46
46
|
- `--format`: Output format - `json` or `console` (default: console)
|
|
47
47
|
|
|
48
48
|
## GitHub Actions Integration
|
|
@@ -89,14 +89,14 @@ jobs:
|
|
|
89
89
|
node bin/quality-lens.js run . \
|
|
90
90
|
--output results.json \
|
|
91
91
|
--format json \
|
|
92
|
-
--lenses eslint,typescript
|
|
92
|
+
--lenses eslint,typescript,knip,test,alexandria
|
|
93
93
|
continue-on-error: true
|
|
94
94
|
|
|
95
95
|
- name: Upload results artifact
|
|
96
96
|
if: always()
|
|
97
97
|
uses: actions/upload-artifact@v4
|
|
98
98
|
with:
|
|
99
|
-
name: quality-lens-results
|
|
99
|
+
name: quality-lens-results-${{ github.sha }}
|
|
100
100
|
path: results.json
|
|
101
101
|
if-no-files-found: warn
|
|
102
102
|
|
|
@@ -156,6 +156,17 @@ The workflow will:
|
|
|
156
156
|
- Automatically comment on PRs with analysis summary
|
|
157
157
|
- Continue workflow execution even if quality checks fail
|
|
158
158
|
|
|
159
|
+
## Retrieving Artifacts from GitHub Actions
|
|
160
|
+
|
|
161
|
+
For detailed instructions on retrieving quality analysis artifacts from GitHub Actions and integrating them with your UI (e.g., Quality Hexagon visualization), see the [Artifact Retrieval Guide](./ARTIFACT_RETRIEVAL_GUIDE.md).
|
|
162
|
+
|
|
163
|
+
The guide covers:
|
|
164
|
+
- Authentication setup (fine-grained tokens, classic tokens, GitHub Apps)
|
|
165
|
+
- Retrieval methods (GitHub CLI, REST API, Octokit)
|
|
166
|
+
- Integration examples for Electron apps
|
|
167
|
+
- Quality Hexagon visualization integration
|
|
168
|
+
- Best practices for caching and error handling
|
|
169
|
+
|
|
159
170
|
## Output Format
|
|
160
171
|
|
|
161
172
|
### JSON Output
|
|
@@ -166,7 +177,12 @@ The workflow will:
|
|
|
166
177
|
"timestamp": "2025-10-16T20:00:00.000Z",
|
|
167
178
|
"version": "1.0.0",
|
|
168
179
|
"totalPackages": 2,
|
|
169
|
-
"totalLenses": 6
|
|
180
|
+
"totalLenses": 6,
|
|
181
|
+
"git": {
|
|
182
|
+
"commit": "1741fd5abc123def456789",
|
|
183
|
+
"branch": "main",
|
|
184
|
+
"repository": "owner/repo"
|
|
185
|
+
}
|
|
170
186
|
},
|
|
171
187
|
"results": [
|
|
172
188
|
{
|
|
@@ -188,7 +204,17 @@ The workflow will:
|
|
|
188
204
|
"metrics": {},
|
|
189
205
|
"qualityContext": {}
|
|
190
206
|
}
|
|
191
|
-
]
|
|
207
|
+
],
|
|
208
|
+
"qualityMetrics": {
|
|
209
|
+
"hexagon": {
|
|
210
|
+
"tests": 100,
|
|
211
|
+
"deadCode": 98.5,
|
|
212
|
+
"formatting": 95,
|
|
213
|
+
"linting": 85,
|
|
214
|
+
"types": 100,
|
|
215
|
+
"documentation": 70
|
|
216
|
+
}
|
|
217
|
+
}
|
|
192
218
|
}
|
|
193
219
|
```
|
|
194
220
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { QualityHexagonMetrics, FormattedResults, GitMetadata } from '@principal-ai/codebase-quality-lenses';
|
|
1
2
|
import type { ToolExecutionResponse } from '../service/QualityLensService';
|
|
3
|
+
export type { QualityHexagonMetrics, FormattedResults, GitMetadata };
|
|
2
4
|
export interface LensExecutionResult {
|
|
3
5
|
package: string;
|
|
4
6
|
packagePath?: string;
|
|
@@ -8,35 +10,11 @@ export interface LensExecutionResult {
|
|
|
8
10
|
error?: string;
|
|
9
11
|
timestamp: number;
|
|
10
12
|
}
|
|
11
|
-
export interface FormattedResults {
|
|
12
|
-
metadata: {
|
|
13
|
-
timestamp: string;
|
|
14
|
-
version: string;
|
|
15
|
-
totalPackages: number;
|
|
16
|
-
totalLenses: number;
|
|
17
|
-
};
|
|
18
|
-
results: Array<{
|
|
19
|
-
package: {
|
|
20
|
-
name: string;
|
|
21
|
-
path?: string;
|
|
22
|
-
};
|
|
23
|
-
lens: {
|
|
24
|
-
id: string;
|
|
25
|
-
command: string;
|
|
26
|
-
};
|
|
27
|
-
execution: {
|
|
28
|
-
success: boolean;
|
|
29
|
-
exitCode?: number;
|
|
30
|
-
duration?: number;
|
|
31
|
-
timestamp: number;
|
|
32
|
-
};
|
|
33
|
-
issues: any[];
|
|
34
|
-
metrics: Record<string, any>;
|
|
35
|
-
qualityContext: Record<string, any>;
|
|
36
|
-
error?: string;
|
|
37
|
-
}>;
|
|
38
|
-
}
|
|
39
13
|
export declare class JsonFormatter {
|
|
14
|
+
private mapLensToHexagonDimension;
|
|
15
|
+
private extractQualityScore;
|
|
16
|
+
private calculateHexagonMetrics;
|
|
17
|
+
private getGitMetadata;
|
|
40
18
|
format(results: LensExecutionResult[]): string;
|
|
41
19
|
}
|
|
42
20
|
//# sourceMappingURL=JsonFormatter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonFormatter.d.ts","sourceRoot":"","sources":["../../src/output/JsonFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"JsonFormatter.d.ts","sourceRoot":"","sources":["../../src/output/JsonFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACZ,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAG3E,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAKrE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,aAAa;IAIxB,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,mBAAmB;IAiD3B,OAAO,CAAC,uBAAuB;IA4B/B,OAAO,CAAC,cAAc;IA8BtB,MAAM,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,MAAM;CA0C/C"}
|
|
@@ -2,13 +2,99 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.JsonFormatter = void 0;
|
|
4
4
|
class JsonFormatter {
|
|
5
|
+
mapLensToHexagonDimension(lensId) {
|
|
6
|
+
const mapping = {
|
|
7
|
+
jest: 'tests',
|
|
8
|
+
test: 'tests',
|
|
9
|
+
knip: 'deadCode',
|
|
10
|
+
deadcode: 'deadCode',
|
|
11
|
+
prettier: 'formatting',
|
|
12
|
+
format: 'formatting',
|
|
13
|
+
eslint: 'linting',
|
|
14
|
+
lint: 'linting',
|
|
15
|
+
typescript: 'types',
|
|
16
|
+
typecheck: 'types',
|
|
17
|
+
tsc: 'types',
|
|
18
|
+
alexandria: 'documentation',
|
|
19
|
+
};
|
|
20
|
+
return mapping[lensId.toLowerCase()] || null;
|
|
21
|
+
}
|
|
22
|
+
extractQualityScore(result) {
|
|
23
|
+
if (result.result?.lensResult?.qualityScore !== undefined &&
|
|
24
|
+
result.result.lensResult.qualityScore !== null) {
|
|
25
|
+
return result.result.lensResult.qualityScore;
|
|
26
|
+
}
|
|
27
|
+
const metrics = result.result?.lensResult?.metrics;
|
|
28
|
+
if (metrics) {
|
|
29
|
+
if (!result.result?.success) {
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
const totalIssues = metrics.totalIssues || 0;
|
|
33
|
+
const filesAnalyzed = metrics.filesAnalyzed || 1;
|
|
34
|
+
if (totalIssues === 0) {
|
|
35
|
+
return 100;
|
|
36
|
+
}
|
|
37
|
+
const issuesBySeverity = metrics.issuesBySeverity || {};
|
|
38
|
+
const errorWeight = (issuesBySeverity.error || 0) * 3;
|
|
39
|
+
const warningWeight = (issuesBySeverity.warning || 0) * 2;
|
|
40
|
+
const infoWeight = (issuesBySeverity.info || 0) * 1;
|
|
41
|
+
const hintWeight = (issuesBySeverity.hint || 0) * 0.5;
|
|
42
|
+
const weightedIssues = errorWeight + warningWeight + infoWeight + hintWeight;
|
|
43
|
+
const issuesPerFile = weightedIssues / filesAnalyzed;
|
|
44
|
+
const score = Math.max(0, 100 - issuesPerFile * 10);
|
|
45
|
+
return Math.round(score);
|
|
46
|
+
}
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
calculateHexagonMetrics(results) {
|
|
50
|
+
const hexagon = {
|
|
51
|
+
tests: 0,
|
|
52
|
+
deadCode: 0,
|
|
53
|
+
formatting: 0,
|
|
54
|
+
linting: 0,
|
|
55
|
+
types: 0,
|
|
56
|
+
documentation: 0,
|
|
57
|
+
};
|
|
58
|
+
for (const result of results) {
|
|
59
|
+
const dimension = this.mapLensToHexagonDimension(result.lens);
|
|
60
|
+
if (dimension) {
|
|
61
|
+
const score = this.extractQualityScore(result);
|
|
62
|
+
hexagon[dimension] = Math.max(hexagon[dimension], score);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return hexagon;
|
|
66
|
+
}
|
|
67
|
+
getGitMetadata() {
|
|
68
|
+
const metadata = {};
|
|
69
|
+
if (process.env['GITHUB_SHA']) {
|
|
70
|
+
metadata.commit = process.env['GITHUB_SHA'];
|
|
71
|
+
}
|
|
72
|
+
if (process.env['GITHUB_REF']) {
|
|
73
|
+
const ref = process.env['GITHUB_REF'];
|
|
74
|
+
if (ref.startsWith('refs/heads/')) {
|
|
75
|
+
metadata.branch = ref.replace('refs/heads/', '');
|
|
76
|
+
}
|
|
77
|
+
else if (ref.startsWith('refs/pull/')) {
|
|
78
|
+
metadata.branch = ref;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (process.env['GITHUB_REPOSITORY']) {
|
|
82
|
+
metadata.repository = process.env['GITHUB_REPOSITORY'];
|
|
83
|
+
}
|
|
84
|
+
if (Object.keys(metadata).length === 0) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
return metadata;
|
|
88
|
+
}
|
|
5
89
|
format(results) {
|
|
90
|
+
const gitMetadata = this.getGitMetadata();
|
|
6
91
|
const formatted = {
|
|
7
92
|
metadata: {
|
|
8
93
|
timestamp: new Date().toISOString(),
|
|
9
94
|
version: '1.0.0',
|
|
10
95
|
totalPackages: new Set(results.map((r) => r.package)).size,
|
|
11
96
|
totalLenses: results.length,
|
|
97
|
+
...(gitMetadata && { git: gitMetadata }),
|
|
12
98
|
},
|
|
13
99
|
results: results.map((r) => ({
|
|
14
100
|
package: {
|
|
@@ -31,6 +117,11 @@ class JsonFormatter {
|
|
|
31
117
|
error: r.error,
|
|
32
118
|
})),
|
|
33
119
|
};
|
|
120
|
+
if (results.length > 0) {
|
|
121
|
+
formatted.qualityMetrics = {
|
|
122
|
+
hexagon: this.calculateHexagonMetrics(results),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
34
125
|
return JSON.stringify(formatted, null, 2);
|
|
35
126
|
}
|
|
36
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonFormatter.js","sourceRoot":"","sources":["../../src/output/JsonFormatter.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"JsonFormatter.js","sourceRoot":"","sources":["../../src/output/JsonFormatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QualityLensService.d.ts","sourceRoot":"","sources":["../../src/service/QualityLensService.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"QualityLensService.d.ts","sourceRoot":"","sources":["../../src/service/QualityLensService.ts"],"names":[],"mappings":"AAKA,OAAO,EASL,KAAK,UAAU,EAChB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAMvF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAKD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,MAAM,CAAoB;;IAclC,OAAO,CAAC,gBAAgB;IAqCX,WAAW,CACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAgBnB,uBAAuB;YAgGvB,qBAAqB;IAwCnC,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,mBAAmB;IAuBpB,kBAAkB,IAAI,MAAM,EAAE;IAO9B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAGjD"}
|
|
@@ -24,8 +24,14 @@ class QualityLensService {
|
|
|
24
24
|
const knipLens = new codebase_quality_lenses_1.KnipLens(this.executor);
|
|
25
25
|
this.lenses.set('knip', knipLens);
|
|
26
26
|
this.lenses.set('deadcode', knipLens);
|
|
27
|
+
const prettierLens = new codebase_quality_lenses_1.PrettierLens(this.executor);
|
|
28
|
+
this.lenses.set('prettier', prettierLens);
|
|
29
|
+
this.lenses.set('format', prettierLens);
|
|
27
30
|
const gitLens = new codebase_quality_lenses_1.GitLens(this.executor);
|
|
28
31
|
this.lenses.set('git', gitLens);
|
|
32
|
+
const alexandriaLens = new codebase_quality_lenses_1.AlexandriaLens(this.executor);
|
|
33
|
+
this.lenses.set('alexandria', alexandriaLens);
|
|
34
|
+
this.lenses.set('docs', alexandriaLens);
|
|
29
35
|
}
|
|
30
36
|
async executeTool(request) {
|
|
31
37
|
const startTime = Date.now();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QualityLensService.js","sourceRoot":"","sources":["../../src/service/QualityLensService.ts"],"names":[],"mappings":";;;AAKA,
|
|
1
|
+
{"version":3,"file":"QualityLensService.js","sourceRoot":"","sources":["../../src/service/QualityLensService.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principal-ai/quality-lens-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "CLI tool for running quality lenses on codebases in CI/CD pipelines",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,9 +15,15 @@
|
|
|
15
15
|
"lint": "eslint . --ext .ts",
|
|
16
16
|
"lint:fix": "eslint . --ext .ts --fix",
|
|
17
17
|
"typecheck": "tsc --noEmit",
|
|
18
|
+
"knip": "knip",
|
|
18
19
|
"test": "jest",
|
|
19
|
-
"test:integration": "jest
|
|
20
|
-
"test:watch": "jest --watch"
|
|
20
|
+
"test:integration": "jest --config jest.config.integration.js",
|
|
21
|
+
"test:watch": "jest --watch",
|
|
22
|
+
"test:all": "npm run test && npm run test:integration",
|
|
23
|
+
"prettier": "prettier --check .",
|
|
24
|
+
"prettier:fix": "prettier --write .",
|
|
25
|
+
"docs": "alexandria lint",
|
|
26
|
+
"alexandria": "alexandria lint"
|
|
21
27
|
},
|
|
22
28
|
"keywords": [
|
|
23
29
|
"quality",
|
|
@@ -26,6 +32,7 @@
|
|
|
26
32
|
"typescript",
|
|
27
33
|
"eslint",
|
|
28
34
|
"jest",
|
|
35
|
+
"knip",
|
|
29
36
|
"ci",
|
|
30
37
|
"cd",
|
|
31
38
|
"github-actions"
|
|
@@ -33,8 +40,8 @@
|
|
|
33
40
|
"author": "Principal AI",
|
|
34
41
|
"license": "MIT",
|
|
35
42
|
"dependencies": {
|
|
36
|
-
"@principal-ai/codebase-composition": "^0.2.
|
|
37
|
-
"@principal-ai/codebase-quality-lenses": "^0.1.
|
|
43
|
+
"@principal-ai/codebase-composition": "^0.2.9",
|
|
44
|
+
"@principal-ai/codebase-quality-lenses": "^0.1.18",
|
|
38
45
|
"@principal-ai/repository-abstraction": "^0.2.0",
|
|
39
46
|
"chalk": "^5.3.0",
|
|
40
47
|
"tslib": "^2.8.1",
|
|
@@ -48,6 +55,8 @@
|
|
|
48
55
|
"@typescript-eslint/parser": "^6.0.0",
|
|
49
56
|
"eslint": "^8.0.0",
|
|
50
57
|
"jest": "^29.7.0",
|
|
58
|
+
"knip": "^5.66.2",
|
|
59
|
+
"prettier": "^3.6.2",
|
|
51
60
|
"ts-jest": "^29.4.5",
|
|
52
61
|
"typescript": "^5.0.0"
|
|
53
62
|
},
|