gh-tldr 1.0.10 → 1.1.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/dist/index.js +46 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -140,30 +140,18 @@ async function fetchUserOrgs(username) {
|
|
|
140
140
|
return [];
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
async function fetchReposCreatedSince(username, since, publicOnly) {
|
|
143
|
+
async function fetchReposCreatedSince(username, since, publicOnly, filterOrgs) {
|
|
144
144
|
const sinceDate = new Date(since);
|
|
145
145
|
const repos = [];
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
]);
|
|
152
|
-
const userRepos = JSON.parse(stdout);
|
|
153
|
-
for (const repo of userRepos) {
|
|
154
|
-
if (new Date(repo.created_at) >= sinceDate) {
|
|
155
|
-
repos.push({ name: repo.name, org: repo.owner.login });
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
} catch {
|
|
159
|
-
}
|
|
160
|
-
const orgs = await fetchUserOrgs(username);
|
|
161
|
-
for (const org of orgs) {
|
|
146
|
+
const orgsToCheck = filterOrgs ?? [
|
|
147
|
+
username,
|
|
148
|
+
...await fetchUserOrgs(username)
|
|
149
|
+
];
|
|
150
|
+
for (const org of orgsToCheck) {
|
|
162
151
|
try {
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
]);
|
|
152
|
+
const isUser = org === username;
|
|
153
|
+
const endpoint = isUser ? `users/${username}/repos?type=${publicOnly ? "public" : "all"}&sort=created&direction=desc&per_page=100` : `orgs/${org}/repos?sort=created&direction=desc&per_page=100`;
|
|
154
|
+
const { stdout } = await execa2("gh", ["api", endpoint]);
|
|
167
155
|
const orgRepos = JSON.parse(stdout);
|
|
168
156
|
for (const repo of orgRepos) {
|
|
169
157
|
if (new Date(repo.created_at) >= sinceDate) {
|
|
@@ -177,10 +165,11 @@ async function fetchReposCreatedSince(username, since, publicOnly) {
|
|
|
177
165
|
(repo, index, self) => self.findIndex((r) => r.name === repo.name && r.org === repo.org) === index
|
|
178
166
|
);
|
|
179
167
|
}
|
|
180
|
-
async function fetchGitHubActivity(username, days, publicOnly) {
|
|
168
|
+
async function fetchGitHubActivity(username, days, publicOnly, filterOrgs = null) {
|
|
181
169
|
const since = getSinceDate(days);
|
|
182
170
|
const today = formatDate(/* @__PURE__ */ new Date());
|
|
183
171
|
const visibilityFilter = publicOnly ? " is:public" : "";
|
|
172
|
+
const orgFilter = filterOrgs ? ` ${filterOrgs.map((o) => `org:${o}`).join(" ")}` : "";
|
|
184
173
|
const [
|
|
185
174
|
prsCreatedItems,
|
|
186
175
|
prsMergedItems,
|
|
@@ -191,24 +180,24 @@ async function fetchGitHubActivity(username, days, publicOnly) {
|
|
|
191
180
|
repos_created
|
|
192
181
|
] = await Promise.all([
|
|
193
182
|
ghApiPaginated("search/issues", {
|
|
194
|
-
q: `author:${username} type:pr created:>=${since}${visibilityFilter}`
|
|
183
|
+
q: `author:${username} type:pr created:>=${since}${visibilityFilter}${orgFilter}`
|
|
195
184
|
}),
|
|
196
185
|
ghApiPaginated("search/issues", {
|
|
197
|
-
q: `author:${username} type:pr merged:>=${since}${visibilityFilter}`
|
|
186
|
+
q: `author:${username} type:pr merged:>=${since}${visibilityFilter}${orgFilter}`
|
|
198
187
|
}),
|
|
199
188
|
ghApiPaginated("search/issues", {
|
|
200
|
-
q: `reviewed-by:${username} type:pr created:>=${since} -author:${username}${visibilityFilter}`
|
|
189
|
+
q: `reviewed-by:${username} type:pr created:>=${since} -author:${username}${visibilityFilter}${orgFilter}`
|
|
201
190
|
}),
|
|
202
191
|
ghApiPaginated("search/issues", {
|
|
203
|
-
q: `author:${username} type:issue created:>=${since}${visibilityFilter}`
|
|
192
|
+
q: `author:${username} type:issue created:>=${since}${visibilityFilter}${orgFilter}`
|
|
204
193
|
}),
|
|
205
194
|
ghApiPaginated("search/issues", {
|
|
206
|
-
q: `author:${username} type:issue closed:>=${since}${visibilityFilter}`
|
|
195
|
+
q: `author:${username} type:issue closed:>=${since}${visibilityFilter}${orgFilter}`
|
|
207
196
|
}),
|
|
208
197
|
ghApiPaginated("search/commits", {
|
|
209
|
-
q: `author:${username} committer-date:>=${since}`
|
|
198
|
+
q: `author:${username} committer-date:>=${since}${orgFilter}`
|
|
210
199
|
}),
|
|
211
|
-
fetchReposCreatedSince(username, since, publicOnly)
|
|
200
|
+
fetchReposCreatedSince(username, since, publicOnly, filterOrgs)
|
|
212
201
|
]);
|
|
213
202
|
const prs_created = prsCreatedItems.map(parsePR);
|
|
214
203
|
const prs_merged = prsMergedItems.map(parsePR);
|
|
@@ -287,6 +276,20 @@ async function runInteractive() {
|
|
|
287
276
|
message: "Include private repos?",
|
|
288
277
|
default: true
|
|
289
278
|
});
|
|
279
|
+
const resolvedUsername = username || await getAuthenticatedUser();
|
|
280
|
+
const userOrgs = await fetchUserOrgs(resolvedUsername);
|
|
281
|
+
const allScopes = [resolvedUsername, ...userOrgs];
|
|
282
|
+
const ALL_VALUE = "__ALL__";
|
|
283
|
+
const scopeChoices = [
|
|
284
|
+
{ name: "All (no filter)", value: ALL_VALUE },
|
|
285
|
+
...allScopes.map((org) => ({ name: org, value: org }))
|
|
286
|
+
];
|
|
287
|
+
const scopeSelection = await select({
|
|
288
|
+
message: "Filter by scope",
|
|
289
|
+
choices: scopeChoices,
|
|
290
|
+
default: ALL_VALUE
|
|
291
|
+
});
|
|
292
|
+
const selectedOrgs = scopeSelection === ALL_VALUE ? null : [scopeSelection];
|
|
290
293
|
const model = await input({
|
|
291
294
|
message: "Claude model (leave empty for default)",
|
|
292
295
|
default: ""
|
|
@@ -298,6 +301,7 @@ async function runInteractive() {
|
|
|
298
301
|
verbosity,
|
|
299
302
|
format,
|
|
300
303
|
includePrivate,
|
|
304
|
+
selectedOrgs,
|
|
301
305
|
model
|
|
302
306
|
};
|
|
303
307
|
}
|
|
@@ -471,15 +475,19 @@ function validateVerbosity(value) {
|
|
|
471
475
|
const valid = ["brief", "normal", "detailed"];
|
|
472
476
|
return valid.includes(value) ? value : "normal";
|
|
473
477
|
}
|
|
474
|
-
async function execute(username, days, lang, format, publicOnly, verbosity, model) {
|
|
478
|
+
async function execute(username, days, lang, format, publicOnly, verbosity, filterOrgs, model) {
|
|
475
479
|
const resolvedUsername = username || await getAuthenticatedUser();
|
|
480
|
+
const scopeInfo = filterOrgs ? ` in ${filterOrgs.join(", ")}` : "";
|
|
476
481
|
console.error(
|
|
477
|
-
chalk.yellow(
|
|
482
|
+
chalk.yellow(
|
|
483
|
+
`Fetching GitHub activity for ${resolvedUsername}${scopeInfo}...`
|
|
484
|
+
)
|
|
478
485
|
);
|
|
479
486
|
const activity = await fetchGitHubActivity(
|
|
480
487
|
resolvedUsername,
|
|
481
488
|
days,
|
|
482
|
-
publicOnly
|
|
489
|
+
publicOnly,
|
|
490
|
+
filterOrgs
|
|
483
491
|
);
|
|
484
492
|
if (!hasActivity(activity)) {
|
|
485
493
|
console.log("");
|
|
@@ -513,6 +521,9 @@ async function run() {
|
|
|
513
521
|
"-v, --verbosity <level>",
|
|
514
522
|
"Summary verbosity: brief|normal|detailed",
|
|
515
523
|
"normal"
|
|
524
|
+
).option(
|
|
525
|
+
"-o, --orgs <orgs>",
|
|
526
|
+
"Filter by organizations/accounts (comma-separated)"
|
|
516
527
|
).option(
|
|
517
528
|
"-m, --model <model>",
|
|
518
529
|
"Claude model to use (e.g., sonnet, opus, haiku)"
|
|
@@ -530,12 +541,14 @@ async function run() {
|
|
|
530
541
|
answers.format,
|
|
531
542
|
!answers.includePrivate,
|
|
532
543
|
answers.verbosity,
|
|
544
|
+
answers.selectedOrgs,
|
|
533
545
|
answers.model || void 0
|
|
534
546
|
);
|
|
535
547
|
} else {
|
|
536
548
|
const days = parseInt(options.days, 10);
|
|
537
549
|
const lang = options.english ? "en" : "de";
|
|
538
550
|
const format = options.format;
|
|
551
|
+
const filterOrgs = options.orgs ? options.orgs.split(",").map((o) => o.trim()).filter(Boolean) : null;
|
|
539
552
|
await execute(
|
|
540
553
|
username || "",
|
|
541
554
|
days,
|
|
@@ -543,6 +556,7 @@ async function run() {
|
|
|
543
556
|
format,
|
|
544
557
|
options.publicOnly,
|
|
545
558
|
validateVerbosity(options.verbosity),
|
|
559
|
+
filterOrgs && filterOrgs.length > 0 ? filterOrgs : null,
|
|
546
560
|
options.model
|
|
547
561
|
);
|
|
548
562
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/claude.ts","../src/github.ts","../src/interactive.ts","../src/output.ts","../src/index.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { generateSummaryText } from \"./claude.js\";\nimport { fetchGitHubActivity, getAuthenticatedUser } from \"./github.js\";\nimport { runInteractive } from \"./interactive.js\";\nimport { formatActivity, hasActivity } from \"./output.js\";\nimport type { Language, OutputFormat, Verbosity } from \"./types.js\";\n\nasync function checkDependencies(): Promise<void> {\n\tconst { execa } = await import(\"execa\");\n\n\tconst deps = [\n\t\t{ cmd: \"gh\", name: \"GitHub CLI\", installHint: \"brew install gh\" },\n\t\t{\n\t\t\tcmd: \"claude\",\n\t\t\tname: \"Claude Code CLI\",\n\t\t\tinstallHint: \"npm install -g @anthropic-ai/claude-code\",\n\t\t},\n\t];\n\n\tconst missing: string[] = [];\n\n\tfor (const dep of deps) {\n\t\ttry {\n\t\t\tawait execa(\"which\", [dep.cmd]);\n\t\t} catch {\n\t\t\tmissing.push(`${dep.name} (${dep.installHint})`);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tconsole.error(chalk.red(\"Missing dependencies:\"));\n\t\tfor (const m of missing) {\n\t\t\tconsole.error(` - ${m}`);\n\t\t}\n\t\tprocess.exit(1);\n\t}\n\n\t// Check gh auth\n\ttry {\n\t\tawait execa(\"gh\", [\"auth\", \"status\"]);\n\t} catch {\n\t\tconsole.error(\n\t\t\tchalk.red(\"GitHub CLI not authenticated. Run 'gh auth login'.\"),\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n\ninterface CliOptions {\n\tdays: string;\n\tenglish: boolean;\n\tformat: OutputFormat;\n\tpublicOnly: boolean;\n\tinteractive: boolean;\n\tverbosity: string;\n\tmodel?: string;\n}\n\nfunction validateVerbosity(value: string): Verbosity {\n\tconst valid: Verbosity[] = [\"brief\", \"normal\", \"detailed\"];\n\treturn valid.includes(value as Verbosity) ? (value as Verbosity) : \"normal\";\n}\n\nasync function execute(\n\tusername: string,\n\tdays: number,\n\tlang: Language,\n\tformat: OutputFormat,\n\tpublicOnly: boolean,\n\tverbosity: Verbosity,\n\tmodel?: string,\n): Promise<void> {\n\t// Resolve username\n\tconst resolvedUsername = username || (await getAuthenticatedUser());\n\n\tconsole.error(\n\t\tchalk.yellow(`Fetching GitHub activity for ${resolvedUsername}...`),\n\t);\n\n\tconst activity = await fetchGitHubActivity(\n\t\tresolvedUsername,\n\t\tdays,\n\t\tpublicOnly,\n\t);\n\n\tif (!hasActivity(activity)) {\n\t\tconsole.log(\"\");\n\t\tconsole.log(`tl;dr ${activity.date}`);\n\t\tconsole.log(\"\");\n\t\tconst noActivity =\n\t\t\tlang === \"en\"\n\t\t\t\t? `No GitHub activity in the ${activity.period}.`\n\t\t\t\t: `Keine GitHub-Aktivität in den ${activity.period}.`;\n\t\tconsole.log(noActivity);\n\t\treturn;\n\t}\n\n\t// Format stats locally\n\tconst stats = formatActivity(activity, format, lang);\n\n\tconsole.error(chalk.yellow(\"Generating summary with Claude...\"));\n\n\t// Only ask Claude for the summary paragraph\n\tconst summaryText = await generateSummaryText(\n\t\tactivity,\n\t\tlang,\n\t\tverbosity,\n\t\tmodel,\n\t);\n\n\tconsole.log(\"\");\n\tconsole.log(stats);\n\tconsole.log(\"\");\n\tconsole.log(\"---\");\n\tconsole.log(summaryText);\n}\n\nexport async function run(): Promise<void> {\n\tconst program = new Command();\n\n\tprogram\n\t\t.name(\"gh-tldr\")\n\t\t.description(\"Generate a TL;DR summary of your GitHub activity\")\n\t\t.version(\"1.0.0\")\n\t\t.argument(\"[username]\", \"GitHub username (defaults to authenticated user)\")\n\t\t.option(\"-d, --days <n>\", \"Time period in days\", \"1\")\n\t\t.option(\"-e, --english\", \"Output in English (default: German)\", false)\n\t\t.option(\n\t\t\t\"-f, --format <type>\",\n\t\t\t\"Output format: slack|markdown|plain\",\n\t\t\t\"slack\",\n\t\t)\n\t\t.option(\"-p, --public-only\", \"Exclude private repositories\", false)\n\t\t.option(\"-i, --interactive\", \"Force interactive mode\", false)\n\t\t.option(\n\t\t\t\"-v, --verbosity <level>\",\n\t\t\t\"Summary verbosity: brief|normal|detailed\",\n\t\t\t\"normal\",\n\t\t)\n\t\t.option(\n\t\t\t\"-m, --model <model>\",\n\t\t\t\"Claude model to use (e.g., sonnet, opus, haiku)\",\n\t\t)\n\t\t.action(async (username: string | undefined, options: CliOptions) => {\n\t\t\ttry {\n\t\t\t\tawait checkDependencies();\n\n\t\t\t\t// Determine if we should run interactive mode\n\t\t\t\tconst hasArgs = process.argv.length > 2;\n\t\t\t\tconst forceInteractive = options.interactive;\n\n\t\t\t\tif (!hasArgs || forceInteractive) {\n\t\t\t\t\t// Interactive mode\n\t\t\t\t\tconst answers = await runInteractive();\n\t\t\t\t\tawait execute(\n\t\t\t\t\t\tanswers.username,\n\t\t\t\t\t\tanswers.days,\n\t\t\t\t\t\tanswers.language,\n\t\t\t\t\t\tanswers.format,\n\t\t\t\t\t\t!answers.includePrivate,\n\t\t\t\t\t\tanswers.verbosity,\n\t\t\t\t\t\tanswers.model || undefined,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Direct mode\n\t\t\t\t\tconst days = parseInt(options.days, 10);\n\t\t\t\t\tconst lang: Language = options.english ? \"en\" : \"de\";\n\t\t\t\t\tconst format = options.format as OutputFormat;\n\n\t\t\t\t\tawait execute(\n\t\t\t\t\t\tusername || \"\",\n\t\t\t\t\t\tdays,\n\t\t\t\t\t\tlang,\n\t\t\t\t\t\tformat,\n\t\t\t\t\t\toptions.publicOnly,\n\t\t\t\t\t\tvalidateVerbosity(options.verbosity),\n\t\t\t\t\t\toptions.model,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error) {\n\t\t\t\t\tconsole.error(chalk.red(`Error: ${error.message}`));\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n\n\tawait program.parseAsync();\n}\n","import { execa } from \"execa\";\nimport type { GitHubActivity, Language, Verbosity } from \"./types.js\";\n\nconst wordLimits: Record<Verbosity, Record<Language, string>> = {\n\tbrief: { en: \"20-40 word\", de: \"20-40 Wörter\" },\n\tnormal: { en: \"50-80 word\", de: \"50-80 Wörter\" },\n\tdetailed: { en: \"150-200 word\", de: \"150-200 Wörter\" },\n};\n\nfunction buildPrompt(lang: Language, verbosity: Verbosity): string {\n\tconst limit = wordLimits[verbosity][lang];\n\n\tif (lang === \"en\") {\n\t\treturn `Based on this GitHub activity data, write a summary of what was accomplished. STRICT LIMIT: ${limit}. Mention specific PR/issue titles. Casual tone, no bullet points, no emojis.\n\nGitHub Activity Data:`;\n\t}\n\n\treturn `Basierend auf diesen GitHub-Aktivitätsdaten, schreibe eine Zusammenfassung was gemacht wurde. STRIKTES LIMIT: ${limit}. Erwähne konkret die PR/Issue-Titel. Lockerer Ton, keine Aufzählungen, keine Emojis.\n\nGitHub-Aktivitätsdaten:`;\n}\n\nexport async function generateSummaryText(\n\tactivity: GitHubActivity,\n\tlang: Language,\n\tverbosity: Verbosity = \"normal\",\n\tmodel?: string,\n): Promise<string> {\n\tconst prompt = buildPrompt(lang, verbosity);\n\tconst fullPrompt = `${prompt}\\n${JSON.stringify(activity, null, 2)}`;\n\n\tconst args = [\"-p\", \"-\", \"--output-format\", \"text\"];\n\tif (model) {\n\t\targs.push(\"--model\", model);\n\t}\n\n\tconst { stdout } = await execa(\"claude\", args, {\n\t\tinput: fullPrompt,\n\t});\n\n\treturn stdout.trim();\n}\n","import { execa } from \"execa\";\nimport type {\n\tCommit,\n\tGitHubActivity,\n\tIssue,\n\tPullRequest,\n\tRepoInfo,\n} from \"./types.js\";\n\nfunction getSinceDate(days: number): string {\n\tconst date = new Date();\n\tdate.setDate(date.getDate() - days);\n\treturn date.toISOString();\n}\n\nfunction formatDate(date: Date): string {\n\tconst day = date.getDate().toString().padStart(2, \"0\");\n\tconst month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n\tconst year = date.getFullYear();\n\treturn `${day}.${month}.${year}`;\n}\n\nasync function ghApi<T>(\n\tendpoint: string,\n\tparams: Record<string, string>,\n): Promise<T> {\n\tconst args = [\n\t\t\"api\",\n\t\t\"-X\",\n\t\t\"GET\",\n\t\tendpoint,\n\t\t...Object.entries(params).flatMap(([key, value]) => [\n\t\t\t\"-f\",\n\t\t\t`${key}=${value}`,\n\t\t]),\n\t];\n\n\tconst { stdout } = await execa(\"gh\", args);\n\treturn JSON.parse(stdout) as T;\n}\n\nasync function ghApiPaginated<T>(\n\tendpoint: string,\n\tparams: Record<string, string>,\n\tmaxPages: number = 10,\n): Promise<T[]> {\n\tconst allItems: T[] = [];\n\tlet page = 1;\n\n\twhile (page <= maxPages) {\n\t\tconst result = await ghApi<SearchResult<T>>(endpoint, {\n\t\t\t...params,\n\t\t\tpage: String(page),\n\t\t\tper_page: \"100\",\n\t\t});\n\n\t\tallItems.push(...result.items);\n\n\t\tif (result.items.length < 100) {\n\t\t\tbreak;\n\t\t}\n\t\tpage++;\n\t}\n\n\treturn allItems;\n}\n\ninterface SearchResult<T> {\n\ttotal_count?: number;\n\titems: T[];\n}\n\ninterface RawPR {\n\trepository_url: string;\n\ttitle: string;\n\tnumber: number;\n\tstate: string;\n\thtml_url: string;\n}\n\ninterface RawCommit {\n\trepository: {\n\t\tname: string;\n\t\towner: { login: string };\n\t};\n\tcommit: {\n\t\tmessage: string;\n\t\tauthor: { date: string };\n\t};\n\thtml_url: string;\n}\n\ninterface RawRepo {\n\tname: string;\n\towner: { login: string };\n\tcreated_at: string;\n\thtml_url: string;\n}\n\nfunction parsePR(item: RawPR): PullRequest {\n\tconst urlParts = item.repository_url.split(\"/\");\n\treturn {\n\t\trepo: urlParts[urlParts.length - 1],\n\t\torg: urlParts[urlParts.length - 2],\n\t\ttitle: item.title,\n\t\tnumber: item.number,\n\t\tstate: item.state,\n\t\turl: item.html_url,\n\t};\n}\n\nfunction parseIssue(item: RawPR): Issue {\n\tconst urlParts = item.repository_url.split(\"/\");\n\treturn {\n\t\trepo: urlParts[urlParts.length - 1],\n\t\torg: urlParts[urlParts.length - 2],\n\t\ttitle: item.title,\n\t\tnumber: item.number,\n\t\turl: item.html_url,\n\t};\n}\n\nfunction parseCommit(item: RawCommit): Commit {\n\treturn {\n\t\trepo: item.repository.name,\n\t\torg: item.repository.owner.login,\n\t\tmessage: item.commit.message.split(\"\\n\")[0],\n\t\turl: item.html_url,\n\t\tdate: item.commit.author.date,\n\t};\n}\n\nexport async function getAuthenticatedUser(): Promise<string> {\n\tconst { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n\treturn stdout.trim();\n}\n\nasync function fetchUserOrgs(username: string): Promise<string[]> {\n\t// First try authenticated user's orgs (includes private memberships)\n\ttry {\n\t\tconst authUser = await getAuthenticatedUser();\n\t\tif (authUser === username) {\n\t\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\t\"api\",\n\t\t\t\t\"user/orgs\",\n\t\t\t\t\"--jq\",\n\t\t\t\t\".[].login\",\n\t\t\t]);\n\t\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t\t}\n\t} catch {\n\t\t// Fall through to public orgs\n\t}\n\n\t// Fallback to public orgs for other users\n\ttry {\n\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\"api\",\n\t\t\t`users/${username}/orgs`,\n\t\t\t\"--jq\",\n\t\t\t\".[].login\",\n\t\t]);\n\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nasync function fetchReposCreatedSince(\n\tusername: string,\n\tsince: string,\n\tpublicOnly: boolean,\n): Promise<RepoInfo[]> {\n\tconst sinceDate = new Date(since);\n\tconst repos: RepoInfo[] = [];\n\n\t// Fetch user's own repos\n\ttry {\n\t\tconst visibility = publicOnly ? \"public\" : \"all\";\n\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\"api\",\n\t\t\t`users/${username}/repos?type=${visibility}&sort=created&direction=desc&per_page=100`,\n\t\t]);\n\t\tconst userRepos = JSON.parse(stdout) as RawRepo[];\n\t\tfor (const repo of userRepos) {\n\t\t\tif (new Date(repo.created_at) >= sinceDate) {\n\t\t\t\trepos.push({ name: repo.name, org: repo.owner.login });\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore errors for user repos\n\t}\n\n\t// Fetch repos from user's orgs\n\tconst orgs = await fetchUserOrgs(username);\n\tfor (const org of orgs) {\n\t\ttry {\n\t\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\t\"api\",\n\t\t\t\t`orgs/${org}/repos?sort=created&direction=desc&per_page=100`,\n\t\t\t]);\n\t\t\tconst orgRepos = JSON.parse(stdout) as RawRepo[];\n\t\t\tfor (const repo of orgRepos) {\n\t\t\t\tif (new Date(repo.created_at) >= sinceDate) {\n\t\t\t\t\trepos.push({ name: repo.name, org: repo.owner.login });\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors for individual orgs\n\t\t}\n\t}\n\n\t// Deduplicate\n\treturn repos.filter(\n\t\t(repo, index, self) =>\n\t\t\tself.findIndex((r) => r.name === repo.name && r.org === repo.org) ===\n\t\t\tindex,\n\t);\n}\n\nexport async function fetchGitHubActivity(\n\tusername: string,\n\tdays: number,\n\tpublicOnly: boolean,\n): Promise<GitHubActivity> {\n\tconst since = getSinceDate(days);\n\tconst today = formatDate(new Date());\n\tconst visibilityFilter = publicOnly ? \" is:public\" : \"\";\n\n\t// Fetch all data in parallel with pagination\n\tconst [\n\t\tprsCreatedItems,\n\t\tprsMergedItems,\n\t\tprsReviewedItems,\n\t\tissuesCreatedItems,\n\t\tissuesClosedItems,\n\t\tcommitsItems,\n\t\trepos_created,\n\t] = await Promise.all([\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:pr created:>=${since}${visibilityFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:pr merged:>=${since}${visibilityFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `reviewed-by:${username} type:pr created:>=${since} -author:${username}${visibilityFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:issue created:>=${since}${visibilityFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:issue closed:>=${since}${visibilityFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawCommit>(\"search/commits\", {\n\t\t\tq: `author:${username} committer-date:>=${since}`,\n\t\t}),\n\t\tfetchReposCreatedSince(username, since, publicOnly),\n\t]);\n\n\tconst prs_created = prsCreatedItems.map(parsePR);\n\tconst prs_merged = prsMergedItems.map(parsePR);\n\tconst prs_reviewed = prsReviewedItems.map(parsePR);\n\tconst issues_created = issuesCreatedItems.map(parseIssue);\n\tconst issues_closed = issuesClosedItems.map(parseIssue);\n\tconst commits = commitsItems.map(parseCommit);\n\n\t// Extract unique repos touched\n\tconst allRepos = [\n\t\t...prs_created,\n\t\t...prs_merged,\n\t\t...prs_reviewed,\n\t\t...issues_created,\n\t\t...issues_closed,\n\t\t...commits,\n\t].map((item) => `${item.org}/${item.repo}`);\n\n\tconst repos_touched = [...new Set(allRepos)];\n\n\tconst periodText =\n\t\tdays === 1\n\t\t\t? \"last 24 hours\"\n\t\t\t: days === 7\n\t\t\t\t? \"last 7 days\"\n\t\t\t\t: days === 30\n\t\t\t\t\t? \"last 30 days\"\n\t\t\t\t\t: `last ${days} days`;\n\n\treturn {\n\t\tuser: username,\n\t\tdate: today,\n\t\tperiod: periodText,\n\t\tprs_created,\n\t\tprs_merged,\n\t\tprs_reviewed,\n\t\tissues_created,\n\t\tissues_closed,\n\t\tcommits,\n\t\trepos_created,\n\t\trepos_touched,\n\t};\n}\n","import { confirm, input, select } from \"@inquirer/prompts\";\nimport type { Language, OutputFormat, Verbosity } from \"./types.js\";\n\ninterface InteractiveOptions {\n\tusername: string;\n\tdays: number;\n\tlanguage: Language;\n\tverbosity: Verbosity;\n\tformat: OutputFormat;\n\tincludePrivate: boolean;\n\tmodel: string;\n}\n\nexport async function runInteractive(): Promise<InteractiveOptions> {\n\tconst username = await input({\n\t\tmessage: \"GitHub username (leave empty for authenticated user)\",\n\t\tdefault: \"\",\n\t});\n\n\tconst days = await select({\n\t\tmessage: \"Time period\",\n\t\tchoices: [\n\t\t\t{ name: \"Last 24 hours\", value: 1 },\n\t\t\t{ name: \"Last 7 days\", value: 7 },\n\t\t\t{ name: \"Last 30 days\", value: 30 },\n\t\t],\n\t\tdefault: 1,\n\t});\n\n\tconst language = await select({\n\t\tmessage: \"Language\",\n\t\tchoices: [\n\t\t\t{ name: \"English\", value: \"en\" as Language },\n\t\t\t{ name: \"German\", value: \"de\" as Language },\n\t\t],\n\t\tdefault: \"en\" as Language,\n\t});\n\n\tconst verbosity = await select({\n\t\tmessage: \"Summary verbosity\",\n\t\tchoices: [\n\t\t\t{ name: \"Brief (~30 words)\", value: \"brief\" as Verbosity },\n\t\t\t{ name: \"Normal (~60 words)\", value: \"normal\" as Verbosity },\n\t\t\t{ name: \"Detailed (~175 words)\", value: \"detailed\" as Verbosity },\n\t\t],\n\t\tdefault: \"normal\" as Verbosity,\n\t});\n\n\tconst format = await select({\n\t\tmessage: \"Output format\",\n\t\tchoices: [\n\t\t\t{ name: \"Plain text\", value: \"plain\" as OutputFormat },\n\t\t\t{ name: \"Markdown\", value: \"markdown\" as OutputFormat },\n\t\t\t{ name: \"Slack\", value: \"slack\" as OutputFormat },\n\t\t],\n\t\tdefault: \"plain\" as OutputFormat,\n\t});\n\n\tconst includePrivate = await confirm({\n\t\tmessage: \"Include private repos?\",\n\t\tdefault: true,\n\t});\n\n\tconst model = await input({\n\t\tmessage: \"Claude model (leave empty for default)\",\n\t\tdefault: \"\",\n\t});\n\n\treturn {\n\t\tusername,\n\t\tdays,\n\t\tlanguage,\n\t\tverbosity,\n\t\tformat,\n\t\tincludePrivate,\n\t\tmodel,\n\t};\n}\n","import type {\n\tCommit,\n\tGitHubActivity,\n\tLanguage,\n\tOutputFormat,\n} from \"./types.js\";\n\n// Gap threshold: if gap between commits > 3 hours, treat as separate session\nconst GAP_THRESHOLD_MS = 3 * 60 * 60 * 1000;\n// Minimum time to count for a single-commit session (15 minutes)\nconst SINGLE_COMMIT_HOURS = 0.25;\n\nfunction calculateWorkSession(\n\tcommits: Commit[],\n\tlang: Language,\n): string | null {\n\tif (commits.length < 2) return null;\n\n\t// Sort timestamps chronologically\n\tconst timestamps = commits\n\t\t.map((c) => new Date(c.date).getTime())\n\t\t.sort((a, b) => a - b);\n\n\t// Group commits into sessions based on gap threshold\n\tconst sessions: number[][] = [];\n\tlet currentSession = [timestamps[0]];\n\n\tfor (let i = 1; i < timestamps.length; i++) {\n\t\tconst gap = timestamps[i] - timestamps[i - 1];\n\t\tif (gap > GAP_THRESHOLD_MS) {\n\t\t\tsessions.push(currentSession);\n\t\t\tcurrentSession = [timestamps[i]];\n\t\t} else {\n\t\t\tcurrentSession.push(timestamps[i]);\n\t\t}\n\t}\n\tsessions.push(currentSession);\n\n\t// Calculate total hours across all sessions\n\tlet totalHours = 0;\n\tfor (const session of sessions) {\n\t\tif (session.length === 1) {\n\t\t\ttotalHours += SINGLE_COMMIT_HOURS;\n\t\t} else {\n\t\t\tconst duration = session[session.length - 1] - session[0];\n\t\t\ttotalHours += duration / (1000 * 60 * 60);\n\t\t}\n\t}\n\n\t// Round to nearest 0.5 hours\n\tconst rounded = Math.round(totalHours * 2) / 2;\n\n\tif (rounded < 0.5) return null;\n\n\tconst label = lang === \"en\" ? \"Work session\" : \"Arbeitszeit\";\n\tconst hoursLabel =\n\t\trounded === 1\n\t\t\t? lang === \"en\"\n\t\t\t\t? \"hour\"\n\t\t\t\t: \"Stunde\"\n\t\t\t: lang === \"en\"\n\t\t\t\t? \"hours\"\n\t\t\t\t: \"Stunden\";\n\n\treturn `${label}: ~${rounded} ${hoursLabel}`;\n}\n\nfunction getRepoNames(items: { repo: string }[]): string {\n\tconst repos = [...new Set(items.map((i) => i.repo))];\n\treturn repos.join(\", \");\n}\n\nfunction formatActivityLine(\n\tcount: number,\n\tlabelEn: string,\n\tlabelDe: string,\n\trepos: string,\n\tlang: Language,\n\tformat: OutputFormat,\n): string | null {\n\tif (count === 0) return null;\n\n\tconst label = lang === \"en\" ? labelEn : labelDe;\n\tconst repoSuffix = repos ? ` (${repos})` : \"\";\n\n\tif (format === \"markdown\") {\n\t\treturn `- **${count}** ${label}${repoSuffix}`;\n\t}\n\treturn `• ${count} ${label}${repoSuffix}`;\n}\n\nexport function formatActivity(\n\tactivity: GitHubActivity,\n\tformat: OutputFormat,\n\tlang: Language,\n): string {\n\tconst lines: string[] = [];\n\n\t// Header\n\tconst headerPrefix = format === \"markdown\" ? \"## \" : \"\";\n\tlines.push(`${headerPrefix}tl;dr ${activity.date}`);\n\tlines.push(\"\");\n\n\tconst activityLines = [\n\t\tformatActivityLine(\n\t\t\tactivity.prs_created.length,\n\t\t\t\"PRs created\",\n\t\t\t\"PRs erstellt\",\n\t\t\tgetRepoNames(activity.prs_created),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.prs_reviewed.length,\n\t\t\t\"PRs reviewed\",\n\t\t\t\"PRs reviewed/approved\",\n\t\t\tgetRepoNames(activity.prs_reviewed),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.prs_merged.length,\n\t\t\t\"PRs merged\",\n\t\t\t\"PRs gemerged\",\n\t\t\tgetRepoNames(activity.prs_merged),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.issues_created.length,\n\t\t\t\"issues created\",\n\t\t\t\"Issues erstellt\",\n\t\t\tgetRepoNames(activity.issues_created),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.issues_closed.length,\n\t\t\t\"issues closed\",\n\t\t\t\"Issues geschlossen\",\n\t\t\tgetRepoNames(activity.issues_closed),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.commits.length,\n\t\t\t\"commits\",\n\t\t\t\"Commits\",\n\t\t\tgetRepoNames(activity.commits),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.repos_created.length,\n\t\t\t\"new repos created\",\n\t\t\t\"neue Repos erstellt\",\n\t\t\tactivity.repos_created.map((r) => r.name).join(\", \"),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t].filter(Boolean) as string[];\n\n\tif (activityLines.length === 0) {\n\t\tconst noActivity =\n\t\t\tlang === \"en\"\n\t\t\t\t? `No GitHub activity in the ${activity.period}.`\n\t\t\t\t: `Keine GitHub-Aktivität in den ${activity.period}.`;\n\t\tlines.push(noActivity);\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tlines.push(...activityLines);\n\n\t// Work session duration\n\tconst workSession = calculateWorkSession(activity.commits, lang);\n\tif (workSession) {\n\t\tlines.push(format === \"markdown\" ? `- ${workSession}` : `• ${workSession}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Repos touched\n\tif (activity.repos_touched.length > 0) {\n\t\tconst reposLabel = lang === \"en\" ? \"Repos\" : \"Repos\";\n\t\tlines.push(`${reposLabel}: ${activity.repos_touched.join(\", \")}`);\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function hasActivity(activity: GitHubActivity): boolean {\n\treturn (\n\t\tactivity.prs_created.length +\n\t\t\tactivity.prs_merged.length +\n\t\t\tactivity.prs_reviewed.length +\n\t\t\tactivity.issues_created.length +\n\t\t\tactivity.issues_closed.length >\n\t\t0\n\t);\n}\n","// gh-tldr - Generate a TL;DR summary of your GitHub activity\n// Entry point: detects mode (interactive vs direct) and runs CLI\n\nimport { run } from \"./cli.js\";\n\nrun();\n"],"mappings":"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","names":["execa","execa"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/claude.ts","../src/github.ts","../src/interactive.ts","../src/output.ts","../src/index.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { generateSummaryText } from \"./claude.js\";\nimport { fetchGitHubActivity, getAuthenticatedUser } from \"./github.js\";\nimport { runInteractive } from \"./interactive.js\";\nimport { formatActivity, hasActivity } from \"./output.js\";\nimport type { Language, OutputFormat, Verbosity } from \"./types.js\";\n\nasync function checkDependencies(): Promise<void> {\n\tconst { execa } = await import(\"execa\");\n\n\tconst deps = [\n\t\t{ cmd: \"gh\", name: \"GitHub CLI\", installHint: \"brew install gh\" },\n\t\t{\n\t\t\tcmd: \"claude\",\n\t\t\tname: \"Claude Code CLI\",\n\t\t\tinstallHint: \"npm install -g @anthropic-ai/claude-code\",\n\t\t},\n\t];\n\n\tconst missing: string[] = [];\n\n\tfor (const dep of deps) {\n\t\ttry {\n\t\t\tawait execa(\"which\", [dep.cmd]);\n\t\t} catch {\n\t\t\tmissing.push(`${dep.name} (${dep.installHint})`);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tconsole.error(chalk.red(\"Missing dependencies:\"));\n\t\tfor (const m of missing) {\n\t\t\tconsole.error(` - ${m}`);\n\t\t}\n\t\tprocess.exit(1);\n\t}\n\n\t// Check gh auth\n\ttry {\n\t\tawait execa(\"gh\", [\"auth\", \"status\"]);\n\t} catch {\n\t\tconsole.error(\n\t\t\tchalk.red(\"GitHub CLI not authenticated. Run 'gh auth login'.\"),\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n\ninterface CliOptions {\n\tdays: string;\n\tenglish: boolean;\n\tformat: OutputFormat;\n\tpublicOnly: boolean;\n\tinteractive: boolean;\n\tverbosity: string;\n\torgs?: string;\n\tmodel?: string;\n}\n\nfunction validateVerbosity(value: string): Verbosity {\n\tconst valid: Verbosity[] = [\"brief\", \"normal\", \"detailed\"];\n\treturn valid.includes(value as Verbosity) ? (value as Verbosity) : \"normal\";\n}\n\nasync function execute(\n\tusername: string,\n\tdays: number,\n\tlang: Language,\n\tformat: OutputFormat,\n\tpublicOnly: boolean,\n\tverbosity: Verbosity,\n\tfilterOrgs: string[] | null,\n\tmodel?: string,\n): Promise<void> {\n\t// Resolve username\n\tconst resolvedUsername = username || (await getAuthenticatedUser());\n\n\tconst scopeInfo = filterOrgs ? ` in ${filterOrgs.join(\", \")}` : \"\";\n\tconsole.error(\n\t\tchalk.yellow(\n\t\t\t`Fetching GitHub activity for ${resolvedUsername}${scopeInfo}...`,\n\t\t),\n\t);\n\n\tconst activity = await fetchGitHubActivity(\n\t\tresolvedUsername,\n\t\tdays,\n\t\tpublicOnly,\n\t\tfilterOrgs,\n\t);\n\n\tif (!hasActivity(activity)) {\n\t\tconsole.log(\"\");\n\t\tconsole.log(`tl;dr ${activity.date}`);\n\t\tconsole.log(\"\");\n\t\tconst noActivity =\n\t\t\tlang === \"en\"\n\t\t\t\t? `No GitHub activity in the ${activity.period}.`\n\t\t\t\t: `Keine GitHub-Aktivität in den ${activity.period}.`;\n\t\tconsole.log(noActivity);\n\t\treturn;\n\t}\n\n\t// Format stats locally\n\tconst stats = formatActivity(activity, format, lang);\n\n\tconsole.error(chalk.yellow(\"Generating summary with Claude...\"));\n\n\t// Only ask Claude for the summary paragraph\n\tconst summaryText = await generateSummaryText(\n\t\tactivity,\n\t\tlang,\n\t\tverbosity,\n\t\tmodel,\n\t);\n\n\tconsole.log(\"\");\n\tconsole.log(stats);\n\tconsole.log(\"\");\n\tconsole.log(\"---\");\n\tconsole.log(summaryText);\n}\n\nexport async function run(): Promise<void> {\n\tconst program = new Command();\n\n\tprogram\n\t\t.name(\"gh-tldr\")\n\t\t.description(\"Generate a TL;DR summary of your GitHub activity\")\n\t\t.version(\"1.0.0\")\n\t\t.argument(\"[username]\", \"GitHub username (defaults to authenticated user)\")\n\t\t.option(\"-d, --days <n>\", \"Time period in days\", \"1\")\n\t\t.option(\"-e, --english\", \"Output in English (default: German)\", false)\n\t\t.option(\n\t\t\t\"-f, --format <type>\",\n\t\t\t\"Output format: slack|markdown|plain\",\n\t\t\t\"slack\",\n\t\t)\n\t\t.option(\"-p, --public-only\", \"Exclude private repositories\", false)\n\t\t.option(\"-i, --interactive\", \"Force interactive mode\", false)\n\t\t.option(\n\t\t\t\"-v, --verbosity <level>\",\n\t\t\t\"Summary verbosity: brief|normal|detailed\",\n\t\t\t\"normal\",\n\t\t)\n\t\t.option(\n\t\t\t\"-o, --orgs <orgs>\",\n\t\t\t\"Filter by organizations/accounts (comma-separated)\",\n\t\t)\n\t\t.option(\n\t\t\t\"-m, --model <model>\",\n\t\t\t\"Claude model to use (e.g., sonnet, opus, haiku)\",\n\t\t)\n\t\t.action(async (username: string | undefined, options: CliOptions) => {\n\t\t\ttry {\n\t\t\t\tawait checkDependencies();\n\n\t\t\t\t// Determine if we should run interactive mode\n\t\t\t\tconst hasArgs = process.argv.length > 2;\n\t\t\t\tconst forceInteractive = options.interactive;\n\n\t\t\t\tif (!hasArgs || forceInteractive) {\n\t\t\t\t\t// Interactive mode\n\t\t\t\t\tconst answers = await runInteractive();\n\t\t\t\t\tawait execute(\n\t\t\t\t\t\tanswers.username,\n\t\t\t\t\t\tanswers.days,\n\t\t\t\t\t\tanswers.language,\n\t\t\t\t\t\tanswers.format,\n\t\t\t\t\t\t!answers.includePrivate,\n\t\t\t\t\t\tanswers.verbosity,\n\t\t\t\t\t\tanswers.selectedOrgs,\n\t\t\t\t\t\tanswers.model || undefined,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Direct mode\n\t\t\t\t\tconst days = parseInt(options.days, 10);\n\t\t\t\t\tconst lang: Language = options.english ? \"en\" : \"de\";\n\t\t\t\t\tconst format = options.format as OutputFormat;\n\n\t\t\t\t\t// Parse orgs flag\n\t\t\t\t\tconst filterOrgs = options.orgs\n\t\t\t\t\t\t? options.orgs\n\t\t\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t\t\t.map((o) => o.trim())\n\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t: null;\n\n\t\t\t\t\tawait execute(\n\t\t\t\t\t\tusername || \"\",\n\t\t\t\t\t\tdays,\n\t\t\t\t\t\tlang,\n\t\t\t\t\t\tformat,\n\t\t\t\t\t\toptions.publicOnly,\n\t\t\t\t\t\tvalidateVerbosity(options.verbosity),\n\t\t\t\t\t\tfilterOrgs && filterOrgs.length > 0 ? filterOrgs : null,\n\t\t\t\t\t\toptions.model,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error) {\n\t\t\t\t\tconsole.error(chalk.red(`Error: ${error.message}`));\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n\n\tawait program.parseAsync();\n}\n","import { execa } from \"execa\";\nimport type { GitHubActivity, Language, Verbosity } from \"./types.js\";\n\nconst wordLimits: Record<Verbosity, Record<Language, string>> = {\n\tbrief: { en: \"20-40 word\", de: \"20-40 Wörter\" },\n\tnormal: { en: \"50-80 word\", de: \"50-80 Wörter\" },\n\tdetailed: { en: \"150-200 word\", de: \"150-200 Wörter\" },\n};\n\nfunction buildPrompt(lang: Language, verbosity: Verbosity): string {\n\tconst limit = wordLimits[verbosity][lang];\n\n\tif (lang === \"en\") {\n\t\treturn `Based on this GitHub activity data, write a summary of what was accomplished. STRICT LIMIT: ${limit}. Mention specific PR/issue titles. Casual tone, no bullet points, no emojis.\n\nGitHub Activity Data:`;\n\t}\n\n\treturn `Basierend auf diesen GitHub-Aktivitätsdaten, schreibe eine Zusammenfassung was gemacht wurde. STRIKTES LIMIT: ${limit}. Erwähne konkret die PR/Issue-Titel. Lockerer Ton, keine Aufzählungen, keine Emojis.\n\nGitHub-Aktivitätsdaten:`;\n}\n\nexport async function generateSummaryText(\n\tactivity: GitHubActivity,\n\tlang: Language,\n\tverbosity: Verbosity = \"normal\",\n\tmodel?: string,\n): Promise<string> {\n\tconst prompt = buildPrompt(lang, verbosity);\n\tconst fullPrompt = `${prompt}\\n${JSON.stringify(activity, null, 2)}`;\n\n\tconst args = [\"-p\", \"-\", \"--output-format\", \"text\"];\n\tif (model) {\n\t\targs.push(\"--model\", model);\n\t}\n\n\tconst { stdout } = await execa(\"claude\", args, {\n\t\tinput: fullPrompt,\n\t});\n\n\treturn stdout.trim();\n}\n","import { execa } from \"execa\";\nimport type {\n\tCommit,\n\tGitHubActivity,\n\tIssue,\n\tPullRequest,\n\tRepoInfo,\n} from \"./types.js\";\n\nfunction getSinceDate(days: number): string {\n\tconst date = new Date();\n\tdate.setDate(date.getDate() - days);\n\treturn date.toISOString();\n}\n\nfunction formatDate(date: Date): string {\n\tconst day = date.getDate().toString().padStart(2, \"0\");\n\tconst month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n\tconst year = date.getFullYear();\n\treturn `${day}.${month}.${year}`;\n}\n\nasync function ghApi<T>(\n\tendpoint: string,\n\tparams: Record<string, string>,\n): Promise<T> {\n\tconst args = [\n\t\t\"api\",\n\t\t\"-X\",\n\t\t\"GET\",\n\t\tendpoint,\n\t\t...Object.entries(params).flatMap(([key, value]) => [\n\t\t\t\"-f\",\n\t\t\t`${key}=${value}`,\n\t\t]),\n\t];\n\n\tconst { stdout } = await execa(\"gh\", args);\n\treturn JSON.parse(stdout) as T;\n}\n\nasync function ghApiPaginated<T>(\n\tendpoint: string,\n\tparams: Record<string, string>,\n\tmaxPages: number = 10,\n): Promise<T[]> {\n\tconst allItems: T[] = [];\n\tlet page = 1;\n\n\twhile (page <= maxPages) {\n\t\tconst result = await ghApi<SearchResult<T>>(endpoint, {\n\t\t\t...params,\n\t\t\tpage: String(page),\n\t\t\tper_page: \"100\",\n\t\t});\n\n\t\tallItems.push(...result.items);\n\n\t\tif (result.items.length < 100) {\n\t\t\tbreak;\n\t\t}\n\t\tpage++;\n\t}\n\n\treturn allItems;\n}\n\ninterface SearchResult<T> {\n\ttotal_count?: number;\n\titems: T[];\n}\n\ninterface RawPR {\n\trepository_url: string;\n\ttitle: string;\n\tnumber: number;\n\tstate: string;\n\thtml_url: string;\n}\n\ninterface RawCommit {\n\trepository: {\n\t\tname: string;\n\t\towner: { login: string };\n\t};\n\tcommit: {\n\t\tmessage: string;\n\t\tauthor: { date: string };\n\t};\n\thtml_url: string;\n}\n\ninterface RawRepo {\n\tname: string;\n\towner: { login: string };\n\tcreated_at: string;\n\thtml_url: string;\n}\n\nfunction parsePR(item: RawPR): PullRequest {\n\tconst urlParts = item.repository_url.split(\"/\");\n\treturn {\n\t\trepo: urlParts[urlParts.length - 1],\n\t\torg: urlParts[urlParts.length - 2],\n\t\ttitle: item.title,\n\t\tnumber: item.number,\n\t\tstate: item.state,\n\t\turl: item.html_url,\n\t};\n}\n\nfunction parseIssue(item: RawPR): Issue {\n\tconst urlParts = item.repository_url.split(\"/\");\n\treturn {\n\t\trepo: urlParts[urlParts.length - 1],\n\t\torg: urlParts[urlParts.length - 2],\n\t\ttitle: item.title,\n\t\tnumber: item.number,\n\t\turl: item.html_url,\n\t};\n}\n\nfunction parseCommit(item: RawCommit): Commit {\n\treturn {\n\t\trepo: item.repository.name,\n\t\torg: item.repository.owner.login,\n\t\tmessage: item.commit.message.split(\"\\n\")[0],\n\t\turl: item.html_url,\n\t\tdate: item.commit.author.date,\n\t};\n}\n\nexport async function getAuthenticatedUser(): Promise<string> {\n\tconst { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n\treturn stdout.trim();\n}\n\nexport async function fetchUserOrgs(username: string): Promise<string[]> {\n\t// First try authenticated user's orgs (includes private memberships)\n\ttry {\n\t\tconst authUser = await getAuthenticatedUser();\n\t\tif (authUser === username) {\n\t\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\t\"api\",\n\t\t\t\t\"user/orgs\",\n\t\t\t\t\"--jq\",\n\t\t\t\t\".[].login\",\n\t\t\t]);\n\t\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t\t}\n\t} catch {\n\t\t// Fall through to public orgs\n\t}\n\n\t// Fallback to public orgs for other users\n\ttry {\n\t\tconst { stdout } = await execa(\"gh\", [\n\t\t\t\"api\",\n\t\t\t`users/${username}/orgs`,\n\t\t\t\"--jq\",\n\t\t\t\".[].login\",\n\t\t]);\n\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nasync function fetchReposCreatedSince(\n\tusername: string,\n\tsince: string,\n\tpublicOnly: boolean,\n\tfilterOrgs: string[] | null,\n): Promise<RepoInfo[]> {\n\tconst sinceDate = new Date(since);\n\tconst repos: RepoInfo[] = [];\n\n\t// Determine which orgs to check\n\tconst orgsToCheck = filterOrgs ?? [\n\t\tusername,\n\t\t...(await fetchUserOrgs(username)),\n\t];\n\n\tfor (const org of orgsToCheck) {\n\t\ttry {\n\t\t\tconst isUser = org === username;\n\t\t\tconst endpoint = isUser\n\t\t\t\t? `users/${username}/repos?type=${publicOnly ? \"public\" : \"all\"}&sort=created&direction=desc&per_page=100`\n\t\t\t\t: `orgs/${org}/repos?sort=created&direction=desc&per_page=100`;\n\n\t\t\tconst { stdout } = await execa(\"gh\", [\"api\", endpoint]);\n\t\t\tconst orgRepos = JSON.parse(stdout) as RawRepo[];\n\t\t\tfor (const repo of orgRepos) {\n\t\t\t\tif (new Date(repo.created_at) >= sinceDate) {\n\t\t\t\t\trepos.push({ name: repo.name, org: repo.owner.login });\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors for individual orgs\n\t\t}\n\t}\n\n\t// Deduplicate\n\treturn repos.filter(\n\t\t(repo, index, self) =>\n\t\t\tself.findIndex((r) => r.name === repo.name && r.org === repo.org) ===\n\t\t\tindex,\n\t);\n}\n\nexport async function fetchGitHubActivity(\n\tusername: string,\n\tdays: number,\n\tpublicOnly: boolean,\n\tfilterOrgs: string[] | null = null,\n): Promise<GitHubActivity> {\n\tconst since = getSinceDate(days);\n\tconst today = formatDate(new Date());\n\tconst visibilityFilter = publicOnly ? \" is:public\" : \"\";\n\n\t// Build org filter string: \"org:X org:Y\" (implicit OR)\n\tconst orgFilter = filterOrgs\n\t\t? ` ${filterOrgs.map((o) => `org:${o}`).join(\" \")}`\n\t\t: \"\";\n\n\t// Fetch all data in parallel with pagination\n\tconst [\n\t\tprsCreatedItems,\n\t\tprsMergedItems,\n\t\tprsReviewedItems,\n\t\tissuesCreatedItems,\n\t\tissuesClosedItems,\n\t\tcommitsItems,\n\t\trepos_created,\n\t] = await Promise.all([\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:pr created:>=${since}${visibilityFilter}${orgFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:pr merged:>=${since}${visibilityFilter}${orgFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `reviewed-by:${username} type:pr created:>=${since} -author:${username}${visibilityFilter}${orgFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:issue created:>=${since}${visibilityFilter}${orgFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawPR>(\"search/issues\", {\n\t\t\tq: `author:${username} type:issue closed:>=${since}${visibilityFilter}${orgFilter}`,\n\t\t}),\n\t\tghApiPaginated<RawCommit>(\"search/commits\", {\n\t\t\tq: `author:${username} committer-date:>=${since}${orgFilter}`,\n\t\t}),\n\t\tfetchReposCreatedSince(username, since, publicOnly, filterOrgs),\n\t]);\n\n\tconst prs_created = prsCreatedItems.map(parsePR);\n\tconst prs_merged = prsMergedItems.map(parsePR);\n\tconst prs_reviewed = prsReviewedItems.map(parsePR);\n\tconst issues_created = issuesCreatedItems.map(parseIssue);\n\tconst issues_closed = issuesClosedItems.map(parseIssue);\n\tconst commits = commitsItems.map(parseCommit);\n\n\t// Extract unique repos touched\n\tconst allRepos = [\n\t\t...prs_created,\n\t\t...prs_merged,\n\t\t...prs_reviewed,\n\t\t...issues_created,\n\t\t...issues_closed,\n\t\t...commits,\n\t].map((item) => `${item.org}/${item.repo}`);\n\n\tconst repos_touched = [...new Set(allRepos)];\n\n\tconst periodText =\n\t\tdays === 1\n\t\t\t? \"last 24 hours\"\n\t\t\t: days === 7\n\t\t\t\t? \"last 7 days\"\n\t\t\t\t: days === 30\n\t\t\t\t\t? \"last 30 days\"\n\t\t\t\t\t: `last ${days} days`;\n\n\treturn {\n\t\tuser: username,\n\t\tdate: today,\n\t\tperiod: periodText,\n\t\tprs_created,\n\t\tprs_merged,\n\t\tprs_reviewed,\n\t\tissues_created,\n\t\tissues_closed,\n\t\tcommits,\n\t\trepos_created,\n\t\trepos_touched,\n\t};\n}\n","import { confirm, input, select } from \"@inquirer/prompts\";\nimport { fetchUserOrgs, getAuthenticatedUser } from \"./github.js\";\nimport type { Language, OutputFormat, Verbosity } from \"./types.js\";\n\ninterface InteractiveOptions {\n\tusername: string;\n\tdays: number;\n\tlanguage: Language;\n\tverbosity: Verbosity;\n\tformat: OutputFormat;\n\tincludePrivate: boolean;\n\tselectedOrgs: string[] | null;\n\tmodel: string;\n}\n\nexport async function runInteractive(): Promise<InteractiveOptions> {\n\tconst username = await input({\n\t\tmessage: \"GitHub username (leave empty for authenticated user)\",\n\t\tdefault: \"\",\n\t});\n\n\tconst days = await select({\n\t\tmessage: \"Time period\",\n\t\tchoices: [\n\t\t\t{ name: \"Last 24 hours\", value: 1 },\n\t\t\t{ name: \"Last 7 days\", value: 7 },\n\t\t\t{ name: \"Last 30 days\", value: 30 },\n\t\t],\n\t\tdefault: 1,\n\t});\n\n\tconst language = await select({\n\t\tmessage: \"Language\",\n\t\tchoices: [\n\t\t\t{ name: \"English\", value: \"en\" as Language },\n\t\t\t{ name: \"German\", value: \"de\" as Language },\n\t\t],\n\t\tdefault: \"en\" as Language,\n\t});\n\n\tconst verbosity = await select({\n\t\tmessage: \"Summary verbosity\",\n\t\tchoices: [\n\t\t\t{ name: \"Brief (~30 words)\", value: \"brief\" as Verbosity },\n\t\t\t{ name: \"Normal (~60 words)\", value: \"normal\" as Verbosity },\n\t\t\t{ name: \"Detailed (~175 words)\", value: \"detailed\" as Verbosity },\n\t\t],\n\t\tdefault: \"normal\" as Verbosity,\n\t});\n\n\tconst format = await select({\n\t\tmessage: \"Output format\",\n\t\tchoices: [\n\t\t\t{ name: \"Plain text\", value: \"plain\" as OutputFormat },\n\t\t\t{ name: \"Markdown\", value: \"markdown\" as OutputFormat },\n\t\t\t{ name: \"Slack\", value: \"slack\" as OutputFormat },\n\t\t],\n\t\tdefault: \"plain\" as OutputFormat,\n\t});\n\n\tconst includePrivate = await confirm({\n\t\tmessage: \"Include private repos?\",\n\t\tdefault: true,\n\t});\n\n\t// Fetch available orgs for the user\n\tconst resolvedUsername = username || (await getAuthenticatedUser());\n\tconst userOrgs = await fetchUserOrgs(resolvedUsername);\n\tconst allScopes = [resolvedUsername, ...userOrgs];\n\n\t// Build choices with \"All\" as first option\n\tconst ALL_VALUE = \"__ALL__\";\n\tconst scopeChoices = [\n\t\t{ name: \"All (no filter)\", value: ALL_VALUE },\n\t\t...allScopes.map((org) => ({ name: org, value: org })),\n\t];\n\n\tconst scopeSelection = await select({\n\t\tmessage: \"Filter by scope\",\n\t\tchoices: scopeChoices,\n\t\tdefault: ALL_VALUE,\n\t});\n\n\t// If \"All\" selected, no filtering; otherwise filter to that single org\n\t// For multi-org selection, user can use CLI --orgs flag\n\tconst selectedOrgs = scopeSelection === ALL_VALUE ? null : [scopeSelection];\n\n\tconst model = await input({\n\t\tmessage: \"Claude model (leave empty for default)\",\n\t\tdefault: \"\",\n\t});\n\n\treturn {\n\t\tusername,\n\t\tdays,\n\t\tlanguage,\n\t\tverbosity,\n\t\tformat,\n\t\tincludePrivate,\n\t\tselectedOrgs,\n\t\tmodel,\n\t};\n}\n","import type {\n\tCommit,\n\tGitHubActivity,\n\tLanguage,\n\tOutputFormat,\n} from \"./types.js\";\n\n// Gap threshold: if gap between commits > 3 hours, treat as separate session\nconst GAP_THRESHOLD_MS = 3 * 60 * 60 * 1000;\n// Minimum time to count for a single-commit session (15 minutes)\nconst SINGLE_COMMIT_HOURS = 0.25;\n\nfunction calculateWorkSession(\n\tcommits: Commit[],\n\tlang: Language,\n): string | null {\n\tif (commits.length < 2) return null;\n\n\t// Sort timestamps chronologically\n\tconst timestamps = commits\n\t\t.map((c) => new Date(c.date).getTime())\n\t\t.sort((a, b) => a - b);\n\n\t// Group commits into sessions based on gap threshold\n\tconst sessions: number[][] = [];\n\tlet currentSession = [timestamps[0]];\n\n\tfor (let i = 1; i < timestamps.length; i++) {\n\t\tconst gap = timestamps[i] - timestamps[i - 1];\n\t\tif (gap > GAP_THRESHOLD_MS) {\n\t\t\tsessions.push(currentSession);\n\t\t\tcurrentSession = [timestamps[i]];\n\t\t} else {\n\t\t\tcurrentSession.push(timestamps[i]);\n\t\t}\n\t}\n\tsessions.push(currentSession);\n\n\t// Calculate total hours across all sessions\n\tlet totalHours = 0;\n\tfor (const session of sessions) {\n\t\tif (session.length === 1) {\n\t\t\ttotalHours += SINGLE_COMMIT_HOURS;\n\t\t} else {\n\t\t\tconst duration = session[session.length - 1] - session[0];\n\t\t\ttotalHours += duration / (1000 * 60 * 60);\n\t\t}\n\t}\n\n\t// Round to nearest 0.5 hours\n\tconst rounded = Math.round(totalHours * 2) / 2;\n\n\tif (rounded < 0.5) return null;\n\n\tconst label = lang === \"en\" ? \"Work session\" : \"Arbeitszeit\";\n\tconst hoursLabel =\n\t\trounded === 1\n\t\t\t? lang === \"en\"\n\t\t\t\t? \"hour\"\n\t\t\t\t: \"Stunde\"\n\t\t\t: lang === \"en\"\n\t\t\t\t? \"hours\"\n\t\t\t\t: \"Stunden\";\n\n\treturn `${label}: ~${rounded} ${hoursLabel}`;\n}\n\nfunction getRepoNames(items: { repo: string }[]): string {\n\tconst repos = [...new Set(items.map((i) => i.repo))];\n\treturn repos.join(\", \");\n}\n\nfunction formatActivityLine(\n\tcount: number,\n\tlabelEn: string,\n\tlabelDe: string,\n\trepos: string,\n\tlang: Language,\n\tformat: OutputFormat,\n): string | null {\n\tif (count === 0) return null;\n\n\tconst label = lang === \"en\" ? labelEn : labelDe;\n\tconst repoSuffix = repos ? ` (${repos})` : \"\";\n\n\tif (format === \"markdown\") {\n\t\treturn `- **${count}** ${label}${repoSuffix}`;\n\t}\n\treturn `• ${count} ${label}${repoSuffix}`;\n}\n\nexport function formatActivity(\n\tactivity: GitHubActivity,\n\tformat: OutputFormat,\n\tlang: Language,\n): string {\n\tconst lines: string[] = [];\n\n\t// Header\n\tconst headerPrefix = format === \"markdown\" ? \"## \" : \"\";\n\tlines.push(`${headerPrefix}tl;dr ${activity.date}`);\n\tlines.push(\"\");\n\n\tconst activityLines = [\n\t\tformatActivityLine(\n\t\t\tactivity.prs_created.length,\n\t\t\t\"PRs created\",\n\t\t\t\"PRs erstellt\",\n\t\t\tgetRepoNames(activity.prs_created),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.prs_reviewed.length,\n\t\t\t\"PRs reviewed\",\n\t\t\t\"PRs reviewed/approved\",\n\t\t\tgetRepoNames(activity.prs_reviewed),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.prs_merged.length,\n\t\t\t\"PRs merged\",\n\t\t\t\"PRs gemerged\",\n\t\t\tgetRepoNames(activity.prs_merged),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.issues_created.length,\n\t\t\t\"issues created\",\n\t\t\t\"Issues erstellt\",\n\t\t\tgetRepoNames(activity.issues_created),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.issues_closed.length,\n\t\t\t\"issues closed\",\n\t\t\t\"Issues geschlossen\",\n\t\t\tgetRepoNames(activity.issues_closed),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.commits.length,\n\t\t\t\"commits\",\n\t\t\t\"Commits\",\n\t\t\tgetRepoNames(activity.commits),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t\tformatActivityLine(\n\t\t\tactivity.repos_created.length,\n\t\t\t\"new repos created\",\n\t\t\t\"neue Repos erstellt\",\n\t\t\tactivity.repos_created.map((r) => r.name).join(\", \"),\n\t\t\tlang,\n\t\t\tformat,\n\t\t),\n\t].filter(Boolean) as string[];\n\n\tif (activityLines.length === 0) {\n\t\tconst noActivity =\n\t\t\tlang === \"en\"\n\t\t\t\t? `No GitHub activity in the ${activity.period}.`\n\t\t\t\t: `Keine GitHub-Aktivität in den ${activity.period}.`;\n\t\tlines.push(noActivity);\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tlines.push(...activityLines);\n\n\t// Work session duration\n\tconst workSession = calculateWorkSession(activity.commits, lang);\n\tif (workSession) {\n\t\tlines.push(format === \"markdown\" ? `- ${workSession}` : `• ${workSession}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Repos touched\n\tif (activity.repos_touched.length > 0) {\n\t\tconst reposLabel = lang === \"en\" ? \"Repos\" : \"Repos\";\n\t\tlines.push(`${reposLabel}: ${activity.repos_touched.join(\", \")}`);\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function hasActivity(activity: GitHubActivity): boolean {\n\treturn (\n\t\tactivity.prs_created.length +\n\t\t\tactivity.prs_merged.length +\n\t\t\tactivity.prs_reviewed.length +\n\t\t\tactivity.issues_created.length +\n\t\t\tactivity.issues_closed.length >\n\t\t0\n\t);\n}\n","// gh-tldr - Generate a TL;DR summary of your GitHub activity\n// Entry point: detects mode (interactive vs direct) and runs CLI\n\nimport { run } from \"./cli.js\";\n\nrun();\n"],"mappings":"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","names":["execa","execa"]}
|