@urmzd/github-insights 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.githooks/commit-msg +4 -0
- package/.githooks/pre-commit +4 -0
- package/AGENTS.md +32 -19
- package/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +18 -19
- package/README.md +21 -24
- package/action.yml +1 -1
- package/assets/insights/index.svg +45 -4
- package/assets/insights/metrics-constellation.svg +55 -0
- package/assets/insights/metrics-impact.svg +55 -0
- package/assets/insights/metrics-rhythm.svg +55 -0
- package/assets/insights/metrics-velocity.svg +55 -0
- package/examples/classic/README.md +36 -2
- package/examples/classic/index.svg +45 -4
- package/examples/classic/metrics-constellation.svg +55 -0
- package/examples/classic/metrics-impact.svg +55 -0
- package/examples/classic/metrics-rhythm.svg +55 -0
- package/examples/classic/metrics-velocity.svg +55 -0
- package/examples/ecosystem/README.md +39 -28
- package/examples/ecosystem/index.svg +45 -4
- package/examples/ecosystem/metrics-constellation.svg +55 -0
- package/examples/ecosystem/metrics-impact.svg +55 -0
- package/examples/ecosystem/metrics-rhythm.svg +55 -0
- package/examples/ecosystem/metrics-velocity.svg +55 -0
- package/examples/minimal/README.md +36 -2
- package/examples/minimal/index.svg +45 -4
- package/examples/minimal/metrics-constellation.svg +55 -0
- package/examples/minimal/metrics-impact.svg +55 -0
- package/examples/minimal/metrics-rhythm.svg +55 -0
- package/examples/minimal/metrics-velocity.svg +55 -0
- package/examples/modern/README.md +62 -50
- package/examples/modern/index.svg +45 -4
- package/examples/modern/metrics-constellation.svg +55 -0
- package/examples/modern/metrics-impact.svg +55 -0
- package/examples/modern/metrics-rhythm.svg +55 -0
- package/examples/modern/metrics-velocity.svg +55 -0
- package/llms.txt +4 -4
- package/package.json +1 -1
- package/skills/github-insights/SKILL.md +35 -81
- package/sr.yaml +9 -0
- package/src/api.ts +3 -141
- package/src/components/contribution-rhythm.tsx +152 -0
- package/src/components/full-svg.test.tsx +4 -1
- package/src/components/full-svg.tsx +14 -7
- package/src/components/impact-trail.tsx +90 -0
- package/src/components/language-velocity.tsx +181 -0
- package/src/components/project-constellation.tsx +97 -0
- package/src/components/section.test.tsx +5 -3
- package/src/components/section.tsx +5 -13
- package/src/components/style-defs.tsx +44 -3
- package/src/index.ts +34 -47
- package/src/metrics.test.ts +50 -57
- package/src/metrics.ts +293 -97
- package/src/readme.test.ts +2 -4
- package/src/templates.test.ts +116 -16
- package/src/templates.ts +68 -27
- package/src/theme.ts +11 -1
- package/src/types.ts +31 -7
- package/assets/insights/metrics-calendar.svg +0 -14
- package/assets/insights/metrics-complexity.svg +0 -14
- package/assets/insights/metrics-contributions.svg +0 -14
- package/assets/insights/metrics-expertise.svg +0 -14
- package/assets/insights/metrics-languages.svg +0 -14
- package/assets/insights/metrics-pulse.svg +0 -14
- package/examples/classic/metrics-calendar.svg +0 -14
- package/examples/classic/metrics-complexity.svg +0 -14
- package/examples/classic/metrics-contributions.svg +0 -14
- package/examples/classic/metrics-expertise.svg +0 -14
- package/examples/classic/metrics-languages.svg +0 -14
- package/examples/classic/metrics-pulse.svg +0 -14
- package/examples/ecosystem/metrics-calendar.svg +0 -14
- package/examples/ecosystem/metrics-complexity.svg +0 -14
- package/examples/ecosystem/metrics-contributions.svg +0 -14
- package/examples/ecosystem/metrics-expertise.svg +0 -14
- package/examples/ecosystem/metrics-languages.svg +0 -14
- package/examples/ecosystem/metrics-pulse.svg +0 -14
- package/examples/minimal/metrics-calendar.svg +0 -14
- package/examples/minimal/metrics-complexity.svg +0 -14
- package/examples/minimal/metrics-contributions.svg +0 -14
- package/examples/minimal/metrics-expertise.svg +0 -14
- package/examples/minimal/metrics-languages.svg +0 -14
- package/examples/minimal/metrics-pulse.svg +0 -14
- package/examples/modern/metrics-calendar.svg +0 -14
- package/examples/modern/metrics-complexity.svg +0 -14
- package/examples/modern/metrics-contributions.svg +0 -14
- package/examples/modern/metrics-expertise.svg +0 -14
- package/examples/modern/metrics-languages.svg +0 -14
- package/examples/modern/metrics-pulse.svg +0 -14
- package/src/components/bar-chart.test.tsx +0 -38
- package/src/components/bar-chart.tsx +0 -54
- package/src/components/contribution-calendar.test.tsx +0 -44
- package/src/components/contribution-calendar.tsx +0 -94
- package/src/components/contribution-cards.test.tsx +0 -36
- package/src/components/contribution-cards.tsx +0 -58
- package/src/components/donut-chart.test.tsx +0 -36
- package/src/components/donut-chart.tsx +0 -102
- package/src/components/project-cards.test.tsx +0 -46
- package/src/components/project-cards.tsx +0 -66
- package/src/components/stat-cards.test.tsx +0 -32
- package/src/components/stat-cards.tsx +0 -57
- package/src/components/tech-highlights.test.tsx +0 -63
- package/src/components/tech-highlights.tsx +0 -109
- package/teasr.toml +0 -14
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="808" height="340" viewBox="0 0 808 340"><defs><style>
|
|
2
|
+
.t { font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; font-variant-numeric: tabular-lining; }
|
|
3
|
+
.t-h { font-size: 14px; fill: #c9d1d9; letter-spacing: 2px; font-weight: 600; }
|
|
4
|
+
.t-sub { font-size: 11px; fill: #6e7681; }
|
|
5
|
+
.t-label { font-size: 12px; fill: #8b949e; }
|
|
6
|
+
.t-value { font-size: 11px; fill: #6e7681; }
|
|
7
|
+
.t-subhdr { font-size: 11px; fill: #8b949e; letter-spacing: 1px; font-weight: 600; }
|
|
8
|
+
.t-stat-label { font-size: 10px; fill: #8b949e; font-weight: 600; }
|
|
9
|
+
.t-stat-value { font-size: 22px; font-weight: 700; }
|
|
10
|
+
.t-card-title { font-size: 12px; fill: #58a6ff; font-weight: 700; }
|
|
11
|
+
.t-card-detail { font-size: 11px; fill: #8b949e; }
|
|
12
|
+
.t-pill { font-size: 11px; font-weight: 600; }
|
|
13
|
+
.t-bullet { font-size: 12px; fill: #c9d1d9; }
|
|
14
|
+
.bg-fill { fill: #0d1117; }
|
|
15
|
+
.card-fill { fill: #161b22; }
|
|
16
|
+
.border-stroke { stroke: #30363d; }
|
|
17
|
+
|
|
18
|
+
@media (prefers-color-scheme: light) {
|
|
19
|
+
.bg-fill { fill: #ffffff; }
|
|
20
|
+
.card-fill { fill: #f6f8fa; }
|
|
21
|
+
.border-stroke { stroke: #d0d7de; }
|
|
22
|
+
.t-h { fill: #1f2328; }
|
|
23
|
+
.t-sub { fill: #656d76; }
|
|
24
|
+
.t-label { fill: #656d76; }
|
|
25
|
+
.t-value { fill: #656d76; }
|
|
26
|
+
.t-subhdr { fill: #656d76; }
|
|
27
|
+
.t-stat-label { fill: #656d76; }
|
|
28
|
+
.t-card-title { fill: #0969da; }
|
|
29
|
+
.t-card-detail { fill: #656d76; }
|
|
30
|
+
.t-bullet { fill: #1f2328; }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@keyframes fadeIn {
|
|
34
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
35
|
+
to { opacity: 1; transform: translateY(0); }
|
|
36
|
+
}
|
|
37
|
+
@keyframes scaleIn {
|
|
38
|
+
from { transform: scale(0); opacity: 0; }
|
|
39
|
+
to { transform: scale(1); opacity: 1; }
|
|
40
|
+
}
|
|
41
|
+
@keyframes drawPath {
|
|
42
|
+
from { stroke-dashoffset: var(--path-length); }
|
|
43
|
+
to { stroke-dashoffset: 0; }
|
|
44
|
+
}
|
|
45
|
+
@keyframes radarReveal {
|
|
46
|
+
from { transform: scale(0); opacity: 0; }
|
|
47
|
+
to { transform: scale(1); opacity: 0.6; }
|
|
48
|
+
}
|
|
49
|
+
.fade-1 { animation: fadeIn 0.6s ease-out 0.1s both; }
|
|
50
|
+
.fade-2 { animation: fadeIn 0.6s ease-out 0.25s both; }
|
|
51
|
+
.fade-3 { animation: fadeIn 0.6s ease-out 0.4s both; }
|
|
52
|
+
.fade-4 { animation: fadeIn 0.6s ease-out 0.55s both; }
|
|
53
|
+
.fade-5 { animation: fadeIn 0.6s ease-out 0.7s both; }
|
|
54
|
+
.fade-6 { animation: fadeIn 0.6s ease-out 0.85s both; }
|
|
55
|
+
</style></defs><rect width="808" height="340" rx="12" class="bg-fill" fill="#0d1117"/><text x="24" y="40" class="t t-h">CONTRIBUTION RHYTHM</text><text x="24" y="56" class="t t-sub">Activity patterns and statistics over the past year</text><circle cx="144" cy="186" r="22.5" fill="none" stroke="#30363d" stroke-width="1" stroke-opacity="0.4"/><circle cx="144" cy="186" r="45" fill="none" stroke="#30363d" stroke-width="1" stroke-opacity="0.4"/><circle cx="144" cy="186" r="67.5" fill="none" stroke="#30363d" stroke-width="1" stroke-opacity="0.4"/><circle cx="144" cy="186" r="90" fill="none" stroke="#30363d" stroke-width="1" stroke-opacity="0.4"/><line x1="144" y1="186" x2="144" y2="96" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="214.36483342212267" y2="129.88591783271397" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="231.74351209636413" y2="206.0268840560683" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="183.04953652058023" y2="267.08719811121773" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="104.95046347941977" y2="267.08719811121773" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="56.25648790363587" y2="206.0268840560683" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><line x1="144" y1="186" x2="73.63516657787731" y2="129.885917832714" stroke="#30363d" stroke-width="1" stroke-opacity="0.3"/><polygon points="144,160.02272727272728 176.46377541975204,160.11100300009304 172.11780728542578,192.41770602705824 154.91612043643494,208.66755765381768 132.551385883739,209.7732921735161 56.25648790363587,206.0268840560683 96.18389728814844,147.86793052723064" fill="#58a6ff" fill-opacity="0.2" stroke="#58a6ff" stroke-width="2" stroke-opacity="0.8" class="fade-2" style="transform-origin: 144px 186px"/><circle cx="144" cy="160.02272727272728" r="3" fill="#58a6ff" class="fade-1"/><circle cx="176.46377541975204" cy="160.11100300009304" r="3" fill="#58a6ff" class="fade-2"/><circle cx="172.11780728542578" cy="192.41770602705824" r="3" fill="#58a6ff" class="fade-3"/><circle cx="154.91612043643494" cy="208.66755765381768" r="3" fill="#58a6ff" class="fade-4"/><circle cx="132.551385883739" cy="209.7732921735161" r="3" fill="#58a6ff" class="fade-5"/><circle cx="56.25648790363587" cy="206.0268840560683" r="3" fill="#58a6ff" class="fade-6"/><circle cx="96.18389728814844" cy="147.86793052723064" r="3" fill="#58a6ff" class="fade-6"/><text x="144" y="84" class="t t-value" text-anchor="middle">Sun</text><text x="226.87413714161116" y="123.91008100297425" class="t t-value" text-anchor="middle">Mon</text><text x="247.34235869127332" y="213.58721899936933" class="t t-value" text-anchor="middle">Tue</text><text x="189.99167634646116" y="285.50269999765646" class="t t-value" text-anchor="middle">Wed</text><text x="98.00832365353884" y="285.50269999765646" class="t t-value" text-anchor="middle">Thu</text><text x="40.657641308726696" y="213.58721899936933" class="t t-value" text-anchor="middle">Fri</text><text x="61.12586285838883" y="123.91008100297427" class="t t-value" text-anchor="middle">Sat</text><text x="324" y="96" class="t t-stat-label">COMMITS</text><text x="324" y="118" fill="#58a6ff" class="t t-stat-value">1,352</text><text x="324" y="138" class="t t-stat-label">PRS</text><text x="324" y="160" fill="#3fb950" class="t t-stat-value">4</text><text x="324" y="180" class="t t-stat-label">REVIEWS</text><text x="324" y="202" fill="#d29922" class="t t-stat-value">5</text><text x="324" y="222" class="t t-stat-label">REPOS</text><text x="324" y="244" fill="#bc8cff" class="t t-stat-value">24</text><text x="324" y="264" class="t t-stat-label">STREAK</text><text x="324" y="286" fill="#39d2c0" class="t t-stat-value">15d</text><text x="324" y="316" class="t t-sub">Most active: Fridays</text></svg>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="808" height="250" viewBox="0 0 808 250"><defs><style>
|
|
2
|
+
.t { font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; font-variant-numeric: tabular-lining; }
|
|
3
|
+
.t-h { font-size: 14px; fill: #c9d1d9; letter-spacing: 2px; font-weight: 600; }
|
|
4
|
+
.t-sub { font-size: 11px; fill: #6e7681; }
|
|
5
|
+
.t-label { font-size: 12px; fill: #8b949e; }
|
|
6
|
+
.t-value { font-size: 11px; fill: #6e7681; }
|
|
7
|
+
.t-subhdr { font-size: 11px; fill: #8b949e; letter-spacing: 1px; font-weight: 600; }
|
|
8
|
+
.t-stat-label { font-size: 10px; fill: #8b949e; font-weight: 600; }
|
|
9
|
+
.t-stat-value { font-size: 22px; font-weight: 700; }
|
|
10
|
+
.t-card-title { font-size: 12px; fill: #58a6ff; font-weight: 700; }
|
|
11
|
+
.t-card-detail { font-size: 11px; fill: #8b949e; }
|
|
12
|
+
.t-pill { font-size: 11px; font-weight: 600; }
|
|
13
|
+
.t-bullet { font-size: 12px; fill: #c9d1d9; }
|
|
14
|
+
.bg-fill { fill: #0d1117; }
|
|
15
|
+
.card-fill { fill: #161b22; }
|
|
16
|
+
.border-stroke { stroke: #30363d; }
|
|
17
|
+
|
|
18
|
+
@media (prefers-color-scheme: light) {
|
|
19
|
+
.bg-fill { fill: #ffffff; }
|
|
20
|
+
.card-fill { fill: #f6f8fa; }
|
|
21
|
+
.border-stroke { stroke: #d0d7de; }
|
|
22
|
+
.t-h { fill: #1f2328; }
|
|
23
|
+
.t-sub { fill: #656d76; }
|
|
24
|
+
.t-label { fill: #656d76; }
|
|
25
|
+
.t-value { fill: #656d76; }
|
|
26
|
+
.t-subhdr { fill: #656d76; }
|
|
27
|
+
.t-stat-label { fill: #656d76; }
|
|
28
|
+
.t-card-title { fill: #0969da; }
|
|
29
|
+
.t-card-detail { fill: #656d76; }
|
|
30
|
+
.t-bullet { fill: #1f2328; }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@keyframes fadeIn {
|
|
34
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
35
|
+
to { opacity: 1; transform: translateY(0); }
|
|
36
|
+
}
|
|
37
|
+
@keyframes scaleIn {
|
|
38
|
+
from { transform: scale(0); opacity: 0; }
|
|
39
|
+
to { transform: scale(1); opacity: 1; }
|
|
40
|
+
}
|
|
41
|
+
@keyframes drawPath {
|
|
42
|
+
from { stroke-dashoffset: var(--path-length); }
|
|
43
|
+
to { stroke-dashoffset: 0; }
|
|
44
|
+
}
|
|
45
|
+
@keyframes radarReveal {
|
|
46
|
+
from { transform: scale(0); opacity: 0; }
|
|
47
|
+
to { transform: scale(1); opacity: 0.6; }
|
|
48
|
+
}
|
|
49
|
+
.fade-1 { animation: fadeIn 0.6s ease-out 0.1s both; }
|
|
50
|
+
.fade-2 { animation: fadeIn 0.6s ease-out 0.25s both; }
|
|
51
|
+
.fade-3 { animation: fadeIn 0.6s ease-out 0.4s both; }
|
|
52
|
+
.fade-4 { animation: fadeIn 0.6s ease-out 0.55s both; }
|
|
53
|
+
.fade-5 { animation: fadeIn 0.6s ease-out 0.7s both; }
|
|
54
|
+
.fade-6 { animation: fadeIn 0.6s ease-out 0.85s both; }
|
|
55
|
+
</style></defs><rect width="808" height="250" rx="12" class="bg-fill" fill="#0d1117"/><text x="24" y="40" class="t t-h">LANGUAGE VELOCITY</text><text x="24" y="56" class="t t-sub">How language usage has evolved over the past year</text><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.24865831842575 150.66666666666669,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,204.4973166368515 214,204.4973166368515 C 245.66666666666669,204.4973166368515 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,195.98211091234347 404,195.98211091234347 C 435.6666666666667,195.98211091234347 435.6666666666667,203.9964221824687 467.33333333333337,203.9964221824687 C 499.00000000000006,203.9964221824687 499.00000000000006,198.23613595706618 530.6666666666667,198.23613595706618 C 562.3333333333334,198.23613595706618 562.3333333333334,204.4973166368515 594,204.4973166368515 C 625.6666666666667,204.4973166368515 625.6666666666667,157.66368515205724 657.3333333333334,157.66368515205724 C 689,157.66368515205724 689,87.28801431127013 720.6666666666667,87.28801431127013 C 752.3333333333334,87.28801431127013 752.3333333333334,66 784,66 L 784,67.25223613595705 C 752.3333333333334,67.25223613595705 752.3333333333334,88.28980322003578 720.6666666666667,88.28980322003578 C 689,88.28980322003578 689,158.16457960644007 657.3333333333334,158.16457960644007 C 625.6666666666667,158.16457960644007 625.6666666666667,204.4973166368515 594,204.4973166368515 C 562.3333333333334,204.4973166368515 562.3333333333334,198.23613595706618 530.6666666666667,198.23613595706618 C 499.00000000000006,198.23613595706618 499.00000000000006,203.9964221824687 467.33333333333337,203.9964221824687 C 435.6666666666667,203.9964221824687 435.6666666666667,195.98211091234347 404,195.98211091234347 C 372.33333333333337,195.98211091234347 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.49910554561717 277.33333333333337,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,204.4973166368515 214,204.4973166368515 C 182.33333333333334,204.4973166368515 182.33333333333334,205.24865831842575 150.66666666666669,205.24865831842575 C 119.00000000000001,205.24865831842575 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#DA5B0B" fill-opacity="0.75" class="fade-1"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.24865831842575 150.66666666666669,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,204.4973166368515 214,204.4973166368515 C 245.66666666666669,204.4973166368515 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,195.98211091234347 404,195.98211091234347 C 435.6666666666667,195.98211091234347 435.6666666666667,203.9964221824687 467.33333333333337,203.9964221824687 C 499.00000000000006,203.9964221824687 499.00000000000006,198.23613595706618 530.6666666666667,198.23613595706618 C 562.3333333333334,198.23613595706618 562.3333333333334,204.4973166368515 594,204.4973166368515 C 625.6666666666667,204.4973166368515 625.6666666666667,158.16457960644007 657.3333333333334,158.16457960644007 C 689,158.16457960644007 689,88.28980322003578 720.6666666666667,88.28980322003578 C 752.3333333333334,88.28980322003578 752.3333333333334,67.25223613595705 784,67.25223613595705 L 784,72.76207513416816 C 752.3333333333334,72.76207513416816 752.3333333333334,93.04830053667264 720.6666666666667,93.04830053667264 C 689,93.04830053667264 689,160.16815742397137 657.3333333333334,160.16815742397137 C 625.6666666666667,160.16815742397137 625.6666666666667,204.4973166368515 594,204.4973166368515 C 562.3333333333334,204.4973166368515 562.3333333333334,198.4865831842576 530.6666666666667,198.4865831842576 C 499.00000000000006,198.4865831842576 499.00000000000006,203.9964221824687 467.33333333333337,203.9964221824687 C 435.6666666666667,203.9964221824687 435.6666666666667,196.4830053667263 404,196.4830053667263 C 372.33333333333337,196.4830053667263 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.49910554561717 277.33333333333337,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,204.4973166368515 214,204.4973166368515 C 182.33333333333334,204.4973166368515 182.33333333333334,205.24865831842575 150.66666666666669,205.24865831842575 C 119.00000000000001,205.24865831842575 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#b07219" fill-opacity="0.75" class="fade-2"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.24865831842575 150.66666666666669,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,204.4973166368515 214,204.4973166368515 C 245.66666666666669,204.4973166368515 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,196.4830053667263 404,196.4830053667263 C 435.6666666666667,196.4830053667263 435.6666666666667,203.9964221824687 467.33333333333337,203.9964221824687 C 499.00000000000006,203.9964221824687 499.00000000000006,198.4865831842576 530.6666666666667,198.4865831842576 C 562.3333333333334,198.4865831842576 562.3333333333334,204.4973166368515 594,204.4973166368515 C 625.6666666666667,204.4973166368515 625.6666666666667,160.16815742397137 657.3333333333334,160.16815742397137 C 689,160.16815742397137 689,93.04830053667264 720.6666666666667,93.04830053667264 C 752.3333333333334,93.04830053667264 752.3333333333334,72.76207513416816 784,72.76207513416816 L 784,87.28801431127013 C 752.3333333333334,87.28801431127013 752.3333333333334,105.32021466905186 720.6666666666667,105.32021466905186 C 689,105.32021466905186 689,165.17710196779964 657.3333333333334,165.17710196779964 C 625.6666666666667,165.17710196779964 625.6666666666667,204.74776386404292 594,204.74776386404292 C 562.3333333333334,204.74776386404292 562.3333333333334,199.23792486583184 530.6666666666667,199.23792486583184 C 499.00000000000006,199.23792486583184 499.00000000000006,204.24686940966012 467.33333333333337,204.24686940966012 C 435.6666666666667,204.24686940966012 435.6666666666667,197.48479427549194 404,197.48479427549194 C 372.33333333333337,197.48479427549194 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.49910554561717 277.33333333333337,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,204.74776386404292 214,204.74776386404292 C 182.33333333333334,204.74776386404292 182.33333333333334,205.24865831842575 150.66666666666669,205.24865831842575 C 119.00000000000001,205.24865831842575 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#3572A5" fill-opacity="0.75" class="fade-3"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.24865831842575 150.66666666666669,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,204.74776386404292 214,204.74776386404292 C 245.66666666666669,204.74776386404292 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,197.48479427549194 404,197.48479427549194 C 435.6666666666667,197.48479427549194 435.6666666666667,204.24686940966012 467.33333333333337,204.24686940966012 C 499.00000000000006,204.24686940966012 499.00000000000006,199.23792486583184 530.6666666666667,199.23792486583184 C 562.3333333333334,199.23792486583184 562.3333333333334,204.74776386404292 594,204.74776386404292 C 625.6666666666667,204.74776386404292 625.6666666666667,165.17710196779964 657.3333333333334,165.17710196779964 C 689,165.17710196779964 689,105.32021466905186 720.6666666666667,105.32021466905186 C 752.3333333333334,105.32021466905186 752.3333333333334,87.28801431127013 784,87.28801431127013 L 784,103.8175313059034 C 752.3333333333334,103.8175313059034 752.3333333333334,119.34525939177102 720.6666666666667,119.34525939177102 C 689,119.34525939177102 689,170.93738819320214 657.3333333333334,170.93738819320214 C 625.6666666666667,170.93738819320214 625.6666666666667,204.99821109123434 594,204.99821109123434 C 562.3333333333334,204.99821109123434 562.3333333333334,200.2397137745975 530.6666666666667,200.2397137745975 C 499.00000000000006,200.2397137745975 499.00000000000006,204.4973166368515 467.33333333333337,204.4973166368515 C 435.6666666666667,204.4973166368515 435.6666666666667,198.737030411449 404,198.737030411449 C 372.33333333333337,198.737030411449 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.49910554561717 277.33333333333337,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,204.99821109123434 214,204.99821109123434 C 182.33333333333334,204.99821109123434 182.33333333333334,205.24865831842575 150.66666666666669,205.24865831842575 C 119.00000000000001,205.24865831842575 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#00ADD8" fill-opacity="0.75" class="fade-4"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.24865831842575 150.66666666666669,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,204.99821109123434 214,204.99821109123434 C 245.66666666666669,204.99821109123434 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,198.737030411449 404,198.737030411449 C 435.6666666666667,198.737030411449 435.6666666666667,204.4973166368515 467.33333333333337,204.4973166368515 C 499.00000000000006,204.4973166368515 499.00000000000006,200.2397137745975 530.6666666666667,200.2397137745975 C 562.3333333333334,200.2397137745975 562.3333333333334,204.99821109123434 594,204.99821109123434 C 625.6666666666667,204.99821109123434 625.6666666666667,170.93738819320214 657.3333333333334,170.93738819320214 C 689,170.93738819320214 689,119.34525939177102 720.6666666666667,119.34525939177102 C 752.3333333333334,119.34525939177102 752.3333333333334,103.8175313059034 784,103.8175313059034 L 784,124.35420393559927 C 752.3333333333334,124.35420393559927 752.3333333333334,136.87656529516994 720.6666666666667,136.87656529516994 C 689,136.87656529516994 689,177.9499105545617 657.3333333333334,177.9499105545617 C 625.6666666666667,177.9499105545617 625.6666666666667,205.24865831842575 594,205.24865831842575 C 562.3333333333334,205.24865831842575 562.3333333333334,201.49194991055455 530.6666666666667,201.49194991055455 C 499.00000000000006,201.49194991055455 499.00000000000006,204.74776386404292 467.33333333333337,204.74776386404292 C 435.6666666666667,204.74776386404292 435.6666666666667,200.2397137745975 404,200.2397137745975 C 372.33333333333337,200.2397137745975 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.49910554561717 277.33333333333337,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,205.24865831842575 214,205.24865831842575 C 182.33333333333334,205.24865831842575 182.33333333333334,205.49910554561717 150.66666666666669,205.49910554561717 C 119.00000000000001,205.49910554561717 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#89e051" fill-opacity="0.75" class="fade-5"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.49910554561717 150.66666666666669,205.49910554561717 C 182.33333333333334,205.49910554561717 182.33333333333334,205.24865831842575 214,205.24865831842575 C 245.66666666666669,205.24865831842575 245.66666666666669,205.49910554561717 277.33333333333337,205.49910554561717 C 309,205.49910554561717 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,200.2397137745975 404,200.2397137745975 C 435.6666666666667,200.2397137745975 435.6666666666667,204.74776386404292 467.33333333333337,204.74776386404292 C 499.00000000000006,204.74776386404292 499.00000000000006,201.49194991055455 530.6666666666667,201.49194991055455 C 562.3333333333334,201.49194991055455 562.3333333333334,205.24865831842575 594,205.24865831842575 C 625.6666666666667,205.24865831842575 625.6666666666667,177.9499105545617 657.3333333333334,177.9499105545617 C 689,177.9499105545617 689,136.87656529516994 720.6666666666667,136.87656529516994 C 752.3333333333334,136.87656529516994 752.3333333333334,124.35420393559927 784,124.35420393559927 L 784,156.912343470483 C 752.3333333333334,156.912343470483 752.3333333333334,164.4257602862254 720.6666666666667,164.4257602862254 C 689,164.4257602862254 689,189.22003577817532 657.3333333333334,189.22003577817532 C 625.6666666666667,189.22003577817532 625.6666666666667,205.49910554561717 594,205.49910554561717 C 562.3333333333334,205.49910554561717 562.3333333333334,203.24508050089446 530.6666666666667,203.24508050089446 C 499.00000000000006,203.24508050089446 499.00000000000006,205.24865831842575 467.33333333333337,205.24865831842575 C 435.6666666666667,205.24865831842575 435.6666666666667,202.4937388193202 404,202.4937388193202 C 372.33333333333337,202.4937388193202 372.33333333333337,206 340.6666666666667,206 C 309,206 309,205.74955277280858 277.33333333333337,205.74955277280858 C 245.66666666666669,205.74955277280858 245.66666666666669,205.49910554561717 214,205.49910554561717 C 182.33333333333334,205.49910554561717 182.33333333333334,205.74955277280858 150.66666666666669,205.74955277280858 C 119.00000000000001,205.74955277280858 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#3178c6" fill-opacity="0.75" class="fade-6"/><path d="M 24,206 C 55.66666666666667,206 55.66666666666667,206 87.33333333333334,206 C 119.00000000000001,206 119.00000000000001,205.74955277280858 150.66666666666669,205.74955277280858 C 182.33333333333334,205.74955277280858 182.33333333333334,205.49910554561717 214,205.49910554561717 C 245.66666666666669,205.49910554561717 245.66666666666669,205.74955277280858 277.33333333333337,205.74955277280858 C 309,205.74955277280858 309,206 340.6666666666667,206 C 372.33333333333337,206 372.33333333333337,202.4937388193202 404,202.4937388193202 C 435.6666666666667,202.4937388193202 435.6666666666667,205.24865831842575 467.33333333333337,205.24865831842575 C 499.00000000000006,205.24865831842575 499.00000000000006,203.24508050089446 530.6666666666667,203.24508050089446 C 562.3333333333334,203.24508050089446 562.3333333333334,205.49910554561717 594,205.49910554561717 C 625.6666666666667,205.49910554561717 625.6666666666667,189.22003577817532 657.3333333333334,189.22003577817532 C 689,189.22003577817532 689,164.4257602862254 720.6666666666667,164.4257602862254 C 752.3333333333334,164.4257602862254 752.3333333333334,156.912343470483 784,156.912343470483 L 784,206 C 752.3333333333334,206 752.3333333333334,206 720.6666666666667,206 C 689,206 689,206 657.3333333333334,206 C 625.6666666666667,206 625.6666666666667,206 594,206 C 562.3333333333334,206 562.3333333333334,206 530.6666666666667,206 C 499.00000000000006,206 499.00000000000006,206 467.33333333333337,206 C 435.6666666666667,206 435.6666666666667,206 404,206 C 372.33333333333337,206 372.33333333333337,206 340.6666666666667,206 C 309,206 309,206 277.33333333333337,206 C 245.66666666666669,206 245.66666666666669,206 214,206 C 182.33333333333334,206 182.33333333333334,206 150.66666666666669,206 C 119.00000000000001,206 119.00000000000001,206 87.33333333333334,206 C 55.66666666666667,206 55.66666666666667,206 24,206 Z" fill="#dea584" fill-opacity="0.75" class="fade-6"/><rect x="24" y="212" width="8" height="8" rx="2" fill="#dea584" opacity="0.85"/><text x="36" y="220" class="t t-value">Rust</text><rect x="80" y="212" width="8" height="8" rx="2" fill="#3178c6" opacity="0.85"/><text x="92" y="220" class="t t-value">TypeScript</text><rect x="178" y="212" width="8" height="8" rx="2" fill="#89e051" opacity="0.85"/><text x="190" y="220" class="t t-value">Shell</text><rect x="241" y="212" width="8" height="8" rx="2" fill="#00ADD8" opacity="0.85"/><text x="253" y="220" class="t t-value">Go</text><rect x="283" y="212" width="8" height="8" rx="2" fill="#3572A5" opacity="0.85"/><text x="295" y="220" class="t t-value">Python</text><rect x="353" y="212" width="8" height="8" rx="2" fill="#b07219" opacity="0.85"/><text x="365" y="220" class="t t-value">Java</text><rect x="409" y="212" width="8" height="8" rx="2" fill="#DA5B0B" opacity="0.85"/><text x="421" y="220" class="t t-value">Jupyter Notebook</text><text x="24" y="220" class="t t-value" text-anchor="start" opacity="0">Feb</text><text x="150.66666666666669" y="220" class="t t-value" text-anchor="start" opacity="0">Apr</text><text x="277.33333333333337" y="220" class="t t-value" text-anchor="start" opacity="0">Jun</text><text x="404" y="220" class="t t-value" text-anchor="start" opacity="0">Aug</text><text x="530.6666666666667" y="220" class="t t-value" text-anchor="start" opacity="0">Oct</text><text x="657.3333333333334" y="220" class="t t-value" text-anchor="start" opacity="0">Dec</text><text x="784" y="220" class="t t-value" text-anchor="start" opacity="0">Feb</text></svg>
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# GitHub
|
|
1
|
+
# GitHub Insights
|
|
2
2
|
|
|
3
|
-
> A GitHub Action that generates beautiful SVG metrics visualizations for GitHub profile READMEs. Produces language
|
|
3
|
+
> A GitHub Action that generates beautiful SVG metrics visualizations for GitHub profile READMEs. Produces language velocity streamgraphs, contribution rhythm radar charts, project constellation maps, open source impact trails, AI-powered project classification, social badges, and an auto-generated profile introduction. SVGs support light/dark theme switching and CSS animations. Built with TypeScript/Node.js using JSX for SVG string rendering.
|
|
4
4
|
|
|
5
5
|
## Docs
|
|
6
6
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
- [src/index.ts](https://github.com/urmzd/github-insights/blob/main/src/index.ts): Main action entry point
|
|
15
15
|
- [src/api.ts](https://github.com/urmzd/github-insights/blob/main/src/api.ts): GitHub GraphQL/REST API calls + AI model calls
|
|
16
|
-
- [src/metrics.ts](https://github.com/urmzd/github-insights/blob/main/src/metrics.ts): Data aggregation
|
|
16
|
+
- [src/metrics.ts](https://github.com/urmzd/github-insights/blob/main/src/metrics.ts): Data aggregation, velocity/rhythm/constellation computation, section definitions
|
|
17
17
|
- [src/types.ts](https://github.com/urmzd/github-insights/blob/main/src/types.ts): Shared type definitions (UserConfig, SectionDef, etc.)
|
|
18
|
-
- [src/components/](https://github.com/urmzd/github-insights/blob/main/src/components/): SVG rendering components (
|
|
18
|
+
- [src/components/](https://github.com/urmzd/github-insights/blob/main/src/components/): SVG rendering components (streamgraph, radar chart, constellation, impact trail)
|
|
19
19
|
- [action.yml](https://github.com/urmzd/github-insights/blob/main/action.yml): GitHub Action definition
|
|
20
20
|
|
|
21
21
|
## Optional
|
package/package.json
CHANGED
|
@@ -8,9 +8,9 @@ description: >-
|
|
|
8
8
|
argument-hint: [setup | customize | generate | debug | extend]
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
# GitHub
|
|
11
|
+
# GitHub Insights — Agent Skill
|
|
12
12
|
|
|
13
|
-
Generate beautiful
|
|
13
|
+
Generate beautiful SVG metrics for GitHub profile READMEs. Sections include language velocity streamgraph, contribution rhythm radar chart, project constellation map, and open source impact trail. SVGs support light/dark theme switching and CSS animations.
|
|
14
14
|
|
|
15
15
|
## Quick Reference
|
|
16
16
|
|
|
@@ -18,7 +18,7 @@ Generate beautiful dark-themed SVG metrics for GitHub profile READMEs. Sections
|
|
|
18
18
|
|------|---------|
|
|
19
19
|
| Generate locally | `npm run generate` (requires `gh auth login`) |
|
|
20
20
|
| Full CI check | `npm run ci` (fmt + lint + typecheck + test + build) |
|
|
21
|
-
| Build bundle | `npm run build` (ncc
|
|
21
|
+
| Build bundle | `npm run build` (ncc -> `dist/`) |
|
|
22
22
|
| Run tests | `npm test` (vitest) |
|
|
23
23
|
| Type-check | `npm run typecheck` |
|
|
24
24
|
| Lint | `npm run lint` (biome) |
|
|
@@ -66,8 +66,7 @@ npm run generate
|
|
|
66
66
|
Local mode differences:
|
|
67
67
|
- `commit-push` defaults to `false` (no git operations)
|
|
68
68
|
- README writes to `_README.md` (not `README.md`)
|
|
69
|
-
- All
|
|
70
|
-
- Both preamble variants (full + short) are generated for preview
|
|
69
|
+
- All four template previews are generated in `examples/{classic,modern,minimal,ecosystem}/`
|
|
71
70
|
|
|
72
71
|
## Configuration
|
|
73
72
|
|
|
@@ -76,18 +75,16 @@ Local mode differences:
|
|
|
76
75
|
```yaml
|
|
77
76
|
name: Display Name # overrides GitHub profile name
|
|
78
77
|
pronunciation: pronunciation # shown as subscript in heading
|
|
79
|
-
title: Software Engineer # blockquote under heading
|
|
80
|
-
desired_title: Senior SWE # AI context only
|
|
78
|
+
title: Software Engineer # blockquote under heading
|
|
79
|
+
desired_title: Senior SWE # AI context only
|
|
81
80
|
bio: Short bio text. # footer text in classic template
|
|
82
81
|
preamble: PREAMBLE.md # path to custom preamble (bypasses AI generation)
|
|
83
|
-
template: classic # "classic" | "modern" | "minimal"
|
|
82
|
+
template: classic # "classic" | "modern" | "minimal" | "ecosystem"
|
|
84
83
|
sections:
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
- contributions
|
|
90
|
-
- calendar
|
|
84
|
+
- velocity
|
|
85
|
+
- rhythm
|
|
86
|
+
- constellation
|
|
87
|
+
- impact
|
|
91
88
|
```
|
|
92
89
|
|
|
93
90
|
### Action inputs
|
|
@@ -109,41 +106,38 @@ sections:
|
|
|
109
106
|
|
|
110
107
|
| Key | SVG filename | What it renders |
|
|
111
108
|
|-----|-------------|-----------------|
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `calendar` | `metrics-calendar.svg` | GitHub contribution heatmap (1 year) |
|
|
117
|
-
| `contributions` | `metrics-contributions.svg` | External repos contributed to |
|
|
109
|
+
| `velocity` | `metrics-velocity.svg` | Streamgraph of language usage over 12 months |
|
|
110
|
+
| `rhythm` | `metrics-rhythm.svg` | 7-spoke radar chart + contribution stats |
|
|
111
|
+
| `constellation` | `metrics-constellation.svg` | Project map by language and complexity |
|
|
112
|
+
| `impact` | `metrics-impact.svg` | External contributions with impact bars |
|
|
118
113
|
|
|
119
114
|
### Templates
|
|
120
115
|
|
|
121
|
-
- **`classic`** (default): Formal layout — `# Name`, blockquote title,
|
|
122
|
-
- **`modern`**: Friendly — `# Hi, I'm {firstName}
|
|
123
|
-
- **`minimal`**: Clean — `# {firstName}`,
|
|
116
|
+
- **`classic`** (default): Formal layout — `# Name`, blockquote title, preamble, social badges, SVG metrics, bio footer.
|
|
117
|
+
- **`modern`**: Friendly — `# Hi, I'm {firstName}`, projects by activity, Project Map, GitHub Stats, Impact.
|
|
118
|
+
- **`minimal`**: Clean — `# {firstName}`, preamble, social badges, SVG metrics.
|
|
119
|
+
- **`ecosystem`**: Categorized — projects by purpose (Developer Tools/SDKs/Applications/Research), Project Map, GitHub Stats, Impact.
|
|
124
120
|
|
|
125
121
|
## Architecture
|
|
126
122
|
|
|
127
123
|
### Execution flow
|
|
128
124
|
|
|
129
125
|
```
|
|
130
|
-
Inputs
|
|
126
|
+
Inputs -> Fetch (parallel) -> AI calls -> Transform -> Compute velocity/rhythm/constellation -> Render sections -> Write SVGs -> Generate README -> Commit
|
|
131
127
|
```
|
|
132
128
|
|
|
133
129
|
### Key source files
|
|
134
130
|
|
|
135
131
|
| File | Role |
|
|
136
132
|
|------|------|
|
|
137
|
-
| `src/index.ts` | Orchestration: fetch
|
|
133
|
+
| `src/index.ts` | Orchestration: fetch -> transform -> render -> write -> commit |
|
|
138
134
|
| `src/api.ts` | GitHub GraphQL queries + GitHub Models AI calls |
|
|
139
|
-
| `src/metrics.ts` | Data aggregation,
|
|
140
|
-
| `src/config.ts` | TOML config loading |
|
|
141
|
-
| `src/types.ts` | All TypeScript interfaces
|
|
142
|
-
| `src/templates.ts` |
|
|
143
|
-
| `src/theme.ts` | `THEME` colors, `LAYOUT` dimensions, `BAR_COLORS` palette |
|
|
144
|
-
| `src/
|
|
145
|
-
| `src/components/` | SVG rendering components (custom JSX → SVG strings) |
|
|
146
|
-
| `src/jsx-factory.ts` | Custom `h()` / `Fragment()` JSX runtime (no React) |
|
|
135
|
+
| `src/metrics.ts` | Data aggregation, velocity/rhythm/constellation computation, section building |
|
|
136
|
+
| `src/config.ts` | YAML/TOML config loading |
|
|
137
|
+
| `src/types.ts` | All TypeScript interfaces |
|
|
138
|
+
| `src/templates.ts` | Four README template functions + social badge builder |
|
|
139
|
+
| `src/theme.ts` | `THEME`/`THEME_LIGHT` colors, `LAYOUT` dimensions, `BAR_COLORS` palette |
|
|
140
|
+
| `src/components/` | SVG rendering components (custom JSX -> SVG strings) |
|
|
147
141
|
|
|
148
142
|
### Component rendering pattern
|
|
149
143
|
|
|
@@ -155,25 +149,6 @@ function renderXxx(data: ..., y: number): { svg: string; height: number }
|
|
|
155
149
|
|
|
156
150
|
Components return SVG string fragments and their rendered height. The `y` parameter is the vertical cursor; heights are accumulated to stack sections vertically.
|
|
157
151
|
|
|
158
|
-
### Theme constants (hardcoded in `src/theme.ts`)
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
THEME.bg = "#0d1117" (dark background)
|
|
162
|
-
THEME.cardBg = "#161b22" (card backgrounds)
|
|
163
|
-
THEME.border = "#30363d" (card borders)
|
|
164
|
-
THEME.link = "#58a6ff" (card titles - blue)
|
|
165
|
-
THEME.text = "#c9d1d9" (primary text)
|
|
166
|
-
THEME.secondary= "#8b949e" (labels)
|
|
167
|
-
THEME.muted = "#6e7681" (values)
|
|
168
|
-
|
|
169
|
-
LAYOUT.width = 808 (fixed SVG canvas width)
|
|
170
|
-
LAYOUT.padX = 24
|
|
171
|
-
LAYOUT.padY = 24
|
|
172
|
-
LAYOUT.sectionGap = 30
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
These are not configurable via inputs or TOML — changing them requires editing source.
|
|
176
|
-
|
|
177
152
|
## Extending
|
|
178
153
|
|
|
179
154
|
### Add a new section
|
|
@@ -183,16 +158,7 @@ These are not configurable via inputs or TOML — changing them requires editing
|
|
|
183
158
|
3. Add the section key to `SECTION_KEYS` map in `src/metrics.ts`
|
|
184
159
|
4. Add a `SectionDef` entry in the `buildSections()` function in `src/metrics.ts`
|
|
185
160
|
5. Fetch any new data needed in `src/index.ts`
|
|
186
|
-
6. Add a `*.test.
|
|
187
|
-
7. Update `action.yml` if new inputs are needed
|
|
188
|
-
|
|
189
|
-
### Add a new dependency parser
|
|
190
|
-
|
|
191
|
-
1. Implement `PackageParser` interface in `src/parsers.ts`:
|
|
192
|
-
```ts
|
|
193
|
-
{ filenames: string[]; parseDependencies(text: string): string[] }
|
|
194
|
-
```
|
|
195
|
-
2. Add it to the `PARSERS` array — it auto-registers in `PARSER_MAP`
|
|
161
|
+
6. Add a `*.test.tsx` file alongside the component
|
|
196
162
|
|
|
197
163
|
### Add a new README template
|
|
198
164
|
|
|
@@ -202,36 +168,24 @@ These are not configurable via inputs or TOML — changing them requires editing
|
|
|
202
168
|
|
|
203
169
|
## Troubleshooting
|
|
204
170
|
|
|
205
|
-
### "
|
|
206
|
-
The
|
|
207
|
-
- Token has `models: read` permission
|
|
208
|
-
- The workflow has `permissions: models: read`
|
|
209
|
-
- GitHub Models endpoint is reachable
|
|
171
|
+
### "Velocity section is flat"
|
|
172
|
+
The streamgraph distributes per-repo commits using the contribution calendar's monthly activity weights. If there's no calendar data, velocity will be empty.
|
|
210
173
|
|
|
211
|
-
### "
|
|
212
|
-
Only rendered when
|
|
174
|
+
### "Constellation section missing"
|
|
175
|
+
Only rendered when there are projects with language data. Ensure repos have detectable languages.
|
|
213
176
|
|
|
214
|
-
### "
|
|
215
|
-
Only rendered when the user has contributed to external (non-owned) repositories
|
|
177
|
+
### "Impact section missing"
|
|
178
|
+
Only rendered when the user has contributed to external (non-owned) repositories.
|
|
216
179
|
|
|
217
180
|
### AI preamble is empty or generic
|
|
218
181
|
- The AI call uses `gpt-4.1` via GitHub Models — it needs diverse profile data to generate good output
|
|
219
|
-
- Provide `title`
|
|
182
|
+
- Provide `title` in config for better results
|
|
220
183
|
- Create a custom `PREAMBLE.md` to bypass AI entirely
|
|
221
184
|
|
|
222
185
|
### Local generation fails
|
|
223
186
|
- Ensure `gh auth login` is done and `gh auth token` returns a valid token
|
|
224
187
|
- Ensure Node.js 22+ (`node --version`)
|
|
225
|
-
- The `GITHUB_TOKEN` and `GITHUB_REPOSITORY_OWNER` env vars are set automatically by `npm run generate` via `gh`
|
|
226
188
|
|
|
227
189
|
### SVG looks wrong after changes
|
|
228
190
|
- Run `npm run build` to rebuild the `dist/` bundle — the action runs `dist/index.js`, not source directly
|
|
229
191
|
- SVG width is fixed at 808px; all layout math depends on this
|
|
230
|
-
|
|
231
|
-
## Code Style Rules
|
|
232
|
-
|
|
233
|
-
- TypeScript strict mode, ES modules
|
|
234
|
-
- Biome for formatting and linting (not ESLint/Prettier)
|
|
235
|
-
- Tests colocated as `*.test.ts` / `*.test.tsx` alongside source
|
|
236
|
-
- Custom JSX factory (`h`, `Fragment`) — NOT React
|
|
237
|
-
- All AI calls and contribution fetches are non-fatal (catch → return empty)
|
package/sr.yaml
CHANGED
package/src/api.ts
CHANGED
|
@@ -7,7 +7,6 @@ import type {
|
|
|
7
7
|
RepoClassificationInput,
|
|
8
8
|
RepoClassificationOutput,
|
|
9
9
|
RepoNode,
|
|
10
|
-
TechHighlight,
|
|
11
10
|
UserConfig,
|
|
12
11
|
UserProfile,
|
|
13
12
|
} from "./types.js";
|
|
@@ -86,7 +85,7 @@ export const fetchAllRepoData = async (
|
|
|
86
85
|
{ username },
|
|
87
86
|
);
|
|
88
87
|
|
|
89
|
-
return data.user.repositories.nodes.filter((r) => !r.
|
|
88
|
+
return data.user.repositories.nodes.filter((r) => !r.isFork);
|
|
90
89
|
};
|
|
91
90
|
|
|
92
91
|
export const fetchManifestsForRepos = async (
|
|
@@ -320,7 +319,6 @@ export interface PreambleContext {
|
|
|
320
319
|
profile: UserProfile;
|
|
321
320
|
userConfig: UserConfig;
|
|
322
321
|
languages: { name: string; percent: string }[];
|
|
323
|
-
techHighlights: TechHighlight[];
|
|
324
322
|
activeProjects: ProjectItem[];
|
|
325
323
|
complexProjects: ProjectItem[];
|
|
326
324
|
}
|
|
@@ -330,21 +328,12 @@ export const fetchAIPreamble = async (
|
|
|
330
328
|
context: PreambleContext,
|
|
331
329
|
): Promise<string | undefined> => {
|
|
332
330
|
try {
|
|
333
|
-
const {
|
|
334
|
-
|
|
335
|
-
userConfig,
|
|
336
|
-
languages,
|
|
337
|
-
techHighlights,
|
|
338
|
-
activeProjects,
|
|
339
|
-
complexProjects,
|
|
340
|
-
} = context;
|
|
331
|
+
const { profile, userConfig, languages, activeProjects, complexProjects } =
|
|
332
|
+
context;
|
|
341
333
|
|
|
342
334
|
const langLines = languages
|
|
343
335
|
.map((l) => `- ${l.name}: ${l.percent}%`)
|
|
344
336
|
.join("\n");
|
|
345
|
-
const techLines = techHighlights
|
|
346
|
-
.map((h) => `- ${h.category}: ${h.items.join(", ")} (score: ${h.score})`)
|
|
347
|
-
.join("\n");
|
|
348
337
|
|
|
349
338
|
const formatProject = (p: ProjectItem): string => {
|
|
350
339
|
const langs = p.languages?.length ? ` [${p.languages.join(", ")}]` : "";
|
|
@@ -373,9 +362,6 @@ ${profileLines}
|
|
|
373
362
|
Languages (by code volume):
|
|
374
363
|
${langLines}
|
|
375
364
|
|
|
376
|
-
Expertise areas:
|
|
377
|
-
${techLines}
|
|
378
|
-
|
|
379
365
|
Most technically complex projects (by language diversity, codebase size, and depth):
|
|
380
366
|
${complexProjectLines || "None"}
|
|
381
367
|
|
|
@@ -474,130 +460,6 @@ Generate 1-2 sentences that:
|
|
|
474
460
|
}
|
|
475
461
|
};
|
|
476
462
|
|
|
477
|
-
export const fetchExpertiseAnalysis = async (
|
|
478
|
-
token: string,
|
|
479
|
-
languages: { name: string; percent: string }[],
|
|
480
|
-
allDeps: string[],
|
|
481
|
-
allTopics: string[],
|
|
482
|
-
repos: RepoNode[],
|
|
483
|
-
readmeMap: ReadmeMap,
|
|
484
|
-
userConfig: UserConfig = {},
|
|
485
|
-
): Promise<TechHighlight[]> => {
|
|
486
|
-
try {
|
|
487
|
-
const langLines = languages
|
|
488
|
-
.map((l) => `- ${l.name}: ${l.percent}%`)
|
|
489
|
-
.join("\n");
|
|
490
|
-
|
|
491
|
-
const repoSummaries = repos
|
|
492
|
-
.slice(0, 20)
|
|
493
|
-
.map((r) => {
|
|
494
|
-
const readme = readmeMap.get(r.name) || "";
|
|
495
|
-
const snippet = readme.slice(0, 500).replace(/\n/g, " ");
|
|
496
|
-
const desc = r.description || "";
|
|
497
|
-
return `- ${r.name}: ${desc} | ${snippet}`;
|
|
498
|
-
})
|
|
499
|
-
.join("\n");
|
|
500
|
-
|
|
501
|
-
const desiredTitle = userConfig.desired_title || userConfig.title;
|
|
502
|
-
let titleContext = "";
|
|
503
|
-
if (userConfig.title) {
|
|
504
|
-
titleContext = `\nDeveloper context:\n- Current title: ${userConfig.title}`;
|
|
505
|
-
if (desiredTitle && desiredTitle !== userConfig.title) {
|
|
506
|
-
titleContext += `\n- Desired title: ${desiredTitle}`;
|
|
507
|
-
}
|
|
508
|
-
titleContext += `\n- Tailor the expertise categories to highlight skills most relevant to ${desiredTitle}. Prioritize domains and technologies that align with this role.\n`;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const prompt = `You are analyzing a developer's GitHub profile to create a curated expertise showcase.
|
|
512
|
-
${titleContext}
|
|
513
|
-
Languages (by code volume):
|
|
514
|
-
${langLines}
|
|
515
|
-
|
|
516
|
-
Dependencies found across repositories:
|
|
517
|
-
${allDeps.join(", ")}
|
|
518
|
-
|
|
519
|
-
Repository topics:
|
|
520
|
-
${allTopics.join(", ")}
|
|
521
|
-
|
|
522
|
-
Repository descriptions and README excerpts:
|
|
523
|
-
${repoSummaries}
|
|
524
|
-
|
|
525
|
-
From this data, produce a curated expertise profile:
|
|
526
|
-
- Group the most notable technologies into 3-6 expertise categories
|
|
527
|
-
- Use domain-oriented category names (e.g., "Machine Learning", "Web Development", "DevOps", "Backend & APIs", "Data Science", "Systems Programming")
|
|
528
|
-
- Include 3-6 of the most relevant technologies/tools per category
|
|
529
|
-
- Normalize names to their common display form (e.g., "pg" → "PostgreSQL", "torch" → "PyTorch", "boto3" → "AWS SDK")
|
|
530
|
-
- Skip trivial utility libraries (lodash, uuid, etc.) that don't showcase meaningful expertise
|
|
531
|
-
- Only include categories where there's meaningful evidence of usage
|
|
532
|
-
- Assign each category a proficiency score from 0 to 100 based on evidence strength:
|
|
533
|
-
language code volume, dependency count, topic mentions, and README depth.
|
|
534
|
-
Use the full range (e.g. 80-95 for primary stack, 50-70 for secondary, 30-50 for minor).`;
|
|
535
|
-
|
|
536
|
-
const res = await fetchWithRetry(
|
|
537
|
-
"https://models.github.ai/inference/chat/completions",
|
|
538
|
-
{
|
|
539
|
-
method: "POST",
|
|
540
|
-
headers: {
|
|
541
|
-
Authorization: `bearer ${token}`,
|
|
542
|
-
"Content-Type": "application/json",
|
|
543
|
-
},
|
|
544
|
-
body: JSON.stringify({
|
|
545
|
-
model: "gpt-4.1",
|
|
546
|
-
messages: [{ role: "user", content: prompt }],
|
|
547
|
-
temperature: 0.1,
|
|
548
|
-
response_format: {
|
|
549
|
-
type: "json_schema",
|
|
550
|
-
json_schema: {
|
|
551
|
-
name: "tech_highlights",
|
|
552
|
-
strict: true,
|
|
553
|
-
schema: {
|
|
554
|
-
type: "object",
|
|
555
|
-
properties: {
|
|
556
|
-
highlights: {
|
|
557
|
-
type: "array",
|
|
558
|
-
items: {
|
|
559
|
-
type: "object",
|
|
560
|
-
properties: {
|
|
561
|
-
category: { type: "string" },
|
|
562
|
-
items: { type: "array", items: { type: "string" } },
|
|
563
|
-
score: { type: "number" },
|
|
564
|
-
},
|
|
565
|
-
required: ["category", "items", "score"],
|
|
566
|
-
additionalProperties: false,
|
|
567
|
-
},
|
|
568
|
-
},
|
|
569
|
-
},
|
|
570
|
-
required: ["highlights"],
|
|
571
|
-
additionalProperties: false,
|
|
572
|
-
},
|
|
573
|
-
},
|
|
574
|
-
},
|
|
575
|
-
}),
|
|
576
|
-
},
|
|
577
|
-
"Expertise",
|
|
578
|
-
);
|
|
579
|
-
|
|
580
|
-
if (!res?.ok) {
|
|
581
|
-
if (res) console.warn(`GitHub Models API error: ${res.status}`);
|
|
582
|
-
return [];
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
const json = (await res.json()) as {
|
|
586
|
-
choices?: { message?: { content?: string } }[];
|
|
587
|
-
};
|
|
588
|
-
const content = json.choices?.[0]?.message?.content || "{}";
|
|
589
|
-
const parsed = JSON.parse(content) as { highlights?: TechHighlight[] };
|
|
590
|
-
return (parsed.highlights || [])
|
|
591
|
-
.filter((h) => h.category && Array.isArray(h.items) && h.items.length > 0)
|
|
592
|
-
.map((h) => ({ ...h, score: Math.max(0, Math.min(100, h.score || 0)) }))
|
|
593
|
-
.sort((a, b) => b.score - a.score);
|
|
594
|
-
} catch (err: unknown) {
|
|
595
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
596
|
-
console.warn(`Expertise analysis failed (non-fatal): ${msg}`);
|
|
597
|
-
return [];
|
|
598
|
-
}
|
|
599
|
-
};
|
|
600
|
-
|
|
601
463
|
export const fetchProjectClassifications = async (
|
|
602
464
|
token: string,
|
|
603
465
|
repos: RepoClassificationInput[],
|