github-weekly-reporter 0.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/LICENSE +38 -0
- package/README.md +163 -0
- package/dist/cli/commands/deploy.d.ts +3 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +55 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +3 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +106 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/config.d.ts +11 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +16 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/config.test.d.ts +2 -0
- package/dist/cli/config.test.d.ts.map +1 -0
- package/dist/cli/config.test.js +32 -0
- package/dist/cli/config.test.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +13 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/collector/aggregate.d.ts +3 -0
- package/dist/collector/aggregate.d.ts.map +1 -0
- package/dist/collector/aggregate.js +34 -0
- package/dist/collector/aggregate.js.map +1 -0
- package/dist/collector/aggregate.test.d.ts +2 -0
- package/dist/collector/aggregate.test.d.ts.map +1 -0
- package/dist/collector/aggregate.test.js +88 -0
- package/dist/collector/aggregate.test.js.map +1 -0
- package/dist/collector/date-range.d.ts +7 -0
- package/dist/collector/date-range.d.ts.map +1 -0
- package/dist/collector/date-range.js +8 -0
- package/dist/collector/date-range.js.map +1 -0
- package/dist/collector/date-range.test.d.ts +2 -0
- package/dist/collector/date-range.test.d.ts.map +1 -0
- package/dist/collector/date-range.test.js +25 -0
- package/dist/collector/date-range.test.js.map +1 -0
- package/dist/collector/fetch-contributions.d.ts +12 -0
- package/dist/collector/fetch-contributions.d.ts.map +1 -0
- package/dist/collector/fetch-contributions.js +24 -0
- package/dist/collector/fetch-contributions.js.map +1 -0
- package/dist/collector/fetch-issues.d.ts +5 -0
- package/dist/collector/fetch-issues.d.ts.map +1 -0
- package/dist/collector/fetch-issues.js +31 -0
- package/dist/collector/fetch-issues.js.map +1 -0
- package/dist/collector/fetch-languages.d.ts +4 -0
- package/dist/collector/fetch-languages.d.ts.map +1 -0
- package/dist/collector/fetch-languages.js +42 -0
- package/dist/collector/fetch-languages.js.map +1 -0
- package/dist/collector/fetch-pull-requests.d.ts +5 -0
- package/dist/collector/fetch-pull-requests.d.ts.map +1 -0
- package/dist/collector/fetch-pull-requests.js +31 -0
- package/dist/collector/fetch-pull-requests.js.map +1 -0
- package/dist/collector/index.d.ts +3 -0
- package/dist/collector/index.d.ts.map +1 -0
- package/dist/collector/index.js +50 -0
- package/dist/collector/index.js.map +1 -0
- package/dist/collector/queries.d.ts +5 -0
- package/dist/collector/queries.d.ts.map +1 -0
- package/dist/collector/queries.js +81 -0
- package/dist/collector/queries.js.map +1 -0
- package/dist/deployer/index-page.d.ts +3 -0
- package/dist/deployer/index-page.d.ts.map +1 -0
- package/dist/deployer/index-page.js +51 -0
- package/dist/deployer/index-page.js.map +1 -0
- package/dist/deployer/index-page.test.d.ts +2 -0
- package/dist/deployer/index-page.test.d.ts.map +1 -0
- package/dist/deployer/index-page.test.js +29 -0
- package/dist/deployer/index-page.test.js.map +1 -0
- package/dist/deployer/index.d.ts +7 -0
- package/dist/deployer/index.d.ts.map +1 -0
- package/dist/deployer/index.js +16 -0
- package/dist/deployer/index.js.map +1 -0
- package/dist/deployer/week.d.ts +7 -0
- package/dist/deployer/week.d.ts.map +1 -0
- package/dist/deployer/week.js +14 -0
- package/dist/deployer/week.js.map +1 -0
- package/dist/deployer/week.test.d.ts +2 -0
- package/dist/deployer/week.test.d.ts.map +1 -0
- package/dist/deployer/week.test.js +21 -0
- package/dist/deployer/week.test.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.d.ts +4 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +25 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/llm.test.d.ts +2 -0
- package/dist/llm/llm.test.d.ts.map +1 -0
- package/dist/llm/llm.test.js +24 -0
- package/dist/llm/llm.test.js.map +1 -0
- package/dist/llm/prompt.d.ts +3 -0
- package/dist/llm/prompt.d.ts.map +1 -0
- package/dist/llm/prompt.js +31 -0
- package/dist/llm/prompt.js.map +1 -0
- package/dist/llm/prompt.test.d.ts +2 -0
- package/dist/llm/prompt.test.d.ts.map +1 -0
- package/dist/llm/prompt.test.js +48 -0
- package/dist/llm/prompt.test.js.map +1 -0
- package/dist/llm/providers/anthropic.d.ts +3 -0
- package/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/llm/providers/anthropic.js +17 -0
- package/dist/llm/providers/anthropic.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +3 -0
- package/dist/llm/providers/gemini.d.ts.map +1 -0
- package/dist/llm/providers/gemini.js +13 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/providers/openai.d.ts +3 -0
- package/dist/llm/providers/openai.d.ts.map +1 -0
- package/dist/llm/providers/openai.js +17 -0
- package/dist/llm/providers/openai.js.map +1 -0
- package/dist/llm/types.d.ts +11 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +3 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/renderer/helpers.d.ts +3 -0
- package/dist/renderer/helpers.d.ts.map +1 -0
- package/dist/renderer/helpers.js +22 -0
- package/dist/renderer/helpers.js.map +1 -0
- package/dist/renderer/index.d.ts +3 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +45 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/renderer.test.d.ts +2 -0
- package/dist/renderer/renderer.test.d.ts.map +1 -0
- package/dist/renderer/renderer.test.js +111 -0
- package/dist/renderer/renderer.test.js.map +1 -0
- package/dist/renderer/themes.d.ts +18 -0
- package/dist/renderer/themes.d.ts.map +1 -0
- package/dist/renderer/themes.js +180 -0
- package/dist/renderer/themes.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
- package/src/renderer/templates/partials/footer.hbs +3 -0
- package/src/renderer/templates/partials/header.hbs +7 -0
- package/src/renderer/templates/partials/heatmap.hbs +11 -0
- package/src/renderer/templates/partials/languages.hbs +19 -0
- package/src/renderer/templates/partials/narrative.hbs +10 -0
- package/src/renderer/templates/partials/repositories.hbs +25 -0
- package/src/renderer/templates/partials/stats.hbs +8 -0
- package/src/renderer/templates/report.hbs +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"week.test.d.ts","sourceRoot":"","sources":["../../src/deployer/week.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { getWeekId } from "./week.js";
|
|
3
|
+
describe("getWeekId", () => {
|
|
4
|
+
it("returns correct ISO week for 2026-04-04 (W14)", () => {
|
|
5
|
+
const result = getWeekId(new Date("2026-04-04T12:00:00Z"));
|
|
6
|
+
expect(result.year).toBe(2026);
|
|
7
|
+
expect(result.week).toBe(14);
|
|
8
|
+
expect(result.path).toBe("2026/W14");
|
|
9
|
+
});
|
|
10
|
+
it("returns correct ISO week for 2026-01-01 (W01)", () => {
|
|
11
|
+
const result = getWeekId(new Date("2026-01-01T12:00:00Z"));
|
|
12
|
+
expect(result.year).toBe(2026);
|
|
13
|
+
expect(result.week).toBe(1);
|
|
14
|
+
expect(result.path).toBe("2026/W01");
|
|
15
|
+
});
|
|
16
|
+
it("pads single-digit week numbers", () => {
|
|
17
|
+
const result = getWeekId(new Date("2026-02-01T12:00:00Z"));
|
|
18
|
+
expect(result.path).toMatch(/^\d{4}\/W\d{2}$/);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=week.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"week.test.js","sourceRoot":"","sources":["../../src/deployer/week.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { collectWeeklyData } from "./collector/index.js";
|
|
2
|
+
export { renderReport } from "./renderer/index.js";
|
|
3
|
+
export { generateNarrative } from "./llm/index.js";
|
|
4
|
+
export type { LLMConfig } from "./llm/index.js";
|
|
5
|
+
export { deploy } from "./deployer/index.js";
|
|
6
|
+
export type { DeployOptions } from "./deployer/index.js";
|
|
7
|
+
export type { WeeklyReportData, ReportConfig, WeeklyStats, RepositoryActivity, LanguageBreakdown, DailyCommitCount, PullRequest, Issue, Theme, } from "./types.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAY5D,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,iBAAiB,GAC5B,OAAO,cAAc,EACrB,QAAQ,SAAS,KAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAYvB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// LLM module: generate narrative with explicit provider/model config
|
|
2
|
+
import { buildPrompt } from "./prompt.js";
|
|
3
|
+
import { createOpenAIProvider } from "./providers/openai.js";
|
|
4
|
+
import { createAnthropicProvider } from "./providers/anthropic.js";
|
|
5
|
+
import { createGeminiProvider } from "./providers/gemini.js";
|
|
6
|
+
const PROVIDER_FACTORIES = {
|
|
7
|
+
openai: createOpenAIProvider,
|
|
8
|
+
anthropic: createAnthropicProvider,
|
|
9
|
+
gemini: createGeminiProvider,
|
|
10
|
+
};
|
|
11
|
+
export const generateNarrative = async (input, config) => {
|
|
12
|
+
try {
|
|
13
|
+
const factory = PROVIDER_FACTORIES[config.provider];
|
|
14
|
+
const provider = factory(config);
|
|
15
|
+
const prompt = buildPrompt(input);
|
|
16
|
+
const narrative = await provider.generate(prompt);
|
|
17
|
+
return narrative || null;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
21
|
+
console.warn(`LLM narrative generation failed (${config.provider}): ${message}`);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,kBAAkB,GAAG;IACzB,MAAM,EAAE,oBAAoB;IAC5B,SAAS,EAAE,uBAAuB;IAClC,MAAM,EAAE,oBAAoB;CACpB,CAAC;AAIX,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,KAAqB,EACrB,MAAiB,EACO,EAAE;IAC1B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,SAAS,IAAI,IAAI,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAC,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.test.d.ts","sourceRoot":"","sources":["../../src/llm/llm.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { generateNarrative } from "./index.js";
|
|
3
|
+
const MOCK_INPUT = {
|
|
4
|
+
username: "testuser",
|
|
5
|
+
avatarUrl: "https://example.com/avatar.png",
|
|
6
|
+
dateRange: { from: "2026-03-28", to: "2026-04-03" },
|
|
7
|
+
stats: { totalCommits: 10, prsOpened: 2, prsMerged: 1, prsReviewed: 3, issuesOpened: 1, issuesClosed: 0 },
|
|
8
|
+
dailyCommits: [],
|
|
9
|
+
repositories: [],
|
|
10
|
+
languages: [],
|
|
11
|
+
pullRequests: [],
|
|
12
|
+
issues: [],
|
|
13
|
+
};
|
|
14
|
+
describe("generateNarrative", () => {
|
|
15
|
+
it("returns null and logs warning when LLM call fails", async () => {
|
|
16
|
+
const spy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
17
|
+
const config = { provider: "openai", apiKey: "invalid-key", model: "gpt-4o-mini" };
|
|
18
|
+
const result = await generateNarrative(MOCK_INPUT, config);
|
|
19
|
+
expect(result).toBeNull();
|
|
20
|
+
expect(spy).toHaveBeenCalledWith(expect.stringContaining("LLM narrative generation failed"));
|
|
21
|
+
spy.mockRestore();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=llm.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.test.js","sourceRoot":"","sources":["../../src/llm/llm.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,UAAU,GAAmB;IACjC,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,gCAAgC;IAC3C,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE;IACnD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE;IACzG,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE,EAAE;IAChB,SAAS,EAAE,EAAE;IACb,YAAY,EAAE,EAAE;IAChB,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEnE,MAAM,MAAM,GAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QAC9F,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAC9B,MAAM,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAC3D,CAAC;QAEF,GAAG,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/llm/prompt.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAcjD,eAAO,MAAM,WAAW,GAAI,OAAO,cAAc,KAAG,MAoB5C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Build the prompt for AI narrative generation
|
|
2
|
+
const formatRepoSummary = (input) => input.repositories
|
|
3
|
+
.slice(0, 5)
|
|
4
|
+
.map((r) => `- ${r.name}: ${r.prsOpened} PRs opened, ${r.prsMerged} merged, ${r.issuesOpened} issues`)
|
|
5
|
+
.join("\n");
|
|
6
|
+
const formatLanguageSummary = (input) => input.languages
|
|
7
|
+
.slice(0, 5)
|
|
8
|
+
.map((l) => `- ${l.language}: ${l.percentage.toFixed(1)}%`)
|
|
9
|
+
.join("\n");
|
|
10
|
+
export const buildPrompt = (input) => `
|
|
11
|
+
You are writing a weekly activity summary for a software developer.
|
|
12
|
+
Write 2-3 short paragraphs summarizing the following GitHub activity.
|
|
13
|
+
Tone: professional but friendly, like a weekly standup summary written for the developer themselves.
|
|
14
|
+
Do not use markdown formatting. Write plain text only.
|
|
15
|
+
|
|
16
|
+
Developer: ${input.username}
|
|
17
|
+
Period: ${input.dateRange.from} to ${input.dateRange.to}
|
|
18
|
+
|
|
19
|
+
Stats:
|
|
20
|
+
- ${input.stats.totalCommits} commits
|
|
21
|
+
- ${input.stats.prsOpened} PRs opened, ${input.stats.prsMerged} merged
|
|
22
|
+
- ${input.stats.prsReviewed} PRs reviewed
|
|
23
|
+
- ${input.stats.issuesOpened} issues opened, ${input.stats.issuesClosed} closed
|
|
24
|
+
|
|
25
|
+
Top repositories:
|
|
26
|
+
${formatRepoSummary(input)}
|
|
27
|
+
|
|
28
|
+
Languages:
|
|
29
|
+
${formatLanguageSummary(input)}
|
|
30
|
+
`.trim();
|
|
31
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/llm/prompt.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAI/C,MAAM,iBAAiB,GAAG,CAAC,KAAqB,EAAU,EAAE,CAC1D,KAAK,CAAC,YAAY;KACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;KACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,gBAAgB,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,YAAY,SAAS,CAAC;KACrG,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhB,MAAM,qBAAqB,GAAG,CAAC,KAAqB,EAAU,EAAE,CAC9D,KAAK,CAAC,SAAS;KACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;KACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;KAC1D,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAqB,EAAU,EAAE,CAAC;;;;;;aAMjD,KAAK,CAAC,QAAQ;UACjB,KAAK,CAAC,SAAS,CAAC,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,EAAE;;;IAGnD,KAAK,CAAC,KAAK,CAAC,YAAY;IACxB,KAAK,CAAC,KAAK,CAAC,SAAS,gBAAgB,KAAK,CAAC,KAAK,CAAC,SAAS;IAC1D,KAAK,CAAC,KAAK,CAAC,WAAW;IACvB,KAAK,CAAC,KAAK,CAAC,YAAY,mBAAmB,KAAK,CAAC,KAAK,CAAC,YAAY;;;EAGrE,iBAAiB,CAAC,KAAK,CAAC;;;EAGxB,qBAAqB,CAAC,KAAK,CAAC;CAC7B,CAAC,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.test.d.ts","sourceRoot":"","sources":["../../src/llm/prompt.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { buildPrompt } from "./prompt.js";
|
|
3
|
+
const MOCK_INPUT = {
|
|
4
|
+
username: "testuser",
|
|
5
|
+
avatarUrl: "https://example.com/avatar.png",
|
|
6
|
+
dateRange: { from: "2026-03-28", to: "2026-04-03" },
|
|
7
|
+
stats: {
|
|
8
|
+
totalCommits: 42,
|
|
9
|
+
prsOpened: 5,
|
|
10
|
+
prsMerged: 3,
|
|
11
|
+
prsReviewed: 8,
|
|
12
|
+
issuesOpened: 2,
|
|
13
|
+
issuesClosed: 1,
|
|
14
|
+
},
|
|
15
|
+
dailyCommits: [],
|
|
16
|
+
repositories: [
|
|
17
|
+
{ name: "org/repo-a", commits: 0, prsOpened: 3, prsMerged: 2, issuesOpened: 1, issuesClosed: 0, url: "" },
|
|
18
|
+
],
|
|
19
|
+
languages: [
|
|
20
|
+
{ language: "TypeScript", bytes: 8000, percentage: 80, color: "#3178c6" },
|
|
21
|
+
],
|
|
22
|
+
pullRequests: [],
|
|
23
|
+
issues: [],
|
|
24
|
+
};
|
|
25
|
+
describe("buildPrompt", () => {
|
|
26
|
+
it("includes username and date range", () => {
|
|
27
|
+
const prompt = buildPrompt(MOCK_INPUT);
|
|
28
|
+
expect(prompt).toContain("testuser");
|
|
29
|
+
expect(prompt).toContain("2026-03-28");
|
|
30
|
+
expect(prompt).toContain("2026-04-03");
|
|
31
|
+
});
|
|
32
|
+
it("includes stats", () => {
|
|
33
|
+
const prompt = buildPrompt(MOCK_INPUT);
|
|
34
|
+
expect(prompt).toContain("42 commits");
|
|
35
|
+
expect(prompt).toContain("5 PRs opened");
|
|
36
|
+
expect(prompt).toContain("3 merged");
|
|
37
|
+
});
|
|
38
|
+
it("includes repository summary", () => {
|
|
39
|
+
const prompt = buildPrompt(MOCK_INPUT);
|
|
40
|
+
expect(prompt).toContain("org/repo-a");
|
|
41
|
+
});
|
|
42
|
+
it("includes language breakdown", () => {
|
|
43
|
+
const prompt = buildPrompt(MOCK_INPUT);
|
|
44
|
+
expect(prompt).toContain("TypeScript");
|
|
45
|
+
expect(prompt).toContain("80.0%");
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=prompt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.test.js","sourceRoot":"","sources":["../../src/llm/prompt.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,UAAU,GAAmB;IACjC,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,gCAAgC;IAC3C,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE;IACnD,KAAK,EAAE;QACL,YAAY,EAAE,EAAE;QAChB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;KAChB;IACD,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE;QACZ,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;KAC1G;IACD,SAAS,EAAE;QACT,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;KAC1E;IACD,YAAY,EAAE,EAAE;IAChB,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;QACxB,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/anthropic.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,uBAAuB,GAAI,QAAQ,SAAS,KAAG,WAc3D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Anthropic provider implementation
|
|
2
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
3
|
+
export const createAnthropicProvider = (config) => {
|
|
4
|
+
const client = new Anthropic({ apiKey: config.apiKey });
|
|
5
|
+
return {
|
|
6
|
+
generate: async (prompt) => {
|
|
7
|
+
const response = await client.messages.create({
|
|
8
|
+
model: config.model,
|
|
9
|
+
max_tokens: 512,
|
|
10
|
+
messages: [{ role: "user", content: prompt }],
|
|
11
|
+
});
|
|
12
|
+
const block = response.content[0];
|
|
13
|
+
return block.type === "text" ? block.text.trim() : "";
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/llm/providers/anthropic.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAiB,EAAe,EAAE;IACxE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAExD,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,MAAc,EAAmB,EAAE;YAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC5C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,UAAU,EAAE,GAAG;gBACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAClC,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/gemini.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,oBAAoB,GAAI,QAAQ,SAAS,KAAG,WAUxD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Google Gemini provider implementation
|
|
2
|
+
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
3
|
+
export const createGeminiProvider = (config) => {
|
|
4
|
+
const genAI = new GoogleGenerativeAI(config.apiKey);
|
|
5
|
+
const model = genAI.getGenerativeModel({ model: config.model });
|
|
6
|
+
return {
|
|
7
|
+
generate: async (prompt) => {
|
|
8
|
+
const result = await model.generateContent(prompt);
|
|
9
|
+
return result.response.text().trim();
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/llm/providers/gemini.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAiB,EAAe,EAAE;IACrE,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAEhE,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,MAAc,EAAmB,EAAE;YAClD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/openai.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,oBAAoB,GAAI,QAAQ,SAAS,KAAG,WAcxD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// OpenAI provider implementation
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
export const createOpenAIProvider = (config) => {
|
|
4
|
+
const client = new OpenAI({ apiKey: config.apiKey });
|
|
5
|
+
return {
|
|
6
|
+
generate: async (prompt) => {
|
|
7
|
+
const response = await client.chat.completions.create({
|
|
8
|
+
model: config.model,
|
|
9
|
+
messages: [{ role: "user", content: prompt }],
|
|
10
|
+
max_tokens: 512,
|
|
11
|
+
temperature: 0.7,
|
|
12
|
+
});
|
|
13
|
+
return response.choices[0]?.message?.content?.trim() ?? "";
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/llm/providers/openai.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAiB,EAAe,EAAE;IACrE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,MAAc,EAAmB,EAAE;YAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;gBACpD,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC7C,UAAU,EAAE,GAAG;gBACf,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7D,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WeeklyReportData, LLMProvider as LLMProviderName } from "../types.js";
|
|
2
|
+
export type LLMConfig = {
|
|
3
|
+
provider: LLMProviderName;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
model: string;
|
|
6
|
+
};
|
|
7
|
+
export type LLMProvider = {
|
|
8
|
+
generate: (prompt: string) => Promise<string>;
|
|
9
|
+
};
|
|
10
|
+
export type NarrativeInput = Omit<WeeklyReportData, "aiNarrative">;
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,aAAa,CAAC;AAEpF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":"AAAA,iCAAiC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/renderer/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,UAAU,MAAM,YAAY,CAAC;AAIpC,eAAO,MAAM,eAAe,GAAI,KAAK,OAAO,UAAU,KAAG,IAqBxD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Handlebars custom helpers
|
|
2
|
+
const WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3
|
+
export const registerHelpers = (hbs) => {
|
|
4
|
+
hbs.registerHelper("heatmapLevel", (count) => {
|
|
5
|
+
if (count === 0)
|
|
6
|
+
return 0;
|
|
7
|
+
if (count <= 2)
|
|
8
|
+
return 1;
|
|
9
|
+
if (count <= 5)
|
|
10
|
+
return 2;
|
|
11
|
+
if (count <= 10)
|
|
12
|
+
return 3;
|
|
13
|
+
return 4;
|
|
14
|
+
});
|
|
15
|
+
hbs.registerHelper("weekday", (dateStr) => {
|
|
16
|
+
const date = new Date(dateStr + "T00:00:00Z");
|
|
17
|
+
return WEEKDAY_SHORT[date.getUTCDay()];
|
|
18
|
+
});
|
|
19
|
+
hbs.registerHelper("fixed", (value, digits) => value.toFixed(digits));
|
|
20
|
+
hbs.registerHelper("paragraphs", (text) => text.split("\n\n").map((p) => p.trim()).filter(Boolean));
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/renderer/helpers.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAI5B,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAsB,EAAQ,EAAE;IAC9D,GAAG,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,KAAa,EAAU,EAAE;QAC3D,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAC1B,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACzB,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACzB,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,OAAe,EAAU,EAAE;QACxD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;QAC9C,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,KAAa,EAAE,MAAc,EAAU,EAAE,CACpE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CACtB,CAAC;IAEF,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,IAAY,EAAY,EAAE,CAC1D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACxD,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA2C3D,eAAO,MAAM,YAAY,GACvB,MAAM,gBAAgB,EACtB,QAAO,KAAiB,KACvB,MASF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Main report renderer: compiles Handlebars templates into a self-contained HTML file
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import Handlebars from "handlebars";
|
|
6
|
+
import { buildCSS } from "./themes.js";
|
|
7
|
+
import { registerHelpers } from "./helpers.js";
|
|
8
|
+
// Templates live at src/renderer/templates/ (both dev and npm package)
|
|
9
|
+
const TEMPLATES_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "src", "renderer", "templates");
|
|
10
|
+
const readTemplate = (path) => readFileSync(join(TEMPLATES_DIR, path), "utf-8");
|
|
11
|
+
const PARTIAL_NAMES = [
|
|
12
|
+
"header",
|
|
13
|
+
"stats",
|
|
14
|
+
"heatmap",
|
|
15
|
+
"languages",
|
|
16
|
+
"repositories",
|
|
17
|
+
"narrative",
|
|
18
|
+
"footer",
|
|
19
|
+
];
|
|
20
|
+
const buildStatCards = (data) => [
|
|
21
|
+
{ value: data.stats.totalCommits, label: "Commits" },
|
|
22
|
+
{ value: data.stats.prsOpened, label: "PRs Opened" },
|
|
23
|
+
{ value: data.stats.prsMerged, label: "PRs Merged" },
|
|
24
|
+
{ value: data.stats.prsReviewed, label: "Reviews" },
|
|
25
|
+
{ value: data.stats.issuesOpened, label: "Issues Opened" },
|
|
26
|
+
{ value: data.stats.issuesClosed, label: "Issues Closed" },
|
|
27
|
+
];
|
|
28
|
+
const createInstance = () => {
|
|
29
|
+
const hbs = Handlebars.create();
|
|
30
|
+
registerHelpers(hbs);
|
|
31
|
+
PARTIAL_NAMES.forEach((name) => {
|
|
32
|
+
hbs.registerPartial(name, readTemplate(`partials/${name}.hbs`));
|
|
33
|
+
});
|
|
34
|
+
return hbs;
|
|
35
|
+
};
|
|
36
|
+
export const renderReport = (data, theme = "default") => {
|
|
37
|
+
const hbs = createInstance();
|
|
38
|
+
const template = hbs.compile(readTemplate("report.hbs"));
|
|
39
|
+
return template({
|
|
40
|
+
...data,
|
|
41
|
+
css: buildCSS(theme),
|
|
42
|
+
statCards: buildStatCards(data),
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,uEAAuE;AACvE,MAAM,aAAa,GAAG,IAAI,CACxB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,CAC3C,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CAC5C,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAEnD,MAAM,aAAa,GAAG;IACpB,QAAQ;IACR,OAAO;IACP,SAAS;IACT,WAAW;IACX,cAAc;IACd,WAAW;IACX,QAAQ;CACA,CAAC;AAEX,MAAM,cAAc,GAAG,CAAC,IAAsB,EAAE,EAAE,CAAC;IACjD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE;IACpD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE;IACpD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE;IACpD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE;IACnD,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE;IAC1D,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE;CAC3D,CAAC;AAEF,MAAM,cAAc,GAAG,GAAsB,EAAE;IAC7C,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,GAAG,CAAC,CAAC;IAErB,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,IAAsB,EACtB,QAAe,SAAS,EAChB,EAAE;IACV,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC;IAEzD,OAAO,QAAQ,CAAC;QACd,GAAG,IAAI;QACP,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC;QACpB,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC;KAChC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.test.d.ts","sourceRoot":"","sources":["../../src/renderer/renderer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { renderReport } from "./index.js";
|
|
3
|
+
const MOCK_DATA = {
|
|
4
|
+
username: "testuser",
|
|
5
|
+
avatarUrl: "https://avatars.githubusercontent.com/u/12345",
|
|
6
|
+
dateRange: { from: "2026-03-28", to: "2026-04-03" },
|
|
7
|
+
stats: {
|
|
8
|
+
totalCommits: 42,
|
|
9
|
+
prsOpened: 5,
|
|
10
|
+
prsMerged: 3,
|
|
11
|
+
prsReviewed: 8,
|
|
12
|
+
issuesOpened: 2,
|
|
13
|
+
issuesClosed: 1,
|
|
14
|
+
},
|
|
15
|
+
dailyCommits: [
|
|
16
|
+
{ date: "2026-03-28", count: 5 },
|
|
17
|
+
{ date: "2026-03-29", count: 0 },
|
|
18
|
+
{ date: "2026-03-30", count: 12 },
|
|
19
|
+
{ date: "2026-03-31", count: 3 },
|
|
20
|
+
{ date: "2026-04-01", count: 8 },
|
|
21
|
+
{ date: "2026-04-02", count: 7 },
|
|
22
|
+
{ date: "2026-04-03", count: 7 },
|
|
23
|
+
],
|
|
24
|
+
repositories: [
|
|
25
|
+
{
|
|
26
|
+
name: "org/repo-a",
|
|
27
|
+
commits: 0,
|
|
28
|
+
prsOpened: 3,
|
|
29
|
+
prsMerged: 2,
|
|
30
|
+
issuesOpened: 1,
|
|
31
|
+
issuesClosed: 0,
|
|
32
|
+
url: "https://github.com/org/repo-a",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
languages: [
|
|
36
|
+
{ language: "TypeScript", bytes: 8000, percentage: 80, color: "#3178c6" },
|
|
37
|
+
{ language: "JavaScript", bytes: 2000, percentage: 20, color: "#f1e05a" },
|
|
38
|
+
],
|
|
39
|
+
pullRequests: [],
|
|
40
|
+
issues: [],
|
|
41
|
+
aiNarrative: null,
|
|
42
|
+
};
|
|
43
|
+
describe("renderReport", () => {
|
|
44
|
+
it("produces valid HTML with DOCTYPE", () => {
|
|
45
|
+
const html = renderReport(MOCK_DATA);
|
|
46
|
+
expect(html).toMatch(/^<!DOCTYPE html>/);
|
|
47
|
+
expect(html).toContain("</html>");
|
|
48
|
+
});
|
|
49
|
+
it("includes username and date range", () => {
|
|
50
|
+
const html = renderReport(MOCK_DATA);
|
|
51
|
+
expect(html).toContain("testuser");
|
|
52
|
+
expect(html).toContain("2026-03-28");
|
|
53
|
+
expect(html).toContain("2026-04-03");
|
|
54
|
+
});
|
|
55
|
+
it("includes stats values", () => {
|
|
56
|
+
const html = renderReport(MOCK_DATA);
|
|
57
|
+
expect(html).toContain("42");
|
|
58
|
+
expect(html).toContain("Commits");
|
|
59
|
+
expect(html).toContain("PRs Opened");
|
|
60
|
+
});
|
|
61
|
+
it("includes heatmap days", () => {
|
|
62
|
+
const html = renderReport(MOCK_DATA);
|
|
63
|
+
expect(html).toContain("heatmap-level-");
|
|
64
|
+
expect(html).toContain("heatmap-day");
|
|
65
|
+
});
|
|
66
|
+
it("includes language breakdown", () => {
|
|
67
|
+
const html = renderReport(MOCK_DATA);
|
|
68
|
+
expect(html).toContain("TypeScript");
|
|
69
|
+
expect(html).toContain("80.0%");
|
|
70
|
+
expect(html).toContain("#3178c6");
|
|
71
|
+
});
|
|
72
|
+
it("includes repository table", () => {
|
|
73
|
+
const html = renderReport(MOCK_DATA);
|
|
74
|
+
expect(html).toContain("org/repo-a");
|
|
75
|
+
expect(html).toContain("Active Repositories");
|
|
76
|
+
});
|
|
77
|
+
it("includes dofollow footer link with UTM params", () => {
|
|
78
|
+
const html = renderReport(MOCK_DATA);
|
|
79
|
+
expect(html).toContain("deariary.com?utm_source=github-weekly-reporter&utm_medium=footer");
|
|
80
|
+
expect(html).not.toContain('rel="nofollow"');
|
|
81
|
+
expect(html).not.toContain('rel="sponsored"');
|
|
82
|
+
});
|
|
83
|
+
it("includes OG meta tags", () => {
|
|
84
|
+
const html = renderReport(MOCK_DATA);
|
|
85
|
+
expect(html).toContain('og:title');
|
|
86
|
+
expect(html).toContain('og:description');
|
|
87
|
+
expect(html).toContain('og:image');
|
|
88
|
+
});
|
|
89
|
+
it("omits AI narrative section when null", () => {
|
|
90
|
+
const html = renderReport(MOCK_DATA);
|
|
91
|
+
expect(html).not.toContain("AI Summary");
|
|
92
|
+
});
|
|
93
|
+
it("includes AI narrative when provided", () => {
|
|
94
|
+
const data = { ...MOCK_DATA, aiNarrative: "This week you focused on TypeScript." };
|
|
95
|
+
const html = renderReport(data);
|
|
96
|
+
expect(html).toContain("AI Summary");
|
|
97
|
+
expect(html).toContain("This week you focused on TypeScript.");
|
|
98
|
+
});
|
|
99
|
+
it("renders dark theme without errors", () => {
|
|
100
|
+
const html = renderReport(MOCK_DATA, "dark");
|
|
101
|
+
expect(html).toContain("#0d1117");
|
|
102
|
+
expect(html).toContain("<!DOCTYPE html>");
|
|
103
|
+
});
|
|
104
|
+
it("produces a single self-contained file (no external links)", () => {
|
|
105
|
+
const html = renderReport(MOCK_DATA);
|
|
106
|
+
// Should not have <link> or <script src=> tags
|
|
107
|
+
expect(html).not.toMatch(/<link\s+rel="stylesheet"/);
|
|
108
|
+
expect(html).not.toMatch(/<script\s+src=/);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=renderer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.test.js","sourceRoot":"","sources":["../../src/renderer/renderer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Theme } from "../types.js";
|
|
2
|
+
type ThemeColors = {
|
|
3
|
+
bg: string;
|
|
4
|
+
bgCard: string;
|
|
5
|
+
text: string;
|
|
6
|
+
textSecondary: string;
|
|
7
|
+
border: string;
|
|
8
|
+
accent: string;
|
|
9
|
+
heatmapEmpty: string;
|
|
10
|
+
heatmapL1: string;
|
|
11
|
+
heatmapL2: string;
|
|
12
|
+
heatmapL3: string;
|
|
13
|
+
heatmapL4: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const getThemeColors: (theme: Theme) => ThemeColors;
|
|
16
|
+
export declare const buildCSS: (theme: Theme) => string;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/renderer/themes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA+BF,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,KAAG,WACb,CAAC;AAElC,eAAO,MAAM,QAAQ,GAAI,OAAO,KAAK,KAAG,MAqJvC,CAAC"}
|