delivery-intel 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/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # Delivery Intel — Software Delivery Intelligence
2
+
3
+ A Next.js dashboard that analyzes any GitHub repository's delivery performance using **DORA metrics**, **dependency vulnerability scanning**, and **heuristic-based improvement suggestions**.
4
+
5
+ ## Features
6
+
7
+ - **DORA Metrics** — Deployment Frequency, Lead Time for Changes, Change Failure Rate, Mean Time to Restore
8
+ - **Smart Fallback Logic** — If a repo doesn't use GitHub Deployments, metrics are estimated from merged PRs
9
+ - **Vulnerability Scanning** — Parses `package.json`, `requirements.txt`, `go.mod` and queries the free [OSV.dev](https://osv.dev) API (no admin permissions needed)
10
+ - **Suggestion Engine** — Heuristic-based, actionable recommendations with severity ratings
11
+ - **Redis Caching** — Respects GitHub rate limits with a 5-minute cache layer (gracefully degrades if Redis is unavailable)
12
+ - **Overall Health Score** — Single 0–100 metric combining all dimensions
13
+
14
+ ## Architecture
15
+
16
+ ```
17
+ ┌──────────────┐ ┌─────────────────────────────┐
18
+ │ Next.js UI │────▶│ /api/analyze (Server-Side) │
19
+ │ (React + │ │ ┌───────────┐ ┌──────────┐ │
20
+ │ Recharts) │ │ │ GitHub │ │ OSV.dev │ │
21
+ └──────────────┘ │ │ REST + │ │ Vuln │ │
22
+ │ │ GraphQL │ │ Scanner │ │
23
+ │ └─────┬─────┘ └────┬─────┘ │
24
+ │ ▼ ▼ │
25
+ │ ┌─────────────────────────┐│
26
+ │ │ DORA Metrics Engine ││
27
+ │ │ + Suggestion Engine ││
28
+ │ └─────────────────────────┘│
29
+ │ ▼ │
30
+ │ ┌─────────────┐ │
31
+ │ │ Redis Cache │ │
32
+ │ └─────────────┘ │
33
+ └─────────────────────────────┘
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### 1. Install dependencies
39
+
40
+ ```bash
41
+ npm install
42
+ ```
43
+
44
+ ### 2. Configure environment
45
+
46
+ ```bash
47
+ cp .env.example .env.local
48
+ ```
49
+
50
+ Edit `.env.local` and add your GitHub Personal Access Token:
51
+
52
+ ```env
53
+ GITHUB_TOKEN=ghp_your_token_here
54
+ ```
55
+
56
+ **Token scopes needed:** `repo` (read), `actions` (read). Create one at [github.com/settings/tokens](https://github.com/settings/tokens).
57
+
58
+ ### 3. Start the dev server
59
+
60
+ ```bash
61
+ npm run dev
62
+ ```
63
+
64
+ Open [http://localhost:3000](http://localhost:3000) and enter any GitHub repository.
65
+
66
+ ### 4. (Optional) Redis caching
67
+
68
+ If you have Redis running locally, the app will auto-connect. Otherwise, it works fine without caching — just consumes more API credits.
69
+
70
+ ```bash
71
+ # macOS
72
+ brew install redis && redis-server
73
+ ```
74
+
75
+ ## Data Sources
76
+
77
+ | Metric | Source | Fallback |
78
+ |---|---|---|
79
+ | Deployment Frequency | GitHub Deployments API | Merged PR count to default branch |
80
+ | Lead Time for Changes | GraphQL: PR → Deployment link | PR created → PR merged |
81
+ | Change Failure Rate | GitHub Actions workflow runs | — |
82
+ | MTTR | Failed → next successful run | — |
83
+ | Vulnerabilities | OSV.dev (free, no auth needed) | — |
84
+
85
+ ## Tech Stack
86
+
87
+ - **Framework:** Next.js 15 (App Router)
88
+ - **Language:** TypeScript
89
+ - **API Clients:** `@octokit/rest`, `@octokit/graphql`
90
+ - **Cache:** Redis via `ioredis`
91
+ - **Charts:** Recharts
92
+ - **Styling:** Tailwind CSS 4
93
+
94
+ ## Project Structure
95
+
96
+ ```
97
+ src/
98
+ ├── app/
99
+ │ ├── api/
100
+ │ │ ├── analyze/route.ts # Main analysis endpoint
101
+ │ │ └── health/route.ts # Healthcheck
102
+ │ ├── globals.css
103
+ │ ├── layout.tsx
104
+ │ └── page.tsx # Dashboard UI
105
+ ├── components/
106
+ │ ├── CommitList.tsx
107
+ │ ├── DORACards.tsx
108
+ │ ├── FailureRateChart.tsx
109
+ │ ├── ScoreRing.tsx
110
+ │ ├── SuggestionsPanel.tsx
111
+ │ └── VulnerabilityTable.tsx
112
+ ├── lib/
113
+ │ ├── cache.ts # Redis caching layer
114
+ │ ├── github.ts # REST + GraphQL service
115
+ │ ├── metrics.ts # DORA metrics engine
116
+ │ ├── suggestions.ts # Heuristic suggestion engine
117
+ │ └── vulnerabilities.ts # OSV.dev scanner
118
+ └── types/
119
+ └── index.ts # All TypeScript types
120
+ ```
121
+
122
+ ## License
123
+
124
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require("../dist/cli/index.js");
@@ -0,0 +1,48 @@
1
+ export interface RepoIdentifier {
2
+ owner: string;
3
+ repo: string;
4
+ }
5
+ export interface DORAMetrics {
6
+ deploymentFrequency: {
7
+ deploymentsPerWeek: number;
8
+ rating: string;
9
+ source: "deployments_api" | "merged_prs_fallback";
10
+ };
11
+ leadTimeForChanges: {
12
+ medianHours: number;
13
+ rating: string;
14
+ };
15
+ changeFailureRate: {
16
+ percentage: number;
17
+ failedRuns: number;
18
+ totalRuns: number;
19
+ rating: string;
20
+ };
21
+ }
22
+ export interface DependencyVulnerability {
23
+ packageName: string;
24
+ currentVersion: string;
25
+ vulnId: string;
26
+ summary: string;
27
+ severity: string;
28
+ aliases: string[];
29
+ fixedVersion: string | null;
30
+ }
31
+ export interface Suggestion {
32
+ category: "performance" | "reliability" | "security";
33
+ severity: "high" | "medium" | "low";
34
+ title: string;
35
+ description: string;
36
+ actionItems: string[];
37
+ }
38
+ export interface AnalysisResult {
39
+ repo: RepoIdentifier;
40
+ fetchedAt: string;
41
+ doraMetrics: DORAMetrics;
42
+ vulnerabilities: DependencyVulnerability[];
43
+ suggestions: Suggestion[];
44
+ overallScore: number;
45
+ }
46
+ export declare function parseRepoSlug(input: string): RepoIdentifier;
47
+ export declare function analyze(repoSlug: string, token?: string): Promise<AnalysisResult>;
48
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/cli/analyzer.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,mBAAmB,EAAE;QACnB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,iBAAiB,GAAG,qBAAqB,CAAC;KACnD,CAAC;IACF,kBAAkB,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,iBAAiB,EAAE;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,GAAG,aAAa,GAAG,UAAU,CAAC;IACrD,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,uBAAuB,EAAE,CAAC;IAC3C,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAW3D;AAgaD,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC,CA4BzB"}
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Delivery Intel — Standalone CLI Analyzer
4
+ // ============================================================================
5
+ // This module re-exports the core analysis logic without Next.js dependencies,
6
+ // so it can be used from the CLI or programmatically.
7
+ // ============================================================================
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.parseRepoSlug = parseRepoSlug;
10
+ exports.analyze = analyze;
11
+ const rest_1 = require("@octokit/rest");
12
+ const date_fns_1 = require("date-fns");
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+ function parseRepoSlug(input) {
17
+ const cleaned = input.trim().replace(/\.git$/, "");
18
+ const urlMatch = cleaned.match(/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)/);
19
+ if (urlMatch)
20
+ return { owner: urlMatch[1], repo: urlMatch[2] };
21
+ const slugMatch = cleaned.match(/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/);
22
+ if (slugMatch)
23
+ return { owner: slugMatch[1], repo: slugMatch[2] };
24
+ throw new Error(`Invalid repository: "${input}". Use "owner/repo" or a GitHub URL.`);
25
+ }
26
+ function median(values) {
27
+ if (values.length === 0)
28
+ return 0;
29
+ const sorted = [...values].sort((a, b) => a - b);
30
+ const mid = Math.floor(sorted.length / 2);
31
+ return sorted.length % 2 !== 0
32
+ ? sorted[mid]
33
+ : (sorted[mid - 1] + sorted[mid]) / 2;
34
+ }
35
+ function rateDeployFreq(v) {
36
+ if (v >= 7)
37
+ return "Elite";
38
+ if (v >= 1)
39
+ return "High";
40
+ if (v >= 0.25)
41
+ return "Medium";
42
+ return "Low";
43
+ }
44
+ function rateLeadTime(h) {
45
+ if (h < 24)
46
+ return "Elite";
47
+ if (h < 168)
48
+ return "High";
49
+ if (h < 720)
50
+ return "Medium";
51
+ return "Low";
52
+ }
53
+ function rateCFR(p) {
54
+ if (p <= 5)
55
+ return "Elite";
56
+ if (p <= 10)
57
+ return "High";
58
+ if (p <= 15)
59
+ return "Medium";
60
+ return "Low";
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // GitHub data fetching
64
+ // ---------------------------------------------------------------------------
65
+ function createOctokit(token) {
66
+ return token ? new rest_1.Octokit({ auth: token }) : new rest_1.Octokit();
67
+ }
68
+ async function fetchDeployments(octokit, id) {
69
+ const { data } = await octokit.repos.listDeployments({
70
+ owner: id.owner,
71
+ repo: id.repo,
72
+ per_page: 50,
73
+ });
74
+ return data;
75
+ }
76
+ async function fetchMergedPRs(octokit, id) {
77
+ const { data } = await octokit.pulls.list({
78
+ owner: id.owner,
79
+ repo: id.repo,
80
+ state: "closed",
81
+ sort: "updated",
82
+ direction: "desc",
83
+ per_page: 30,
84
+ });
85
+ return data.filter((pr) => pr.merged_at !== null);
86
+ }
87
+ async function fetchWorkflowRuns(octokit, id) {
88
+ const { data } = await octokit.actions.listWorkflowRunsForRepo({
89
+ owner: id.owner,
90
+ repo: id.repo,
91
+ per_page: 50,
92
+ });
93
+ return data.workflow_runs;
94
+ }
95
+ async function fetchFileContent(octokit, id, path) {
96
+ try {
97
+ const { data } = await octokit.repos.getContent({
98
+ owner: id.owner,
99
+ repo: id.repo,
100
+ path,
101
+ });
102
+ if ("content" in data && typeof data.content === "string") {
103
+ return Buffer.from(data.content, "base64").toString("utf-8");
104
+ }
105
+ return null;
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Metrics computation
113
+ // ---------------------------------------------------------------------------
114
+ async function computeDeployFrequency(octokit, id) {
115
+ const deployments = await fetchDeployments(octokit, id);
116
+ if (deployments.length >= 2) {
117
+ const dates = deployments.map((d) => (0, date_fns_1.parseISO)(d.created_at));
118
+ const weeks = (0, date_fns_1.differenceInCalendarWeeks)(dates[0], dates[dates.length - 1]) || 1;
119
+ const perWeek = +(deployments.length / weeks).toFixed(2);
120
+ return {
121
+ deploymentsPerWeek: perWeek,
122
+ rating: rateDeployFreq(perWeek),
123
+ source: "deployments_api",
124
+ };
125
+ }
126
+ const mergedPRs = await fetchMergedPRs(octokit, id);
127
+ if (mergedPRs.length < 2) {
128
+ return { deploymentsPerWeek: 0, rating: "Low", source: "merged_prs_fallback" };
129
+ }
130
+ const prDates = mergedPRs
131
+ .map((pr) => (0, date_fns_1.parseISO)(pr.merged_at))
132
+ .sort((a, b) => b.getTime() - a.getTime());
133
+ const weeks = (0, date_fns_1.differenceInCalendarWeeks)(prDates[0], prDates[prDates.length - 1]) || 1;
134
+ const perWeek = +(mergedPRs.length / weeks).toFixed(2);
135
+ return {
136
+ deploymentsPerWeek: perWeek,
137
+ rating: rateDeployFreq(perWeek),
138
+ source: "merged_prs_fallback",
139
+ };
140
+ }
141
+ async function computeLeadTime(octokit, id) {
142
+ const mergedPRs = await fetchMergedPRs(octokit, id);
143
+ const hours = mergedPRs
144
+ .filter((pr) => pr.merged_at)
145
+ .map((pr) => (0, date_fns_1.differenceInHours)((0, date_fns_1.parseISO)(pr.merged_at), (0, date_fns_1.parseISO)(pr.created_at)));
146
+ const med = median(hours);
147
+ return { medianHours: +med.toFixed(1), rating: rateLeadTime(med) };
148
+ }
149
+ async function computeCFR(octokit, id) {
150
+ const runs = await fetchWorkflowRuns(octokit, id);
151
+ if (runs.length === 0) {
152
+ return { percentage: 0, failedRuns: 0, totalRuns: 0, rating: "Elite" };
153
+ }
154
+ const completed = runs.filter((r) => r.status === "completed");
155
+ if (completed.length === 0) {
156
+ return { percentage: 0, failedRuns: 0, totalRuns: 0, rating: "Elite" };
157
+ }
158
+ const failures = completed.filter((r) => r.conclusion === "failure");
159
+ const pct = +((failures.length / completed.length) * 100).toFixed(1);
160
+ return {
161
+ percentage: pct,
162
+ failedRuns: failures.length,
163
+ totalRuns: completed.length,
164
+ rating: rateCFR(pct),
165
+ };
166
+ }
167
+ function parsePackageJson(raw) {
168
+ try {
169
+ const pkg = JSON.parse(raw);
170
+ const deps = [];
171
+ for (const section of ["dependencies", "devDependencies"]) {
172
+ const map = pkg[section];
173
+ if (!map)
174
+ continue;
175
+ for (const [name, spec] of Object.entries(map)) {
176
+ deps.push({ name, version: spec.replace(/^[\^~>=<]+/, ""), ecosystem: "npm" });
177
+ }
178
+ }
179
+ return deps;
180
+ }
181
+ catch {
182
+ return [];
183
+ }
184
+ }
185
+ function parseRequirementsTxt(raw) {
186
+ const deps = [];
187
+ for (const line of raw.split("\n")) {
188
+ const t = line.trim();
189
+ if (!t || t.startsWith("#"))
190
+ continue;
191
+ const m = t.match(/^([A-Za-z0-9_.-]+)\s*[=><~!]+\s*([0-9.]+)/);
192
+ if (m)
193
+ deps.push({ name: m[1], version: m[2], ecosystem: "PyPI" });
194
+ }
195
+ return deps;
196
+ }
197
+ async function queryOSV(ecosystem, name, version) {
198
+ try {
199
+ const res = await fetch("https://api.osv.dev/v1/query", {
200
+ method: "POST",
201
+ headers: { "Content-Type": "application/json" },
202
+ body: JSON.stringify({ version, package: { name, ecosystem } }),
203
+ });
204
+ if (!res.ok)
205
+ return [];
206
+ const data = (await res.json());
207
+ return data.vulns || [];
208
+ }
209
+ catch {
210
+ return [];
211
+ }
212
+ }
213
+ async function scanVulnerabilities(octokit, id) {
214
+ const [pkgJson, reqTxt] = await Promise.all([
215
+ fetchFileContent(octokit, id, "package.json"),
216
+ fetchFileContent(octokit, id, "requirements.txt"),
217
+ ]);
218
+ const allDeps = [];
219
+ if (pkgJson)
220
+ allDeps.push(...parsePackageJson(pkgJson));
221
+ if (reqTxt)
222
+ allDeps.push(...parseRequirementsTxt(reqTxt));
223
+ if (allDeps.length === 0)
224
+ return [];
225
+ const vulnerabilities = [];
226
+ const BATCH = 10;
227
+ for (let i = 0; i < allDeps.length; i += BATCH) {
228
+ const batch = allDeps.slice(i, i + BATCH);
229
+ const results = await Promise.all(batch.map((d) => queryOSV(d.ecosystem, d.name, d.version)));
230
+ for (let j = 0; j < batch.length; j++) {
231
+ const dep = batch[j];
232
+ for (const vuln of results[j]) {
233
+ let fixedVersion = null;
234
+ const affected = vuln.affected?.find((a) => a.package.name === dep.name && a.package.ecosystem === dep.ecosystem);
235
+ if (affected?.ranges) {
236
+ for (const range of affected.ranges) {
237
+ for (const ev of range.events) {
238
+ if (ev.fixed) {
239
+ fixedVersion = ev.fixed;
240
+ break;
241
+ }
242
+ }
243
+ }
244
+ }
245
+ let severity = "unknown";
246
+ if (vuln.severity?.length > 0) {
247
+ const cvss = parseFloat(vuln.severity[0].score);
248
+ if (cvss >= 9)
249
+ severity = "critical";
250
+ else if (cvss >= 7)
251
+ severity = "high";
252
+ else if (cvss >= 4)
253
+ severity = "medium";
254
+ else
255
+ severity = "low";
256
+ }
257
+ vulnerabilities.push({
258
+ packageName: dep.name,
259
+ currentVersion: dep.version,
260
+ vulnId: vuln.id,
261
+ summary: vuln.summary || "No description.",
262
+ severity,
263
+ aliases: vuln.aliases || [],
264
+ fixedVersion,
265
+ });
266
+ }
267
+ }
268
+ }
269
+ return vulnerabilities;
270
+ }
271
+ // ---------------------------------------------------------------------------
272
+ // Suggestion engine
273
+ // ---------------------------------------------------------------------------
274
+ function generateSuggestions(dora, vulns) {
275
+ const suggestions = [];
276
+ if (dora.changeFailureRate.percentage > 15) {
277
+ suggestions.push({
278
+ category: "reliability",
279
+ severity: "high",
280
+ title: "High Pipeline Failure Rate",
281
+ description: `${dora.changeFailureRate.percentage}% failure rate (${dora.changeFailureRate.failedRuns}/${dora.changeFailureRate.totalRuns} runs). Above the 15% threshold.`,
282
+ actionItems: [
283
+ "Enable Branch Protection Rules requiring passing status checks.",
284
+ "Add required code reviews before merging.",
285
+ "Implement pre-merge CI: lint, type-check, unit tests.",
286
+ ],
287
+ });
288
+ }
289
+ else if (dora.changeFailureRate.percentage > 10) {
290
+ suggestions.push({
291
+ category: "reliability",
292
+ severity: "medium",
293
+ title: "Moderate Pipeline Failure Rate",
294
+ description: `${dora.changeFailureRate.percentage}% failure rate. Room for improvement.`,
295
+ actionItems: [
296
+ "Review recent failures for common patterns.",
297
+ "Add retry logic for flaky tests.",
298
+ ],
299
+ });
300
+ }
301
+ if (dora.leadTimeForChanges.medianHours > 168) {
302
+ suggestions.push({
303
+ category: "performance",
304
+ severity: "high",
305
+ title: "Slow Lead Time for Changes",
306
+ description: `Median ${dora.leadTimeForChanges.medianHours}h (${(dora.leadTimeForChanges.medianHours / 24).toFixed(1)} days). Too long to merge.`,
307
+ actionItems: [
308
+ "Break features into smaller PRs (<400 lines).",
309
+ "Set up CODEOWNERS for automatic review routing.",
310
+ "Consider trunk-based development with feature flags.",
311
+ ],
312
+ });
313
+ }
314
+ else if (dora.leadTimeForChanges.medianHours > 48) {
315
+ suggestions.push({
316
+ category: "performance",
317
+ severity: "medium",
318
+ title: "PRs Sitting Too Long",
319
+ description: `Median ${dora.leadTimeForChanges.medianHours}h. PRs may be waiting for review.`,
320
+ actionItems: [
321
+ "Set a team SLA for reviews (< 4 hours for first review).",
322
+ "Use auto-assign to distribute review load.",
323
+ ],
324
+ });
325
+ }
326
+ if (dora.deploymentFrequency.rating === "Low") {
327
+ suggestions.push({
328
+ category: "performance",
329
+ severity: "medium",
330
+ title: "Low Deployment Frequency",
331
+ description: `Only ${dora.deploymentFrequency.deploymentsPerWeek}/week.`,
332
+ actionItems: [
333
+ "Set up continuous deployment for your default branch.",
334
+ "Deploy smaller changes more frequently.",
335
+ ],
336
+ });
337
+ }
338
+ const critical = vulns.filter((v) => v.severity === "critical");
339
+ const high = vulns.filter((v) => v.severity === "high");
340
+ if (critical.length > 0) {
341
+ suggestions.push({
342
+ category: "security",
343
+ severity: "high",
344
+ title: `${critical.length} Critical Vulnerabilit${critical.length === 1 ? "y" : "ies"}`,
345
+ description: `In: ${[...new Set(critical.map((v) => v.packageName))].join(", ")}`,
346
+ actionItems: critical
347
+ .filter((v) => v.fixedVersion)
348
+ .map((v) => `Update ${v.packageName} → ${v.fixedVersion} (${v.vulnId})`),
349
+ });
350
+ }
351
+ if (high.length > 0) {
352
+ suggestions.push({
353
+ category: "security",
354
+ severity: "medium",
355
+ title: `${high.length} High-Severity Vulnerabilit${high.length === 1 ? "y" : "ies"}`,
356
+ description: `In: ${[...new Set(high.map((v) => v.packageName))].join(", ")}`,
357
+ actionItems: high
358
+ .filter((v) => v.fixedVersion)
359
+ .map((v) => `Update ${v.packageName} → ${v.fixedVersion} (${v.vulnId})`),
360
+ });
361
+ }
362
+ if (vulns.length === 0) {
363
+ suggestions.push({
364
+ category: "security",
365
+ severity: "low",
366
+ title: "No Known Vulnerabilities",
367
+ description: "OSV.dev found no known issues. Keep dependencies updated.",
368
+ actionItems: ["Enable Dependabot or Renovate for automated updates."],
369
+ });
370
+ }
371
+ const order = { high: 0, medium: 1, low: 2 };
372
+ suggestions.sort((a, b) => order[a.severity] - order[b.severity]);
373
+ return suggestions;
374
+ }
375
+ // ---------------------------------------------------------------------------
376
+ // Overall score
377
+ // ---------------------------------------------------------------------------
378
+ const SCORES = {
379
+ Elite: 100, High: 75, Medium: 50, Low: 25,
380
+ };
381
+ function computeScore(dora, vulns) {
382
+ const doraScore = (SCORES[dora.deploymentFrequency.rating] +
383
+ SCORES[dora.leadTimeForChanges.rating] +
384
+ SCORES[dora.changeFailureRate.rating]) / 3;
385
+ const penalty = vulns.reduce((sum, v) => {
386
+ if (v.severity === "critical")
387
+ return sum + 5;
388
+ if (v.severity === "high")
389
+ return sum + 2;
390
+ if (v.severity === "medium")
391
+ return sum + 1;
392
+ return sum;
393
+ }, 0);
394
+ return Math.max(0, Math.min(100, Math.round(doraScore - penalty)));
395
+ }
396
+ // ---------------------------------------------------------------------------
397
+ // Public: Full analysis
398
+ // ---------------------------------------------------------------------------
399
+ async function analyze(repoSlug, token) {
400
+ const id = parseRepoSlug(repoSlug);
401
+ const octokit = createOctokit(token);
402
+ const [deployFreq, leadTime, cfr, vulns] = await Promise.all([
403
+ computeDeployFrequency(octokit, id),
404
+ computeLeadTime(octokit, id),
405
+ computeCFR(octokit, id),
406
+ scanVulnerabilities(octokit, id),
407
+ ]);
408
+ const doraMetrics = {
409
+ deploymentFrequency: deployFreq,
410
+ leadTimeForChanges: leadTime,
411
+ changeFailureRate: cfr,
412
+ };
413
+ const suggestions = generateSuggestions(doraMetrics, vulns);
414
+ const overallScore = computeScore(doraMetrics, vulns);
415
+ return {
416
+ repo: id,
417
+ fetchedAt: new Date().toISOString(),
418
+ doraMetrics,
419
+ vulnerabilities: vulns,
420
+ suggestions,
421
+ overallScore,
422
+ };
423
+ }
424
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/cli/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,355 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // ============================================================================
4
+ // delivery-intel CLI
5
+ // ============================================================================
6
+ // Usage:
7
+ // npx delivery-intel <owner/repo>
8
+ // npx delivery-intel vercel/next.js
9
+ // npx delivery-intel https://github.com/facebook/react
10
+ // npx delivery-intel vercel/next.js --json
11
+ // npx delivery-intel vercel/next.js --json --output report.json
12
+ // ============================================================================
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ const analyzer_1 = require("./analyzer");
48
+ const fs = __importStar(require("fs"));
49
+ const child_process_1 = require("child_process");
50
+ // ---------------------------------------------------------------------------
51
+ // Secure token resolution
52
+ // ---------------------------------------------------------------------------
53
+ // Priority order:
54
+ // 1. --token flag (explicit, least recommended)
55
+ // 2. GITHUB_TOKEN env var
56
+ // 3. gh auth token (GitHub CLI — recommended, token stays in OS keychain)
57
+ // ---------------------------------------------------------------------------
58
+ function resolveTokenFromGHCli() {
59
+ try {
60
+ const token = (0, child_process_1.execSync)("gh auth token", {
61
+ encoding: "utf-8",
62
+ timeout: 5000,
63
+ stdio: ["pipe", "pipe", "pipe"],
64
+ }).trim();
65
+ return token || null;
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ function resolveToken(explicitToken) {
72
+ if (explicitToken) {
73
+ return { token: explicitToken, source: "--token flag" };
74
+ }
75
+ if (process.env.GITHUB_TOKEN) {
76
+ return { token: process.env.GITHUB_TOKEN, source: "GITHUB_TOKEN env var" };
77
+ }
78
+ const ghToken = resolveTokenFromGHCli();
79
+ if (ghToken) {
80
+ return { token: ghToken, source: "GitHub CLI (gh auth token)" };
81
+ }
82
+ return null;
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // ANSI color helpers
86
+ // ---------------------------------------------------------------------------
87
+ const c = {
88
+ reset: "\x1b[0m",
89
+ bold: "\x1b[1m",
90
+ dim: "\x1b[2m",
91
+ red: "\x1b[31m",
92
+ green: "\x1b[32m",
93
+ yellow: "\x1b[33m",
94
+ blue: "\x1b[34m",
95
+ magenta: "\x1b[35m",
96
+ cyan: "\x1b[36m",
97
+ white: "\x1b[37m",
98
+ bgRed: "\x1b[41m",
99
+ bgGreen: "\x1b[42m",
100
+ bgYellow: "\x1b[43m",
101
+ bgBlue: "\x1b[44m",
102
+ gray: "\x1b[90m",
103
+ };
104
+ function ratingColor(rating) {
105
+ switch (rating) {
106
+ case "Elite": return c.green;
107
+ case "High": return c.blue;
108
+ case "Medium": return c.yellow;
109
+ case "Low": return c.red;
110
+ default: return c.dim;
111
+ }
112
+ }
113
+ function severityColor(sev) {
114
+ switch (sev) {
115
+ case "critical": return c.bgRed + c.white;
116
+ case "high": return c.red;
117
+ case "medium": return c.yellow;
118
+ case "low": return c.blue;
119
+ default: return c.dim;
120
+ }
121
+ }
122
+ // ---------------------------------------------------------------------------
123
+ // Score bar visualization
124
+ // ---------------------------------------------------------------------------
125
+ function scoreBar(score) {
126
+ const width = 30;
127
+ const filled = Math.round((score / 100) * width);
128
+ const empty = width - filled;
129
+ let barColor = c.red;
130
+ if (score >= 75)
131
+ barColor = c.green;
132
+ else if (score >= 50)
133
+ barColor = c.yellow;
134
+ else if (score >= 25)
135
+ barColor = c.blue;
136
+ return (barColor + "█".repeat(filled) + c.dim + "░".repeat(empty) + c.reset +
137
+ ` ${c.bold}${score}${c.reset}${c.dim}/100${c.reset}`);
138
+ }
139
+ // ---------------------------------------------------------------------------
140
+ // Pretty-print sections
141
+ // ---------------------------------------------------------------------------
142
+ function printHeader(result) {
143
+ console.log();
144
+ console.log(`${c.bold}${c.cyan} ┌─────────────────────────────────────────────────┐${c.reset}`);
145
+ console.log(`${c.bold}${c.cyan} │${c.reset} ${c.bold}📊 Delivery Intel${c.reset} ${c.dim}— Software Delivery Intelligence${c.reset} ${c.bold}${c.cyan}│${c.reset}`);
146
+ console.log(`${c.bold}${c.cyan} └─────────────────────────────────────────────────┘${c.reset}`);
147
+ console.log();
148
+ console.log(` ${c.dim}Repository:${c.reset} ${c.bold}${result.repo.owner}/${result.repo.repo}${c.reset}`);
149
+ console.log(` ${c.dim}Analyzed:${c.reset} ${result.fetchedAt}`);
150
+ console.log();
151
+ }
152
+ function printScore(score) {
153
+ console.log(` ${c.bold}Overall Health Score${c.reset}`);
154
+ console.log(` ${scoreBar(score)}`);
155
+ console.log();
156
+ }
157
+ function printDORA(dora) {
158
+ console.log(` ${c.bold}DORA Metrics${c.reset} ${c.dim}─────────────────────────────────────${c.reset}`);
159
+ console.log();
160
+ // Deploy Frequency
161
+ const df = dora.deploymentFrequency;
162
+ console.log(` ${c.bold}Deploy Frequency${c.reset} ${ratingColor(df.rating)}${df.rating}${c.reset}`);
163
+ console.log(` ${c.dim}How often code ships to production${c.reset}`);
164
+ console.log(` ${c.bold}${df.deploymentsPerWeek}${c.reset} ${c.dim}deployments/week${c.reset} ${c.gray}(source: ${df.source === "merged_prs_fallback" ? "merged PRs" : "Deployments API"})${c.reset}`);
165
+ console.log();
166
+ // Lead Time
167
+ const lt = dora.leadTimeForChanges;
168
+ console.log(` ${c.bold}Lead Time${c.reset} ${ratingColor(lt.rating)}${lt.rating}${c.reset}`);
169
+ console.log(` ${c.dim}Time from PR creation to merge (branch active duration)${c.reset}`);
170
+ console.log(` ${c.bold}${lt.medianHours}${c.reset} ${c.dim}hours median${c.reset} ${c.gray}(${(lt.medianHours / 24).toFixed(1)} days)${c.reset}`);
171
+ console.log();
172
+ // Change Failure Rate
173
+ const cfr = dora.changeFailureRate;
174
+ console.log(` ${c.bold}Change Failure Rate${c.reset} ${ratingColor(cfr.rating)}${cfr.rating}${c.reset}`);
175
+ console.log(` ${c.dim}Percentage of deployment pipeline runs that failed${c.reset}`);
176
+ console.log(` ${c.bold}${cfr.percentage}%${c.reset} ${c.gray}(${cfr.failedRuns} failed / ${cfr.totalRuns} total pipeline runs)${c.reset}`);
177
+ console.log();
178
+ }
179
+ function printVulnerabilities(vulns) {
180
+ console.log(` ${c.bold}Vulnerability Scan${c.reset} ${c.dim}(OSV.dev)${c.reset} ${c.dim}───────────────────${c.reset}`);
181
+ console.log();
182
+ if (vulns.length === 0) {
183
+ console.log(` ${c.green}✓ No known vulnerabilities found${c.reset}`);
184
+ console.log();
185
+ return;
186
+ }
187
+ console.log(` ${c.red}${c.bold}${vulns.length}${c.reset}${c.red} vulnerabilit${vulns.length === 1 ? "y" : "ies"} found${c.reset}`);
188
+ console.log();
189
+ // Group by severity
190
+ const grouped = {};
191
+ for (const v of vulns) {
192
+ if (!grouped[v.severity])
193
+ grouped[v.severity] = [];
194
+ grouped[v.severity].push(v);
195
+ }
196
+ const order = ["critical", "high", "medium", "low", "unknown"];
197
+ for (const sev of order) {
198
+ const list = grouped[sev];
199
+ if (!list)
200
+ continue;
201
+ console.log(` ${severityColor(sev)} ${sev.toUpperCase()} ${c.reset} ${c.dim}(${list.length})${c.reset}`);
202
+ for (const v of list.slice(0, 5)) {
203
+ const fix = v.fixedVersion
204
+ ? `${c.green}→ ${v.fixedVersion}${c.reset}`
205
+ : `${c.dim}no fix${c.reset}`;
206
+ console.log(` ${c.dim}•${c.reset} ${v.packageName}${c.dim}@${v.currentVersion}${c.reset} ${v.vulnId} ${fix}`);
207
+ }
208
+ if (list.length > 5) {
209
+ console.log(` ${c.dim} + ${list.length - 5} more${c.reset}`);
210
+ }
211
+ }
212
+ console.log();
213
+ }
214
+ function printSuggestions(suggestions) {
215
+ console.log(` ${c.bold}Suggestions${c.reset} ${c.dim}────────────────────────────────────${c.reset}`);
216
+ console.log();
217
+ for (const s of suggestions) {
218
+ const icon = s.category === "security" ? "🔒" : s.category === "reliability" ? "🛡️ " : "⚡";
219
+ const sevTag = `${severityColor(s.severity)} ${s.severity.toUpperCase()} ${c.reset}`;
220
+ console.log(` ${icon} ${sevTag} ${c.bold}${s.title}${c.reset}`);
221
+ console.log(` ${c.dim}${s.description}${c.reset}`);
222
+ for (const action of s.actionItems) {
223
+ console.log(` ${c.cyan}→${c.reset} ${action}`);
224
+ }
225
+ console.log();
226
+ }
227
+ }
228
+ // ---------------------------------------------------------------------------
229
+ // Help & Version
230
+ // ---------------------------------------------------------------------------
231
+ const VERSION = "1.0.0";
232
+ function printHelp() {
233
+ console.log(`
234
+ ${c.bold}delivery-intel${c.reset} v${VERSION}
235
+ ${c.dim}Software Delivery Intelligence for any GitHub repository${c.reset}
236
+
237
+ ${c.bold}USAGE${c.reset}
238
+ ${c.cyan}npx delivery-intel${c.reset} <owner/repo> [options]
239
+
240
+ ${c.bold}EXAMPLES${c.reset}
241
+ ${c.cyan}npx delivery-intel${c.reset} vercel/next.js
242
+ ${c.cyan}npx delivery-intel${c.reset} https://github.com/facebook/react
243
+ ${c.cyan}npx delivery-intel${c.reset} vercel/next.js ${c.dim}--json${c.reset}
244
+ ${c.cyan}npx delivery-intel${c.reset} vercel/next.js ${c.dim}--json --output report.json${c.reset}
245
+
246
+ ${c.bold}OPTIONS${c.reset}
247
+ ${c.yellow}--json${c.reset} Output raw JSON instead of formatted report
248
+ ${c.yellow}--output <file>${c.reset} Write JSON output to a file
249
+ ${c.yellow}--token <token>${c.reset} GitHub token (not recommended — prefer gh auth)
250
+ ${c.yellow}--help${c.reset} Show this help message
251
+ ${c.yellow}--version${c.reset} Show version number
252
+
253
+ ${c.bold}AUTHENTICATION${c.reset} ${c.dim}(token is resolved in this order)${c.reset}
254
+ ${c.green}1. gh auth login${c.reset} ${c.bold}← Recommended${c.reset} (token stays in OS keychain, never exposed)
255
+ Install: https://cli.github.com
256
+ ${c.yellow}2. GITHUB_TOKEN${c.reset} Environment variable (OK for CI — use secrets)
257
+ ${c.red}3. --token${c.reset} Inline flag (avoid — visible in shell history & ps)
258
+
259
+ ${c.bold}CI / GITHUB ACTIONS${c.reset}
260
+ The built-in $GITHUB_TOKEN is auto-scoped and expires per job:
261
+ ${c.dim}npx delivery-intel \${{ github.repository }} --token \${{ secrets.GITHUB_TOKEN }}${c.reset}
262
+
263
+ ${c.bold}WHAT IT MEASURES${c.reset}
264
+ ${c.bold}Deploy Frequency${c.reset} How often code ships to production
265
+ ${c.bold}Lead Time${c.reset} PR creation → merge (branch active duration)
266
+ ${c.bold}Change Failure Rate${c.reset} % of deployment pipeline runs that failed
267
+ ${c.bold}Vulnerabilities${c.reset} OSV.dev scan of dependency manifests
268
+ `);
269
+ }
270
+ // ---------------------------------------------------------------------------
271
+ // Main
272
+ // ---------------------------------------------------------------------------
273
+ async function main() {
274
+ const args = process.argv.slice(2);
275
+ if (args.includes("--help") || args.includes("-h") || args.length === 0) {
276
+ printHelp();
277
+ process.exit(0);
278
+ }
279
+ if (args.includes("--version") || args.includes("-v")) {
280
+ console.log(VERSION);
281
+ process.exit(0);
282
+ }
283
+ // Parse args
284
+ const jsonMode = args.includes("--json");
285
+ let outputFile = null;
286
+ let token = null;
287
+ let repo = null;
288
+ for (let i = 0; i < args.length; i++) {
289
+ if (args[i] === "--output" && args[i + 1]) {
290
+ outputFile = args[++i];
291
+ }
292
+ else if (args[i] === "--token" && args[i + 1]) {
293
+ token = args[++i];
294
+ }
295
+ else if (!args[i].startsWith("--")) {
296
+ repo = args[i];
297
+ }
298
+ }
299
+ const resolved = resolveToken(token);
300
+ if (resolved) {
301
+ token = resolved.token;
302
+ }
303
+ else {
304
+ token = null;
305
+ }
306
+ if (!repo) {
307
+ console.error(`${c.red}Error:${c.reset} No repository specified.`);
308
+ console.error(`${c.dim}Usage: npx delivery-intel <owner/repo>${c.reset}`);
309
+ process.exit(1);
310
+ }
311
+ // Run analysis
312
+ if (!jsonMode) {
313
+ console.log();
314
+ console.log(` ${c.dim}Analyzing ${c.reset}${c.bold}${repo}${c.reset}${c.dim}...${c.reset}`);
315
+ if (resolved) {
316
+ console.log(` ${c.dim}Auth: ${resolved.source}${c.reset}`);
317
+ }
318
+ else {
319
+ console.log(` ${c.yellow}⚠ No token — using unauthenticated mode (60 req/hr, public repos only)${c.reset}`);
320
+ console.log(` ${c.dim}Tip: run ${c.cyan}gh auth login${c.dim} for 5,000 req/hr + private repo access${c.reset}`);
321
+ }
322
+ }
323
+ try {
324
+ const result = await (0, analyzer_1.analyze)(repo, token || undefined);
325
+ if (jsonMode || outputFile) {
326
+ const json = JSON.stringify(result, null, 2);
327
+ if (outputFile) {
328
+ fs.writeFileSync(outputFile, json, "utf-8");
329
+ if (!jsonMode) {
330
+ console.log(` ${c.green}✓${c.reset} Report saved to ${c.bold}${outputFile}${c.reset}`);
331
+ }
332
+ }
333
+ if (jsonMode) {
334
+ console.log(json);
335
+ }
336
+ }
337
+ else {
338
+ printHeader(result);
339
+ printScore(result.overallScore);
340
+ printDORA(result.doraMetrics);
341
+ printVulnerabilities(result.vulnerabilities);
342
+ printSuggestions(result.suggestions);
343
+ }
344
+ // Exit code based on score
345
+ if (result.overallScore < 25)
346
+ process.exit(2);
347
+ }
348
+ catch (err) {
349
+ const msg = err instanceof Error ? err.message : String(err);
350
+ console.error(`${c.red}Error:${c.reset} ${msg}`);
351
+ process.exit(1);
352
+ }
353
+ }
354
+ main();
355
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "delivery-intel",
3
+ "version": "1.0.0",
4
+ "description": "Software Delivery Intelligence — DORA metrics, vulnerability scanning, and actionable suggestions for any GitHub repository.",
5
+ "keywords": [
6
+ "dora",
7
+ "devops",
8
+ "metrics",
9
+ "github",
10
+ "ci-cd",
11
+ "deployment",
12
+ "vulnerability",
13
+ "cli",
14
+ "dashboard"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "ParthibanRajasekaran",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/ParthibanRajasekaran/growth-agent"
21
+ },
22
+ "bin": {
23
+ "delivery-intel": "./bin/delivery-intel.js"
24
+ },
25
+ "main": "./dist/cli/analyzer.js",
26
+ "types": "./dist/cli/analyzer.d.ts",
27
+ "files": [
28
+ "dist/cli/",
29
+ "bin/"
30
+ ],
31
+ "scripts": {
32
+ "dev": "next dev",
33
+ "build": "next build",
34
+ "build:cli": "tsc -p tsconfig.cli.json",
35
+ "prepublishOnly": "npm run build:cli",
36
+ "start": "next start",
37
+ "lint": "next lint"
38
+ },
39
+ "dependencies": {
40
+ "@octokit/graphql": "^9.0.3",
41
+ "@octokit/rest": "^22.0.1",
42
+ "@types/node": "^25.2.3",
43
+ "@types/react": "^19.2.14",
44
+ "date-fns": "^4.1.0",
45
+ "framer-motion": "^12.34.2",
46
+ "ioredis": "^5.9.3",
47
+ "next": "^16.1.6",
48
+ "react": "^19.2.4",
49
+ "react-dom": "^19.2.4",
50
+ "recharts": "^3.7.0",
51
+ "typescript": "^5.9.3"
52
+ },
53
+ "devDependencies": {
54
+ "@tailwindcss/postcss": "^4.2.0",
55
+ "@types/react-dom": "^19.2.3",
56
+ "autoprefixer": "^10.4.24",
57
+ "postcss": "^8.5.6",
58
+ "tailwindcss": "^4.2.0"
59
+ }
60
+ }