@ankh-studio/ai-enablement 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/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/analyzers/tech-stack-analyzer.d.ts +63 -0
- package/dist/analyzers/tech-stack-analyzer.d.ts.map +1 -0
- package/dist/analyzers/tech-stack-analyzer.js +401 -0
- package/dist/analyzers/tech-stack-analyzer.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +347 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/collectors/evidence-collector.d.ts +57 -0
- package/dist/collectors/evidence-collector.d.ts.map +1 -0
- package/dist/collectors/evidence-collector.js +386 -0
- package/dist/collectors/evidence-collector.js.map +1 -0
- package/dist/core/assessment-engine.d.ts +76 -0
- package/dist/core/assessment-engine.d.ts.map +1 -0
- package/dist/core/assessment-engine.js +310 -0
- package/dist/core/assessment-engine.js.map +1 -0
- package/dist/generators/adr-generator.d.ts +35 -0
- package/dist/generators/adr-generator.d.ts.map +1 -0
- package/dist/generators/adr-generator.js +339 -0
- package/dist/generators/adr-generator.js.map +1 -0
- package/dist/generators-backup-phase-2/adr-generator.d.ts +31 -0
- package/dist/generators-backup-phase-2/adr-generator.d.ts.map +1 -0
- package/dist/generators-backup-phase-2/adr-generator.js +309 -0
- package/dist/generators-backup-phase-2/adr-generator.js.map +1 -0
- package/dist/llm/coalescer.d.ts +45 -0
- package/dist/llm/coalescer.d.ts.map +1 -0
- package/dist/llm/coalescer.js +258 -0
- package/dist/llm/coalescer.js.map +1 -0
- package/dist/llm/copilot-client.d.ts +53 -0
- package/dist/llm/copilot-client.d.ts.map +1 -0
- package/dist/llm/copilot-client.js +198 -0
- package/dist/llm/copilot-client.js.map +1 -0
- package/dist/llm/prompt-templates.d.ts +24 -0
- package/dist/llm/prompt-templates.d.ts.map +1 -0
- package/dist/llm/prompt-templates.js +255 -0
- package/dist/llm/prompt-templates.js.map +1 -0
- package/dist/llm/response-processor.d.ts +50 -0
- package/dist/llm/response-processor.d.ts.map +1 -0
- package/dist/llm/response-processor.js +321 -0
- package/dist/llm/response-processor.js.map +1 -0
- package/dist/llm/structured-types.d.ts +184 -0
- package/dist/llm/structured-types.d.ts.map +1 -0
- package/dist/llm/structured-types.js +61 -0
- package/dist/llm/structured-types.js.map +1 -0
- package/dist/llm/validation.d.ts +57 -0
- package/dist/llm/validation.d.ts.map +1 -0
- package/dist/llm/validation.js +273 -0
- package/dist/llm/validation.js.map +1 -0
- package/dist/llm-backup-phase-1/coalescer.d.ts +40 -0
- package/dist/llm-backup-phase-1/coalescer.d.ts.map +1 -0
- package/dist/llm-backup-phase-1/coalescer.js +209 -0
- package/dist/llm-backup-phase-1/coalescer.js.map +1 -0
- package/dist/llm-backup-phase-1/copilot-client.d.ts +53 -0
- package/dist/llm-backup-phase-1/copilot-client.d.ts.map +1 -0
- package/dist/llm-backup-phase-1/copilot-client.js +198 -0
- package/dist/llm-backup-phase-1/copilot-client.js.map +1 -0
- package/dist/llm-backup-phase-1/prompt-templates.d.ts +23 -0
- package/dist/llm-backup-phase-1/prompt-templates.d.ts.map +1 -0
- package/dist/llm-backup-phase-1/prompt-templates.js +197 -0
- package/dist/llm-backup-phase-1/prompt-templates.js.map +1 -0
- package/dist/llm-backup-phase-1/response-processor.d.ts +44 -0
- package/dist/llm-backup-phase-1/response-processor.d.ts.map +1 -0
- package/dist/llm-backup-phase-1/response-processor.js +200 -0
- package/dist/llm-backup-phase-1/response-processor.js.map +1 -0
- package/dist/llm-backup-phase-1/validation.d.ts +57 -0
- package/dist/llm-backup-phase-1/validation.d.ts.map +1 -0
- package/dist/llm-backup-phase-1/validation.js +273 -0
- package/dist/llm-backup-phase-1/validation.js.map +1 -0
- package/dist/personas/base-persona.d.ts +28 -0
- package/dist/personas/base-persona.d.ts.map +1 -0
- package/dist/personas/base-persona.js +140 -0
- package/dist/personas/base-persona.js.map +1 -0
- package/dist/personas/consultant-persona.d.ts +25 -0
- package/dist/personas/consultant-persona.d.ts.map +1 -0
- package/dist/personas/consultant-persona.js +288 -0
- package/dist/personas/consultant-persona.js.map +1 -0
- package/dist/personas/persona-factory.d.ts +17 -0
- package/dist/personas/persona-factory.d.ts.map +1 -0
- package/dist/personas/persona-factory.js +53 -0
- package/dist/personas/persona-factory.js.map +1 -0
- package/dist/personas/research-backed-consultant.d.ts +12 -0
- package/dist/personas/research-backed-consultant.d.ts.map +1 -0
- package/dist/personas/research-backed-consultant.js +100 -0
- package/dist/personas/research-backed-consultant.js.map +1 -0
- package/dist/personas-backup-phase-1/base-persona.d.ts +28 -0
- package/dist/personas-backup-phase-1/base-persona.d.ts.map +1 -0
- package/dist/personas-backup-phase-1/base-persona.js +140 -0
- package/dist/personas-backup-phase-1/base-persona.js.map +1 -0
- package/dist/personas-backup-phase-1/consultant-persona.d.ts +24 -0
- package/dist/personas-backup-phase-1/consultant-persona.d.ts.map +1 -0
- package/dist/personas-backup-phase-1/consultant-persona.js +197 -0
- package/dist/personas-backup-phase-1/consultant-persona.js.map +1 -0
- package/dist/personas-backup-phase-1/persona-factory.d.ts +17 -0
- package/dist/personas-backup-phase-1/persona-factory.d.ts.map +1 -0
- package/dist/personas-backup-phase-1/persona-factory.js +53 -0
- package/dist/personas-backup-phase-1/persona-factory.js.map +1 -0
- package/dist/scanners/copilot-feature-scanner.d.ts +55 -0
- package/dist/scanners/copilot-feature-scanner.d.ts.map +1 -0
- package/dist/scanners/copilot-feature-scanner.js +259 -0
- package/dist/scanners/copilot-feature-scanner.js.map +1 -0
- package/dist/scorers/readiness-scorer.d.ts +42 -0
- package/dist/scorers/readiness-scorer.d.ts.map +1 -0
- package/dist/scorers/readiness-scorer.js +279 -0
- package/dist/scorers/readiness-scorer.js.map +1 -0
- package/dist/types/persona.d.ts +69 -0
- package/dist/types/persona.d.ts.map +1 -0
- package/dist/types/persona.js +9 -0
- package/dist/types/persona.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot Feature Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans repository for GitHub Copilot integration features:
|
|
5
|
+
* - Copilot instructions (.github/copilot-instructions.md)
|
|
6
|
+
* - CODEOWNERS file
|
|
7
|
+
* - Copilot-compatible documentation
|
|
8
|
+
* - AI-friendly code patterns
|
|
9
|
+
*/
|
|
10
|
+
export interface CopilotFeatureAnalysis {
|
|
11
|
+
githubFeatures: {
|
|
12
|
+
copilotInstructions: {
|
|
13
|
+
found: boolean;
|
|
14
|
+
path?: string;
|
|
15
|
+
content?: string;
|
|
16
|
+
quality: "excellent" | "good" | "basic" | "missing";
|
|
17
|
+
};
|
|
18
|
+
codeowners: {
|
|
19
|
+
found: boolean;
|
|
20
|
+
path?: string;
|
|
21
|
+
content?: string;
|
|
22
|
+
coverage: "comprehensive" | "partial" | "minimal" | "missing";
|
|
23
|
+
};
|
|
24
|
+
issueTemplates: {
|
|
25
|
+
found: boolean;
|
|
26
|
+
count: number;
|
|
27
|
+
aiFriendly: boolean;
|
|
28
|
+
};
|
|
29
|
+
prTemplates: {
|
|
30
|
+
found: boolean;
|
|
31
|
+
aiFriendly: boolean;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
codePatterns: {
|
|
35
|
+
aiFriendlyComments: number;
|
|
36
|
+
documentationCoverage: number;
|
|
37
|
+
typeScriptUsage: boolean;
|
|
38
|
+
testCoverage: boolean;
|
|
39
|
+
};
|
|
40
|
+
recommendations: string[];
|
|
41
|
+
}
|
|
42
|
+
export declare class CopilotFeatureScanner {
|
|
43
|
+
private git;
|
|
44
|
+
scan(repoPath: string): Promise<CopilotFeatureAnalysis>;
|
|
45
|
+
private scanCopilotInstructions;
|
|
46
|
+
private scanCodeowners;
|
|
47
|
+
private scanTemplates;
|
|
48
|
+
private scanTemplateDirectory;
|
|
49
|
+
private scanCodePatterns;
|
|
50
|
+
private evaluateInstructionQuality;
|
|
51
|
+
private evaluateCodeownersCoverage;
|
|
52
|
+
private isAiFriendlyTemplate;
|
|
53
|
+
private generateRecommendations;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=copilot-feature-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-feature-scanner.d.ts","sourceRoot":"","sources":["../../src/scanners/copilot-feature-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE;QACd,mBAAmB,EAAE;YACnB,KAAK,EAAE,OAAO,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;SACrD,CAAC;QACF,UAAU,EAAE;YACV,KAAK,EAAE,OAAO,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;SAC/D,CAAC;QACF,cAAc,EAAE;YACd,KAAK,EAAE,OAAO,CAAC;YACf,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;QACF,WAAW,EAAE;YACX,KAAK,EAAE,OAAO,CAAC;YACf,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;KACH,CAAC;IACF,YAAY,EAAE;QACZ,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,eAAe,EAAE,OAAO,CAAC;QACzB,YAAY,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,GAAG,CAAe;IAEpB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;YAuC/C,uBAAuB;YA6BvB,cAAc;YA6Bd,aAAa;YAwCb,qBAAqB;YAOrB,gBAAgB;IAiD9B,OAAO,CAAC,0BAA0B;IAqBlC,OAAO,CAAC,0BAA0B;IAiBlC,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,uBAAuB;CAmDhC"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copilot Feature Scanner
|
|
4
|
+
*
|
|
5
|
+
* Scans repository for GitHub Copilot integration features:
|
|
6
|
+
* - Copilot instructions (.github/copilot-instructions.md)
|
|
7
|
+
* - CODEOWNERS file
|
|
8
|
+
* - Copilot-compatible documentation
|
|
9
|
+
* - AI-friendly code patterns
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CopilotFeatureScanner = void 0;
|
|
13
|
+
const promises_1 = require("fs/promises");
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
const simple_git_1 = require("simple-git");
|
|
16
|
+
class CopilotFeatureScanner {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.git = (0, simple_git_1.simpleGit)();
|
|
19
|
+
}
|
|
20
|
+
async scan(repoPath) {
|
|
21
|
+
const analysis = {
|
|
22
|
+
githubFeatures: {
|
|
23
|
+
copilotInstructions: { found: false, quality: "missing" },
|
|
24
|
+
codeowners: { found: false, coverage: "missing" },
|
|
25
|
+
issueTemplates: { found: false, count: 0, aiFriendly: false },
|
|
26
|
+
prTemplates: { found: false, aiFriendly: false },
|
|
27
|
+
},
|
|
28
|
+
codePatterns: {
|
|
29
|
+
aiFriendlyComments: 0,
|
|
30
|
+
documentationCoverage: 0,
|
|
31
|
+
typeScriptUsage: false,
|
|
32
|
+
testCoverage: false,
|
|
33
|
+
},
|
|
34
|
+
recommendations: [],
|
|
35
|
+
};
|
|
36
|
+
try {
|
|
37
|
+
await this.git.cwd(repoPath);
|
|
38
|
+
// Scan GitHub features
|
|
39
|
+
await this.scanCopilotInstructions(repoPath, analysis);
|
|
40
|
+
await this.scanCodeowners(repoPath, analysis);
|
|
41
|
+
await this.scanTemplates(repoPath, analysis);
|
|
42
|
+
// Scan code patterns
|
|
43
|
+
await this.scanCodePatterns(repoPath, analysis);
|
|
44
|
+
// Generate recommendations
|
|
45
|
+
this.generateRecommendations(analysis);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.warn(`Warning: Could not complete Copilot feature scan: ${error}`);
|
|
49
|
+
}
|
|
50
|
+
return analysis;
|
|
51
|
+
}
|
|
52
|
+
async scanCopilotInstructions(repoPath, analysis) {
|
|
53
|
+
const instructionPaths = [
|
|
54
|
+
".github/copilot-instructions.md",
|
|
55
|
+
".github/copilot-instructions.txt",
|
|
56
|
+
".github/COPYLOIT_INSTRUCTIONS.md",
|
|
57
|
+
];
|
|
58
|
+
for (const path of instructionPaths) {
|
|
59
|
+
const fullPath = (0, path_1.join)(repoPath, path);
|
|
60
|
+
try {
|
|
61
|
+
await (0, promises_1.access)(fullPath, promises_1.constants.R_OK);
|
|
62
|
+
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
|
|
63
|
+
analysis.githubFeatures.copilotInstructions = {
|
|
64
|
+
found: true,
|
|
65
|
+
path,
|
|
66
|
+
content,
|
|
67
|
+
quality: this.evaluateInstructionQuality(content),
|
|
68
|
+
};
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// File doesn't exist, try next path
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async scanCodeowners(repoPath, analysis) {
|
|
77
|
+
const codeownersPaths = [
|
|
78
|
+
".github/CODEOWNERS",
|
|
79
|
+
"CODEOWNERS",
|
|
80
|
+
"docs/CODEOWNERS",
|
|
81
|
+
];
|
|
82
|
+
for (const path of codeownersPaths) {
|
|
83
|
+
const fullPath = (0, path_1.join)(repoPath, path);
|
|
84
|
+
try {
|
|
85
|
+
await (0, promises_1.access)(fullPath, promises_1.constants.R_OK);
|
|
86
|
+
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
|
|
87
|
+
analysis.githubFeatures.codeowners = {
|
|
88
|
+
found: true,
|
|
89
|
+
path,
|
|
90
|
+
content,
|
|
91
|
+
coverage: this.evaluateCodeownersCoverage(content),
|
|
92
|
+
};
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// File doesn't exist, try next path
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async scanTemplates(repoPath, analysis) {
|
|
101
|
+
try {
|
|
102
|
+
// Scan issue templates
|
|
103
|
+
const issueTemplates = await this.scanTemplateDirectory();
|
|
104
|
+
analysis.githubFeatures.issueTemplates = {
|
|
105
|
+
found: issueTemplates.length > 0,
|
|
106
|
+
count: issueTemplates.length,
|
|
107
|
+
aiFriendly: issueTemplates.some((template) => this.isAiFriendlyTemplate(template)),
|
|
108
|
+
};
|
|
109
|
+
// Scan PR templates
|
|
110
|
+
const prTemplatePaths = [
|
|
111
|
+
".github/pull_request_template.md",
|
|
112
|
+
".github/PULL_REQUEST_TEMPLATE.md",
|
|
113
|
+
];
|
|
114
|
+
for (const path of prTemplatePaths) {
|
|
115
|
+
const fullPath = (0, path_1.join)(repoPath, path);
|
|
116
|
+
try {
|
|
117
|
+
await (0, promises_1.access)(fullPath, promises_1.constants.R_OK);
|
|
118
|
+
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
|
|
119
|
+
analysis.githubFeatures.prTemplates = {
|
|
120
|
+
found: true,
|
|
121
|
+
aiFriendly: this.isAiFriendlyTemplate(content),
|
|
122
|
+
};
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// File doesn't exist
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.warn(`Warning: Could not scan templates: ${error}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async scanTemplateDirectory() {
|
|
135
|
+
const templates = [];
|
|
136
|
+
// This would require fs.readdir, but for now return empty
|
|
137
|
+
// Implementation would scan directory and read template files
|
|
138
|
+
return templates;
|
|
139
|
+
}
|
|
140
|
+
async scanCodePatterns(repoPath, analysis) {
|
|
141
|
+
try {
|
|
142
|
+
// Check for TypeScript usage
|
|
143
|
+
const tsconfigPath = (0, path_1.join)(repoPath, "tsconfig.json");
|
|
144
|
+
try {
|
|
145
|
+
await (0, promises_1.access)(tsconfigPath, promises_1.constants.R_OK);
|
|
146
|
+
analysis.codePatterns.typeScriptUsage = true;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
analysis.codePatterns.typeScriptUsage = false;
|
|
150
|
+
}
|
|
151
|
+
// Check for test setup
|
|
152
|
+
const testIndicators = [
|
|
153
|
+
"jest.config.js",
|
|
154
|
+
"jest.config.json",
|
|
155
|
+
"vitest.config.ts",
|
|
156
|
+
"test/",
|
|
157
|
+
"tests/",
|
|
158
|
+
"__tests__/",
|
|
159
|
+
];
|
|
160
|
+
for (const indicator of testIndicators) {
|
|
161
|
+
const indicatorPath = (0, path_1.join)(repoPath, indicator);
|
|
162
|
+
try {
|
|
163
|
+
await (0, promises_1.access)(indicatorPath, indicator.endsWith("/") ? promises_1.constants.F_OK : promises_1.constants.R_OK);
|
|
164
|
+
analysis.codePatterns.testCoverage = true;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Continue checking
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// In a full implementation, we would scan source files for:
|
|
172
|
+
// - AI-friendly comments
|
|
173
|
+
// - Documentation coverage
|
|
174
|
+
// For now, set reasonable defaults
|
|
175
|
+
analysis.codePatterns.aiFriendlyComments = 5;
|
|
176
|
+
analysis.codePatterns.documentationCoverage = 60;
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.warn(`Warning: Could not scan code patterns: ${error}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
evaluateInstructionQuality(content) {
|
|
183
|
+
if (!content || content.trim().length === 0)
|
|
184
|
+
return "missing";
|
|
185
|
+
const lines = content.split("\n").length;
|
|
186
|
+
const hasSections = content.includes("#") || content.includes("##");
|
|
187
|
+
const hasExamples = content.includes("example") || content.includes("Example");
|
|
188
|
+
const hasSpecificGuidelines = content.includes("should") ||
|
|
189
|
+
content.includes("must") ||
|
|
190
|
+
content.includes("avoid");
|
|
191
|
+
if (lines > 20 && hasSections && hasExamples && hasSpecificGuidelines)
|
|
192
|
+
return "excellent";
|
|
193
|
+
if (lines > 10 && hasSections && hasSpecificGuidelines)
|
|
194
|
+
return "good";
|
|
195
|
+
if (lines > 3)
|
|
196
|
+
return "basic";
|
|
197
|
+
return "missing";
|
|
198
|
+
}
|
|
199
|
+
evaluateCodeownersCoverage(content) {
|
|
200
|
+
if (!content || content.trim().length === 0)
|
|
201
|
+
return "missing";
|
|
202
|
+
const lines = content
|
|
203
|
+
.split("\n")
|
|
204
|
+
.filter((line) => !line.startsWith("#") && line.trim().length > 0).length;
|
|
205
|
+
const hasWildcards = content.includes("*");
|
|
206
|
+
const hasSpecificFiles = content.includes("/") && !content.includes("*/");
|
|
207
|
+
if (lines > 5 && hasSpecificFiles)
|
|
208
|
+
return "comprehensive";
|
|
209
|
+
if (lines > 2 && (hasWildcards || hasSpecificFiles))
|
|
210
|
+
return "partial";
|
|
211
|
+
if (lines > 0)
|
|
212
|
+
return "minimal";
|
|
213
|
+
return "missing";
|
|
214
|
+
}
|
|
215
|
+
isAiFriendlyTemplate(content) {
|
|
216
|
+
const aiFriendlyKeywords = [
|
|
217
|
+
"steps to reproduce",
|
|
218
|
+
"expected behavior",
|
|
219
|
+
"actual behavior",
|
|
220
|
+
"environment",
|
|
221
|
+
"context",
|
|
222
|
+
"acceptance criteria",
|
|
223
|
+
"testing",
|
|
224
|
+
"reproduction",
|
|
225
|
+
];
|
|
226
|
+
const lowerContent = content.toLowerCase();
|
|
227
|
+
return aiFriendlyKeywords.some((keyword) => lowerContent.includes(keyword));
|
|
228
|
+
}
|
|
229
|
+
generateRecommendations(analysis) {
|
|
230
|
+
const recommendations = [];
|
|
231
|
+
if (!analysis.githubFeatures.copilotInstructions.found) {
|
|
232
|
+
recommendations.push("Add .github/copilot-instructions.md to guide AI assistance");
|
|
233
|
+
}
|
|
234
|
+
else if (analysis.githubFeatures.copilotInstructions.quality === "basic") {
|
|
235
|
+
recommendations.push("Enhance copilot-instructions.md with more detailed guidance and examples");
|
|
236
|
+
}
|
|
237
|
+
if (!analysis.githubFeatures.codeowners.found) {
|
|
238
|
+
recommendations.push("Add CODEOWNERS file to define code ownership and improve review processes");
|
|
239
|
+
}
|
|
240
|
+
else if (analysis.githubFeatures.codeowners.coverage === "minimal") {
|
|
241
|
+
recommendations.push("Expand CODEOWNERS coverage for better security and governance");
|
|
242
|
+
}
|
|
243
|
+
if (!analysis.githubFeatures.issueTemplates.found) {
|
|
244
|
+
recommendations.push("Create issue templates with AI-friendly structure for better bug reports");
|
|
245
|
+
}
|
|
246
|
+
if (!analysis.githubFeatures.prTemplates.found) {
|
|
247
|
+
recommendations.push("Add PR template to guide contributors and improve AI assistance");
|
|
248
|
+
}
|
|
249
|
+
if (!analysis.codePatterns.typeScriptUsage) {
|
|
250
|
+
recommendations.push("Consider adopting TypeScript for better AI code understanding");
|
|
251
|
+
}
|
|
252
|
+
if (!analysis.codePatterns.testCoverage) {
|
|
253
|
+
recommendations.push("Add testing framework to improve code quality and AI assistance");
|
|
254
|
+
}
|
|
255
|
+
analysis.recommendations = recommendations;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
exports.CopilotFeatureScanner = CopilotFeatureScanner;
|
|
259
|
+
//# sourceMappingURL=copilot-feature-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-feature-scanner.js","sourceRoot":"","sources":["../../src/scanners/copilot-feature-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readiness Scorer
|
|
3
|
+
*
|
|
4
|
+
* Calculates deterministic readiness scores for repository, team, and organization
|
|
5
|
+
* based on collected evidence and analysis data
|
|
6
|
+
*/
|
|
7
|
+
import { TechStackAnalysis } from "../analyzers/tech-stack-analyzer";
|
|
8
|
+
import { EvidenceData } from "../collectors/evidence-collector";
|
|
9
|
+
import { CopilotFeatureAnalysis } from "../scanners/copilot-feature-scanner";
|
|
10
|
+
export interface ReadinessScores {
|
|
11
|
+
repoReadiness: number;
|
|
12
|
+
teamReadiness: number;
|
|
13
|
+
orgReadiness: number;
|
|
14
|
+
overallMaturity: number;
|
|
15
|
+
confidence: "high" | "medium" | "low";
|
|
16
|
+
breakdown: {
|
|
17
|
+
foundation: number;
|
|
18
|
+
security: number;
|
|
19
|
+
workflow: number;
|
|
20
|
+
ai: number;
|
|
21
|
+
governance: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface ScoringContext {
|
|
25
|
+
copilotFeatures: CopilotFeatureAnalysis;
|
|
26
|
+
techStack: TechStackAnalysis;
|
|
27
|
+
evidence: EvidenceData;
|
|
28
|
+
}
|
|
29
|
+
export declare class ReadinessScorer {
|
|
30
|
+
calculate(context: ScoringContext): Promise<ReadinessScores>;
|
|
31
|
+
private calculateFoundationScore;
|
|
32
|
+
private calculateSecurityScore;
|
|
33
|
+
private calculateWorkflowScore;
|
|
34
|
+
private calculateAIScore;
|
|
35
|
+
private calculateGovernanceScore;
|
|
36
|
+
private calculateRepoReadiness;
|
|
37
|
+
private calculateTeamReadiness;
|
|
38
|
+
private calculateOrgReadiness;
|
|
39
|
+
private calculateOverallMaturity;
|
|
40
|
+
private calculateConfidence;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=readiness-scorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness-scorer.d.ts","sourceRoot":"","sources":["../../src/scorers/readiness-scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,sBAAsB,CAAC;IACxC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,qBAAa,eAAe;IACpB,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA+ClE,OAAO,CAAC,wBAAwB;IAgChC,OAAO,CAAC,sBAAsB;IA+B9B,OAAO,CAAC,sBAAsB;IAyB9B,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,sBAAsB;IAqB9B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,wBAAwB;IAkBhC,OAAO,CAAC,mBAAmB;CAuB5B"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Readiness Scorer
|
|
4
|
+
*
|
|
5
|
+
* Calculates deterministic readiness scores for repository, team, and organization
|
|
6
|
+
* based on collected evidence and analysis data
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ReadinessScorer = void 0;
|
|
10
|
+
class ReadinessScorer {
|
|
11
|
+
async calculate(context) {
|
|
12
|
+
const { copilotFeatures, techStack, evidence } = context;
|
|
13
|
+
// Calculate component scores
|
|
14
|
+
const foundation = this.calculateFoundationScore(evidence, techStack);
|
|
15
|
+
const security = this.calculateSecurityScore(copilotFeatures, evidence);
|
|
16
|
+
const workflow = this.calculateWorkflowScore(copilotFeatures, evidence);
|
|
17
|
+
const ai = this.calculateAIScore(copilotFeatures, techStack);
|
|
18
|
+
const governance = this.calculateGovernanceScore(evidence, copilotFeatures);
|
|
19
|
+
// Calculate overall readiness scores
|
|
20
|
+
const repoReadiness = this.calculateRepoReadiness(foundation, security, workflow, ai, governance);
|
|
21
|
+
const teamReadiness = this.calculateTeamReadiness(workflow, ai, governance);
|
|
22
|
+
const orgReadiness = this.calculateOrgReadiness(governance, security);
|
|
23
|
+
// Calculate overall maturity (1-8 scale)
|
|
24
|
+
const overallMaturity = this.calculateOverallMaturity(repoReadiness, teamReadiness, orgReadiness);
|
|
25
|
+
// Determine confidence level
|
|
26
|
+
const confidence = this.calculateConfidence(evidence);
|
|
27
|
+
return {
|
|
28
|
+
repoReadiness,
|
|
29
|
+
teamReadiness,
|
|
30
|
+
orgReadiness,
|
|
31
|
+
overallMaturity,
|
|
32
|
+
confidence,
|
|
33
|
+
breakdown: {
|
|
34
|
+
foundation,
|
|
35
|
+
security,
|
|
36
|
+
workflow,
|
|
37
|
+
ai,
|
|
38
|
+
governance,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
calculateFoundationScore(evidence, techStack) {
|
|
43
|
+
let score = 0;
|
|
44
|
+
const maxScore = 100;
|
|
45
|
+
// Basic documentation (20 points)
|
|
46
|
+
if (evidence.structure.hasReadme)
|
|
47
|
+
score += 10;
|
|
48
|
+
if (evidence.structure.hasLicense)
|
|
49
|
+
score += 5;
|
|
50
|
+
if (evidence.structure.hasContributing)
|
|
51
|
+
score += 5;
|
|
52
|
+
// Configuration files (25 points)
|
|
53
|
+
if (evidence.configuration.hasGitignore)
|
|
54
|
+
score += 5;
|
|
55
|
+
if (evidence.configuration.hasEditorconfig)
|
|
56
|
+
score += 5;
|
|
57
|
+
if (evidence.configuration.hasPrettier)
|
|
58
|
+
score += 5;
|
|
59
|
+
if (evidence.configuration.hasEslint)
|
|
60
|
+
score += 5;
|
|
61
|
+
if (evidence.configuration.hasTypeScript)
|
|
62
|
+
score += 5;
|
|
63
|
+
// Development setup (25 points)
|
|
64
|
+
if (evidence.configuration.hasTests)
|
|
65
|
+
score += 10;
|
|
66
|
+
if (evidence.configuration.hasCi)
|
|
67
|
+
score += 10;
|
|
68
|
+
if (techStack.infrastructure.packageManager !== "unknown")
|
|
69
|
+
score += 5;
|
|
70
|
+
// Code quality (30 points)
|
|
71
|
+
if (techStack.aiReadiness.modernFramework)
|
|
72
|
+
score += 10;
|
|
73
|
+
if (techStack.aiReadiness.typescriptUsage)
|
|
74
|
+
score += 10;
|
|
75
|
+
if (evidence.patterns.codeComplexity !== "high")
|
|
76
|
+
score += 10;
|
|
77
|
+
return Math.min(score, maxScore);
|
|
78
|
+
}
|
|
79
|
+
calculateSecurityScore(copilotFeatures, evidence) {
|
|
80
|
+
let score = 0;
|
|
81
|
+
const maxScore = 100;
|
|
82
|
+
// Code ownership (30 points)
|
|
83
|
+
if (copilotFeatures.githubFeatures.codeowners.found) {
|
|
84
|
+
const coverage = copilotFeatures.githubFeatures.codeowners.coverage;
|
|
85
|
+
if (coverage === "comprehensive")
|
|
86
|
+
score += 30;
|
|
87
|
+
else if (coverage === "partial")
|
|
88
|
+
score += 20;
|
|
89
|
+
else if (coverage === "minimal")
|
|
90
|
+
score += 10;
|
|
91
|
+
}
|
|
92
|
+
// Branch protection (25 points) - would need git API
|
|
93
|
+
if (copilotFeatures.githubFeatures.codeowners.found)
|
|
94
|
+
score += 15; // Proxy for security awareness
|
|
95
|
+
if (evidence.configuration.hasCi)
|
|
96
|
+
score += 10;
|
|
97
|
+
// Dependency security (25 points)
|
|
98
|
+
if (evidence.metrics.dependencyHealth === "excellent")
|
|
99
|
+
score += 25;
|
|
100
|
+
else if (evidence.metrics.dependencyHealth === "good")
|
|
101
|
+
score += 20;
|
|
102
|
+
else if (evidence.metrics.dependencyHealth === "fair")
|
|
103
|
+
score += 10;
|
|
104
|
+
// Security patterns (20 points)
|
|
105
|
+
if (evidence.structure.hasLicense)
|
|
106
|
+
score += 10;
|
|
107
|
+
if (evidence.configuration.hasEslint)
|
|
108
|
+
score += 10;
|
|
109
|
+
return Math.min(score, maxScore);
|
|
110
|
+
}
|
|
111
|
+
calculateWorkflowScore(copilotFeatures, evidence) {
|
|
112
|
+
let score = 0;
|
|
113
|
+
const maxScore = 100;
|
|
114
|
+
// Templates and automation (30 points)
|
|
115
|
+
if (copilotFeatures.githubFeatures.prTemplates.found)
|
|
116
|
+
score += 15;
|
|
117
|
+
if (copilotFeatures.githubFeatures.issueTemplates.found)
|
|
118
|
+
score += 15;
|
|
119
|
+
// CI/CD setup (25 points)
|
|
120
|
+
if (evidence.configuration.hasCi)
|
|
121
|
+
score += 25;
|
|
122
|
+
// Testing infrastructure (25 points)
|
|
123
|
+
if (evidence.configuration.hasTests)
|
|
124
|
+
score += 15;
|
|
125
|
+
if (evidence.configuration.hasTests)
|
|
126
|
+
score += 10; // Use evidence instead of techStack
|
|
127
|
+
// Documentation and collaboration (20 points)
|
|
128
|
+
if (evidence.structure.hasContributing)
|
|
129
|
+
score += 10;
|
|
130
|
+
if (evidence.patterns.documentationCoverage > 20)
|
|
131
|
+
score += 10;
|
|
132
|
+
return Math.min(score, maxScore);
|
|
133
|
+
}
|
|
134
|
+
calculateAIScore(copilotFeatures, techStack) {
|
|
135
|
+
let score = 0;
|
|
136
|
+
const maxScore = 100;
|
|
137
|
+
// Copilot integration (35 points)
|
|
138
|
+
if (copilotFeatures.githubFeatures.copilotInstructions.found) {
|
|
139
|
+
const quality = copilotFeatures.githubFeatures.copilotInstructions.quality;
|
|
140
|
+
if (quality === "excellent")
|
|
141
|
+
score += 35;
|
|
142
|
+
else if (quality === "good")
|
|
143
|
+
score += 25;
|
|
144
|
+
else if (quality === "basic")
|
|
145
|
+
score += 15;
|
|
146
|
+
}
|
|
147
|
+
// AI-friendly tech stack (30 points)
|
|
148
|
+
if (techStack.aiReadiness.typescriptUsage)
|
|
149
|
+
score += 15;
|
|
150
|
+
if (techStack.aiReadiness.modernFramework)
|
|
151
|
+
score += 10;
|
|
152
|
+
if (techStack.aiReadiness.testCoverage)
|
|
153
|
+
score += 5;
|
|
154
|
+
// AI dependencies (20 points)
|
|
155
|
+
const aiDeps = techStack.dependencies.aiRelated.length;
|
|
156
|
+
if (aiDeps > 0)
|
|
157
|
+
score += Math.min(aiDeps * 10, 20);
|
|
158
|
+
// Code patterns (15 points)
|
|
159
|
+
if (copilotFeatures.codePatterns.aiFriendlyComments > 5)
|
|
160
|
+
score += 10;
|
|
161
|
+
if (copilotFeatures.codePatterns.documentationCoverage > 50)
|
|
162
|
+
score += 5;
|
|
163
|
+
return Math.min(score, maxScore);
|
|
164
|
+
}
|
|
165
|
+
calculateGovernanceScore(evidence, copilotFeatures) {
|
|
166
|
+
let score = 0;
|
|
167
|
+
const maxScore = 100;
|
|
168
|
+
// Project governance (30 points)
|
|
169
|
+
if (evidence.structure.hasContributing)
|
|
170
|
+
score += 15;
|
|
171
|
+
if (evidence.structure.hasChangelog)
|
|
172
|
+
score += 10;
|
|
173
|
+
if (evidence.structure.hasLicense)
|
|
174
|
+
score += 5;
|
|
175
|
+
// Code review processes (25 points)
|
|
176
|
+
if (copilotFeatures.githubFeatures.codeowners.found)
|
|
177
|
+
score += 15;
|
|
178
|
+
if (copilotFeatures.githubFeatures.prTemplates.found)
|
|
179
|
+
score += 10;
|
|
180
|
+
// Issue tracking (25 points)
|
|
181
|
+
if (copilotFeatures.githubFeatures.issueTemplates.found)
|
|
182
|
+
score += 15;
|
|
183
|
+
if (copilotFeatures.githubFeatures.issueTemplates.aiFriendly)
|
|
184
|
+
score += 10;
|
|
185
|
+
// Documentation standards (20 points)
|
|
186
|
+
if (evidence.structure.hasDocs)
|
|
187
|
+
score += 10;
|
|
188
|
+
if (evidence.patterns.documentationCoverage > 30)
|
|
189
|
+
score += 10;
|
|
190
|
+
return Math.min(score, maxScore);
|
|
191
|
+
}
|
|
192
|
+
calculateRepoReadiness(foundation, security, workflow, ai, governance) {
|
|
193
|
+
// Weighted average: Foundation (30%), Security (25%), Workflow (20%), AI (15%), Governance (10%)
|
|
194
|
+
const weights = {
|
|
195
|
+
foundation: 0.3,
|
|
196
|
+
security: 0.25,
|
|
197
|
+
workflow: 0.2,
|
|
198
|
+
ai: 0.15,
|
|
199
|
+
governance: 0.1,
|
|
200
|
+
};
|
|
201
|
+
const weightedScore = foundation * weights.foundation +
|
|
202
|
+
security * weights.security +
|
|
203
|
+
workflow * weights.workflow +
|
|
204
|
+
ai * weights.ai +
|
|
205
|
+
governance * weights.governance;
|
|
206
|
+
return Math.round(weightedScore);
|
|
207
|
+
}
|
|
208
|
+
calculateTeamReadiness(workflow, ai, governance) {
|
|
209
|
+
// Team readiness focuses on workflow, AI adoption, and governance
|
|
210
|
+
// Weighted average: Workflow (40%), AI (35%), Governance (25%)
|
|
211
|
+
const weights = {
|
|
212
|
+
workflow: 0.4,
|
|
213
|
+
ai: 0.35,
|
|
214
|
+
governance: 0.25,
|
|
215
|
+
};
|
|
216
|
+
const weightedScore = workflow * weights.workflow +
|
|
217
|
+
ai * weights.ai +
|
|
218
|
+
governance * weights.governance;
|
|
219
|
+
return Math.round(weightedScore);
|
|
220
|
+
}
|
|
221
|
+
calculateOrgReadiness(governance, security) {
|
|
222
|
+
// Organization readiness focuses on governance and security
|
|
223
|
+
// Weighted average: Governance (60%), Security (40%)
|
|
224
|
+
const weights = {
|
|
225
|
+
governance: 0.6,
|
|
226
|
+
security: 0.4,
|
|
227
|
+
};
|
|
228
|
+
const weightedScore = governance * weights.governance + security * weights.security;
|
|
229
|
+
return Math.round(weightedScore);
|
|
230
|
+
}
|
|
231
|
+
calculateOverallMaturity(repoReadiness, teamReadiness, orgReadiness) {
|
|
232
|
+
// Convert 0-100 scores to 1-8 maturity scale
|
|
233
|
+
const averageReadiness = (repoReadiness + teamReadiness + orgReadiness) / 3;
|
|
234
|
+
if (averageReadiness >= 90)
|
|
235
|
+
return 8; // Advanced
|
|
236
|
+
if (averageReadiness >= 80)
|
|
237
|
+
return 7; // Advanced
|
|
238
|
+
if (averageReadiness >= 70)
|
|
239
|
+
return 6; // Developing
|
|
240
|
+
if (averageReadiness >= 60)
|
|
241
|
+
return 5; // Developing
|
|
242
|
+
if (averageReadiness >= 50)
|
|
243
|
+
return 4; // Basic
|
|
244
|
+
if (averageReadiness >= 40)
|
|
245
|
+
return 3; // Basic
|
|
246
|
+
if (averageReadiness >= 25)
|
|
247
|
+
return 2; // Initial
|
|
248
|
+
return 1; // Initial
|
|
249
|
+
}
|
|
250
|
+
calculateConfidence(evidence) {
|
|
251
|
+
let confidenceFactors = 0;
|
|
252
|
+
const totalFactors = 8;
|
|
253
|
+
// Check if we have sufficient data for confident scoring
|
|
254
|
+
if (evidence.structure.fileCount > 0)
|
|
255
|
+
confidenceFactors++;
|
|
256
|
+
if (evidence.structure.hasReadme)
|
|
257
|
+
confidenceFactors++;
|
|
258
|
+
if (evidence.configuration.hasGitignore)
|
|
259
|
+
confidenceFactors++;
|
|
260
|
+
if (evidence.configuration.hasTypeScript || evidence.configuration.hasTests)
|
|
261
|
+
confidenceFactors++;
|
|
262
|
+
if (evidence.patterns.documentationCoverage > 0)
|
|
263
|
+
confidenceFactors++;
|
|
264
|
+
if (evidence.metrics.linesOfCode > 0)
|
|
265
|
+
confidenceFactors++;
|
|
266
|
+
if (evidence.metrics.dependencyHealth !== "fair")
|
|
267
|
+
confidenceFactors++;
|
|
268
|
+
if (evidence.structure.directoryDepth > 0)
|
|
269
|
+
confidenceFactors++;
|
|
270
|
+
const confidenceRatio = confidenceFactors / totalFactors;
|
|
271
|
+
if (confidenceRatio >= 0.8)
|
|
272
|
+
return "high";
|
|
273
|
+
if (confidenceRatio >= 0.5)
|
|
274
|
+
return "medium";
|
|
275
|
+
return "low";
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
exports.ReadinessScorer = ReadinessScorer;
|
|
279
|
+
//# sourceMappingURL=readiness-scorer.js.map
|