swadhinbiswas feat: complete DevPulse production developer operating system for Discord · 9/6/2026
4a8d707
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import type {
GitHubCommit,
GitHubIssue,
GitHubPullRequest,
GitHubRelease,
RepoDashboardMetrics,
} from "./types.js";
export function computeRepoDashboardMetrics(
commits: GitHubCommit[],
prs: GitHubPullRequest[],
issues: GitHubIssue[],
releases: GitHubRelease[],
): RepoDashboardMetrics {
// 1. Activity Log
const mergedPrs = prs.filter((p) => p.mergedAt !== null);
const closedIssues = issues.filter((i) => i.closedAt !== null);
const activity = {
commitsCount: commits.length,
prsOpened: prs.length,
prsMerged: mergedPrs.length,
issuesOpened: issues.length,
issuesClosed: closedIssues.length,
releasesCount: releases.length,
};
// 2. Workload balance across days of the week
const workload = {
mon: 0,
tue: 0,
wed: 0,
thu: 0,
fri: 0,
sat: 0,
sun: 0,
};
const dayKeys: Array<keyof typeof workload> = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
for (const c of commits) {
const d = new Date(c.author.date);
const day = dayKeys[d.getUTCDay()];
workload[day] += 1;
}
for (const p of prs) {
const d = new Date(p.createdAt);
const day = dayKeys[d.getUTCDay()];
workload[day] += 1;
}
// 3. Focus breakdown
// Coding (commits + prs)
// Reviews (estimated based on merged & closed PR ratio)
// Issues (issue discussions)
// Docs (commits or PRs mentioning docs, readme, guide)
// Maintenance (ci, chore, refactor, deps)
let docsScore = 0;
let maintenanceScore = 0;
let generalCodingScore = 0;
for (const c of commits) {
const msg = c.message.toLowerCase();
if (msg.includes("doc") || msg.includes("readme")) {
docsScore += 1;
} else if (
msg.includes("chore") ||
msg.includes("ci") ||
msg.includes("dep") ||
msg.includes("bump")
) {
maintenanceScore += 1;
} else {
generalCodingScore += 1;
}
}
const reviewScore = Math.round(mergedPrs.length * 1.5);
const issuesScore = issues.length;
const totalFocusPoints = Math.max(
1,
generalCodingScore + reviewScore + issuesScore + docsScore + maintenanceScore,
);
const focus = {
codingPercent: Math.round((generalCodingScore / totalFocusPoints) * 100),
reviewsPercent: Math.round((reviewScore / totalFocusPoints) * 100),
issuesPercent: Math.round((issuesScore / totalFocusPoints) * 100),
docsPercent: Math.round((docsScore / totalFocusPoints) * 100),
maintenancePercent: Math.round((maintenanceScore / totalFocusPoints) * 100),
};
// 4. Cycle time calculations
let totalPrCycleMs = 0;
let prCycleCount = 0;
for (const pr of mergedPrs) {
if (pr.mergedAt) {
const created = new Date(pr.createdAt).getTime();
const merged = new Date(pr.mergedAt).getTime();
const diff = merged - created;
if (diff > 0) {
totalPrCycleMs += diff;
prCycleCount += 1;
}
}
}
const avgTimeToMergeMs = prCycleCount > 0 ? Math.round(totalPrCycleMs / prCycleCount) : 0;
const avgPrCycleTimeMs = avgTimeToMergeMs;
let totalIssueCycleMs = 0;
let issueCycleCount = 0;
for (const issue of closedIssues) {
if (issue.closedAt) {
const created = new Date(issue.createdAt).getTime();
const closed = new Date(issue.closedAt).getTime();
const diff = closed - created;
if (diff > 0) {
totalIssueCycleMs += diff;
issueCycleCount += 1;
}
}
}
const avgIssueCycleTimeMs =
issueCycleCount > 0 ? Math.round(totalIssueCycleMs / issueCycleCount) : 0;
// 5. Coding metrics
const commitFrequencyPerDay = Number.parseFloat((commits.length / 14).toFixed(1)); // based on last 14 days
const prThroughputPerWeek = Number.parseFloat((mergedPrs.length / 2).toFixed(1));
const issueResolutionRatePercent =
issues.length > 0 ? Math.round((closedIssues.length / issues.length) * 100) : 100;
return {
activity,
workload,
focus,
cycleTime: {
avgPrCycleTimeMs,
avgIssueCycleTimeMs,
avgTimeToMergeMs,
},
codingMetrics: {
commitFrequencyPerDay,
prThroughputPerWeek,
issueResolutionRatePercent,
},
};
}