github-personality-analyser 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 +116 -0
- package/dist/ai/groq.d.ts +5 -0
- package/dist/ai/groq.d.ts.map +1 -0
- package/dist/ai/groq.js +103 -0
- package/dist/ai/groq.js.map +1 -0
- package/dist/analyser/prompt.d.ts +16 -0
- package/dist/analyser/prompt.d.ts.map +1 -0
- package/dist/analyser/prompt.js +222 -0
- package/dist/analyser/prompt.js.map +1 -0
- package/dist/github/fetcher.d.ts +59 -0
- package/dist/github/fetcher.d.ts.map +1 -0
- package/dist/github/fetcher.js +207 -0
- package/dist/github/fetcher.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# github-personality-analyser
|
|
2
|
+
|
|
3
|
+
> Analyse any GitHub user's developer personality using their public activity and AI (Groq + LLaMA 3.3).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install github-personality-analyser
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { analyseGitHubPersonality } from "github-personality-analyser";
|
|
15
|
+
|
|
16
|
+
const result = await analyseGitHubPersonality("torvalds", {
|
|
17
|
+
githubToken: "ghp_xxxxxxxxxxxxxxxxxxxx",
|
|
18
|
+
groqApiKey: "gsk_xxxxxxxxxxxxxxxxxxxx",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
console.log(result.archetype); // "The Ruthless Architect"
|
|
22
|
+
console.log(result.summary); // full personality summary
|
|
23
|
+
console.log(result.roastLine); // 😄
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API Keys
|
|
27
|
+
|
|
28
|
+
| Key | Where to get it | Free? |
|
|
29
|
+
|-----|----------------|-------|
|
|
30
|
+
| `githubToken` | [github.com](https://github.com) → Settings → Developer Settings → Personal Access Tokens | ✅ Yes |
|
|
31
|
+
| `groqApiKey` | [console.groq.com](https://console.groq.com) → API Keys | ✅ Yes |
|
|
32
|
+
|
|
33
|
+
## Functions
|
|
34
|
+
|
|
35
|
+
### `analyseGitHubPersonality(username, config)` — Full Pipeline
|
|
36
|
+
Fetches GitHub data and analyses personality in one call.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const result = await analyseGitHubPersonality("gaearon", {
|
|
40
|
+
githubToken: "...",
|
|
41
|
+
groqApiKey: "...",
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `getGitHubData(username, config)` — Data Only
|
|
46
|
+
Fetch only the raw GitHub data without AI analysis.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { getGitHubData } from "github-personality-analyser";
|
|
50
|
+
|
|
51
|
+
const data = await getGitHubData("sindresorhus", {
|
|
52
|
+
githubToken: "...",
|
|
53
|
+
groqApiKey: "...",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
console.log(data.mostUsedLanguage); // "JavaScript"
|
|
57
|
+
console.log(data.totalStarsReceived); // 50000
|
|
58
|
+
console.log(data.profile.followers); // 45000
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### `getPersonalityFromData(githubData, config)` — AI Only
|
|
62
|
+
Run AI analysis on already-fetched GitHub data. Useful if you want to cache the data and re-run analysis.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { getGitHubData, getPersonalityFromData } from "github-personality-analyser";
|
|
66
|
+
|
|
67
|
+
const data = await getGitHubData("username", config);
|
|
68
|
+
|
|
69
|
+
// run analysis multiple times on same data
|
|
70
|
+
const personality = await getPersonalityFromData(data, config);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Result Shape — `PersonalityResult`
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
{
|
|
77
|
+
archetype: string; // "The Midnight Systems Architect"
|
|
78
|
+
archetypeEmoji: string; // "🏗️"
|
|
79
|
+
summary: string; // 2-3 sentence personality summary
|
|
80
|
+
workStyle: string; // when and how they work
|
|
81
|
+
communicationStyle: string; // based on commit messages
|
|
82
|
+
strengths: string[]; // 3 key strengths
|
|
83
|
+
funFacts: string[]; // 3 fun observations
|
|
84
|
+
techIdentity: string; // relationship with tech/languages
|
|
85
|
+
collaborationStyle: string; // solo wolf or team player
|
|
86
|
+
developerQuote: string; // a made-up fitting quote
|
|
87
|
+
roastLine: string; // one funny roast line 😄
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## GitHub Data Shape — `GitHubData`
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
{
|
|
95
|
+
profile: UserProfile; // name, bio, location, followers...
|
|
96
|
+
repositories: Repository[]; // all public repos
|
|
97
|
+
languages: Record<string, number>; // language → bytes
|
|
98
|
+
commits: CommitInfo[]; // recent commit messages + timing
|
|
99
|
+
commitHours: number[]; // hours of day they commit
|
|
100
|
+
commitDays: string[]; // days of week they commit
|
|
101
|
+
activity: ActivitySummary; // push/PR/issue counts
|
|
102
|
+
topReadme: string | null; // README content
|
|
103
|
+
totalStarsReceived: number; // total stars across all repos
|
|
104
|
+
mostUsedLanguage: string | null; // top language
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Requirements
|
|
109
|
+
|
|
110
|
+
- Node.js 18+
|
|
111
|
+
- A free GitHub account with a Personal Access Token
|
|
112
|
+
- A free Groq account with an API key
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { GitHubData } from "../github/fetcher";
|
|
2
|
+
import { PersonalityResult } from "../analyser/prompt";
|
|
3
|
+
import { AnalyserConfig } from "../types";
|
|
4
|
+
export declare function analysePersonality(githubData: GitHubData, config: AnalyserConfig): Promise<PersonalityResult>;
|
|
5
|
+
//# sourceMappingURL=groq.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groq.d.ts","sourceRoot":"","sources":["../../src/ai/groq.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAe,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA6F1C,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,iBAAiB,CAAC,CA0B5B"}
|
package/dist/ai/groq.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.analysePersonality = analysePersonality;
|
|
7
|
+
const groq_sdk_1 = __importDefault(require("groq-sdk"));
|
|
8
|
+
const prompt_1 = require("../analyser/prompt");
|
|
9
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
10
|
+
const GROQ_MODEL = "llama-3.3-70b-versatile";
|
|
11
|
+
// ─── Helper: Strip Markdown Fences ───────────────────────────────────────────
|
|
12
|
+
function stripMarkdownFences(text) {
|
|
13
|
+
return text
|
|
14
|
+
.replace(/^```json\s*/i, "")
|
|
15
|
+
.replace(/^```\s*/i, "")
|
|
16
|
+
.replace(/```\s*$/i, "")
|
|
17
|
+
.trim();
|
|
18
|
+
}
|
|
19
|
+
// ─── Helper: Validate Personality Result ─────────────────────────────────────
|
|
20
|
+
function validateResult(obj) {
|
|
21
|
+
const requiredFields = [
|
|
22
|
+
"archetype",
|
|
23
|
+
"archetypeEmoji",
|
|
24
|
+
"summary",
|
|
25
|
+
"workStyle",
|
|
26
|
+
"communicationStyle",
|
|
27
|
+
"strengths",
|
|
28
|
+
"funFacts",
|
|
29
|
+
"techIdentity",
|
|
30
|
+
"collaborationStyle",
|
|
31
|
+
"developerQuote",
|
|
32
|
+
"roastLine",
|
|
33
|
+
];
|
|
34
|
+
for (const field of requiredFields) {
|
|
35
|
+
if (!(field in obj))
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (!Array.isArray(obj.strengths) || obj.strengths.length === 0)
|
|
39
|
+
return false;
|
|
40
|
+
if (!Array.isArray(obj.funFacts) || obj.funFacts.length === 0)
|
|
41
|
+
return false;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
// ─── Helper: Parse Groq Response ─────────────────────────────────────────────
|
|
45
|
+
function parseGroqResponse(rawText) {
|
|
46
|
+
if (!rawText || rawText.trim() === "") {
|
|
47
|
+
throw new Error("Groq returned an empty response.");
|
|
48
|
+
}
|
|
49
|
+
const cleaned = stripMarkdownFences(rawText);
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = JSON.parse(cleaned);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error(`Groq did not return valid JSON. Raw response: ${rawText.slice(0, 200)}`);
|
|
56
|
+
}
|
|
57
|
+
if (!validateResult(parsed)) {
|
|
58
|
+
throw new Error("Groq response is missing required personality fields.");
|
|
59
|
+
}
|
|
60
|
+
return parsed;
|
|
61
|
+
}
|
|
62
|
+
// ─── Helper: Retry Logic ──────────────────────────────────────────────────────
|
|
63
|
+
async function withRetry(fn, retries = 2, delayMs = 2000) {
|
|
64
|
+
let lastError = null;
|
|
65
|
+
for (let attempt = 1; attempt <= retries + 1; attempt++) {
|
|
66
|
+
try {
|
|
67
|
+
return await fn();
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
lastError = err;
|
|
71
|
+
if (attempt <= retries) {
|
|
72
|
+
await new Promise((res) => setTimeout(res, delayMs));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
throw lastError;
|
|
77
|
+
}
|
|
78
|
+
// ─── Main Exported Function ───────────────────────────────────────────────────
|
|
79
|
+
async function analysePersonality(githubData, config) {
|
|
80
|
+
// Groq client is now created with the user-provided key
|
|
81
|
+
const groq = new groq_sdk_1.default({ apiKey: config.groqApiKey });
|
|
82
|
+
const prompt = (0, prompt_1.buildPrompt)(githubData);
|
|
83
|
+
return await withRetry(async () => {
|
|
84
|
+
const response = await groq.chat.completions.create({
|
|
85
|
+
model: GROQ_MODEL,
|
|
86
|
+
temperature: 0.85,
|
|
87
|
+
max_tokens: 1500,
|
|
88
|
+
messages: [
|
|
89
|
+
{
|
|
90
|
+
role: "system",
|
|
91
|
+
content: "You are a witty developer personality analyser. You always respond with valid raw JSON only. No markdown, no backticks, no explanation — just the JSON object.",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
role: "user",
|
|
95
|
+
content: prompt,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
const rawText = response.choices[0]?.message?.content ?? "";
|
|
100
|
+
return parseGroqResponse(rawText);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=groq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/ai/groq.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GitHubData } from "../github/fetcher.js";
|
|
2
|
+
export interface PersonalityResult {
|
|
3
|
+
archetype: string;
|
|
4
|
+
archetypeEmoji: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
workStyle: string;
|
|
7
|
+
communicationStyle: string;
|
|
8
|
+
strengths: string[];
|
|
9
|
+
funFacts: string[];
|
|
10
|
+
techIdentity: string;
|
|
11
|
+
collaborationStyle: string;
|
|
12
|
+
developerQuote: string;
|
|
13
|
+
roastLine: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildPrompt(data: GitHubData): string;
|
|
16
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/analyser/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIvD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AA0KD,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAmGpD"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildPrompt = buildPrompt;
|
|
4
|
+
function analyseCommitTiming(commitHours) {
|
|
5
|
+
if (commitHours.length === 0)
|
|
6
|
+
return "unknown schedule";
|
|
7
|
+
const avg = commitHours.reduce((a, b) => a + b, 0) / commitHours.length;
|
|
8
|
+
const nightOwl = commitHours.filter((h) => h >= 22 || h <= 4).length;
|
|
9
|
+
const earlyBird = commitHours.filter((h) => h >= 5 && h <= 9).length;
|
|
10
|
+
const officer = commitHours.filter((h) => h >= 9 && h <= 17).length;
|
|
11
|
+
const eveningCoder = commitHours.filter((h) => h >= 17 && h <= 22).length;
|
|
12
|
+
const total = commitHours.length;
|
|
13
|
+
const nightPct = Math.round((nightOwl / total) * 100);
|
|
14
|
+
const earlyPct = Math.round((earlyBird / total) * 100);
|
|
15
|
+
const officePct = Math.round((officer / total) * 100);
|
|
16
|
+
const eveningPct = Math.round((eveningCoder / total) * 100);
|
|
17
|
+
return [
|
|
18
|
+
`Average commit hour: ${Math.round(avg)}:00`,
|
|
19
|
+
`Night owl commits (10pm–4am): ${nightPct}%`,
|
|
20
|
+
`Early bird commits (5am–9am): ${earlyPct}%`,
|
|
21
|
+
`Office hours commits (9am–5pm): ${officePct}%`,
|
|
22
|
+
`Evening commits (5pm–10pm): ${eveningPct}%`,
|
|
23
|
+
].join("\n");
|
|
24
|
+
}
|
|
25
|
+
function analyseCommitDays(commitDays) {
|
|
26
|
+
if (commitDays.length === 0)
|
|
27
|
+
return "unknown days";
|
|
28
|
+
const dayCounts = {};
|
|
29
|
+
for (const day of commitDays) {
|
|
30
|
+
dayCounts[day] = (dayCounts[day] ?? 0) + 1;
|
|
31
|
+
}
|
|
32
|
+
const weekendDays = ["Saturday", "Sunday"];
|
|
33
|
+
const weekendCommits = commitDays.filter((d) => weekendDays.includes(d)).length;
|
|
34
|
+
const weekdayCommits = commitDays.length - weekendCommits;
|
|
35
|
+
const weekendPct = Math.round((weekendCommits / commitDays.length) * 100);
|
|
36
|
+
const topDay = Object.entries(dayCounts).sort(([, a], [, b]) => b - a)[0]?.[0];
|
|
37
|
+
return [
|
|
38
|
+
`Most active day: ${topDay}`,
|
|
39
|
+
`Weekday commits: ${weekdayCommits} | Weekend commits: ${weekendCommits} (${weekendPct}% weekend)`,
|
|
40
|
+
`Day breakdown: ${Object.entries(dayCounts)
|
|
41
|
+
.map(([d, c]) => `${d}: ${c}`)
|
|
42
|
+
.join(", ")}`,
|
|
43
|
+
].join("\n");
|
|
44
|
+
}
|
|
45
|
+
function analyseCommitMessages(messages) {
|
|
46
|
+
if (messages.length === 0)
|
|
47
|
+
return "No commit messages found.";
|
|
48
|
+
const avgLength = Math.round(messages.reduce((sum, m) => sum + m.length, 0) / messages.length);
|
|
49
|
+
const hasEmoji = messages.filter((m) => /\p{Emoji}/u.test(m)).length;
|
|
50
|
+
const hasConventional = messages.filter((m) => /^(feat|fix|chore|docs|style|refactor|test|perf)(\(.+\))?:/i.test(m)).length;
|
|
51
|
+
const hasCaps = messages.filter((m) => m[0] === m[0]?.toUpperCase()).length;
|
|
52
|
+
const veryShort = messages.filter((m) => m.length < 15).length;
|
|
53
|
+
const veryLong = messages.filter((m) => m.length > 72).length;
|
|
54
|
+
const emojiPct = Math.round((hasEmoji / messages.length) * 100);
|
|
55
|
+
const conventionalPct = Math.round((hasConventional / messages.length) * 100);
|
|
56
|
+
return [
|
|
57
|
+
`Total commit messages analysed: ${messages.length}`,
|
|
58
|
+
`Average message length: ${avgLength} characters`,
|
|
59
|
+
`Uses emoji in commits: ${emojiPct}%`,
|
|
60
|
+
`Follows conventional commits: ${conventionalPct}%`,
|
|
61
|
+
`Starts with capital letter: ${hasCaps}/${messages.length}`,
|
|
62
|
+
`Very short messages (<15 chars): ${veryShort}`,
|
|
63
|
+
`Very long messages (>72 chars): ${veryLong}`,
|
|
64
|
+
`Sample messages:\n${messages.slice(0, 8).map((m) => ` - "${m}"`).join("\n")}`,
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
function analyseLanguages(languages) {
|
|
68
|
+
if (Object.keys(languages).length === 0)
|
|
69
|
+
return "No language data found.";
|
|
70
|
+
const sorted = Object.entries(languages).sort(([, a], [, b]) => b - a);
|
|
71
|
+
const total = sorted.reduce((sum, [, b]) => sum + b, 0);
|
|
72
|
+
const topLanguages = sorted.slice(0, 6).map(([lang, bytes]) => {
|
|
73
|
+
const pct = Math.round((bytes / total) * 100);
|
|
74
|
+
return `${lang}: ${pct}%`;
|
|
75
|
+
});
|
|
76
|
+
const isPolyglot = sorted.length >= 5;
|
|
77
|
+
const isSpecialist = sorted.length <= 2;
|
|
78
|
+
return [
|
|
79
|
+
`Languages used (${sorted.length} total):`,
|
|
80
|
+
topLanguages.join(" | "),
|
|
81
|
+
isPolyglot ? "Profile: Polyglot developer (5+ languages)" : "",
|
|
82
|
+
isSpecialist ? "Profile: Specialist (1-2 languages)" : "",
|
|
83
|
+
]
|
|
84
|
+
.filter(Boolean)
|
|
85
|
+
.join("\n");
|
|
86
|
+
}
|
|
87
|
+
function analyseRepositories(repos) {
|
|
88
|
+
if (repos.length === 0)
|
|
89
|
+
return "No repositories found.";
|
|
90
|
+
const nonForked = repos.filter((r) => !r.isForked);
|
|
91
|
+
const forked = repos.filter((r) => r.isForked);
|
|
92
|
+
const withDescription = repos.filter((r) => r.description).length;
|
|
93
|
+
const withTopics = repos.filter((r) => r.topics?.length > 0).length;
|
|
94
|
+
const topStarred = [...repos]
|
|
95
|
+
.sort((a, b) => b.stars - a.stars)
|
|
96
|
+
.slice(0, 5)
|
|
97
|
+
.map((r) => `"${r.name}" (⭐ ${r.stars})`);
|
|
98
|
+
const allTopics = repos
|
|
99
|
+
.flatMap((r) => r.topics ?? [])
|
|
100
|
+
.reduce((acc, t) => {
|
|
101
|
+
acc[t] = (acc[t] ?? 0) + 1;
|
|
102
|
+
return acc;
|
|
103
|
+
}, {});
|
|
104
|
+
const topTopics = Object.entries(allTopics)
|
|
105
|
+
.sort(([, a], [, b]) => b - a)
|
|
106
|
+
.slice(0, 6)
|
|
107
|
+
.map(([t]) => t);
|
|
108
|
+
return [
|
|
109
|
+
`Total repos: ${repos.length} (${nonForked.length} original, ${forked.length} forked)`,
|
|
110
|
+
`Repos with description: ${withDescription}/${repos.length}`,
|
|
111
|
+
`Repos with topics/tags: ${withTopics}/${repos.length}`,
|
|
112
|
+
`Top starred repos: ${topStarred.join(", ")}`,
|
|
113
|
+
topTopics.length > 0 ? `Common topics: ${topTopics.join(", ")}` : "",
|
|
114
|
+
]
|
|
115
|
+
.filter(Boolean)
|
|
116
|
+
.join("\n");
|
|
117
|
+
}
|
|
118
|
+
function analyseActivity(activity) {
|
|
119
|
+
const total = activity.totalEvents;
|
|
120
|
+
if (total === 0)
|
|
121
|
+
return "No recent public activity found.";
|
|
122
|
+
const dominant = Object.entries({
|
|
123
|
+
Pushing: activity.pushCount,
|
|
124
|
+
"Opening PRs": activity.pullRequestCount,
|
|
125
|
+
"Filing Issues": activity.issueCount,
|
|
126
|
+
Forking: activity.forkCount,
|
|
127
|
+
Reviewing: activity.reviewCount,
|
|
128
|
+
})
|
|
129
|
+
.sort(([, a], [, b]) => b - a)
|
|
130
|
+
.filter(([, v]) => v > 0)
|
|
131
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
132
|
+
.join(" | ");
|
|
133
|
+
return [
|
|
134
|
+
`Total recent public events: ${total}`,
|
|
135
|
+
dominant,
|
|
136
|
+
].join("\n");
|
|
137
|
+
}
|
|
138
|
+
function buildPrompt(data) {
|
|
139
|
+
const { profile, repositories, languages, commits, commitHours, commitDays, activity, topReadme, totalStarsReceived, mostUsedLanguage, } = data;
|
|
140
|
+
const timingAnalysis = analyseCommitTiming(commitHours);
|
|
141
|
+
const dayAnalysis = analyseCommitDays(commitDays);
|
|
142
|
+
const messageAnalysis = analyseCommitMessages(commits.map((c) => c.message));
|
|
143
|
+
const languageAnalysis = analyseLanguages(languages);
|
|
144
|
+
const repoAnalysis = analyseRepositories(repositories);
|
|
145
|
+
const activityAnalysis = analyseActivity(activity);
|
|
146
|
+
const prompt = `
|
|
147
|
+
You are a witty, insightful developer personality analyser. Based on the GitHub data below, generate a fun and accurate personality profile for this developer.
|
|
148
|
+
|
|
149
|
+
═══════════════════════════════════════════
|
|
150
|
+
GITHUB DATA FOR: @${profile.username}
|
|
151
|
+
═══════════════════════════════════════════
|
|
152
|
+
|
|
153
|
+
PROFILE
|
|
154
|
+
──────────
|
|
155
|
+
Name: ${profile.name ?? "Not provided"}
|
|
156
|
+
Bio: ${profile.bio ?? "No bio"}
|
|
157
|
+
Location: ${profile.location ?? "Unknown"}
|
|
158
|
+
Company: ${profile.company ?? "None listed"}
|
|
159
|
+
Account age: ${profile.accountAgeYears} years
|
|
160
|
+
Followers: ${profile.followers} | Following: ${profile.following}
|
|
161
|
+
Total stars received: ${totalStarsReceived}
|
|
162
|
+
Public repos: ${profile.publicRepos}
|
|
163
|
+
Hireable: ${profile.hireable ?? "Not specified"}
|
|
164
|
+
Blog/Website: ${profile.blog ?? "None"}
|
|
165
|
+
|
|
166
|
+
REPOSITORIES
|
|
167
|
+
────────────────
|
|
168
|
+
${repoAnalysis}
|
|
169
|
+
|
|
170
|
+
LANGUAGES
|
|
171
|
+
─────────────
|
|
172
|
+
${languageAnalysis}
|
|
173
|
+
Most used language overall: ${mostUsedLanguage ?? "Unknown"}
|
|
174
|
+
|
|
175
|
+
COMMIT MESSAGES
|
|
176
|
+
───────────────────
|
|
177
|
+
${messageAnalysis}
|
|
178
|
+
|
|
179
|
+
COMMIT TIMING
|
|
180
|
+
─────────────────
|
|
181
|
+
${timingAnalysis}
|
|
182
|
+
|
|
183
|
+
COMMIT DAYS
|
|
184
|
+
───────────────
|
|
185
|
+
${dayAnalysis}
|
|
186
|
+
|
|
187
|
+
RECENT ACTIVITY (last 100 events)
|
|
188
|
+
──────────────────────────────────────
|
|
189
|
+
${activityAnalysis}
|
|
190
|
+
|
|
191
|
+
${topReadme
|
|
192
|
+
? `README SAMPLE (first 1500 chars)
|
|
193
|
+
──────────────────────────────────
|
|
194
|
+
${topReadme.slice(0, 1500)}`
|
|
195
|
+
: "README: None found"}
|
|
196
|
+
|
|
197
|
+
═══════════════════════════════════════════
|
|
198
|
+
YOUR TASK
|
|
199
|
+
═══════════════════════════════════════════
|
|
200
|
+
|
|
201
|
+
Based on ALL the data above, generate a developer personality profile. Be specific — reference actual data points (languages, commit times, repo names, message style etc). Be witty but fair.
|
|
202
|
+
|
|
203
|
+
Respond ONLY with a valid JSON object. No markdown, no backticks, no explanation. Just raw JSON.
|
|
204
|
+
|
|
205
|
+
The JSON must follow this exact structure:
|
|
206
|
+
{
|
|
207
|
+
"archetype": "A creative 3-5 word title e.g. 'The Midnight Systems Architect'",
|
|
208
|
+
"archetypeEmoji": "One relevant emoji",
|
|
209
|
+
"summary": "2-3 sentence personality summary. Be specific, witty, and reference actual data.",
|
|
210
|
+
"workStyle": "1-2 sentences about WHEN and HOW they work based on commit timing and activity.",
|
|
211
|
+
"communicationStyle": "1-2 sentences about how they communicate based on commit messages.",
|
|
212
|
+
"strengths": ["Strength 1 (be specific)", "Strength 2", "Strength 3"],
|
|
213
|
+
"funFacts": ["A fun specific observation from the data", "Another fun fact", "One more"],
|
|
214
|
+
"techIdentity": "1-2 sentences about their relationship with technology and languages.",
|
|
215
|
+
"collaborationStyle": "1-2 sentences — are they a solo builder or team player? Based on forks, PRs, reviews.",
|
|
216
|
+
"developerQuote": "A made-up quote that perfectly fits this developer's personality. Make it funny/insightful.",
|
|
217
|
+
"roastLine": "One short, funny, affectionate roast line based on something specific in their data."
|
|
218
|
+
}
|
|
219
|
+
`.trim();
|
|
220
|
+
return prompt;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/analyser/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AnalyserConfig } from "../types";
|
|
2
|
+
export interface UserProfile {
|
|
3
|
+
username: string;
|
|
4
|
+
name: string | null;
|
|
5
|
+
bio: string | null;
|
|
6
|
+
location: string | null;
|
|
7
|
+
company: string | null;
|
|
8
|
+
email: string | null;
|
|
9
|
+
blog: string | null;
|
|
10
|
+
followers: number;
|
|
11
|
+
following: number;
|
|
12
|
+
publicRepos: number;
|
|
13
|
+
accountCreatedAt: string;
|
|
14
|
+
accountAgeYears: number;
|
|
15
|
+
avatarUrl: string;
|
|
16
|
+
hireable: boolean | null;
|
|
17
|
+
}
|
|
18
|
+
export interface Repository {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string | null;
|
|
21
|
+
language: string | null;
|
|
22
|
+
stars: number;
|
|
23
|
+
forks: number;
|
|
24
|
+
topics: string[];
|
|
25
|
+
isForked: boolean;
|
|
26
|
+
hasReadme: boolean;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
size: number;
|
|
30
|
+
}
|
|
31
|
+
export interface CommitInfo {
|
|
32
|
+
message: string;
|
|
33
|
+
hourOfDay: number;
|
|
34
|
+
dayOfWeek: string;
|
|
35
|
+
repoName: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ActivitySummary {
|
|
38
|
+
pushCount: number;
|
|
39
|
+
pullRequestCount: number;
|
|
40
|
+
issueCount: number;
|
|
41
|
+
forkCount: number;
|
|
42
|
+
watchCount: number;
|
|
43
|
+
reviewCount: number;
|
|
44
|
+
totalEvents: number;
|
|
45
|
+
}
|
|
46
|
+
export interface GitHubData {
|
|
47
|
+
profile: UserProfile;
|
|
48
|
+
repositories: Repository[];
|
|
49
|
+
languages: Record<string, number>;
|
|
50
|
+
commits: CommitInfo[];
|
|
51
|
+
commitHours: number[];
|
|
52
|
+
commitDays: string[];
|
|
53
|
+
activity: ActivitySummary;
|
|
54
|
+
topReadme: string | null;
|
|
55
|
+
totalStarsReceived: number;
|
|
56
|
+
mostUsedLanguage: string | null;
|
|
57
|
+
}
|
|
58
|
+
export declare function fetchGitHubData(username: string, config: AnalyserConfig): Promise<GitHubData>;
|
|
59
|
+
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/github/fetcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAyND,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,UAAU,CAAC,CA+BrB"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchGitHubData = fetchGitHubData;
|
|
4
|
+
const rest_1 = require("@octokit/rest");
|
|
5
|
+
// ─── Helper: Get Day Name ─────────────────────────────────────────────────────
|
|
6
|
+
function getDayName(dateStr) {
|
|
7
|
+
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
8
|
+
return days[new Date(dateStr).getDay()];
|
|
9
|
+
}
|
|
10
|
+
// ─── 1. Fetch User Profile ────────────────────────────────────────────────────
|
|
11
|
+
async function fetchProfile(octokit, username) {
|
|
12
|
+
const { data } = await octokit.rest.users.getByUsername({ username });
|
|
13
|
+
const createdAt = data.created_at;
|
|
14
|
+
const accountAgeYears = Math.floor((Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24 * 365));
|
|
15
|
+
return {
|
|
16
|
+
username: data.login,
|
|
17
|
+
name: data.name ?? null,
|
|
18
|
+
bio: data.bio ?? null,
|
|
19
|
+
location: data.location ?? null,
|
|
20
|
+
company: data.company ?? null,
|
|
21
|
+
email: data.email ?? null,
|
|
22
|
+
blog: data.blog ?? null,
|
|
23
|
+
followers: data.followers,
|
|
24
|
+
following: data.following,
|
|
25
|
+
publicRepos: data.public_repos,
|
|
26
|
+
accountCreatedAt: createdAt,
|
|
27
|
+
accountAgeYears,
|
|
28
|
+
avatarUrl: data.avatar_url,
|
|
29
|
+
hireable: data.hireable ?? null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// ─── 2. Fetch Repositories ────────────────────────────────────────────────────
|
|
33
|
+
async function fetchRepositories(octokit, username) {
|
|
34
|
+
const { data } = await octokit.rest.repos.listForUser({
|
|
35
|
+
username,
|
|
36
|
+
per_page: 100,
|
|
37
|
+
sort: "updated",
|
|
38
|
+
type: "owner",
|
|
39
|
+
});
|
|
40
|
+
return data.map((repo) => ({
|
|
41
|
+
name: repo.name,
|
|
42
|
+
description: repo.description ?? null,
|
|
43
|
+
language: repo.language ?? null,
|
|
44
|
+
stars: repo.stargazers_count ?? 0,
|
|
45
|
+
forks: repo.forks_count ?? 0,
|
|
46
|
+
topics: repo.topics ?? [],
|
|
47
|
+
isForked: repo.fork,
|
|
48
|
+
hasReadme: false,
|
|
49
|
+
createdAt: repo.created_at ?? "",
|
|
50
|
+
updatedAt: repo.updated_at ?? "",
|
|
51
|
+
size: repo.size ?? 0,
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
// ─── 3. Fetch Languages ───────────────────────────────────────────────────────
|
|
55
|
+
async function fetchLanguages(octokit, username, repos) {
|
|
56
|
+
const topRepos = [...repos].sort((a, b) => b.stars - a.stars).slice(0, 10);
|
|
57
|
+
const languageMaps = await Promise.all(topRepos.map(async (repo) => {
|
|
58
|
+
try {
|
|
59
|
+
const { data } = await octokit.rest.repos.listLanguages({
|
|
60
|
+
owner: username,
|
|
61
|
+
repo: repo.name,
|
|
62
|
+
});
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
const combined = {};
|
|
70
|
+
for (const langMap of languageMaps) {
|
|
71
|
+
for (const [lang, bytes] of Object.entries(langMap)) {
|
|
72
|
+
combined[lang] = (combined[lang] ?? 0) + bytes;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return combined;
|
|
76
|
+
}
|
|
77
|
+
// ─── 4. Fetch Commits ─────────────────────────────────────────────────────────
|
|
78
|
+
async function fetchCommits(octokit, username, repos) {
|
|
79
|
+
const targetRepos = repos
|
|
80
|
+
.filter((r) => !r.isForked)
|
|
81
|
+
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
|
|
82
|
+
.slice(0, 5);
|
|
83
|
+
const commitArrays = await Promise.all(targetRepos.map(async (repo) => {
|
|
84
|
+
try {
|
|
85
|
+
const { data } = await octokit.rest.repos.listCommits({
|
|
86
|
+
owner: username,
|
|
87
|
+
repo: repo.name,
|
|
88
|
+
author: username,
|
|
89
|
+
per_page: 20,
|
|
90
|
+
});
|
|
91
|
+
return data.map((commit) => {
|
|
92
|
+
const dateStr = commit.commit.author?.date ?? new Date().toISOString();
|
|
93
|
+
return {
|
|
94
|
+
message: commit.commit.message.split("\n")[0],
|
|
95
|
+
hourOfDay: new Date(dateStr).getHours(),
|
|
96
|
+
dayOfWeek: getDayName(dateStr),
|
|
97
|
+
repoName: repo.name,
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}));
|
|
105
|
+
return commitArrays.flat();
|
|
106
|
+
}
|
|
107
|
+
// ─── 5. Fetch Activity ────────────────────────────────────────────────────────
|
|
108
|
+
async function fetchActivity(octokit, username) {
|
|
109
|
+
const { data } = await octokit.rest.activity.listPublicEventsForUser({
|
|
110
|
+
username,
|
|
111
|
+
per_page: 100,
|
|
112
|
+
});
|
|
113
|
+
const summary = {
|
|
114
|
+
pushCount: 0,
|
|
115
|
+
pullRequestCount: 0,
|
|
116
|
+
issueCount: 0,
|
|
117
|
+
forkCount: 0,
|
|
118
|
+
watchCount: 0,
|
|
119
|
+
reviewCount: 0,
|
|
120
|
+
totalEvents: data.length,
|
|
121
|
+
};
|
|
122
|
+
for (const event of data) {
|
|
123
|
+
switch (event.type) {
|
|
124
|
+
case "PushEvent":
|
|
125
|
+
summary.pushCount++;
|
|
126
|
+
break;
|
|
127
|
+
case "PullRequestEvent":
|
|
128
|
+
summary.pullRequestCount++;
|
|
129
|
+
break;
|
|
130
|
+
case "IssuesEvent":
|
|
131
|
+
summary.issueCount++;
|
|
132
|
+
break;
|
|
133
|
+
case "ForkEvent":
|
|
134
|
+
summary.forkCount++;
|
|
135
|
+
break;
|
|
136
|
+
case "WatchEvent":
|
|
137
|
+
summary.watchCount++;
|
|
138
|
+
break;
|
|
139
|
+
case "PullRequestReviewEvent":
|
|
140
|
+
summary.reviewCount++;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return summary;
|
|
145
|
+
}
|
|
146
|
+
// ─── 6. Fetch README ──────────────────────────────────────────────────────────
|
|
147
|
+
async function fetchTopReadme(octokit, username, repos) {
|
|
148
|
+
const candidates = [
|
|
149
|
+
username,
|
|
150
|
+
...repos
|
|
151
|
+
.filter((r) => !r.isForked)
|
|
152
|
+
.sort((a, b) => b.stars - a.stars)
|
|
153
|
+
.slice(0, 3)
|
|
154
|
+
.map((r) => r.name),
|
|
155
|
+
];
|
|
156
|
+
for (const repoName of candidates) {
|
|
157
|
+
try {
|
|
158
|
+
const { data } = await octokit.rest.repos.getReadme({
|
|
159
|
+
owner: username,
|
|
160
|
+
repo: repoName,
|
|
161
|
+
});
|
|
162
|
+
const content = Buffer.from(data.content, "base64").toString("utf-8");
|
|
163
|
+
return content.slice(0, 3000);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
// ─── 7. Derived Fields ────────────────────────────────────────────────────────
|
|
172
|
+
function computeDerivedFields(repos, languages, commits) {
|
|
173
|
+
const totalStarsReceived = repos.reduce((sum, r) => sum + r.stars, 0);
|
|
174
|
+
const mostUsedLanguage = Object.entries(languages).sort(([, a], [, b]) => b - a)[0]?.[0] ?? null;
|
|
175
|
+
const commitHours = commits.map((c) => c.hourOfDay);
|
|
176
|
+
const commitDays = commits.map((c) => c.dayOfWeek);
|
|
177
|
+
return { totalStarsReceived, mostUsedLanguage, commitHours, commitDays };
|
|
178
|
+
}
|
|
179
|
+
// ─── Main Exported Function ───────────────────────────────────────────────────
|
|
180
|
+
async function fetchGitHubData(username, config) {
|
|
181
|
+
// Octokit is now created with the user-provided token
|
|
182
|
+
const octokit = new rest_1.Octokit({ auth: config.githubToken });
|
|
183
|
+
const [profile, repositories, activity] = await Promise.all([
|
|
184
|
+
fetchProfile(octokit, username),
|
|
185
|
+
fetchRepositories(octokit, username),
|
|
186
|
+
fetchActivity(octokit, username),
|
|
187
|
+
]);
|
|
188
|
+
const [languages, commits, topReadme] = await Promise.all([
|
|
189
|
+
fetchLanguages(octokit, username, repositories),
|
|
190
|
+
fetchCommits(octokit, username, repositories),
|
|
191
|
+
fetchTopReadme(octokit, username, repositories),
|
|
192
|
+
]);
|
|
193
|
+
const { totalStarsReceived, mostUsedLanguage, commitHours, commitDays } = computeDerivedFields(repositories, languages, commits);
|
|
194
|
+
return {
|
|
195
|
+
profile,
|
|
196
|
+
repositories,
|
|
197
|
+
languages,
|
|
198
|
+
commits,
|
|
199
|
+
commitHours,
|
|
200
|
+
commitDays,
|
|
201
|
+
activity,
|
|
202
|
+
topReadme,
|
|
203
|
+
totalStarsReceived,
|
|
204
|
+
mostUsedLanguage,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/github/fetcher.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnalyserConfig, PersonalityResult } from "./types";
|
|
2
|
+
import { GitHubData } from "./github/fetcher";
|
|
3
|
+
export type { AnalyserConfig, PersonalityResult, GitHubData };
|
|
4
|
+
export type { UserProfile, Repository, CommitInfo, ActivitySummary, } from "./github/fetcher";
|
|
5
|
+
export declare function analyseGitHubPersonality(username: string, config: AnalyserConfig): Promise<PersonalityResult>;
|
|
6
|
+
export declare function getGitHubData(username: string, config: AnalyserConfig): Promise<GitHubData>;
|
|
7
|
+
export declare function getPersonalityFromData(githubData: GitHubData, config: AnalyserConfig): Promise<PersonalityResult>;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC;AAC9D,YAAY,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAK1B,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,iBAAiB,CAAC,CAQ5B;AAKD,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,UAAU,CAAC,CAKrB;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,iBAAiB,CAAC,CAI5B"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyseGitHubPersonality = analyseGitHubPersonality;
|
|
4
|
+
exports.getGitHubData = getGitHubData;
|
|
5
|
+
exports.getPersonalityFromData = getPersonalityFromData;
|
|
6
|
+
const fetcher_1 = require("./github/fetcher");
|
|
7
|
+
const groq_1 = require("./ai/groq");
|
|
8
|
+
// ─── Main Function — Full Pipeline ───────────────────────────────────────────
|
|
9
|
+
// Fetches GitHub data + analyses personality in one call
|
|
10
|
+
async function analyseGitHubPersonality(username, config) {
|
|
11
|
+
validateConfig(config);
|
|
12
|
+
validateUsername(username);
|
|
13
|
+
const githubData = await (0, fetcher_1.fetchGitHubData)(username, config);
|
|
14
|
+
const personality = await (0, groq_1.analysePersonality)(githubData, config);
|
|
15
|
+
return personality;
|
|
16
|
+
}
|
|
17
|
+
// ─── Individual Functions — For Advanced Use ──────────────────────────────────
|
|
18
|
+
// Users can call these separately if they want more control
|
|
19
|
+
async function getGitHubData(username, config) {
|
|
20
|
+
validateConfig(config);
|
|
21
|
+
validateUsername(username);
|
|
22
|
+
return await (0, fetcher_1.fetchGitHubData)(username, config);
|
|
23
|
+
}
|
|
24
|
+
async function getPersonalityFromData(githubData, config) {
|
|
25
|
+
validateConfig(config);
|
|
26
|
+
return await (0, groq_1.analysePersonality)(githubData, config);
|
|
27
|
+
}
|
|
28
|
+
// ─── Validators ───────────────────────────────────────────────────────────────
|
|
29
|
+
function validateConfig(config) {
|
|
30
|
+
if (!config) {
|
|
31
|
+
throw new Error("[github-personality-analyser] config is required. Pass { githubToken, groqApiKey }.");
|
|
32
|
+
}
|
|
33
|
+
if (!config.githubToken || config.githubToken.trim() === "") {
|
|
34
|
+
throw new Error("[github-personality-analyser] config.githubToken is missing or empty.");
|
|
35
|
+
}
|
|
36
|
+
if (!config.groqApiKey || config.groqApiKey.trim() === "") {
|
|
37
|
+
throw new Error("[github-personality-analyser] config.groqApiKey is missing or empty.");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function validateUsername(username) {
|
|
41
|
+
if (!username || username.trim() === "") {
|
|
42
|
+
throw new Error("[github-personality-analyser] username is required and cannot be empty.");
|
|
43
|
+
}
|
|
44
|
+
if (!/^[a-zA-Z0-9-]+$/.test(username)) {
|
|
45
|
+
throw new Error(`[github-personality-analyser] "${username}" is not a valid GitHub username.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAkBA,4DAWC;AAKD,sCAQC;AAED,wDAOC;AAnDD,8CAAmD;AACnD,oCAA+C;AAc/C,gFAAgF;AAChF,yDAAyD;AAElD,KAAK,UAAU,wBAAwB,CAC5C,QAAgB,EAChB,MAAsB;IAEtB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE3B,MAAM,UAAU,GAAG,MAAM,IAAA,yBAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,MAAM,IAAA,yBAAkB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEjE,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,iFAAiF;AACjF,4DAA4D;AAErD,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,MAAsB;IAEtB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE3B,OAAO,MAAM,IAAA,yBAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,UAAsB,EACtB,MAAsB;IAEtB,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,MAAM,IAAA,yBAAkB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,iFAAiF;AAEjF,SAAS,cAAc,CAAC,MAAsB;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,kCAAkC,QAAQ,mCAAmC,CAC9E,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface AnalyserConfig {
|
|
2
|
+
githubToken: string;
|
|
3
|
+
groqApiKey: string;
|
|
4
|
+
}
|
|
5
|
+
export type { GitHubData, UserProfile, Repository, CommitInfo, ActivitySummary, } from "./github/fetcher";
|
|
6
|
+
export type { PersonalityResult } from "./analyser/prompt";
|
|
7
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,YAAY,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,sDAAsD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "github-personality-analyser",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Analyse a GitHub user's developer personality using their public activity and AI",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/types/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"prepare": "npm run build",
|
|
15
|
+
"dev": "tsx watch src/index.ts"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"github",
|
|
19
|
+
"personality",
|
|
20
|
+
"analyser",
|
|
21
|
+
"developer",
|
|
22
|
+
"ai",
|
|
23
|
+
"groq",
|
|
24
|
+
"llama"
|
|
25
|
+
],
|
|
26
|
+
"author": "your-name",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@octokit/rest": "^20.0.0",
|
|
30
|
+
"groq-sdk": "^0.5.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.0.0",
|
|
34
|
+
"tsx": "^4.0.0",
|
|
35
|
+
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|