From b7528507af5a4ea04b5165ac64d30f504e898f19 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 7 Sep 2026 13:01:26 -0700 Subject: [PATCH] feat(team-reports): match the maintainer report site layout (#141384) * feat(team-reports): match the maintainer report site layout * fix(team-reports): address review findings on the site layout * fix(team-reports): ship the crab artwork and resolve assets from the plugin root * fix(team-reports): drop repeated fallback highlights and empty role breakdowns --- docs/plugins/team-reports.md | 33 +- extensions/team-reports/assets/crab.avif | Bin 0 -> 183569 bytes extensions/team-reports/index.ts | 6 + extensions/team-reports/package.json | 8 +- extensions/team-reports/src/http.test.ts | 83 ++- extensions/team-reports/src/http.ts | 74 ++- extensions/team-reports/src/render/charts.ts | 64 ++ extensions/team-reports/src/render/html.ts | 309 ++++----- extensions/team-reports/src/render/page.ts | 166 +++++ extensions/team-reports/src/render/people.ts | 317 ++++++++++ extensions/team-reports/src/render/report.ts | 236 +++++++ extensions/team-reports/src/render/script.ts | 98 +++ extensions/team-reports/src/render/shared.ts | 8 +- .../team-reports/src/render/site.test.ts | 373 +++++++++++ extensions/team-reports/src/render/styles.ts | 594 +++++++++++++++--- .../team-reports/src/render/theme.test.ts | 113 ++++ extensions/team-reports/src/scheduler.test.ts | 42 ++ extensions/team-reports/src/scheduler.ts | 57 +- extensions/team-reports/src/store.test.ts | 82 +++ extensions/team-reports/src/store.ts | 68 +- 20 files changed, 2366 insertions(+), 365 deletions(-) create mode 100644 extensions/team-reports/assets/crab.avif create mode 100644 extensions/team-reports/src/render/charts.ts create mode 100644 extensions/team-reports/src/render/page.ts create mode 100644 extensions/team-reports/src/render/people.ts create mode 100644 extensions/team-reports/src/render/report.ts create mode 100644 extensions/team-reports/src/render/script.ts create mode 100644 extensions/team-reports/src/render/site.test.ts create mode 100644 extensions/team-reports/src/render/theme.test.ts diff --git a/docs/plugins/team-reports.md b/docs/plugins/team-reports.md index b89db83749cb..305f447c831d 100644 --- a/docs/plugins/team-reports.md +++ b/docs/plugins/team-reports.md @@ -120,13 +120,28 @@ page includes **Open in a new window** with that page's own URL. If the browser blocks that action too, copy the link into a new tab. Gateway authentication still applies there. -Pages render on the server and work without JavaScript. They use the Carapace -visual contract, with a dark default and a light palette when your operating -system prefers light mode. The embedded page follows that preference independently -of the Control UI theme. The index shows recent reports and a 28-day activity -trend; people pages show each member's recent daily history. Closed and partial -periods have distinct status badges, and coverage and summary warnings remain -visible alongside the report. +Pages mirror the maintainer report site layout: a banner and activity dateline, +latest-period quick cards, day/week/month history, people timelines, and a +per-person calendar. The generation panel shows scheduler and source health. +Closed and partial periods remain distinct, with coverage and summary warnings +alongside the report. + +The theme choice follows you through in-tab navigation via the page fragment +(`#theme=light` or `#theme=dark`). Inside the sandboxed Reports tab, it lasts for +that visit. It persists per browser only where storage is available, such as in +a separate window. Pages choose the theme from the fragment first, then browser +storage when available, then the operating system's light or dark preference, +independently of the Control UI theme. + +Relative times and open-day countdowns refresh with a small +inline script that the Content Security Policy allows by nonce. The same script +enables history toggles, member filtering, and the quiet-member switch. Pages +still work without JavaScript: all history rows and members remain available, +and timestamps have server-rendered fallbacks. + +The crab artwork and icon are served from the plugin's own `assets` route under +the same authentication and scope checks as report pages. Those assets use a +private one-day cache; report pages and exports remain uncached. Roster members and other GitHub actors show GitHub avatars from `avatars.githubusercontent.com`, using the primary GitHub login. Images load @@ -352,11 +367,11 @@ With the default `basePath`, authenticated readers can use: | `/reports/day//report.md` | Markdown export; also available for weeks and months. | | `/reports/day//data.json` | Structured report; also available for weeks and months. | | `/reports/people/` | Roster index. | -| `/reports/people//` | Per-person history and 28-day trend. | +| `/reports/people//` | Per-person history, calendar, and 30-day trend. | | `/reports/index.json` | Latest keys and stored-period index. | | `/reports/status` | Run status, schedule, and source warnings as JSON. | -These routes accept only `GET` and `HEAD` and send `Cache-Control: private, +Report and export routes accept only `GET` and `HEAD` and send `Cache-Control: private, no-store`. Use the CLI or authenticated Gateway method to generate reports; reading a report page does not trigger collection. diff --git a/extensions/team-reports/assets/crab.avif b/extensions/team-reports/assets/crab.avif new file mode 100644 index 0000000000000000000000000000000000000000..6422f46eeed788cf68c82cd056a2dcef38c4f219 GIT binary patch literal 183569 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%0DA;`Bch1W&!SJMmT}lrikFV%W2YbZ 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

K}8l%Xj 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 z zeyceFn_U~eZv)p?Kn@y|T{FA}>hpad2Ly@#RN=+)j}6)dnlbEX#( zMx+TNA^EaR*DnX0Gq0E{Jd9;r#cAG5f?p&ky4vJKgX3O)!Ak zSR^DWo;DhmG03Kc$_;rf`*V;%>By=5n2I7E_H@6CN&nmky{DLstm|2T6Y2q~-nswS za=isu<$GLym#W(lvm!^TUSgax9dkr6pP+y^5eoe=Vp=|YT%kl#(b*LPUzr$>PrPGg z`XQK;|Ke{AQoUnXtSYh&P4y+2jt&&jjps;KI2^Wavdg?w8YfCmLwo@Rt$`#JZ{oX# zWPjuhY!w^I1cbV8-Q&PJ;3*0g1YdMYT&J;J6U&1v^j+?y?46W0`t=`46-%8uvgQ>% z7&=Z%$Vs|9>lDeYnFP?$cVxNw`~_*U$sJ@P5}e7N4aKobOuE##OHcKP%l$u5B-H7; zV(DgLmO83VmT9-oqe}Bi((k?6W=e8O~4WW3I`cxfBff# zKr)5+0}(I;5K#2NG)@B=1y+2+>?jNRi}$EE*d!z6fu52L3Ra!{>Xe0N&c%uo=(hOo zqmb!Ia1j&;-{H?k(o6rwTv);oR~RUb1^~I5TR0CaI+>h7M${iQsM-A`xswOt@dfLr zP3%CpnytP$m9h%6EwJHazCDw4trsun5r+km5Da>%R5a?Q*`kpi#&MYs{MXYMzJEp6 zimcdIuHo4A-tXhJQC;sJ#O1tc76Ae`%!6w2N84O&O&>jCa>=){aTc^~J5u189L%86 zgb*;+Lz-94znVX+jQDqA)*BvISne_8B0$WI{!k5r>95wOmN$c4Y=j3m(H!1G(-Tss zjY*qi5u!|2AuJes`QKv5+33SClg#7+5#ZfB@P z){_N?$V*@eQ{=MoS}iCfW=X=>9&6_VwMJBWWuX7w4tY9*AN^xI(UA#{^qwXM@g7=6uw%31<^Bhj#fUkNwzjG}y8;2D1^ReGq%&M* zMO=anBNU1XlLliRXe~?owq4FkOPuKrJ+Be1^1rXPiu#t72T*hi>r^JBZ=5aQOP0#i zy!L6+lJ18Lj1BgRS_lAbWI8>nZH;u`%4uN4t@9y@!@(;WtNHT{KxXYnZZr|Qp4XPE^IC{>!>Gj`|AQ@NA!Ko)R{br$yi8#I9W98v>~5PLkG~7g z%~6qYZa3oHH;vwZ(V7tzG6rx4god>7Vl5Y;G$JdNXk|WH6a?-+n;Wg4$n2=_e<$Q z>%#%aOhDW1K&lOKEXF8NI}axU{yc6IkrMKrT`{Vy0gmU2&bH2xX7BXEOt3n=z_f#T z(I!M)^*#=0I{_Jz4XlJFw6-~Gf0l9cAFBqL3e6eur}O9Qt*TXTFM(K&h>{o~qEZ(G z!kvCMzhWyPO_)W?egk9hV9mET$y9{&FW@`Vtg%$48W&o|SbZ!#U-LjoR0|R6AWFGr zx}SvT&`)zK@A|?7sLr}$kcg2>CUvp@cGpjac!shd7pFL3sp5?f1pt6b{;`r7^uj+{ zJFm^>)#K{7VlDp!=j;Bqk+JQ+#|yUs{;a93WZ8yYEv}8dWWroxx}GH$FQ>0Aavfzz zE~r2;b>H4V-HDY!T@knt$}QQE3#T4$d2@h#%&(5+U}X1ZFGs;T9wP$dHPL>)uG%lD zWSqLVh@v(x7->1bIJ(swgnwQeg}xg%zs%7ubFl<)vqcvdD-M(F?^E(oh*LCct;HkC zHizJmi;EnsKYh=l4L-aNbwE`~A9uty$kK#`Tlh+_$CNo>sbrJk67SL z04lr4rAz$)(tc(Zt?mhxS2!Z`*Zzl9lX>Nj6epoGv;(e=nV7tF+kiE&z-kYlB}=1S zlYNA&{)R%cK=VcLz43dsccPMK8&w}AZ zL=aSNfcQgjxrd5mS;7Hn%hd$xaEHM5!q4Ct=|i;z_Ds0Y)^nsm

g5>HI~EsxOlHq^2ClyUglh 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 NSnW store, status: () => requireScheduler().status(), + health: () => requireScheduler().health(), + orgs: () => scheduler?.orgs() ?? initial.github.orgs, people: () => scheduler?.people() ?? initial.people ?? [], }), }); diff --git a/extensions/team-reports/package.json b/extensions/team-reports/package.json index 519b9f1eee66..aaca6f752481 100644 --- a/extensions/team-reports/package.json +++ b/extensions/team-reports/package.json @@ -37,7 +37,13 @@ }, "build": { "openclawVersion": "2026.9.2", - "bundledDist": false + "bundledDist": false, + "staticAssets": [ + { + "source": "./assets/crab.avif", + "output": "assets/crab.avif" + } + ] }, "release": { "publishToClawHub": true, diff --git a/extensions/team-reports/src/http.test.ts b/extensions/team-reports/src/http.test.ts index fafc1fdd4b3f..1a59dab2930d 100644 --- a/extensions/team-reports/src/http.test.ts +++ b/extensions/team-reports/src/http.test.ts @@ -3,6 +3,7 @@ import fs from "node:fs"; import { createServer, request, type IncomingHttpHeaders, type Server } from "node:http"; import os from "node:os"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { createTeamReportsHttpHandler } from "./http.js"; import { describePeriod } from "./periods.js"; @@ -82,11 +83,13 @@ let store: TeamReportsStore; let server: Server; let port: number; let available = true; +let currentOrgs = ["configured-example"]; const getStore = vi.fn(() => (available ? store : undefined)); beforeEach(() => { runtimeScopeMock.mockReturnValue({ client: { connect: { scopes: ["operator.read"] } } }); getStore.mockClear(); + currentOrgs = ["configured-example"]; }); function fetchPath( @@ -141,8 +144,11 @@ beforeAll(async () => { const handler = createTeamReportsHttpHandler({ basePath: "/reports", displayTimezone: "UTC", + assetsDir: fileURLToPath(new URL("../assets", import.meta.url)), getStore, status: () => ({ running: false, lastRun: "fixture-run" }), + health: () => ({ running: false, warnings: 1 }), + orgs: () => currentOrgs, people: () => [ { github: ["alice", "alice-alias"], @@ -183,6 +189,8 @@ describe("Team Reports HTTP responses", () => { runtimeScopeMock.mockReturnValue(scopes ? { client: { connect: { scopes } } } : undefined); for (const url of [ "/reports/", + "/reports/assets/crab.avif", + "/reports/assets/icon.png", "/reports/status", "/reports/index.json", "/reports/latest/", @@ -230,7 +238,7 @@ describe("Team Reports HTTP responses", () => { }, ); - it("serves no-script escaped HTML with nonce-based CSP and safe navigation", async () => { + it("serves escaped HTML with one nonce-authorized script and safe navigation", async () => { const response = await fetchPath("/reports/day/2026-08-20/", "GET", { "x-forwarded-proto": "https", }); @@ -244,31 +252,27 @@ describe("Team Reports HTTP responses", () => { const nonce = typeof csp === "string" ? /style-src 'nonce-([^']+)'/.exec(csp)?.[1] : undefined; expect(nonce).toBeTruthy(); expect(csp).toBe( - `default-src 'none'; style-src 'nonce-${nonce}'; img-src https://avatars.githubusercontent.com data:; base-uri 'none'; form-action 'none'`, + `default-src 'none'; style-src 'nonce-${nonce}'; script-src 'nonce-${nonce}'; img-src 'self' https://avatars.githubusercontent.com data:; base-uri 'none'; form-action 'none'`, ); expect(response.body).toContain(`

${body}
Report windows use UTC. Generation times are shown in ${escapeHtml(ctx.displayTimezone)}. Links may not open inside the Control UI frame.
`; +function homeMetric(label: string, value: string | number): string { + return `
${escapeHtml(label)}${value}
`; } - -function renderTrend(days: TrendDay[]): string { - if (days.length === 0) { - return '

No stored daily activity yet.

'; - } - const maximum = Math.max(1, ...days.flatMap((day) => [day.github, day.discord])); - const timestamps = days.map((day) => Date.parse(`${day.key}T00:00:00Z`)); - const startMs = timestamps[0] ?? 0; - const spanMs = Math.max(DAY_MS, (timestamps.at(-1) ?? startMs) - startMs); - const x = (index: number) => 42 + (((timestamps[index] ?? startMs) - startMs) / spanMs) * 696; - const y = (value: number) => 152 - (value / maximum) * 128; - const line = (kind: "github" | "discord") => { - const path = days - .map((day, index) => { - const previous = timestamps[index - 1]; - const connected = previous !== undefined && (timestamps[index] ?? 0) - previous === DAY_MS; - return `${connected ? "L" : "M"}${x(index).toFixed(1)},${y(day[kind]).toFixed(1)}`; - }) - .join(" "); - return `${days.map((day, index) => ``).join("")}`; - }; - return `
GitHub events and Discord messages per stored day${maximum}0${line("github")}${line("discord")}${escapeHtml(days[0]?.key ?? "")}${escapeHtml(days.at(-1)?.key ?? "")}
GitHub eventsDiscord messages
`; -} - -function statusBadge(status: ReportDocument["status"]): string { - return `${escapeHtml(status)}`; -} - -function pills(person: Pick): string { - return [person.affiliation, person.roleLabel ?? person.roleGroup] - .filter((value): value is string => Boolean(value)) - .map((value) => `${escapeHtml(value)}`) - .join(""); -} - -function banner(tone: "warning" | "info" | "neutral", content: string): string { - return `
${content}
`; -} - -function sectionHeading(title: string): string { - return `

${escapeHtml(title)}

`; -} - -function history(ctx: PageContext, entries: PeriodListEntry[]): string { - if (entries.length === 0) { - return '

No reports generated yet.

'; - } - return ``; -} - export function renderIndexPage( ctx: PageContext, index: PeriodIndex, - days: ReportDocument[], + options: OverviewOptions, ): string { - const periods: Period[] = ["day", "week", "month"]; - const cards = periods - .map((period) => { - const entry = index[period][0]; - return `

Latest ${period}

${entry ? statusBadge(entry.status) : ""}
${entry ? `${escapeHtml(entry.key)}

Generated ${escapeHtml(date(entry.generatedAtMs, ctx.displayTimezone))}

` : '

No reports yet.

'}
`; - }) - .join(""); + const days = index.day.toSorted((a, b) => a.key.localeCompare(b.key)); + const latestDay = index.day[0]; + const generated = Math.max( + 0, + ...PERIODS.flatMap((period) => index[period].map((entry) => entry.generatedAtMs)), + ); + const orgs = options.orgs.join(", "); + const dateline = + days.length >= 2 + ? `` + : ""; + const open = PERIODS.filter((period) => index[period][0] && isOpen(ctx, index[period][0])); + const openBanner = open.length + ? banner( + "info", + `Open reporting windows

The current UTC ${open.join(", ")} ${open.length === 1 ? "remains" : "remain"} open. ${open.length === 1 ? "Its total is a snapshot" : "Their totals are snapshots"} and update as new activity arrives.

`, + ) + : ""; + const health = options.health; + const lastRun = health.lastRun + ? `${health.lastRun.status} ${relativeTime(ctx, health.lastRun.finishedAtMs)}` + : "—"; return shell( ctx, "Overview", - `

Team activity

Overview

GitHub contributions and Discord discussion, by day, week, and month.

${cards}
${sectionHeading("Daily activity · last 28 days")}${renderTrend(days.map((day) => ({ key: day.period.key, github: day.totals.github.total, discord: day.totals.discord.messages })))}

Only stored days are shown. Missing days are not counted as zero activity.

${sectionHeading("Report history")}
${periods.map((period) => `

${period === "day" ? "Days" : period === "week" ? "Weeks" : "Months"}

${history(ctx, index[period])}
`).join("")}
`, - ); -} - -export function renderReportPage( - ctx: PageContext, - report: ReportDocument, - summary: SummaryDocument | null, -): string { - const path = href(ctx.basePath, report.period.period, report.period.key); - const warnings = [...report.sources.github.warnings, ...(report.sources.discord?.warnings ?? [])]; - if (!report.sources.github.ok || report.sources.github.stale) { - warnings.unshift("GitHub coverage is incomplete. Counts may be lower than actual activity."); - } - if (report.sources.discord && (!report.sources.discord.ok || report.sources.discord.stale)) { - warnings.push("Discord coverage is incomplete. Counts may be lower than actual activity."); - } - if (report.truncated) { - warnings.push("Item lists were truncated; aggregate counts are preserved."); - } - const summaryNotices = (summary?.warnings ?? []) - .map((warning) => banner("warning", `

${escapeHtml(warning)}

`)) - .join(""); - const notices = [ - report.status === "partial" - ? banner( - "warning", - "

This period is still open. Activity and summaries may change as new reports are generated.

", - ) - : "", - !summary || summary.source === "fallback" - ? banner( - "info", - "

Deterministic summary: model summaries are disabled, pending, or unavailable.

", - ) - : "", - warnings.length - ? banner( - "warning", - `

Coverage notes

    ${warnings.map((warning) => `
  • ${escapeHtml(warning)}
  • `).join("")}
`, - ) - : "", - ].join(""); - const members = report.members - .map( - (member) => - `
  • ${renderAvatar(member.login, member.display, "md")}

    ${escapeHtml(member.display)}

    @${escapeHtml(member.login)}${pills(member)}

    ${escapeHtml(countDescription(member.github))} · ${member.discord.total} Discord messages

    ${escapeHtml(memberSummary(member))}

    ${member.areas.length ? `

    Areas: ${member.areas.map(escapeHtml).join(", ")}

    ` : ""}${member.access.length ? `

    Access: ${member.access.map(escapeHtml).join(", ")}

    ` : ""}${member.github.items.length ? `
    ${member.github.items.length} GitHub items
      ${member.github.items.map((item) => `
    • ${ITEM_LABELS[item.kind]} · ${escapeHtml(item.repo)} — ${externalLink(item.url, item.title)}
    • `).join("")}
    ` : ""}${member.discord.excerpts.length ? `
    Discord excerpts${member.discord.excerpts.map((excerpt) => `
    #${escapeHtml(excerpt.channel)} · ${escapeHtml(date(excerpt.atMs, ctx.displayTimezone))}
    ${escapeHtml(excerpt.excerpt)}
    `).join("")}
    ` : ""}
  • `, - ) - .join(""); - const other = report.otherActors.length - ? `
    ${sectionHeading("Other GitHub actors")}

    Activity by accounts outside the current roster.

      ${report.otherActors.map((actor) => `
    • ${renderAvatar(actor.login, actor.login, "xs")}@${escapeHtml(actor.login)}${actor.github.total} GitHub events
    • `).join("")}
    ` - : ""; - const unmatched = report.unmatchedDiscord.length - ? `
    ${sectionHeading("Unmatched Discord authors")}

    These messages count toward Discord totals. No message content is included.

      ${report.unmatchedDiscord.map((actor) => `
    • ${escapeHtml(actor.authorId)}: ${actor.messages} messages
    • `).join("")}
    ` - : ""; - const periodLabel = { day: "Day", week: "Week", month: "Month" }[report.period.period]; - return shell( - ctx, - report.period.title, - `

    ${periodLabel} · ${escapeHtml(report.orgs.join(", "))}

    ${escapeHtml(report.period.title)}

    ${statusBadge(report.status)}

    Generated ${escapeHtml(date(report.generatedAtMs, ctx.displayTimezone))}

    UTC window: ${escapeHtml(new Date(report.period.sinceMs).toISOString())} – ${escapeHtml(new Date(report.period.untilMs).toISOString())} (exclusive)

    ${report.totals.github.total}GitHub events
    ${report.totals.discord.messages}Discord messages
    ${report.activeMembers} / ${report.memberCount}Active members
    ${notices ? `
    ${notices}
    ` : ""}${summary ? `
    ${sectionHeading("Summary")}${summaryNotices ? `
    ${summaryNotices}
    ` : ""}${markdownBlocks(summary.globalSummary)}

    Highlights

      ${summary.highlights.map((highlight) => `
    • ${escapeHtml(highlight)}
    • `).join("")}
    ` : ""}
    ${sectionHeading("Members")}${members ? `
      ${members}
    ` : "

    No members are configured for this period.

    "}
    ${other}${unmatched}`, - ); -} - -export function renderPeoplePage(ctx: PageContext, people: Person[]): string { - const rows = people - .map((person) => { - const login = person.github[0] ?? ""; - const display = person.display ?? login; - const path = escapeHtml(href(ctx.basePath, "people", login)); - return `${renderAvatar(login, display, "md")}${escapeHtml(display)}@${escapeHtml(login)}${escapeHtml(person.affiliation ?? "—")}${escapeHtml(person.roleLabel ?? person.roleGroup ?? "—")}${person.status === "archived" ? "Archived" : "Active"}History`; - }) - .join(""); - return shell( - ctx, - "People", - `

    Team activity

    People

    Current roster and archived members with retained history.

    ${rows}
    PersonLoginAffiliationRoleStatusHistory
    `, - ); -} - -export function renderPersonPage(ctx: PageContext, person: Person, days: PersonDay[]): string { - const login = person.github[0] ?? ""; - const trend = days - .toSorted((a, b) => a.dayKey.localeCompare(b.dayKey)) - .map((day) => ({ key: day.dayKey, github: day.githubTotal, discord: day.discordMessages })); - return shell( - ctx, - person.display ?? login, - `
    ${renderAvatar(login, person.display ?? login, "xl")}

    ${escapeHtml(person.display ?? login)}

    @${escapeHtml(login)}
    ${pills(person)}
    ${person.github.length > 1 ? `

    Aliases: ${person.github.slice(1).map(escapeHtml).join(", ")}

    ` : ""}
    ${person.status === "archived" ? banner("neutral", `

    Archived${person.archivedAt ? ` on ${escapeHtml(person.archivedAt)}` : ""}. Historical reports remain available.

    `) : ""}
    ${sectionHeading("Daily activity")}${renderTrend(trend)}
    ${sectionHeading("Last 28 days with retained history")}${days.length ? `
    ${days.map((day) => ``).join("")}
    UTC dayGitHub eventsCommitsPRs mergedDiscord messages
    ${escapeHtml(day.dayKey)}${day.githubTotal}${day.commits}${day.prsMerged}${day.discordMessages}
    ` : "

    No stored daily reports for this person yet.

    "}
    `, + `

    ${escapeHtml(orgs)} · team

    Team Reports

    Daily, weekly, and monthly GitHub and Discord activity for ${escapeHtml(orgs)}. Access is enforced by the Gateway; history is stored by the plugin.

    generated ${generated ? relativeTime(ctx, generated) : "—"}
    ${dateline}${openBanner}${options.latest ? sourceBanners(options.latest.report, options.latest.summary) : ""}${PERIODS.map((period) => quickCard(ctx, index, period)).join("")}
    people

    People Archive

    Activity timelines and repository history by team member.

    ${homeMetric("People", latestDay?.memberCount ?? 0)}${homeMetric("Active today", latestDay?.activeMembers ?? 0)}${homeMetric("Report days", days.length)}
    runs

    Generation Status

    Scheduler and source health.

    ${homeMetric("Last run", lastRun)}${homeMetric("Next due", health.nextDueMs === undefined ? "—" : relativeTime(ctx, health.nextDueMs))}${homeMetric("Source warnings", health.warnings)}
    ${PERIODS.map((period) => history(ctx, index[period], period)).join("")}
    `, + "home", ); } diff --git a/extensions/team-reports/src/render/page.ts b/extensions/team-reports/src/render/page.ts new file mode 100644 index 000000000000..25f3916af87f --- /dev/null +++ b/extensions/team-reports/src/render/page.ts @@ -0,0 +1,166 @@ +import type { PeriodDescriptor, Person, ReportDocument, SummaryDocument } from "../types.js"; +import { REPORT_SCRIPT } from "./script.js"; +import { escapeHtml, safeExternalUrl } from "./shared.js"; +import { REPORT_STYLES } from "./styles.js"; + +export type PageContext = { + basePath: string; + nonce: string; + absoluteUrl: string; + displayTimezone: string; + nowMs?: number; +}; +type Window = Pick; +type Snapshot = Window & { generatedAtMs: number; status: ReportDocument["status"] }; + +export function href(basePath: string, ...segments: string[]): string { + return `${basePath}/${segments.map(encodeURIComponent).join("/")}/`; +} +export function date(value: number, timezone: string): string { + return new Intl.DateTimeFormat("en-US", { + dateStyle: "medium", + timeStyle: "short", + timeZone: timezone, + }).format(value); +} +export function relativeTime(ctx: PageContext, ms: number): string { + const exact = escapeHtml(date(ms, ctx.displayTimezone)); + return ``; +} +export function periodTitle(entry: Window): string { + if (entry.period === "week") { + return `Week ${entry.key.replace(/^\d+-W/, "")}`; + } + return new Intl.DateTimeFormat("en-US", { + month: entry.period === "month" ? "long" : "short", + ...(entry.period === "day" ? { day: "numeric" } : {}), + year: "numeric", + timeZone: "UTC", + }).format(entry.sinceMs); +} +export function formatWindow(entry: Pick): string { + const start = new Date(entry.sinceMs); + const end = new Date(entry.untilMs - 1); + const day = (value: Date) => + new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + year: "numeric", + timeZone: "UTC", + }).format(value); + if (start.toISOString().slice(0, 10) === end.toISOString().slice(0, 10)) { + return day(start); + } + if ( + start.getUTCFullYear() === end.getUTCFullYear() && + start.getUTCMonth() === end.getUTCMonth() + ) { + const monthDay = new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + timeZone: "UTC", + }).format(start); + return `${monthDay}-${end.getUTCDate()}, ${end.getUTCFullYear()}`; + } + return `${day(start)}-${day(end)}`; +} +export function isOpen(ctx: PageContext, entry: Pick): boolean { + const now = ctx.nowMs ?? Date.now(); + return now >= entry.sinceMs && now < entry.untilMs; +} +export function openPeriodStatus(ctx: PageContext, entry: Snapshot): string { + if (!isOpen(ctx, entry)) { + return ""; + } + const minutes = Math.max(1, Math.ceil((entry.untilMs - (ctx.nowMs ?? Date.now())) / 60000)); + const remaining = minutes >= 60 ? `${Math.floor(minutes / 60)}h ${minutes % 60}m` : `${minutes}m`; + const until = new Date(entry.untilMs).toISOString(); + const asOf = new Date(entry.generatedAtMs).toISOString(); + const label = + entry.period === "day" ? "Today" : entry.period === "week" ? "Week to date" : "Month to date"; + return `${label}, as of · ${relativeTime(ctx, entry.generatedAtMs)}${entry.period === "day" ? `closes in ${remaining} (${until.slice(11, 16)} UTC)` : ""}`; +} +export function banner(tone: "warning" | "info" | "neutral", content: string): string { + return `
    ${content}
    `; +} +export function sourceBanners(report: ReportDocument, summary: SummaryDocument | null): string { + const banners: string[] = []; + const source = (title: string, warnings: string[]) => + banner( + "warning", + `${title}

    ${warnings.length ? warnings.map(escapeHtml).join(" · ") : "Counts may be lower than actual activity."}

    `, + ); + const github = report.sources.github; + if (!github.ok || github.stale || github.warnings.length) { + banners.push( + source( + !github.ok ? "GitHub sources unavailable" : "GitHub coverage is incomplete", + github.warnings, + ), + ); + } + const discord = report.sources.discord; + if (discord && (!discord.ok || discord.stale || discord.warnings.length)) { + banners.push(source("Discord coverage is incomplete", discord.warnings)); + } + const warnings = [ + ...(summary?.warnings ?? []), + ...(report.truncated ? ["Item lists were truncated; aggregate counts are preserved."] : []), + ]; + if (warnings.length) { + banners.push(source("Summary and coverage notes", warnings)); + } + return banners.slice(0, 3).join(""); +} +export function sectionHeading(title: string, eyebrow?: string, note?: string): string { + return `
    ${eyebrow ? `
    ${escapeHtml(eyebrow)}
    ` : ""}

    ${escapeHtml(title)}

    ${note ? `${escapeHtml(note)}` : ""}
    `; +} +export function affiliation(person: Pick): string { + const variant = + person.roleGroup === "readonly" + ? "is-readonly" + : person.roleGroup === "volunteer" + ? "is-na" + : !person.affiliation || person.affiliation === "Independent" + ? "is-independent" + : ""; + return `${escapeHtml(person.affiliation || (person.roleGroup === "readonly" ? "Read-only" : person.roleGroup === "volunteer" ? "Volunteer" : "Independent"))}`; +} +export function externalLink(url: string, label: string): string { + const safe = safeExternalUrl(url); + return safe + ? `${escapeHtml(label)}` + : escapeHtml(label); +} +export function markdownBlocks(value: string): string { + return value + .split(/\n\s*\n/) + .map((block) => { + const lines = block.split("\n"); + const inline = (line: string) => + escapeHtml(line).replace(/\*\*([^*]+)\*\*/g, "$1"); + return lines.every((line) => /^\s*[-*] /.test(line)) + ? `
      ${lines.map((line) => `
    • ${inline(line.replace(/^\s*[-*] /, ""))}
    • `).join("")}
    ` + : `

    ${lines.map(inline).join("
    ")}

    `; + }) + .join(""); +} +export function shell( + ctx: PageContext, + title: string, + body: string, + page: "home" | "report" | "people" | "person", +): string { + const active = page === "home" || page === "report" ? "Reports" : "People"; + const links = [ + ["Reports", `${ctx.basePath}/`], + ["Latest", `${ctx.basePath}/latest/`], + ["People", `${ctx.basePath}/people/`], + ] + .map( + ([label, url]) => + `${label}`, + ) + .join(""); + return `${escapeHtml(title)} · Team Reports
    ${body}
    Report windows use UTC. Generation times are shown in ${escapeHtml(ctx.displayTimezone)}. Links may not open inside the Control UI frame.
    `; +} diff --git a/extensions/team-reports/src/render/people.ts b/extensions/team-reports/src/render/people.ts new file mode 100644 index 000000000000..f10f721c5a07 --- /dev/null +++ b/extensions/team-reports/src/render/people.ts @@ -0,0 +1,317 @@ +import { DAY_MS } from "../periods.js"; +import type { PersonDay } from "../store.js"; +import type { Person } from "../types.js"; +import { affiliation, href, type PageContext, sectionHeading, shell } from "./page.js"; +import { escapeHtml, renderAvatar } from "./shared.js"; + +function activityLevel(count: number): number { + if (count <= 0) { + return 0; + } + if (count < 5) { + return 1; + } + if (count < 15) { + return 2; + } + if (count < 40) { + return 3; + } + return 4; +} + +function total(day: PersonDay): number { + return day.githubTotal + day.discordMessages; +} + +function dayTitle(key: string): string { + return new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + year: "numeric", + timeZone: "UTC", + }).format(Date.parse(`${key}T00:00:00Z`)); +} + +function peopleMetric(label: string, value: number | string): string { + return `
    ${escapeHtml(label)}${escapeHtml(String(value))}
    `; +} + +function roleBadge(person: Person): string { + const role = person.roleLabel ?? person.roleGroup; + return `${role ? `${escapeHtml(role)}` : ""}${person.status === "archived" ? 'Archived' : ""}`; +} + +function rankingStats(days: PersonDay[]) { + return days.reduce( + (result, day) => ({ + github: result.github + day.githubTotal, + discord: result.discord + day.discordMessages, + active: result.active + (total(day) > 0 ? 1 : 0), + }), + { github: 0, discord: 0, active: 0 }, + ); +} + +export function renderPeoplePage( + ctx: PageContext, + people: Person[], + days: PersonDay[] = [], + endKey?: string, +): string { + const last = + endKey ?? + days + .map((day) => day.dayKey) + .toSorted() + .at(-1) ?? + new Date(ctx.nowMs ?? Date.now()).toISOString().slice(0, 10); + const end = Date.parse(`${last}T00:00:00Z`); + const keys = Array.from({ length: 28 }, (_, index) => + new Date(end - (27 - index) * DAY_MS).toISOString().slice(0, 10), + ); + const first = keys[0] ?? last; + const rankedDays = days.filter((day) => day.dayKey >= first && day.dayKey <= last); + const dayCount = new Set(rankedDays.map((day) => day.dayKey)).size; + const byLogin = new Map(); + for (const day of rankedDays) { + const login = day.login.toLowerCase(); + const entries = byLogin.get(login) ?? []; + entries.push(day); + byLogin.set(login, entries); + } + const ranked = people + .map((person) => { + const entries = byLogin.get((person.github[0] ?? "").toLowerCase()) ?? []; + return { person, entries, stats: rankingStats(entries) }; + }) + .toSorted( + (a, b) => + b.stats.github + b.stats.discord - a.stats.github - a.stats.discord || + b.stats.active - a.stats.active || + (a.person.display ?? a.person.github[0] ?? "").localeCompare( + b.person.display ?? b.person.github[0] ?? "", + ), + ); + const groups = [ + { + key: "active", + label: "Active members", + rows: ranked.filter( + ({ person, stats }) => + person.status !== "archived" && person.roleGroup !== "readonly" && stats.active > 0, + ), + }, + { + key: "quiet", + label: "No visible activity in the ranking window", + rows: ranked.filter( + ({ person, stats }) => + person.status !== "archived" && person.roleGroup !== "readonly" && stats.active === 0, + ), + }, + { + key: "readonly", + label: "Read-only access", + rows: ranked.filter( + ({ person }) => person.status !== "archived" && person.roleGroup === "readonly", + ), + }, + { + key: "archived", + label: "Former members", + rows: ranked.filter(({ person }) => person.status === "archived"), + }, + ]; + const cards = groups + .filter((group) => group.rows.length) + .map((group) => { + const heading = `
    ${group.label}${group.rows.length} ${group.key === "quiet" ? "quiet" : group.key === "archived" ? "archived" : "people"}
    `; + return `${heading}${group.rows + .map(({ person, entries, stats }) => { + const login = person.github[0] ?? ""; + const display = person.display ?? login; + const archived = person.status === "archived"; + const inactive = stats.active === 0; + const points = new Map(entries.map((day) => [day.dayKey, day])); + const strip = keys + .map((key) => { + const point = points.get(key); + const count = point ? total(point) : 0; + const title = `${key}: ${point ? `${count} events` : "No stored report"}`; + return ``; + }) + .join(""); + return `${renderAvatar(login, display, "sm")}${escapeHtml(display)}@${escapeHtml(login)}${affiliation(person)}${strip}${roleBadge(person)}${stats.github + stats.discord} events · ${stats.github} GitHub · ${stats.discord} Discord${stats.active} out of ${dayCount} days active`; + }) + .join("")}`; + }) + .join(""); + const archived = people.filter((person) => person.status === "archived").length; + const quiet = groups.find((group) => group.key === "quiet")?.rows.length ?? 0; + return shell( + ctx, + "People", + `
    people

    Member Activity Timelines

    Current members ranked by the last 28 days, with former members retained in the archive. Darker cells mean heavier GitHub or Discord activity. Open a person to explore their daily reports.

    Ranking Window28 days${people.length - archived} current, ${quiet} quiet, ${archived} archived · ${dayCount} report days
    GitHubDiscord
    ${cards || '

    No member activity yet.

    '}
    `, + "people", + ); +} + +function personActivityChart(login: string, days: PersonDay[]): string { + const latest = days.at(-1); + if (!latest) { + return `
    ${sectionHeading("Last 30 Days", "activity")}

    No daily report data is available.

    `; + } + const end = Date.parse(`${latest.dayKey}T00:00:00Z`); + const start = end - 29 * DAY_MS; + const points = days.filter((day) => Date.parse(`${day.dayKey}T00:00:00Z`) >= start); + const maximum = (field: "githubTotal" | "discordMessages") => { + const value = Math.max(0, ...points.map((day) => day[field])); + if (value <= 4) { + return 4; + } + const magnitude = 10 ** Math.floor(Math.log10(value / 4)); + const normalized = value / 4 / magnitude; + const step = (normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10) * magnitude; + return Math.ceil(value / step) * step; + }; + const githubMax = maximum("githubTotal"); + const discordMax = maximum("discordMessages"); + const x = (day: PersonDay) => + 78 + ((Date.parse(`${day.dayKey}T00:00:00Z`) - start) / (29 * DAY_MS)) * 782; + const y = (value: number, max: number) => 298 - (value / max) * 234; + const fixed = (value: number) => value.toFixed(1); + const series = (field: "githubTotal" | "discordMessages", source: string, max: number) => { + const path = points + .map((day, index) => { + const previous = points[index - 1]; + const connected = + previous && + Date.parse(`${day.dayKey}T00:00:00Z`) - Date.parse(`${previous.dayKey}T00:00:00Z`) === + DAY_MS; + return connected + ? `H${fixed(x(day))} V${fixed(y(day[field], max))}` + : `M${fixed(x(day))} ${fixed(y(day[field], max))}`; + }) + .join(" "); + return `${points.map((day) => `${escapeHtml(`${day.dayKey}: ${day[field]} ${source === "github" ? "GitHub events" : "Discord messages"}`)}`).join("")}`; + }; + const ticks = Array.from({ length: 5 }, (_, index) => { + const fraction = index / 4; + const yy = fixed(y(fraction, 1)); + return `${Math.round(githubMax * fraction)}${Math.round(discordMax * fraction)}`; + }).join(""); + const dateTicks = [0, 7, 14, 21, 29] + .map((offset) => { + const time = start + offset * DAY_MS; + const label = new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + timeZone: "UTC", + }).format(time); + return `${escapeHtml(label)}`; + }) + .join(""); + const svg = `${escapeHtml(`Last 30 Days for @${login}`)}Only stored daily values are plotted. Gaps indicate missing reports, not zero activity.${ticks}GitHub events · left axisDiscord messages · right axis${series("githubTotal", "github", githubMax)}${series("discordMessages", "discord", discordMax)}${dateTicks}`; + return `
    ${sectionHeading("Last 30 Days", "activity", "Daily GitHub events and report-scoped Discord messages. UTC.")}
    • GitHub events · left axis
    • Discord messages · right axis
    ${svg}

    Only stored days are shown. Missing days are not counted as zero activity.

    Exact daily values
    ${points.map((day) => ``).join("")}
    UTC dayGitHub eventsDiscord messages
    ${day.githubTotal}${day.discordMessages}
    `; +} + +function reportHref(ctx: PageContext, login: string, key: string): string { + return escapeHtml(`${href(ctx.basePath, "day", key)}?person=${encodeURIComponent(login)}`); +} + +function archiveTimeline(ctx: PageContext, login: string, days: PersonDay[]): string { + const months = new Map(); + for (const day of days) { + const month = day.dayKey.slice(0, 7); + const entries = months.get(month) ?? []; + entries.push(day); + months.set(month, entries); + } + return [...months.entries()] + .toReversed() + .map(([month, entries]) => { + const first = new Date(`${month}-01T00:00:00Z`); + const offset = (first.getUTCDay() + 6) % 7; + const monthEnd = new Date(first); + monthEnd.setUTCMonth(monthEnd.getUTCMonth() + 1); + const length = (monthEnd.getTime() - first.getTime()) / DAY_MS; + const points = new Map(entries.map((day) => [day.dayKey, day])); + const cells = Array.from({ length }, (_, index) => { + const key = `${month}-${String(index + 1).padStart(2, "0")}`; + const point = points.get(key); + if (!point) { + return `${index + 1}`; + } + const label = `${key}: ${total(point)} events for @${login}`; + return `${index + 1}`; + }).join(""); + const label = new Intl.DateTimeFormat("en-US", { + month: "long", + year: "numeric", + timeZone: "UTC", + }).format(first); + return `
    ${escapeHtml(label)}
    ${Array.from({ length: offset }, () => '').join("")}${cells}
    `; + }) + .join(""); +} + +export function renderPersonPage(ctx: PageContext, person: Person, days: PersonDay[]): string { + const login = person.github[0] ?? ""; + const display = person.display ?? login; + const ordered = days.toSorted((a, b) => a.dayKey.localeCompare(b.dayKey)); + const active = ordered.filter((day) => total(day) > 0); + const latest = active.at(-1); + const sum = (value: (day: PersonDay) => number) => + days.reduce((result, day) => result + value(day), 0); + const totals = [ + peopleMetric( + "GitHub", + sum((day) => day.githubTotal), + ), + peopleMetric( + "Comments", + sum((day) => day.issueComments + day.reviewComments), + ), + peopleMetric( + "Discord", + sum((day) => day.discordMessages), + ), + peopleMetric( + "Commits", + sum((day) => day.commits), + ), + peopleMetric( + "PRs", + sum((day) => day.prsOpened + day.prsMerged + day.prsClosed), + ), + peopleMetric( + "Issues", + sum((day) => day.issuesOpened + day.issuesClosed), + ), + ].join(""); + const lifecycle = + person.status === "archived" + ? `

    Archived${person.archivedAt ? ` on ${escapeHtml(person.archivedAt)}` : ""}. Historical reports remain available.

    ` + : ""; + const rows = active + .toReversed() + .map( + (day) => + `${escapeHtml(dayTitle(day.dayKey))}${total(day)} events${day.githubTotal} GitHub · ${day.issueComments + day.reviewComments} comments · ${day.discordMessages} Discord · ${day.commits} commits · ${day.prsOpened + day.prsMerged + day.prsClosed} PRs`, + ) + .join(""); + return shell( + ctx, + display, + `
    ${renderAvatar(login, display, "xl")}

    ${escapeHtml(display)}

    ${affiliation(person)}@${escapeHtml(login)}${roleBadge(person)}
    ${lifecycle}${ + person.github.length > 1 + ? `

    Aliases: ${person.github + .slice(1) + .map((alias) => `@${escapeHtml(alias)}`) + .join(" · ")}

    ` + : "" + }
    Active Days${active.length}/${days.length}${latest ? `Latest activity ${escapeHtml(dayTitle(latest.dayKey))}` : "No active days"}
    ${totals}
    ${personActivityChart(login, ordered)}
    ${sectionHeading("Daily Archive", "timeline")}
    ${archiveTimeline(ctx, login, ordered) || '

    No stored daily reports for this person yet.

    '}
    ${sectionHeading("Active Days", "history")}
    ${rows || '

    No active days recorded.

    '}
    `, + "person", + ); +} diff --git a/extensions/team-reports/src/render/report.ts b/extensions/team-reports/src/render/report.ts new file mode 100644 index 000000000000..657e9a3749ba --- /dev/null +++ b/extensions/team-reports/src/render/report.ts @@ -0,0 +1,236 @@ +import type { PeriodListEntry } from "../store.js"; +import type { GithubCounts, PersonReport, ReportDocument, SummaryDocument } from "../types.js"; +import { deltaMarkup, sparklineSvg, splitMarkup } from "./charts.js"; +import { + affiliation, + banner, + date, + externalLink, + formatWindow, + href, + isOpen, + markdownBlocks, + openPeriodStatus, + type PageContext, + periodTitle, + relativeTime, + sectionHeading, + shell, + sourceBanners, +} from "./page.js"; +import { escapeHtml, ITEM_LABELS, memberSummary, renderAvatar } from "./shared.js"; + +function activitySegments(github: GithubCounts, discord: number) { + const prs = github.prsOpened + github.prsMerged + github.prsClosed; + const issues = github.issuesOpened + github.issuesClosed; + const comments = github.issueComments + github.reviewComments; + return [ + { label: "Commits", value: github.commits, tone: "primary" }, + { label: "PRs", value: prs, tone: "secondary" }, + { label: "Issues", value: issues, tone: "tertiary" }, + { label: "Comments", value: comments, tone: "quaternary" }, + { label: "GHSAs", value: github.securityAdvisories, tone: "error" }, + { + label: "Other GitHub", + value: Math.max( + 0, + github.total - github.commits - prs - issues - comments - github.securityAdvisories, + ), + tone: "neutral", + }, + { label: "Discord", value: discord, tone: "muted" }, + ].filter((segment) => segment.value > 0); +} + +function metric(label: string, value: string | number, detail = "", trend = ""): string { + return `
    ${escapeHtml(label)}${escapeHtml(String(value))}${detail ? `${escapeHtml(detail)}` : ""}${trend}
    `; +} + +function distribution(ctx: PageContext, members: PersonReport[]): string { + const ranked = members + .filter((member) => member.github.total + member.discord.total > 0) + .toSorted( + (a, b) => + b.github.total + b.discord.total - a.github.total - a.discord.total || + a.login.localeCompare(b.login), + ); + const total = ranked.reduce((sum, member) => sum + member.github.total + member.discord.total, 0); + if (total === 0) { + return '

    No member activity recorded in this window.

    '; + } + const row = (member: PersonReport) => { + const value = member.github.total + member.discord.total; + const segments = activitySegments(member.github, member.discord.total); + let offset = 0; + const rectangles = segments + .map((segment) => { + const width = (segment.value / total) * 100; + const rect = `${escapeHtml(segment.label)}: ${segment.value}`; + offset += width; + return rect; + }) + .join(""); + const breakdown = segments + .map( + (segment) => + `${escapeHtml(segment.label)} ${segment.value}`, + ) + .join(""); + return `
  • @${escapeHtml(member.login)}${escapeHtml(member.display)}${rectangles}${value}${Math.round((value / total) * 100)}%${breakdown}
  • `; + }; + return `
      ${ranked.slice(0, 12).map(row).join("")}
    ${ranked.length > 12 ? `
    Show remaining ${ranked.length - 12}
      ${ranked.slice(12).map(row).join("")}
    ` : ""}
    `; +} + +function roleBadges(member: PersonReport): string { + const role = member.roleLabel ?? member.roleGroup; + return `${role ? `${escapeHtml(role)}` : ""}${member.access.map((access) => `${escapeHtml(access)}`).join("")}`; +} + +function searchText(member: PersonReport): string { + return escapeHtml( + [member.login, member.display, ...member.aliases, member.affiliation, ...member.areas] + .filter(Boolean) + .join(" ") + .toLowerCase(), + ); +} + +function personRow(ctx: PageContext, member: PersonReport): string { + const top = (values: Record, limit: number) => + Object.entries(values) + .toSorted(([a, countA], [b, countB]) => countB - countA || a.localeCompare(b)) + .slice(0, limit); + const chips = [ + ...top(member.github.repos, 4).map(([repo, count]) => `${repo}: ${count}`), + ...top(member.discord.channels, 3).map(([channel, count]) => `#${channel}: ${count}`), + ...member.areas.map((area) => `owns: ${area}`), + ] + .map((text) => `${escapeHtml(text)}`) + .join(""); + const themes = member.github.items + .slice(0, 3) + .map( + (item) => + `
    ${ITEM_LABELS[item.kind]} ${externalLink(item.url, item.title)}
    `, + ) + .join(""); + const counts: Array<[string, number]> = [ + ["GitHub", member.github.total], + ["Commits", member.github.commits], + ["GHSAs", member.github.securityAdvisories], + ["PRs", member.github.prsOpened + member.github.prsMerged + member.github.prsClosed], + ["Issues", member.github.issuesOpened + member.github.issuesClosed], + ["Comments", member.github.issueComments + member.github.reviewComments], + ["Discord", member.discord.total], + ]; + const excerpts = member.discord.excerpts.length + ? `
    Discord excerpts${member.discord.excerpts.map((excerpt) => `
    #${escapeHtml(excerpt.channel)} · ${escapeHtml(date(excerpt.atMs, ctx.displayTimezone))}
    ${escapeHtml(excerpt.excerpt)}
    `).join("")}
    ` + : ""; + const items = member.github.items.length + ? `
    ${member.github.items.length} GitHub items
      ${member.github.items.map((item) => `
    • ${ITEM_LABELS[item.kind]} · ${escapeHtml(item.repo)}${externalLink(item.url, item.title)}
    • `).join("")}
    ` + : ""; + return `
    ${renderAvatar(member.login, member.display, "md")}
    @${escapeHtml(member.login)}
    ${escapeHtml(member.display)}
    ${member.aliases.length ? `
    ${member.aliases.map((alias) => `@${escapeHtml(alias)}`).join(" · ")}
    ` : ""}
    ${affiliation(member)}
    ${roleBadges(member)}
    ${chips}

    ${escapeHtml(memberSummary(member))}

    ${themes}${items}${excerpts}
    ${counts.map(([label, count]) => `
    ${label}${count}
    `).join("")}
    `; +} + +export function renderReportPage( + ctx: PageContext, + report: ReportDocument, + summary: SummaryDocument | null, + history: PeriodListEntry[] = [], +): string { + const entry = { ...report.period, status: report.status, generatedAtMs: report.generatedAtMs }; + const open = isOpen(ctx, entry); + const period = report.period.period; + const path = href(ctx.basePath, period, report.period.key); + const incomplete = + open || (report.status === "partial" && report.generatedAtMs < report.period.untilMs); + const partialBanner = incomplete + ? banner( + "info", + `Partial reportIncomplete snapshot

    ${open ? `This UTC ${period} is still in progress.` : `This UTC ${period} was still in progress when this snapshot was generated.`} Totals include activity collected through ${relativeTime(ctx, report.generatedAtMs)}. ${open ? "Activity may increase before the window closes." : "The window has since closed, so these totals remain incomplete."}

    `, + ) + : ""; + const github = report.totals.github; + const prior = history + .filter((row) => row.period === period && row.sinceMs < report.period.sinceMs) + .toSorted((a, b) => a.sinceMs - b.sinceMs) + .slice(-({ day: 28, week: 12, month: 6 }[period] - 1)); + const trend = ( + field: "activeMembers" | "githubTotal" | "discordMessages" | "prsOpened" | "securityAdvisories", + value: number, + label: string, + badUp = false, + ) => { + const values = [...prior.map((row) => row[field]), value]; + return `${deltaMarkup(value, prior.at(-1)?.[field], `prev ${period}${open ? " (in progress)" : ""}`, badUp)}${sparklineSvg(values, `${label} by ${period}`)}`; + }; + const active = report.members.filter((member) => member.github.total + member.discord.total > 0); + const quiet = report.members.filter((member) => member.github.total + member.discord.total === 0); + const roleCounts = ["core", "volunteer", "readonly"].map( + (role) => active.filter((member) => member.roleGroup === role).length, + ); + const repositories = + Number(report.sources.github.stats.reposScanned) || Object.keys(github.repos).length; + const channels = + Number(report.sources.discord?.stats.channelsScanned) || + Object.keys(report.totals.discord.channels).length; + const totals = [ + metric( + "Active", + `${report.activeMembers}/${report.memberCount}`, + roleCounts.some((count) => count > 0) + ? `${roleCounts[0]} Core / ${roleCounts[1]} Community / ${roleCounts[2]} Read-only` + : "members with activity", + trend("activeMembers", report.activeMembers, "Active members"), + ), + metric("GitHub", github.total, "events", trend("githubTotal", github.total, "GitHub events")), + metric( + "Discord", + report.totals.discord.messages, + "messages", + trend("discordMessages", report.totals.discord.messages, "Discord messages"), + ), + metric( + "PRs Opened", + github.prsOpened, + `${github.prsMerged} merged`, + trend("prsOpened", github.prsOpened, "PRs opened"), + ), + metric( + "Security", + github.securityAdvisories, + "advisories", + trend("securityAdvisories", github.securityAdvisories, "Security advisories", true), + ), + metric( + "Repos", + Object.entries(github.repos).filter(([, count]) => count > 0).length, + "active repositories", + ), + ].join(""); + const mix = [ + metric("Commits", github.commits), + metric("GHSAs", github.securityAdvisories), + metric("Issue/PR comments", github.issueComments), + metric("PR review comments", github.reviewComments), + metric("Discord messages", report.totals.discord.messages), + ].join(""); + const quietBlock = quiet.length + ? `` + : ""; + const other = report.otherActors.length + ? `
    ${sectionHeading("Other GitHub actors", "Outside the roster")}
      ${report.otherActors.map((actor) => `
    • ${renderAvatar(actor.login, actor.login, "xs")}@${escapeHtml(actor.login)}${actor.github.total} GitHub events
    • `).join("")}
    ` + : ""; + const unmatched = report.unmatchedDiscord.length + ? `
    ${sectionHeading("Unmatched Discord authors", "Coverage")}

    These messages count toward Discord totals. No message content is included.

      ${report.unmatchedDiscord.map((actor) => `
    • ${escapeHtml(actor.authorId)}${actor.messages} messages
    • `).join("")}
    ` + : ""; + // Fallback summaries restate their bullets as highlights; only list what the overview text lacks. + const highlights = + summary?.highlights.filter((highlight) => !summary.globalSummary.includes(highlight)) ?? []; + return shell( + ctx, + periodTitle(report.period), + `

    ${escapeHtml(periodTitle(report.period))}

    Evidence report across ${repositories} GitHub repositories and ${channels} Discord channels for ${escapeHtml(report.orgs.join(", "))}. Roster: ${report.memberCount} people.

    Window${escapeHtml(formatWindow(report.period))}${open ? openPeriodStatus(ctx, entry) : `As of ${relativeTime(ctx, report.generatedAtMs)}`}
    ${partialBanner}${sourceBanners(report, summary)}
    ${totals}
    ${sectionHeading("Global Summary", "Overview", summary?.source === "model" ? "Model summary" : "Deterministic summary")}
    ${summary ? `${markdownBlocks(summary.globalSummary)}${highlights.length ? `
      ${highlights.map((highlight) => `
    • ${escapeHtml(highlight)}
    • `).join("")}
    ` : ""}` : `

    ${report.activeMembers} of ${report.memberCount} members recorded ${github.total} GitHub events and ${report.totals.discord.messages} Discord messages in this window.

    `}
    ${sectionHeading("Activity Mix", "Hard Numbers")}
    ${mix}
    ${splitMarkup(activitySegments(github, report.totals.discord.messages))}
    Mapped activity

    Activity by Member

    Bar length shows share; colors show activity type

    ${distribution(ctx, report.members)}
    Members

    Members

    showing ${active.length} of ${active.length} active
    ${active.map((member) => personRow(ctx, member)).join("") || '

    No visible GitHub or Discord activity in this window.

    '}
    ${quietBlock}
    ${other}${unmatched}`, + "report", + ); +} diff --git a/extensions/team-reports/src/render/script.ts b/extensions/team-reports/src/render/script.ts new file mode 100644 index 000000000000..ade46c1aded1 --- /dev/null +++ b/extensions/team-reports/src/render/script.ts @@ -0,0 +1,98 @@ +// One head script initializes the theme before paint, then enhances server-rendered content. +export const REPORT_SCRIPT = `(() => { + const root = document.documentElement; + const query = matchMedia('(prefers-color-scheme: light)'); + const storedTheme = () => { + try { const value = localStorage.getItem('theme'); return value === 'light' || value === 'dark' ? value : ''; } catch { return ''; } + }; + const fragmentTheme = () => { + const value = new URLSearchParams(location.hash.slice(1)).get('theme'); + return value === 'light' || value === 'dark' ? value : ''; + }; + root.dataset.theme = fragmentTheme() || storedTheme() || (query.matches ? 'light' : 'dark'); + document.addEventListener('DOMContentLoaded', () => { + root.dataset.js = 'true'; + const applyTheme = (theme, persist) => { + root.dataset.theme = theme; + if (persist) { + try { localStorage.setItem('theme', theme); } catch {} + history.replaceState(null, '', '#theme=' + theme); + } + // Opaque-origin frames cannot use storage; carry their choice through report links. + const basePath = root.dataset.reportBasePath; + for (const link of document.querySelectorAll('a[href]')) { + const href = link.getAttribute('href'); + const target = new URL(href, location.href); + const internal = target.origin === location.origin && + (target.pathname === basePath || target.pathname.startsWith(basePath + '/')); + if (internal || link.hasAttribute('data-report-open-window')) { + link.setAttribute('href', href.split('#')[0] + '#theme=' + theme); + } + } + for (const button of document.querySelectorAll('[data-theme-toggle]')) { + button.setAttribute('aria-label', 'Switch to ' + (theme === 'light' ? 'dark' : 'light') + ' theme'); + } + }; + applyTheme(root.dataset.theme, false); + query.addEventListener('change', event => { if (!fragmentTheme() && !storedTheme()) applyTheme(event.matches ? 'light' : 'dark', false); }); + for (const button of document.querySelectorAll('[data-theme-toggle]')) { + button.addEventListener('click', () => applyTheme(root.dataset.theme === 'light' ? 'dark' : 'light', true)); + } + const relative = new Intl.RelativeTimeFormat('en', {numeric:'auto'}); + const units = [['year',31536000000],['month',2592000000],['week',604800000],['day',86400000],['hour',3600000],['minute',60000],['second',1000]]; + const refresh = () => { + for (const node of document.querySelectorAll('[data-relative-time]')) { + const diff = Date.parse(node.getAttribute('datetime')) - Date.now(); + if (!Number.isFinite(diff)) continue; + const [unit, ms] = units.find(([unit, ms]) => Math.abs(diff) >= ms || unit === 'second'); + node.textContent = relative.format(Math.round(diff / ms), unit); + } + for (const node of document.querySelectorAll('[data-day-countdown]')) { + const until = Date.parse(node.dataset.until); + if (!Number.isFinite(until)) continue; + const minutes = Math.max(1, Math.ceil((until - Date.now()) / 60000)); + const remaining = minutes >= 60 ? Math.floor(minutes / 60) + 'h ' + minutes % 60 + 'm' : minutes + 'm'; + const close = new Date(until).toISOString().slice(11,16) + ' UTC'; + node.textContent = until <= Date.now() ? 'day closed at ' + close : 'closes in ' + remaining + ' (' + close + ')'; + } + }; + refresh(); + setInterval(refresh, 60000); + const nav = document.querySelector('.site-nav'); + const scrolled = () => { if (nav) nav.dataset.scrolled = window.scrollY > 0 ? 'true' : 'false'; }; + scrolled(); + window.addEventListener('scroll', scrolled, {passive:true}); + for (const button of document.querySelectorAll('[data-toggle]')) { + const list = document.querySelector('[data-list="' + button.dataset.toggle + '"]'); + if (!list) continue; + button.addEventListener('click', () => { + const rows = [...list.querySelectorAll('[data-extra]')]; + const show = rows.some(row => row.hidden); + for (const row of rows) row.hidden = !show; + button.setAttribute('aria-expanded', String(show)); + button.textContent = show ? 'Show latest only' : 'Show all ' + list.querySelectorAll('.row').length; + }); + } + const filter = document.querySelector('[data-maintainer-filter]'); + const status = document.querySelector('[data-maintainer-filter-status]'); + const empty = document.querySelector('[data-maintainer-filter-empty]'); + if (filter) { + const applyFilter = () => { + const value = filter.value.trim().replace(/^@/, '').toLocaleLowerCase(); + const rows = [...document.querySelectorAll('[data-maintainer-search]')]; + for (const row of rows) row.hidden = !row.dataset.maintainerSearch.toLocaleLowerCase().includes(value); + const shown = rows.filter(row => !row.hidden).length; + if (status) status.textContent = shown + ' of ' + rows.length + ' members shown'; + if (empty) empty.hidden = shown > 0; + }; + const params = new URLSearchParams(location.search); + filter.value = params.get('person') || params.get('q') || ''; + filter.addEventListener('input', applyFilter); + applyFilter(); + } + const quiet = document.querySelector('[data-hide-inactive-toggle]'); + if (quiet) quiet.addEventListener('change', () => { + root.dataset.peopleHideInactive = quiet.checked ? 'true' : 'false'; + }); + }); +})();`; diff --git a/extensions/team-reports/src/render/shared.ts b/extensions/team-reports/src/render/shared.ts index e4d109480024..b042e43e6384 100644 --- a/extensions/team-reports/src/render/shared.ts +++ b/extensions/team-reports/src/render/shared.ts @@ -17,7 +17,11 @@ export function escapeHtml(value: string): string { }); } -export function renderAvatar(login: string, display: string, size: "xs" | "md" | "xl"): string { +export function renderAvatar( + login: string, + display: string, + size: "xs" | "sm" | "md" | "xl", +): string { const words = (display.trim() || login).split(/\s+/); const initials = ( words.length > 1 @@ -26,7 +30,7 @@ export function renderAvatar(login: string, display: string, size: "xs" | "md" | .slice(0, 2) .join("") ).toUpperCase(); - const pixels = { xs: 20, md: 40, xl: 72 }[size]; + const pixels = { xs: 20, sm: 36, md: 40, xl: 72 }[size]; const image = /^[A-Za-z0-9-]{1,39}$/.test(login) ? `` : ""; diff --git a/extensions/team-reports/src/render/site.test.ts b/extensions/team-reports/src/render/site.test.ts new file mode 100644 index 000000000000..3de1ecbc6d65 --- /dev/null +++ b/extensions/team-reports/src/render/site.test.ts @@ -0,0 +1,373 @@ +import { describe, expect, it } from "vitest"; +import { DAY_MS, describePeriod } from "../periods.js"; +import { githubCounts } from "../reports.fixtures.js"; +import type { PeriodListEntry, PersonDay } from "../store.js"; +import type { Period, Person, ReportDocument } from "../types.js"; +import { + renderIndexPage, + renderPeoplePage, + renderPersonPage, + renderReportPage, + type PageContext, + type PeriodIndex, +} from "./html.js"; + +const ctx: PageContext = { + basePath: "/reports", + nonce: "fixture", + absoluteUrl: "https://example.test/reports/", + displayTimezone: "America/Los_Angeles", + nowMs: Date.parse("2026-09-07T16:44:00Z"), +}; +function entry(period: Period, key: string, total = 10): PeriodListEntry { + const window = describePeriod(period, key); + return { + ...window, + status: window.untilMs > (ctx.nowMs ?? 0) ? "partial" : "closed", + generatedAtMs: Math.min(window.untilMs, ctx.nowMs ?? 0), + activeMembers: 1, + memberCount: 2, + githubTotal: total, + discordMessages: total, + commits: total, + prsOpened: 0, + prsMerged: 0, + securityAdvisories: 0, + }; +} +function document(period: Period = "day", key = "2026-09-07"): ReportDocument { + const row = entry(period, key); + return { + version: 1, + period: describePeriod(period, key), + status: row.status, + generatedAtMs: row.generatedAtMs, + orgs: ["example"], + memberCount: 2, + activeMembers: 1, + totals: { github: githubCounts(10), discord: { messages: 10, channels: { general: 10 } } }, + members: [ + { + login: "alice", + display: "Alice", + aliases: [], + access: [], + areas: [], + github: { ...githubCounts(10), items: [] }, + discord: { total: 10, channels: { general: 10 }, excerpts: [] }, + }, + ], + otherActors: [], + unmatchedDiscord: [], + sources: { github: { ok: true, warnings: [], stats: { reposScanned: 1 } } }, + }; +} +function home(index: Partial): string { + return renderIndexPage( + ctx, + { day: [], week: [], month: [], ...index }, + { orgs: ["example"], health: { running: true, warnings: 0 } }, + ); +} +function personDay(login: string, dayKey: string, total: number): PersonDay { + return { + login, + dayKey, + githubTotal: total, + discordMessages: total, + commits: total, + prsOpened: 0, + prsMerged: 0, + prsClosed: 0, + issuesOpened: 0, + issuesClosed: 0, + issueComments: 0, + reviewComments: 0, + }; +} + +describe("Team Reports site behavior", () => { + it("shows a dateline only with multiple stored days and keeps the whole retained range", () => { + expect(home({ day: [entry("day", "2026-09-07")] })).not.toContain( + 'aria-label="Activity dateline"', + ); + const days = Array.from({ length: 400 }, (_, index) => + entry( + "day", + new Date(Date.parse("2026-09-07T00:00:00Z") - index * DAY_MS).toISOString().slice(0, 10), + ), + ); + const html = home({ day: days }); + expect(html).toContain('aria-label="Activity dateline"'); + expect(html).toContain("400 report days"); + expect(html).toContain(days.at(-1)?.key); + expect(html).toContain('href="/reports/day/2026-09-07/"'); + }); + + it("uses UTC windows for open guidance, countdowns and intraday badges", () => { + const closed = entry("day", "2026-09-06"); + const today = entry("day", "2026-09-07"); + const html = home({ day: [today, closed] }); + expect(html).toContain("Open reporting windows"); + expect(html).toContain("Today, as of"); + expect(html).toContain("16:44 UTC"); + expect(html).toContain("closes in 7h 16m (00:00 UTC)"); + expect(html).toContain(">Intraday"); + expect(home({ day: [closed] })).not.toContain("Open reporting windows"); + expect(home({ day: [{ ...today, generatedAtMs: today.untilMs }] })).not.toContain( + ">Intraday", + ); + expect( + home({ day: [{ ...closed, status: "partial", generatedAtMs: closed.untilMs - 1000 }] }), + ).not.toContain(">Intraday"); + const closedToday = home({ day: [{ ...today, status: "closed" }] }); + expect(closedToday).not.toContain(">Intraday"); + expect(closedToday).not.toContain('class="quick-card oc-card oc-card-interactive partial"'); + }); + + it.each<{ period: Period; key: string }>([ + { period: "day", key: "2026-09-06" }, + { period: "week", key: "2026-W36" }, + { period: "month", key: "2026-08" }, + ])("preserves stored $period completeness in overview cards and history", ({ period, key }) => { + const closed = entry(period, key); + const incomplete = home({ [period]: [{ ...closed, status: "partial" }] }); + expect(incomplete.match(/oc-badge-warning[^>]*>Incomplete<\/span>/g)).toHaveLength(2); + expect(incomplete).toContain('class="quick-card oc-card oc-card-interactive partial"'); + expect(incomplete).not.toContain(">Intraday"); + expect(incomplete).not.toContain("Open reporting windows"); + const complete = home({ [period]: [closed] }); + expect(complete).not.toContain(">Incomplete"); + expect(complete).not.toContain(">Intraday"); + expect(complete).not.toContain('class="quick-card oc-card oc-card-interactive partial"'); + }); + + it("compares an open aggregate snapshot to elapsed prior days instead of the full period", () => { + const previous = entry("week", "2026-W36", 100); + const current = entry("week", "2026-W37", 15); + const html = home({ day: [entry("day", "2026-08-31", 10)], week: [current, previous] }); + expect(html).toContain("+50% vs prev week to date"); + const monthDays = Array.from({ length: 7 }, (_, index) => + entry("day", `2026-08-${String(index + 1).padStart(2, "0")}`, 1), + ); + expect( + home({ + day: monthDays, + month: [entry("month", "2026-09", 14), entry("month", "2026-08", 100)], + }), + ).toContain("+100% vs prev month to date"); + expect(home({ week: [current, previous] })).toContain("-85% vs prev week"); + expect( + home({ day: [entry("day", "2026-09-07", 20), entry("day", "2026-09-06", 10)] }), + ).toContain("+100% vs prev day"); + }); + + it.each(["day", "week", "month"])( + "offers Show all only above the visible %s history limit", + (period) => { + const count = period === "day" ? 7 : 12; + const entries = Array.from({ length: count + 1 }, (_, index) => + entry( + period, + period === "day" + ? `2026-08-${String(31 - index).padStart(2, "0")}` + : period === "week" + ? `2026-W${String(34 - index).padStart(2, "0")}` + : `${2026 - Math.floor(index / 12)}-${String(12 - (index % 12)).padStart(2, "0")}`, + ), + ); + expect(home({ [period]: entries.slice(0, count) })).not.toContain(`data-toggle="${period}"`); + const html = home({ [period]: entries }); + expect(html).toContain(`Show all ${count + 1}`); + expect(html).toContain(" data-extra hidden"); + expect(html).toContain(`href="/reports/${period}/${entries.at(-1)?.key}/"`); + }, + ); + + it("renders metric deltas only against preceding periods and labels in-progress totals", () => { + const report = document(); + const html = renderReportPage(ctx, report, null, [ + entry("day", "2026-09-08", 100), + entry("day", "2026-09-07", 10), + entry("day", "2026-09-06", 5), + ]); + expect(html).toContain("+100% vs prev day (in progress)"); + const closed = renderReportPage(ctx, document("day", "2026-09-06"), null, [ + entry("day", "2026-09-06", 10), + entry("day", "2026-09-05", 5), + ]); + expect(closed).toContain("+100% vs prev day"); + expect(closed).not.toContain("(in progress)"); + }); + + it("ranks member distribution by activity and exposes members after the first twelve", () => { + const report = document(); + const member = report.members[0]!; + report.members = Array.from({ length: 14 }, (_, index) => ({ + ...member, + login: `member-${index}`, + display: `Member ${index}`, + github: { ...githubCounts(index + 1), items: [] }, + discord: { total: 0, channels: {}, excerpts: [] }, + })); + const html = renderReportPage(ctx, report, null, []); + const distribution = html.slice( + html.indexOf("Activity by Member"), + html.indexOf("data-maintainer-filter-root"), + ); + expect(distribution.indexOf("member-13")).toBeLessThan(distribution.indexOf("member-12")); + expect(distribution).toContain("Show remaining 2"); + }); + + it("keeps every retained GitHub item accessible beyond the three-item preview", () => { + const report = document(); + const member = report.members[0]!; + member.github.items = ["First change", "Second change", "Third change", "Fourth "].map( + (title, index) => ({ + kind: "pr_opened", + repo: `example/repo-${index}`, + title, + url: `https://github.com/example/repo-${index}/pull/1`, + atMs: report.generatedAtMs, + actor: member.login, + }), + ); + member.github.items[3]!.repo = "example/"; + member.github.items[3]!.url = "javascript:alert(1)"; + const html = renderReportPage(ctx, report, null, []); + expect(html.match(/class="theme"/g)).toHaveLength(3); + const details = html.match(/
    4 GitHub items<\/summary>(.*?)<\/details>/s)?.[1]; + expect(details).toBeDefined(); + for (const title of [ + "First change", + "Second change", + "Third change", + "Fourth <change>", + ]) { + expect(details).toContain(title); + } + expect(details?.match(/PR opened/g)).toHaveLength(4); + expect(details).toContain("example/repo-0"); + expect(details).toContain("example/<hostile-repo>"); + expect(details).toContain( + 'href="https://github.com/example/repo-0/pull/1" target="_blank" rel="noopener"', + ); + expect(details).not.toContain("javascript:"); + expect(details).not.toContain(""); + expect(details).not.toContain("Fourth "); + }); + + it("keeps source warning banners bounded and escapes hostile data on every page", () => { + const hostile = 'bad">'; + const report = document(); + report.orgs = [hostile]; + report.sources.github = { ok: false, warnings: [hostile], stats: {} }; + report.sources.discord = { ok: true, stale: true, warnings: [hostile], stats: {} }; + const member = report.members[0]!; + member.login = hostile; + member.display = hostile; + member.affiliation = hostile; + member.areas = [hostile]; + member.github.repos = { [hostile]: 10 }; + member.discord.channels = { [hostile]: 10 }; + const summary = { + source: "fallback" as const, + generatedAtMs: report.generatedAtMs, + globalSummary: hostile, + highlights: [hostile], + fingerprint: "fixture", + warnings: [hostile, hostile], + }; + const person: Person = { github: [hostile], display: hostile, affiliation: hostile }; + const days = [personDay(hostile, "2026-09-07", 10), personDay(hostile, "2026-09-05", 5)]; + const overview = renderIndexPage( + ctx, + { day: [entry("day", "2026-09-07")], week: [], month: [] }, + { orgs: [hostile], latest: { report, summary }, health: { running: true, warnings: 3 } }, + ); + const reportHtml = renderReportPage(ctx, report, summary, []); + for (const html of [ + overview, + reportHtml, + renderPeoplePage(ctx, [person], days, "2026-09-07"), + renderPersonPage(ctx, person, days), + ]) { + expect(html).not.toContain(hostile); + expect(html).not.toContain(" { + const people: Person[] = [ + { github: ["quiet"] }, + { github: ["reader"], roleGroup: "readonly" }, + { github: ["archived"], status: "archived" }, + { github: ["active"] }, + ]; + const days = [ + personDay("active", "2026-09-07", 20), + personDay("quiet", "2026-09-07", 0), + personDay("reader", "2026-09-07", 3), + personDay("archived", "2026-09-07", 50), + ]; + const html = renderPeoplePage(ctx, people, days, "2026-09-07"); + const grid = html.slice(html.indexOf('class="people-grid"')); + expect(grid.indexOf("/people/active/")).toBeLessThan(grid.indexOf("/people/quiet/")); + expect(grid.indexOf("/people/quiet/")).toBeLessThan(grid.indexOf("/people/reader/")); + expect(grid.indexOf("/people/reader/")).toBeLessThan(grid.indexOf("/people/archived/")); + expect(grid).toContain("level-0"); + expect(grid).toContain("level-4"); + expect(grid).toContain("is-archived"); + expect(html).toContain("28 days"); + }); + + it("keeps closed intraday snapshots visibly incomplete", () => { + const report = document("day", "2026-09-06"); + report.status = "partial"; + report.generatedAtMs = report.period.untilMs - 3_600_000; + const html = renderReportPage(ctx, report, null, []); + expect(html).toContain("Incomplete snapshot"); + expect(html).toContain("The window has since closed, so these totals remain incomplete."); + expect(html).not.toContain("data-day-countdown data-until="); + }); + + it("shades activity at the site bucket boundaries within the ranking window", () => { + const totals = [0, 1, 4, 5, 14, 15, 39, 40]; + const levels = [0, 1, 1, 2, 2, 3, 3, 4]; + const days = totals.map((total, index) => ({ + ...personDay("alice", `2026-09-${String(index + 1).padStart(2, "0")}`, 0), + githubTotal: total, + })); + days.push({ ...personDay("alice", "2026-07-01", 1000) }); + const html = renderPeoplePage(ctx, [{ github: ["alice"] }], days, "2026-09-08"); + for (const [index, level] of levels.entries()) { + const key = `2026-09-${String(index + 1).padStart(2, "0")}`; + expect(html).toContain( + `class="day-dot level-${level}" title="${key}: ${totals[index]} events"`, + ); + } + expect(html).toContain("118 events · 118 GitHub · 0 Discord"); + expect(html).toContain("7 out of 8 days active"); + }); + + it("links retained calendar cells to daily reports and leaves missing chart days as gaps", () => { + const html = renderPersonPage(ctx, { github: ["alice"], display: "Alice" }, [ + personDay("alice", "2026-09-07", 12), + personDay("alice", "2026-09-05", 6), + ]); + expect(html).toMatch(/class="day-cell[^"\n]*"[^>]*href="\/reports\/day\/2026-09-07\//); + expect(html).not.toContain('href="/reports/day/2026-09-06/'); + expect(html).toContain("GitHub events · left axis"); + expect(html).toContain("Discord messages · right axis"); + const paths = [...html.matchAll(/class="person-activity-line[^"]*" d="([^"]*)"/g)]; + expect(paths).toHaveLength(2); + for (const path of paths) { + expect(path[1]?.match(/M/g)).toHaveLength(2); + } + expect(html).toContain("Exact daily values"); + }); +}); diff --git a/extensions/team-reports/src/render/styles.ts b/extensions/team-reports/src/render/styles.ts index 38329fd31cab..503f4bcb132f 100644 --- a/extensions/team-reports/src/render/styles.ts +++ b/extensions/team-reports/src/render/styles.ts @@ -1,22 +1,30 @@ /* - * Vendored Carapace v0.6.2 subset: styles/tokens.css, styles/themes.css, - * styles/themes/product.css, styles/typography.css, styles/components.css, - * and styles/candidate/{data,feedback,embed}.css. Theme values include the - * neutral application overrides. Use embed font stacks and the skill's square - * surface/control/inset geometry; no external CSS or fonts under the nonce CSP. + * Vendored Carapace v0.6.2 (MIT) primitives from styles/tokens.css, + * themes.css, themes/product.css, components.css, and candidate/{controls, + * feedback,data,application,embed}.css. Uses the neutral application palette, + * product radii, shadows, and motion with embed system font stacks. + * Page composition follows the maintainer report site's home/report/people + * styles, scoped here so each self-contained page works under the nonce CSP. */ const LIGHT_THEME = ` color-scheme: light; --oc-bg-page: oklch(0.985 0 0); --oc-bg-surface: oklch(0.97 0 0); --oc-bg-elevated: oklch(1 0 0); + --oc-bg-recessed: color-mix(in oklch, var(--oc-bg-page) 94%, var(--oc-text-primary)); --oc-text-primary: oklch(0.205 0 0); --oc-text-secondary: oklch(0.269 0 0); --oc-text-muted: oklch(0.555 0 0); --oc-text-link: var(--oc-accent-primary); --oc-accent-primary: color-mix(in srgb, #c24028 60%, #9c3222 40%); --oc-accent-primary-hover: color-mix(in srgb, #c24028 30%, #9c3222 70%); + --oc-accent-primary-deep: #9c3222; --oc-accent-secondary: #14806e; + --oc-accent-secondary-deep: #0f6355; + --oc-text-on-accent: oklch(1 0 0); + --oc-border-accent: rgb(216 74 49 / 0.42); + --oc-status-error-bg: rgb(239 68 68 / 0.1); + --oc-status-error-fg: #b91c1c; --oc-border-subtle: oklch(0.922 0 0); --oc-border-strong: color-mix(in oklch, var(--oc-text-primary) 28%, transparent); --oc-surface-card: oklch(1 0 0); @@ -42,13 +50,20 @@ export const REPORT_STYLES = ` --oc-bg-page: oklch(0.135 0 0); --oc-bg-surface: oklch(0.178 0 0); --oc-bg-elevated: oklch(0.205 0 0); + --oc-bg-recessed: color-mix(in oklch, var(--oc-bg-page) 86%, oklch(0 0 0)); --oc-text-primary: oklch(0.985 0 0); --oc-text-secondary: oklch(0.87 0 0); --oc-text-muted: oklch(0.716 0 0); --oc-text-link: var(--oc-accent-primary); --oc-accent-primary: #f5654a; --oc-accent-primary-hover: #e05540; + --oc-accent-primary-deep: #b23a28; --oc-accent-secondary: #4fc8ae; + --oc-accent-secondary-deep: #2fa48d; + --oc-text-on-accent: oklch(0.135 0 0); + --oc-border-accent: rgb(245 101 74 / 0.4); + --oc-status-error-bg: rgb(239 68 68 / 0.12); + --oc-status-error-fg: #f87171; --oc-border-subtle: oklch(0.269 0 0); --oc-border-strong: color-mix(in oklch, var(--oc-text-primary) 32%, transparent); --oc-surface-card: oklch(0.178 0 0 / 0.82); @@ -82,10 +97,21 @@ export const REPORT_STYLES = ` --oc-font-size-xl: 1.25rem; --oc-font-size-2xl: 1.5rem; --oc-font-size-3xl: 2rem; - --oc-radius-surface: 0; - --oc-radius-control: 0; - --oc-radius-inset: 0; + --oc-radius-surface: 0.5rem; + --oc-radius-control: 0.5rem; + --oc-radius-inset: 0.25rem; --oc-radius-round: 999px; + --oc-radius-full: 999px; + --oc-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.12); + --oc-shadow-md: 0 8px 24px -6px rgb(0 0 0 / 0.28); + --oc-shadow-lg: 0 24px 48px -12px rgb(0 0 0 / 0.42); + --oc-duration-fast: 160ms; + --oc-duration-ui: 200ms; + --oc-ease-out: cubic-bezier(0.23, 1, 0.32, 1); + --oc-control-min-height: 2.75rem; + --oc-content-max: 75rem; + --oc-input-bg: var(--oc-bg-elevated); + --oc-input-border: var(--oc-border-subtle); --oc-font-embed-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; --oc-font-embed-mono: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --oc-font-body: var(--oc-font-embed-sans); @@ -97,113 +123,483 @@ export const REPORT_STYLES = ` } html[data-theme="light"] {${LIGHT_THEME}} -* { box-sizing: border-box; } -body { margin: 0; font: var(--oc-font-size-base)/1.6 var(--oc-font-body); } -::selection { background: var(--oc-selection-bg); } -a { color: var(--oc-text-link); overflow-wrap: anywhere; } -a:hover { color: var(--oc-accent-primary-hover); } -:where(a, summary, [tabindex]):focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 3px; } -h1, h2, h3, p { margin: 0; } -h3 { font-size: var(--oc-font-size-md); line-height: 1.4; } -p + p { margin-top: var(--oc-space-2); } -ul { padding-left: var(--oc-space-5); } -li { overflow-wrap: anywhere; } -small, .muted { color: var(--oc-text-muted); } -.details { color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); } -.oc-app-surface { min-width: 0; min-height: 100%; background: var(--oc-bg-page); color: var(--oc-text-primary); font-family: var(--oc-font-body); } -.report-toolbar { border-bottom: 1px solid var(--oc-border-subtle); background: var(--oc-bg-surface); } -.report-toolbar-inner, main, footer { max-width: 75rem; margin: auto; padding: var(--oc-space-5) var(--oc-space-6); } -.report-toolbar-inner { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--oc-space-2); padding-block: var(--oc-space-2); } -nav, .actions, .identity-line, .pills { display: flex; flex-wrap: wrap; align-items: center; gap: var(--oc-space-2); } -.brand { margin-right: var(--oc-space-4); color: var(--oc-text-primary); font-weight: 750; text-decoration: none; } -main { display: grid; gap: var(--oc-space-6); overflow-wrap: anywhere; } -footer { color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); border-top: 1px solid var(--oc-border-subtle); } -.oc-section { width: 100%; min-width: 0; color: var(--oc-text-primary); } -.oc-section-header { display: flex; align-items: end; justify-content: space-between; gap: var(--oc-space-5); margin-bottom: var(--oc-space-4); } + + +.oc-app-surface { --oc-component-surface: var(--oc-surface-card); --oc-component-surface-strong: var(--oc-surface-card-strong); --oc-component-surface-hover: var(--oc-surface-interactive); --oc-component-border: var(--oc-border-subtle); --oc-component-border-hover: color-mix( in srgb, var(--oc-text-primary) 28%, var(--oc-border-subtle) ); --oc-component-shadow: var(--oc-shadow-sm); --oc-component-shadow-hover: var(--oc-shadow-md); min-width: 0; min-height: 100%; background: var(--oc-bg-page); color: var(--oc-text-primary); font-family: var(--oc-font-body); } +.oc-section { width: 100%; color: var(--oc-text-primary); } +.oc-section-header { display: flex; align-items: end; justify-content: space-between; gap: var(--oc-space-5); } .oc-section-header > * { min-width: 0; } -.oc-section-heading { display: grid; gap: var(--oc-space-2); } -.oc-eyebrow { color: var(--oc-accent-primary); font: 700 var(--oc-font-size-xs)/1.4 var(--oc-font-mono); text-transform: uppercase; } -.oc-section-title { color: var(--oc-text-primary); font-family: var(--oc-font-display); font-size: var(--oc-font-size-2xl); font-weight: 750; line-height: 1.2; overflow-wrap: anywhere; } -h2.oc-section-title { font-size: var(--oc-font-size-lg); } -.oc-section-copy { max-width: 60ch; color: var(--oc-text-secondary); overflow-wrap: anywhere; } -.oc-card { padding: var(--oc-space-4); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-card); color: var(--oc-text-primary); } -.stats, .history-columns { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--oc-space-3); } -.stat-heading { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--oc-space-2); margin-bottom: var(--oc-space-2); } -.stat-value { display: block; font-size: var(--oc-font-size-2xl); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.4; } -.stat-date { font: 650 var(--oc-font-size-xl)/1.5 var(--oc-font-mono); } -.oc-action { display: inline-flex; min-height: 2.5rem; align-items: center; justify-content: center; gap: var(--oc-space-2); padding: var(--oc-space-2) var(--oc-space-3); border: 1px solid transparent; border-radius: var(--oc-radius-control); font-size: var(--oc-font-size-base); font-weight: 650; line-height: 1.2; text-decoration: none; touch-action: manipulation; } -.oc-action-ghost { background: transparent; color: var(--oc-text-secondary); } -.oc-action-ghost:hover { background: var(--oc-surface-interactive-hover); color: var(--oc-text-primary); } -.oc-pill { display: inline-flex; max-width: 100%; min-width: 0; min-height: 1.75rem; align-items: center; padding: var(--oc-space-1) var(--oc-space-3); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-control); background: var(--oc-surface-card); color: var(--oc-text-secondary); font-size: var(--oc-font-size-xs); font-weight: 650; line-height: 1.2; overflow-wrap: anywhere; } -.oc-badge { display: inline-flex; max-width: 100%; min-width: 0; min-height: 1.5rem; align-items: center; gap: var(--oc-space-2); padding: var(--oc-space-1) var(--oc-space-2); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-control); color: var(--oc-text-secondary); background: var(--oc-bg-elevated); font-size: var(--oc-font-size-xs); font-weight: 650; line-height: 1; white-space: nowrap; vertical-align: middle; } +.oc-eyebrow { margin: 0; color: var(--oc-accent-primary); font-family: var(--oc-font-mono); font-size: var(--oc-font-size-xs); font-weight: 700; line-height: 1.4; letter-spacing: 0; text-transform: uppercase; } +.oc-card { border: 1px solid var(--oc-component-border); border-radius: var(--oc-radius-surface); background: var(--oc-component-surface); color: var(--oc-text-primary); box-shadow: var(--oc-component-shadow); } +.oc-card-interactive { transition: background var(--oc-duration-ui) var(--oc-ease-out), border-color var(--oc-duration-ui) var(--oc-ease-out), box-shadow var(--oc-duration-ui) var(--oc-ease-out), transform var(--oc-duration-ui) var(--oc-ease-out); } +.oc-card-interactive:hover, .oc-card-interactive:focus-visible { border-color: var(--oc-component-border-hover); background: var(--oc-component-surface-hover); box-shadow: var(--oc-component-shadow-hover); transform: translateY(-1px); } +.oc-card-interactive:focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 3px; } +.oc-card-interactive:active { transform: translateY(0) scale(0.995); } +.oc-action { display: inline-flex; min-height: 2.5rem; align-items: center; justify-content: center; gap: var(--oc-space-2); padding: var(--oc-space-2) var(--oc-space-4); border: 1px solid transparent; border-radius: var(--oc-radius-control); font: inherit; font-size: var(--oc-font-size-base); font-weight: 700; line-height: 1.2; text-decoration: none; touch-action: manipulation; cursor: pointer; transition: background var(--oc-duration-fast) var(--oc-ease-out), border-color var(--oc-duration-fast) var(--oc-ease-out), color var(--oc-duration-fast) var(--oc-ease-out), transform var(--oc-duration-fast) var(--oc-ease-out); } +.oc-action:hover { text-decoration: none; } +.oc-action:focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 3px; } +.oc-action:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(0.98); } +.oc-action:disabled, .oc-action[aria-disabled="true"] { cursor: not-allowed; opacity: 0.5; } +.oc-action[aria-disabled="true"] { pointer-events: none; } +.oc-action-ghost { border-color: transparent; background: transparent; color: var(--oc-text-secondary); } +.oc-action-ghost:hover { background: var(--oc-surface-interactive); color: var(--oc-text-primary); } +.oc-action-icon { width: 2.5rem; padding: 0; } +.oc-segmented { display: inline-flex; max-width: 100%; align-items: center; gap: var(--oc-space-1); overflow-x: auto; padding: var(--oc-space-1); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-control); background: var(--oc-surface-card); } +.oc-segmented-item { display: inline-flex; min-height: 2rem; align-items: center; justify-content: center; gap: var(--oc-space-2); padding: var(--oc-space-1) var(--oc-space-3); border: 0; border-radius: var(--oc-radius-inset); background: transparent; color: var(--oc-text-secondary); font: inherit; font-size: var(--oc-font-size-base); font-weight: 650; line-height: 1; white-space: nowrap; touch-action: manipulation; cursor: pointer; transition: background var(--oc-duration-fast) var(--oc-ease-out), color var(--oc-duration-fast) var(--oc-ease-out), transform var(--oc-duration-fast) var(--oc-ease-out); } +.oc-segmented-item:active:not(:disabled) { transform: scale(0.98); } +.oc-segmented-item:disabled { cursor: not-allowed; opacity: 0.5; } +.oc-segmented-item:hover { color: var(--oc-text-primary); } +.oc-segmented-item[aria-selected="true"], .oc-segmented-item[aria-pressed="true"], .oc-segmented-item.is-active { background: var(--oc-surface-interactive-hover); color: var(--oc-text-primary); } +.oc-segmented-item:focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 2px; } +@media (prefers-reduced-motion: reduce) { +.oc-card-interactive { transition: none; } +.oc-card-interactive:hover, .oc-card-interactive:focus-visible, .oc-card-interactive:active { transform: none; } +} +@media (max-width: 42rem) { +.oc-section-header { align-items: start; flex-direction: column; } +} +.oc-badge { display: inline-flex; box-sizing: border-box; max-width: 100%; min-width: 0; min-height: 1.5rem; align-items: center; gap: var(--oc-space-2); padding: var(--oc-space-1) var(--oc-space-2); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-round); background: var(--oc-surface-secondary-soft); color: var(--oc-text-secondary); font-size: var(--oc-font-size-xs); font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .oc-badge::before { width: 0.375rem; height: 0.375rem; flex: 0 0 auto; border-radius: var(--oc-radius-round); background: currentColor; content: ""; } .oc-badge-neutral::before { display: none; } .oc-badge-success { border-color: var(--oc-status-success-fg); background: var(--oc-status-success-bg); color: var(--oc-status-success-fg); } .oc-badge-warning { border-color: var(--oc-status-warning-fg); background: var(--oc-status-warning-bg); color: var(--oc-status-warning-fg); } -.notices { display: grid; gap: var(--oc-space-3); } -.oc-banner { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--oc-space-3); padding: var(--oc-space-4); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-card-strong); color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); line-height: 1.45; } +.oc-badge-info { border-color: var(--oc-status-info-fg); background: var(--oc-status-info-bg); color: var(--oc-status-info-fg); } +.oc-banner { display: grid; box-sizing: border-box; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: var(--oc-space-3); padding: var(--oc-space-4); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-card-strong); color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); line-height: 1.45; } .oc-banner-indicator { width: 0.375rem; height: 0.375rem; margin-top: 0.45em; border-radius: var(--oc-radius-round); background: var(--oc-text-muted); } +.oc-banner-content { display: grid; min-width: 0; gap: var(--oc-space-1); } +.oc-banner-title { color: var(--oc-text-primary); font-weight: 650; } +.oc-banner p { margin: 0; overflow-wrap: anywhere; } .oc-banner-warning .oc-banner-indicator { background: var(--oc-status-warning-fg); } .oc-banner-info .oc-banner-indicator { background: var(--oc-status-info-fg); } -.oc-banner-content { display: grid; min-width: 0; gap: var(--oc-space-1); overflow-wrap: anywhere; } -.oc-banner-title { color: var(--oc-text-primary); font-size: inherit; font-weight: 650; } -.oc-banner ul { margin: 0; } -.oc-table-wrap { width: 100%; overflow-x: auto; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); overscroll-behavior-inline: contain; scrollbar-gutter: stable; } -.oc-table { width: 100%; min-width: 36rem; border-collapse: collapse; background: var(--oc-surface-card); color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); } -.oc-table :is(th, td) { padding: var(--oc-space-3) var(--oc-space-4); border-bottom: 1px solid var(--oc-border-subtle); text-align: left; } -.oc-table th { color: var(--oc-text-muted); font-family: var(--oc-font-mono); font-size: var(--oc-font-size-xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; } -.oc-table tbody tr:last-child td { border-bottom: 0; } -.oc-table tbody tr:focus-within, .oc-table tbody tr:hover { background: var(--oc-surface-interactive); } -.oc-table td:first-child { color: var(--oc-text-primary); font-weight: 650; } -.oc-table .number { text-align: right; font-variant-numeric: tabular-nums; } -.oc-resource-list { width: 100%; margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-card); list-style: none; } -.oc-resource-list-item { margin: 0; } -.oc-resource-list-item + .oc-resource-list-item { border-top: 1px solid var(--oc-border-subtle); } -.oc-resource-list-link, .resource-row { display: flex; align-items: center; justify-content: space-between; gap: var(--oc-space-3); padding: var(--oc-space-2) var(--oc-space-3); } -.oc-resource-list-link { color: inherit; text-decoration: none; } -.oc-resource-list-link:hover { background: var(--oc-surface-interactive); color: var(--oc-text-primary); } -.oc-resource-list-link:focus-visible { outline-offset: -2px; } -.oc-resource-list-title { color: var(--oc-text-primary); font-size: var(--oc-font-size-sm); overflow-wrap: anywhere; } -.oc-resource-list-meta { color: var(--oc-text-muted); font-size: var(--oc-font-size-sm); } -.history-columns h3 { margin-bottom: var(--oc-space-3); } -.member-list { margin: 0; padding: 0; list-style: none; } -.member { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--oc-space-3); padding: var(--oc-space-4) 0; border-top: 1px solid var(--oc-border-subtle); } -.member-content { display: grid; gap: var(--oc-space-2); min-width: 0; overflow-wrap: anywhere; } -.member-content p { margin: 0; } -.member-items .resource-row { display: block; } +.oc-empty { display: grid; box-sizing: border-box; min-height: 12rem; place-items: center; padding: var(--oc-space-5); text-align: center; } +.oc-empty-description { max-width: 42ch; margin: 0; color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); line-height: 1.5; overflow-wrap: anywhere; text-wrap: pretty; } +@media (max-width: 42rem) { +.oc-banner, .oc-banner:has(.oc-banner-action):has(.oc-banner-dismiss) { grid-template-columns: auto minmax(0, 1fr) auto; } +.oc-banner > :is(button, a):not(.oc-banner-dismiss) { grid-column: 2 / -1; grid-row: 2; justify-self: start; margin-left: 0; } +} +.oc-sparkline { display: block; width: 100%; max-width: 8.5rem; height: 1.5rem; } +.oc-sparkline-line { fill: none; stroke: var(--oc-text-muted); stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter; vector-effect: non-scaling-stroke; } +.oc-sparkline[data-tone="accent"] .oc-sparkline-line { stroke: var(--oc-accent-primary); } +.oc-sparkline-endpoint { fill: var(--oc-accent-primary); stroke: none; } +.oc-delta { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); font-variant-numeric: tabular-nums; white-space: nowrap; } +.oc-delta-arrow { font-size: 0.625rem; line-height: 1; } +.oc-delta[data-tone="positive"] { color: var(--oc-status-success-fg); } +.oc-delta[data-tone="negative"] { color: var(--oc-status-error-fg); } +.oc-delta:not([data-tone])[data-direction="up"] .oc-delta-arrow { color: var(--oc-status-success-fg); } +.oc-delta:not([data-tone])[data-direction="down"] .oc-delta-arrow { color: var(--oc-status-error-fg); } +.oc-sparkline[data-size="lg"] { max-width: none; height: 3rem; } +.oc-split { display: block; overflow: hidden; width: 100%; height: 0.5rem; border-radius: 2px; } +.oc-split-segment { fill: var(--oc-chart-color, var(--oc-accent-primary)); } +.oc-split-secondary { --oc-chart-color: var(--oc-accent-secondary); } +.oc-split-error { --oc-chart-color: var(--oc-status-error-fg); } +.oc-split-muted { --oc-chart-color: var(--oc-border-strong); } +.oc-split-legend { display: flex; flex-wrap: wrap; gap: var(--oc-space-1) var(--oc-space-3); margin: 0; padding: 0; color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); list-style: none; } +.oc-split-legend li { display: inline-flex; align-items: center; gap: var(--oc-space-1); } +.oc-split-key { width: 0.5rem; height: 0.5rem; border-radius: 2px; background: var(--oc-chart-color, var(--oc-accent-primary)); } +.oc-switch { position: relative; box-sizing: border-box; width: 2.25rem; height: 1.25rem; flex: 0 0 auto; appearance: none; border: 1px solid var(--oc-input-border); border-radius: var(--oc-radius-round); margin: 0; background: var(--oc-input-bg); cursor: inherit; touch-action: manipulation; transition: background var(--oc-duration-fast) var(--oc-ease-out), border-color var(--oc-duration-fast) var(--oc-ease-out); } +.oc-switch::before { position: absolute; top: 0.1875rem; left: 0.1875rem; width: 0.75rem; height: 0.75rem; border-radius: var(--oc-radius-round); background: var(--oc-text-muted); content: ""; transition: background var(--oc-duration-fast) var(--oc-ease-out), transform var(--oc-duration-fast) var(--oc-ease-out); } +.oc-switch:hover:not(:disabled) { border-color: var(--oc-border-strong); } +.oc-switch:checked { border-color: var(--oc-accent-primary); background: var(--oc-accent-primary); } +.oc-switch:checked::before { background: var(--oc-text-on-accent); transform: translateX(1rem); } +.oc-switch:focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 2px; } +@media (forced-colors: active) { +.oc-switch { appearance: auto; forced-color-adjust: auto; } +.oc-switch::before { display: none; } +} +.oc-summary-strip { display: grid; gap: 1px; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-border-subtle); grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); overflow: hidden; } +.oc-summary-metric { display: flex; align-items: center; gap: var(--oc-space-2); padding: var(--oc-space-2) var(--oc-space-3); background: var(--oc-bg-surface); } +.oc-summary-metric-copy { display: grid; min-width: 0; line-height: 1.3; } +.oc-summary-metric-copy strong { font-size: var(--oc-font-size-md); font-variant-numeric: tabular-nums; } +.oc-summary-metric-copy small { overflow: hidden; color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); text-overflow: ellipsis; white-space: nowrap; } +.oc-brand-banner { position: relative; display: grid; min-height: 16rem; align-content: end; overflow: hidden; padding: var(--oc-space-6); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-bg-surface); } +.oc-brand-banner-art { position: absolute; z-index: 0; inset: 0; overflow: hidden; pointer-events: none; } +.oc-brand-banner-art img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; opacity: 0.82; } +.oc-brand-banner[data-anchor="top"] .oc-brand-banner-art img { object-position: 50% 0%; } +.oc-brand-banner[data-effect="fade"][data-anchor="top"] .oc-brand-banner-art img { -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 36%, transparent 78%); mask-image: linear-gradient(to bottom, #000 0%, #000 36%, transparent 78%); } +.oc-brand-banner-content { position: relative; z-index: 1; display: grid; max-width: 36rem; gap: var(--oc-space-2); } +.oc-brand-banner-content h3 { margin: 0; font-size: var(--oc-font-size-2xl); } +.oc-brand-banner-content p { margin: 0; color: var(--oc-text-secondary); } + +* { box-sizing: border-box; } +body { margin: 0; color: var(--oc-text-secondary); background: var(--oc-bg-page); -webkit-font-smoothing: antialiased; } +main { width: min(var(--oc-content-max), calc(100vw - 36px)); margin: 0 auto; padding: var(--oc-space-6) 0 var(--oc-space-8); } +a { color: inherit; text-decoration: none; } +a:hover { color: var(--oc-text-primary); text-decoration: underline; text-underline-offset: 3px; } +@media (max-width: 760px) { +main { width: min(100vw - 24px, var(--oc-content-max)); padding-top: var(--oc-space-5); } +} + +:root { --activity-0-bg: var(--oc-bg-elevated); --activity-0-border: var(--oc-border-subtle); --activity-1-bg: color-mix(in srgb, var(--oc-accent-primary) 16%, var(--oc-bg-elevated)); --activity-1-border: color-mix(in srgb, var(--oc-accent-primary) 30%, var(--oc-border-subtle)); --activity-2-bg: color-mix(in srgb, var(--oc-accent-primary) 34%, var(--oc-bg-elevated)); --activity-2-border: color-mix(in srgb, var(--oc-accent-primary) 50%, var(--oc-border-subtle)); --activity-3-bg: color-mix(in srgb, var(--oc-accent-primary) 68%, var(--oc-bg-elevated)); --activity-3-border: var(--oc-accent-primary-hover); --activity-4-bg: var(--oc-accent-primary); --activity-4-border: var(--oc-accent-primary-deep); --activity-3-text: var(--oc-text-primary); --activity-4-text: var(--oc-text-on-accent); font-family: var(--oc-font-body); } +.open-period-status { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; color: var(--oc-text-muted); font-family: var(--oc-font-mono); font-size: 0.75rem; line-height: 1.4; } +.open-period-status time { color: inherit; } +.open-period-status [data-day-countdown] { color: var(--oc-text-secondary); } +.partial-report-badge { min-height: 1.25rem; padding: 0.2rem 0.4rem; font-family: var(--oc-font-body); font-size: 0.6875rem; } + +.site-nav { position: sticky; top: 0; z-index: 20; border-bottom: 1px solid var(--oc-border-subtle); background: var(--oc-bg-page); } +.site-nav[data-scrolled="true"] { box-shadow: var(--oc-shadow-md, 0 6px 16px rgb(0 0 0 / 0.28)); } +.site-nav-inner { width: min(var(--oc-content-max), calc(100vw - 36px)); min-height: 58px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: var(--oc-space-5); } +.site-brand { display: inline-flex; align-items: center; gap: var(--oc-space-3); color: var(--oc-text-primary); font: 750 15px/1 var(--oc-font-display); } +.site-brand:hover { text-decoration: none; color: var(--oc-text-primary); } +.brand-mark { display: grid; place-items: center; width: 26px; height: 26px; flex: 0 0 26px; } +.brand-mark img { display: block; width: 100%; height: 100%; object-fit: contain; } +.site-links { display: flex; align-items: center; justify-content: flex-end; gap: var(--oc-space-1); overflow-x: auto; white-space: nowrap; } +.site-links a { min-height: 32px; padding: var(--oc-space-2) var(--oc-space-3); color: var(--oc-text-muted); font: 650 13px/1 var(--oc-font-body); } +.site-links a:hover { color: var(--oc-text-primary); text-decoration: none; } +.site-links a.is-active { color: var(--oc-text-primary); background: var(--oc-surface-interactive-hover); } +.theme-toggle { flex: 0 0 auto; width: 34px; min-height: 34px; height: 34px; padding: 0; color: var(--oc-text-primary); cursor: pointer; } +.theme-toggle svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; display: block; } +@media (max-width: 760px) { +.site-nav-inner { width: min(100vw - 24px, var(--oc-content-max)); height: auto; min-height: 58px; padding: var(--oc-space-3) 0; align-items: flex-start; flex-direction: column; } +.site-links { width: 100%; justify-content: flex-start; padding-bottom: 2px; } +} + + +body { font: var(--oc-font-size-base)/1.5 var(--oc-font-body); } +::selection { background: var(--oc-selection-bg); } +:where(a, button, input, summary, [tabindex]):focus-visible { outline: 2px solid var(--oc-focus-ring); outline-offset: 3px; } +[hidden] { display: none !important; } +:root:not([data-js]) .js-only, :root:not([data-js]) [data-toggle], :root:not([data-js]) [data-theme-toggle] { display: none !important; } +:root:not([data-js]) [data-extra][hidden] { display: grid !important; } +:root[data-people-hide-inactive="true"] [data-inactive="true"] { display: none !important; } +.theme-toggle .theme-moon { display: none; } +:root[data-theme="light"] .theme-toggle .theme-sun { display: none; } +:root[data-theme="light"] .theme-toggle .theme-moon { display: block; } +h1, h2, h3, p { margin: 0; } +h3 { color: var(--oc-text-primary); font-size: var(--oc-font-size-lg); line-height: 1.4; } +a, li, p { overflow-wrap: anywhere; } +small, .muted { color: var(--oc-text-muted); } +.details { color: var(--oc-text-secondary); font-size: var(--oc-font-size-sm); } +.actions, .identity-line, .pills { display: flex; flex-wrap: wrap; align-items: center; gap: var(--oc-space-2); } +.person-identity { display: flex; align-items: center; gap: var(--oc-space-3); min-width: 0; } +.oc-banner-content { overflow-wrap: anywhere; } +.oc-banner-content > .oc-badge { justify-self: start; } +.oc-banner ul { margin: 0; padding-left: var(--oc-space-5); } +.oc-section { min-width: 0; } +.oc-section-header { margin-bottom: var(--oc-space-4); } +main > .oc-section { margin-block: var(--oc-space-7); } +main > .oc-section:first-child { margin-top: 0; } +footer { width: min(var(--oc-content-max), calc(100vw - 36px)); margin: 28px auto 0; padding: 14px 0 var(--oc-space-5); color: var(--oc-text-muted); font-size: 12px; line-height: 1.5; border-top: 1px solid var(--oc-border-strong); } +.oc-action-icon svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } summary { width: fit-content; max-width: 100%; color: var(--oc-text-secondary); cursor: pointer; font-size: var(--oc-font-size-sm); } details[open] > summary { margin-bottom: var(--oc-space-2); } blockquote { border-left: 2px solid var(--oc-border-strong); padding: var(--oc-space-2) var(--oc-space-4); margin: var(--oc-space-2) 0; overflow-wrap: anywhere; } -.person-identity { display: flex; align-items: center; gap: var(--oc-space-3); min-width: 0; } -.person-heading { display: grid; gap: var(--oc-space-2); min-width: 0; } -.oc-avatar { position: relative; display: inline-grid; flex: 0 0 auto; place-items: center; overflow: hidden; border-radius: var(--oc-radius-round); background: var(--oc-surface-secondary-soft); color: var(--oc-accent-secondary); font-weight: 650; line-height: 1; } +.oc-table :is(th, td) { padding: var(--oc-space-3) var(--oc-space-4); border-bottom: 1px solid var(--oc-border-subtle); text-align: left; } +.oc-resource-list { width: 100%; margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-card); list-style: none; } +.oc-resource-list-item + .oc-resource-list-item { border-top: 1px solid var(--oc-border-subtle); } +.oc-resource-list-link, .resource-row { display: flex; align-items: center; justify-content: space-between; gap: var(--oc-space-3); padding: var(--oc-space-2) var(--oc-space-3); } +.oc-avatar { position: relative; display: inline-grid; flex: 0 0 auto; place-items: center; overflow: hidden; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-surface-secondary-soft); color: var(--oc-accent-secondary); font-weight: 650; line-height: 1; } .oc-avatar::before { content: attr(data-initials); } /* Transparent failed images leave the CSS initials beneath them visible. */ .oc-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; color: transparent; font-size: 0; } .oc-avatar-xs { width: 20px; height: 20px; font-size: var(--oc-font-size-xs); } .oc-avatar-md { width: 40px; height: 40px; font-size: var(--oc-font-size-sm); } +.oc-avatar-sm { width: 36px; height: 36px; font-size: var(--oc-font-size-sm); } .oc-avatar-xl { width: 72px; height: 72px; font-size: var(--oc-font-size-2xl); } -.chart { padding-block: var(--oc-space-3); border-block: 1px solid var(--oc-border-subtle); } -.chart .oc-sparkline { display: block; width: 100%; height: auto; } -.oc-sparkline-line { fill: none; stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter; vector-effect: non-scaling-stroke; } -.github-line { stroke: var(--oc-accent-primary); } -.discord-line { stroke: var(--oc-accent-secondary); } -.chart-axis { stroke: var(--oc-chart-line); stroke-width: 1; } -.chart-label { fill: var(--oc-text-muted); font: var(--oc-font-size-xs) var(--oc-font-mono); } -.legend { display: flex; flex-wrap: wrap; gap: var(--oc-space-4); font-size: var(--oc-font-size-xs); } -.github-key { color: var(--oc-accent-primary); background: var(--oc-surface-accent-soft); } -.discord-key { color: var(--oc-accent-secondary); background: var(--oc-surface-secondary-soft); } -.legend span { padding-inline: var(--oc-space-2); border-radius: var(--oc-radius-inset); } -.prose { overflow-wrap: anywhere; } -.prose h3 { margin-top: var(--oc-space-4); } -.prose .notices { margin-bottom: var(--oc-space-3); } -@media (max-width: 42rem) { - .report-toolbar-inner, main, footer { padding-inline: var(--oc-space-4); } - .report-toolbar-inner, .oc-section-header { align-items: start; flex-direction: column; } - .stats, .history-columns { grid-template-columns: 1fr; } - .oc-section-header { gap: var(--oc-space-3); } - .brand { width: 100%; } - .report-toolbar nav { gap: var(--oc-space-1); } - .report-toolbar .oc-action { padding-inline: var(--oc-space-2); } +@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; } } +@media (max-width: 760px) { footer { width: calc(100vw - 24px); } } + + +body[data-report-page="home"] main { width:min(var(--oc-content-max),calc(100vw - 36px)); margin:0 auto; padding:var(--oc-space-6) 0 var(--oc-space-8); } +body[data-report-page="home"] header { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--oc-space-6); align-items:end; border-bottom:1px solid var(--oc-border-subtle); padding-bottom:var(--oc-space-5); margin-bottom:var(--oc-space-4); } +body[data-report-page="home"] h1 { margin:0; color:var(--oc-text-primary); font:740 34px/1.05 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; letter-spacing:0; } +body[data-report-page="home"] h2 { margin:4px 0 16px; color:var(--oc-text-primary); font:740 22px/1.2 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; letter-spacing:0; } +body[data-report-page="home"] .subtitle, body[data-report-page="home"] .meta { color:var(--oc-text-muted); line-height:1.45; } +body[data-report-page="home"] .grid { display:grid; gap:var(--oc-space-7); } +body[data-report-page="home"] .quick-card { display:grid; align-content:start; gap:var(--oc-space-1); min-height:104px; padding:var(--oc-space-4); } +body[data-report-page="home"] .quick-card.partial { border-color:var(--oc-border-accent); } +body[data-report-page="home"] .quick-card:hover { text-decoration:none; border-color:var(--oc-component-border-hover); background:var(--oc-surface-interactive); } +body[data-report-page="home"] .quick-title { display:block; margin-top:4px; font-size:20px; font-weight:800; line-height:1.15; } +body[data-report-page="home"] .quick-meta { display:block; margin-top:2px; text-wrap:balance; color:var(--oc-text-muted); font-size:13px; line-height:1.35; } +body[data-report-page="home"] .panel { padding:0; } +body[data-report-page="home"] .toggle { appearance:none; border-radius:var(--oc-radius-control); font-family:var(--oc-font-mono); cursor:pointer; } +body[data-report-page="home"] .toggle:hover { background:var(--oc-surface-accent-soft); } +body[data-report-page="home"] .row { display:grid; grid-template-columns:minmax(0,1fr) auto 15.5rem; gap:16px; align-items:center; padding:12px 0; border-top:1px solid var(--oc-border-subtle); } +body[data-report-page="home"] .row-trend { display:block; } +body[data-report-page="home"] .row-trend .oc-sparkline { width:6.5rem; } +body[data-report-page="home"] .row:first-child { border-top:0; } +body[data-report-page="home"] .row[hidden] { display:none; } +body[data-report-page="home"] .title { color:var(--oc-text-primary); font-size:17px; font-weight:800; } +body[data-report-page="home"] .date { color:var(--oc-text-muted); font-size:14px; line-height:1.35; } +body[data-report-page="home"] .row-title-line { display:inline-flex; flex-wrap:wrap; align-items:center; gap:var(--oc-space-2); } +body[data-report-page="home"] .stats { color:var(--oc-text-muted); font-size:13px; text-align:right; } +body[data-report-page="home"] .stats strong { color:var(--oc-text-primary); } +body[data-report-page="home"] .home-banner { margin: 0; } +body[data-report-page="home"] .home-banner .oc-brand-banner-content h1 { margin: 0; color: var(--oc-text-primary); font: 740 34px/1.05 var(--oc-font-display); } +body[data-report-page="home"] .home-banner .oc-brand-banner-content p:last-child { color: var(--oc-text-secondary); } +body[data-report-page="home"] .home-banner-stamp { position: absolute; top: var(--oc-space-4); right: var(--oc-space-4); z-index: 1; padding: var(--oc-space-1) var(--oc-space-3); border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-full, 999px); background: color-mix(in srgb, var(--oc-bg-page) 72%, transparent); backdrop-filter: blur(6px); color: var(--oc-text-muted); font-family: var(--oc-font-mono); font-size: 11px; line-height: 1.6; text-transform: lowercase; letter-spacing: 0.02em; } +body[data-report-page="home"] .home-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 1px; margin-bottom: var(--oc-space-7); overflow: hidden; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-border-subtle); } +body[data-report-page="home"] .home-grid > * { border: 0; border-radius: 0; background: var(--oc-bg-surface); } +body[data-report-page="home"] .home-grid > .home-banner { grid-column: 1 / -1; } +body[data-report-page="home"] .home-grid > .oc-banner { grid-column: 1 / -1; } +body[data-report-page="home"] .home-grid > .quick-card { grid-column: span 2; min-height: 0; } +body[data-report-page="home"] .home-grid > .home-card { grid-column: span 3; } +body[data-report-page="home"] .home-grid .oc-summary-strip { background: transparent; } +body[data-report-page="home"] .home-grid .oc-summary-strip { grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr)); } +body[data-report-page="home"] .home-grid .oc-summary-strip { border: 0; border-radius: 0; margin-top: auto; } +body[data-report-page="home"] .home-grid .oc-summary-metric { padding-inline: 0; } +body[data-report-page="home"] .home-grid .oc-summary-metric-copy small:last-child { overflow: visible; white-space: normal; } +body[data-report-page="home"] .home-grid > .home-card { display: flex; flex-direction: column; gap: var(--oc-space-3); padding: var(--oc-space-4); } +body[data-report-page="home"] .panel-link { min-height: 2rem; padding: var(--oc-space-1) var(--oc-space-3); border-color: var(--oc-border-subtle); color: var(--oc-text-secondary); font-size: var(--oc-font-size-xs); font-weight: 600; } +body[data-report-page="home"] .panel-link:hover { border-color: var(--oc-border-strong); background: var(--oc-surface-interactive-hover); color: var(--oc-text-primary); text-decoration: none; } +body[data-report-page="home"] .panel-link span { transition: transform var(--oc-duration-fast, 140ms) var(--oc-ease-out, ease); } +body[data-report-page="home"] .panel-link:hover span { transform: translateX(2px); } +body[data-report-page="home"] .home-dateline { display: grid; grid-column: 1 / -1; gap: var(--oc-space-2); padding: var(--oc-space-4); } +body[data-report-page="home"] .home-dateline-scale { display: flex; justify-content: space-between; color: var(--oc-text-muted); font-family: var(--oc-font-mono); font-size: 11px; } +body[data-report-page="home"] .quick-trend { display: grid; gap: var(--oc-space-1); margin-top: var(--oc-space-2); } +body[data-report-page="home"] .quick-trend .oc-sparkline { max-width: none; } +body[data-report-page="home"] .home-card-top { display:flex; align-items:flex-start; justify-content:space-between; gap:14px; } +body[data-report-page="home"] .home-card-top h2 { margin:4px 0 0; font-size:18px; } +body[data-report-page="home"] .home-card-top p { margin:4px 0 0; color:var(--oc-text-muted); font-size:13px; line-height:1.45; } +body[data-report-page="home"] .home-actions-row { flex:0 0 auto; display:flex; justify-content:flex-end; } +@media (max-width: 860px) { +body[data-report-page="home"] .home-grid { grid-template-columns: minmax(0, 1fr); } +body[data-report-page="home"] .home-grid > .quick-card, body[data-report-page="home"] .home-grid > .home-card { grid-column: 1 / -1; } } +@media (max-width: 760px) { +body[data-report-page="home"] main { width:min(100vw - 24px,1120px); padding-top:24px; } +body[data-report-page="home"] h1 { font-size:30px; } +body[data-report-page="home"] header { grid-template-columns:1fr; } +body[data-report-page="home"] .quick { grid-template-columns:1fr; } +body[data-report-page="home"] .home-banner-stamp { position: static; margin-bottom: var(--oc-space-3); width: fit-content; } +body[data-report-page="home"] .home-banner .oc-brand-banner-content h1 { font-size: 28px; } +body[data-report-page="home"] .home-card-top { flex-direction:column; } +body[data-report-page="home"] .home-actions-row { justify-content:flex-start; } +body[data-report-page="home"] .row { grid-template-columns:1fr; gap:6px; } +body[data-report-page="home"] .row-trend { display:none; } +body[data-report-page="home"] .stats { text-align:left; } +} + +body[data-report-page="report"] .oc-summary-strip .oc-summary-metric { align-items: flex-start; } +body[data-report-page="report"] .oc-summary-strip .oc-summary-metric-copy small { overflow: visible; white-space: normal; } +body[data-report-page="report"] .mix-split { display: grid; gap: var(--oc-space-2); margin-top: var(--oc-space-3); } +body[data-report-page="report"] .maintainer-distribution { display:grid; gap:var(--oc-space-3); margin-top:var(--oc-space-5); padding-top:var(--oc-space-5); border-top:1px solid var(--oc-border-subtle); } +body[data-report-page="report"] .distribution-heading { display:flex; align-items:end; justify-content:space-between; gap:var(--oc-space-4); } +body[data-report-page="report"] .distribution-heading h3 { margin:var(--oc-space-1) 0 0; color:var(--oc-text-primary); font:740 18px/1.2 var(--oc-font-display); } +body[data-report-page="report"] .ranked-distribution-list { display:grid; gap:var(--oc-space-1); margin:0; padding:0; list-style:none; counter-reset:distribution-rank; } +body[data-report-page="report"] .distribution-more .ranked-distribution-list { margin-top:var(--oc-space-2); } +body[data-report-page="report"] .ranked-distribution-list li { counter-increment:distribution-rank; } +body[data-report-page="report"] .ranked-distribution-list li > a, body[data-report-page="report"] .ranked-distribution-list li > span { display:grid; grid-template-columns:minmax(8rem, 14rem) minmax(5rem, 1fr) 5rem 3rem; align-items:center; gap:var(--oc-space-3); min-height:2rem; color:var(--oc-text-secondary); } +body[data-report-page="report"] .ranked-distribution-list li > a:hover { color:var(--oc-text-primary); text-decoration:none; } +body[data-report-page="report"] .distribution-label { display:grid; min-width:0; overflow:hidden; align-content:center; gap:1px; } +body[data-report-page="report"] .distribution-label-primary, body[data-report-page="report"] .distribution-label-detail { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } +body[data-report-page="report"] .distribution-label-primary { color:var(--oc-text-primary); font-weight:650; } +body[data-report-page="report"] .distribution-label-detail { color:var(--oc-text-muted); font-size:var(--oc-font-size-xs); font-weight:500; line-height:1.2; } +body[data-report-page="report"] .distribution-track { height:0.55rem; overflow:hidden; border-radius:var(--oc-radius-round); background:var(--oc-surface-secondary-soft); } +body[data-report-page="report"] .distribution-segment { display:block; min-width:1px; height:100%; background:var(--oc-chart-color,var(--oc-accent-primary)); } +body[data-report-page="report"] .oc-split-tertiary { --oc-chart-color:color-mix(in srgb,var(--oc-accent-primary) 48%,var(--oc-accent-secondary)); } +body[data-report-page="report"] .oc-split-quaternary { --oc-chart-color:var(--oc-accent-secondary-deep); } +body[data-report-page="report"] .oc-split-neutral { --oc-chart-color:color-mix(in srgb,var(--oc-border-strong) 58%,var(--oc-text-muted)); } +body[data-report-page="report"] .distribution-total { color:var(--oc-text-primary); font-variant-numeric:tabular-nums; text-align:right; } +body[data-report-page="report"] .distribution-share { color:var(--oc-text-muted); font-family:var(--oc-font-mono); font-size:var(--oc-font-size-xs); text-align:right; } +body[data-report-page="report"] .distribution-breakdown { grid-column:2 / -1; display:flex; flex-wrap:wrap; gap:var(--oc-space-1) var(--oc-space-3); color:var(--oc-text-muted); font-size:var(--oc-font-size-xs); line-height:1.25; } +body[data-report-page="report"] .distribution-breakdown-item { display:inline-flex; align-items:center; gap:var(--oc-space-1); white-space:nowrap; } +body[data-report-page="report"] .distribution-breakdown-key { width:0.45rem; height:0.45rem; flex:0 0 auto; border-radius:2px; background:var(--oc-chart-color,var(--oc-accent-primary)); } +body[data-report-page="report"] .distribution-more { border-top:1px solid var(--oc-border-subtle); padding-top:var(--oc-space-2); } +body[data-report-page="report"] .distribution-more summary { width:fit-content; color:var(--oc-text-secondary); font-size:var(--oc-font-size-sm); cursor:pointer; } +body[data-report-page="report"] { margin: 0; background: var(--oc-bg-page); color: var(--oc-text-secondary); -webkit-font-smoothing: antialiased; } +body[data-report-page="report"] .shell { width: min(var(--oc-content-max), calc(100vw - 36px)); margin: 0 auto; padding: var(--oc-space-6) 0 var(--oc-space-8); } +body[data-report-page="report"] header { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--oc-space-6); align-items: end; padding: 0 0 var(--oc-space-5); border-bottom: 1px solid var(--oc-border-subtle); } +body[data-report-page="report"] h1 { margin: 0; color: var(--oc-text-primary); font: 740 34px/1.05 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; letter-spacing: 0; } +body[data-report-page="report"] .subtitle { margin: 12px 0 0; color: var(--oc-text-muted); font-size: 14px; line-height: 1.5; max-width: 760px; } +body[data-report-page="report"] .stamp .label, body[data-report-page="report"] .metric .label, body[data-report-page="report"] .section-kicker, body[data-report-page="report"] .person-meta, body[data-report-page="report"] .small { color: var(--oc-text-muted); font-family: var(--oc-font-mono); font-size: 12px; line-height: 1.35; text-transform: uppercase; } +body[data-report-page="report"] .panel { margin: var(--oc-space-7) 0; padding: 0; } +body[data-report-page="report"] .collection-section { padding: 0; border: 0; background: transparent; box-shadow: none; } +body[data-report-page="report"] .people-head { align-items: start; } +body[data-report-page="report"] .people-tools { width: min(390px, 100%); display: grid; gap: 8px; } +body[data-report-page="report"] .person-filter { width: 100%; min-height: 42px; padding: 9px 12px; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-control); background: var(--oc-surface-card-strong); color: var(--oc-text-primary); font: 740 14px/1.2 var(--oc-font-mono); outline: none; box-shadow: inset 0 0 0 1px rgba(24, 23, 20, 0); } +body[data-report-page="report"] .person-filter:focus { box-shadow: inset 0 0 0 1px var(--oc-accent-primary), 0 0 0 3px color-mix(in srgb, var(--oc-accent-primary) 18%, transparent); } +body[data-report-page="report"] .filter-status { min-height: 17px; color: var(--oc-text-muted); font-size: 12px; line-height: 1.35; text-transform: uppercase; } +body[data-report-page="report"] h2 { margin: 0; color: var(--oc-text-primary); font: 740 20px/1.2 var(--oc-font-display); letter-spacing: 0; } +body[data-report-page="report"] .shell > .oc-section { margin: var(--oc-space-7) 0; } +body[data-report-page="report"] .shell > .oc-section:first-of-type { margin-top: var(--oc-space-5); } +body[data-report-page="report"] .oc-section-header { margin-bottom: var(--oc-space-4); } +body[data-report-page="report"] .section-note { max-width: 46ch; margin: 0; color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); line-height: 1.45; text-align: right; } +body[data-report-page="report"] .summary-markdown { color: var(--oc-text-primary); font-size: 15px; line-height: 1.48; } +body[data-report-page="report"] .summary-markdown p { margin: 0 0 12px; } +body[data-report-page="report"] .summary-markdown p:last-child { margin-bottom: 0; } +body[data-report-page="report"] .summary-markdown ul { display: grid; gap: 8px; margin: 14px 0 0; padding: 0; list-style: none; } +body[data-report-page="report"] .summary-markdown li { position: relative; padding-left: 18px; } +body[data-report-page="report"] .summary-markdown li::before { content: ""; position: absolute; left: 0; top: 0.72em; width: 7px; height: 7px; border-radius: 999px; background: var(--oc-status-error-fg); } +body[data-report-page="report"] .summary-markdown strong { font-weight: 800; } +body[data-report-page="report"] .summary-markdown code { padding: 1px 5px; border: 1px solid var(--oc-border-subtle); border-radius: 5px; background: color-mix(in srgb, var(--oc-surface-card) 84%, transparent); font: 0.92em ui-monospace, SFMono-Regular, Menlo, monospace; } +body[data-report-page="report"] .summary-markdown a { color: inherit; text-decoration-color: var(--oc-border-strong); text-underline-offset: 3px; } +body[data-report-page="report"] .people { display: grid; gap: 12px; } +body[data-report-page="report"] .person { display: grid; grid-template-columns: 198px minmax(0, 1fr) 150px; gap: 16px; padding: 14px; } +body[data-report-page="report"] .person:hover { border-color: color-mix(in srgb, var(--oc-accent-primary) 42%, var(--oc-border-strong)); background: color-mix(in srgb, var(--oc-surface-card) 82%, var(--oc-accent-primary) 8%); } +body[data-report-page="report"] .person[hidden] { display: none; } +body[data-report-page="report"] .quiet-maintainers { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--oc-border-subtle); } +body[data-report-page="report"] .quiet-title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 14px; margin-bottom: 10px; } +body[data-report-page="report"] .quiet-title h3 { margin: 0; font-size: 15px; line-height: 1.25; letter-spacing: 0; } +body[data-report-page="report"] .quiet-list { display: flex; flex-wrap: wrap; gap: 7px; margin: 0; padding: 0; list-style: none; } +body[data-report-page="report"] .quiet-list li { max-width: 100%; padding: 4px 8px; border: 1px solid var(--oc-border-strong); border-radius: 999px; background: color-mix(in srgb, var(--oc-surface-accent-soft) 72%, transparent); color: var(--oc-text-muted); font-size: 12px; line-height: 1.25; overflow-wrap: anywhere; } +body[data-report-page="report"] .person-title { min-width: 0; } +body[data-report-page="report"] .person-heading { display: flex; align-items: center; gap: 10px; min-width: 0; } +body[data-report-page="report"] .person-heading > div { min-width: 0; } +body[data-report-page="report"] .handle { color: var(--oc-text-primary); font: 800 17px/1.15 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; overflow-wrap: anywhere; } +body[data-report-page="report"] .person-name { margin-top: 3px; color: var(--oc-text-muted); font-size: 13px; line-height: 1.35; overflow-wrap: anywhere; } +body[data-report-page="report"] .affiliation { margin-top: 7px; display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 8px; border: 1px solid var(--oc-border-strong); border-radius: 999px; background: color-mix(in srgb, var(--oc-status-success-fg) 14%, var(--oc-surface-card-strong)); color: var(--oc-status-success-fg); font-size: 12px; font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; } +body[data-report-page="report"] .affiliation.is-na { border-color: var(--oc-border-strong); background: color-mix(in srgb, var(--oc-bg-elevated) 82%, var(--oc-surface-card-strong)); color: var(--oc-text-muted); } +body[data-report-page="report"] .affiliation.is-readonly { border-color: color-mix(in srgb, var(--oc-status-info-fg) 46%, var(--oc-border-strong)); background: color-mix(in srgb, var(--oc-status-info-fg) 13%, var(--oc-surface-card-strong)); color: color-mix(in srgb, var(--oc-status-info-fg) 76%, var(--oc-text-primary)); } +body[data-report-page="report"] .affiliation.is-independent { border-color: color-mix(in srgb, var(--oc-status-warning-fg) 46%, var(--oc-border-strong)); background: color-mix(in srgb, var(--oc-status-warning-fg) 16%, var(--oc-surface-card-strong)); color: color-mix(in srgb, var(--oc-status-warning-fg) 88%, var(--oc-text-primary)); } +body[data-report-page="report"] .role-line { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; } +body[data-report-page="report"] .person-body { min-width: 0; display: grid; gap: 10px; } +body[data-report-page="report"] .chips { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 7px; } +body[data-report-page="report"] .theme { margin: 0; color: var(--oc-text-primary); font-size: 13px; line-height: 1.42; } +body[data-report-page="report"] .theme + .theme { color: var(--oc-text-muted); } +body[data-report-page="report"] .focus { margin: 0; color: var(--oc-text-primary); font-size: 14px; line-height: 1.48; } +body[data-report-page="report"] .person-numbers { display: grid; gap: 8px; align-content: start; } +body[data-report-page="report"] .number-line { display: flex; justify-content: space-between; gap: 8px; color: var(--oc-text-muted); font-size: 13px; border-bottom: 1px solid var(--oc-border-subtle); padding-bottom: 5px; } +body[data-report-page="report"] .number-line strong { color: var(--oc-text-primary); } +body[data-report-page="report"] footer { margin-top: 28px; color: var(--oc-text-muted); font-size: 12px; line-height: 1.5; border-top: 1px solid var(--oc-border-strong); padding-top: 14px; } +@media (max-width: 980px) { +body[data-report-page="report"] header, body[data-report-page="report"] .mix { grid-template-columns: 1fr; } +body[data-report-page="report"] .person { grid-template-columns: 1fr; } +body[data-report-page="report"] .people-head { align-items: stretch; } +} +@media (max-width: 640px) { +body[data-report-page="report"] .shell { width: min(100vw - 24px, 1180px); padding-top: 20px; } +body[data-report-page="report"] h1 { font-size: 28px; } +body[data-report-page="report"] .distribution-heading { align-items:start; flex-direction:column; } +body[data-report-page="report"] .distribution-heading .section-note { text-align:left; } +body[data-report-page="report"] .ranked-distribution-list li > a, body[data-report-page="report"] .ranked-distribution-list li > span { grid-template-columns:minmax(7rem,1fr) 5rem 2.5rem; gap:var(--oc-space-2); } +body[data-report-page="report"] .distribution-track { grid-column:1 / -1; grid-row:2; } +body[data-report-page="report"] .distribution-breakdown { grid-column:1 / -1; grid-row:3; } +} + +body[data-report-page="people"] .people-header, body[data-report-page="person"] .people-header { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--oc-space-6); align-items: end; padding-bottom: var(--oc-space-5); margin-bottom: var(--oc-space-5); border-bottom: 1px solid var(--oc-border-subtle); } +body[data-report-page="people"] h1, body[data-report-page="person"] h1 { margin: 0; color: var(--oc-text-primary); font: 740 34px/1.05 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } +body[data-report-page="people"] h2, body[data-report-page="person"] h2 { margin: 4px 0 0; color: var(--oc-text-primary); font: 740 22px/1.2 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } +body[data-report-page="people"] p, body[data-report-page="person"] p { margin: 10px 0 0; color: var(--oc-text-muted); } +body[data-report-page="people"] .people-grid, body[data-report-page="person"] .people-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); gap: 12px; } +body[data-report-page="people"] .people-break, body[data-report-page="person"] .people-break { grid-column: 1 / -1; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 6px 0 -2px; padding: 12px 2px 2px; border-top: 1px solid var(--oc-border-subtle); color: var(--oc-text-muted); font-size: 12px; line-height: 1.35; text-transform: uppercase; } +body[data-report-page="people"] .people-break span:first-child, body[data-report-page="person"] .people-break span:first-child { color: var(--oc-text-primary); font: 800 13px/1.2 ui-sans-serif, system-ui, sans-serif; text-transform: none; } +body[data-report-page="people"] .person-card, body[data-report-page="person"] .person-card { display: grid; gap: 10px; padding: 14px; } +body[data-report-page="people"] .person-card:hover, body[data-report-page="person"] .person-card:hover { border-color: var(--oc-accent-primary); background: color-mix(in srgb, var(--oc-surface-card) 82%, var(--oc-accent-primary) 8%); } +body[data-report-page="people"] .person-card.is-inactive, body[data-report-page="person"] .person-card.is-inactive { background: color-mix(in srgb, var(--oc-surface-card) 78%, var(--oc-bg-elevated)); } +body[data-report-page="people"] .person-card-head, body[data-report-page="person"] .person-card-head, body[data-report-page="people"] .person-hero, body[data-report-page="person"] .person-hero { display: flex; align-items: center; gap: 10px; min-width: 0; } +body[data-report-page="people"] .person-card-head > span, body[data-report-page="person"] .person-card-head > span, body[data-report-page="people"] .person-hero > div, body[data-report-page="person"] .person-hero > div { min-width: 0; } +body[data-report-page="people"] .person-card-identity, body[data-report-page="person"] .person-card-identity { display: grid; gap: 2px; min-width: 0; } +body[data-report-page="people"] .person-card strong, body[data-report-page="person"] .person-card strong { display: block; color: var(--oc-text-primary); font: 760 17px/1.2 ui-sans-serif, system-ui, sans-serif; overflow-wrap: anywhere; } +body[data-report-page="people"] .person-handle, body[data-report-page="person"] .person-handle, body[data-report-page="people"] .person-card-meta, body[data-report-page="person"] .person-card-meta { color: var(--oc-text-muted); font-size: 12px; line-height: 1.35; overflow-wrap: anywhere; } +body[data-report-page="people"] .person-company, body[data-report-page="person"] .person-company, body[data-report-page="people"] .person-company-line, body[data-report-page="person"] .person-company-line { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; min-width: 0; color: var(--oc-text-secondary); font-size: 13px; line-height: 1.35; } +body[data-report-page="people"] .person-company span, body[data-report-page="person"] .person-company span, body[data-report-page="people"] .person-company-line span, body[data-report-page="person"] .person-company-line span { min-width: 0; overflow-wrap: anywhere; } +body[data-report-page="people"] .person-card-meta, body[data-report-page="person"] .person-card-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; } +body[data-report-page="people"] .mini-strip, body[data-report-page="person"] .mini-strip { display: grid; grid-template-columns: repeat(28, minmax(0, 1fr)); gap: 3px; align-items: center; } +body[data-report-page="people"] .legend, body[data-report-page="person"] .legend { display: flex; gap: 4px; align-items: center; } +body[data-report-page="people"] .day-dot, body[data-report-page="person"] .day-dot, body[data-report-page="people"] .legend span, body[data-report-page="person"] .legend span { min-width: 0; height: 10px; border: 1px solid var(--activity-0-border); border-radius: 3px; background: var(--activity-0-bg); } +body[data-report-page="people"] .legend span, body[data-report-page="person"] .legend span { width: 13px; height: 13px; } +body[data-report-page="people"] .archive-panel, body[data-report-page="person"] .archive-panel { padding: 0; margin: 32px 0; } +body[data-report-page="people"] .month-row, body[data-report-page="person"] .month-row { display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 18px; align-items: start; padding: 14px 0; border-top: 1px solid var(--oc-border-subtle); } +body[data-report-page="people"] .month-row:first-child, body[data-report-page="person"] .month-row:first-child { border-top: 0; } +body[data-report-page="people"] .month-label, body[data-report-page="person"] .month-label { color: var(--oc-text-primary); font-weight: 760; padding-top: 26px; } +body[data-report-page="people"] .calendar, body[data-report-page="person"] .calendar { width: min(100%, 268px); --calendar-gap: 5px; } +body[data-report-page="people"] .weekday-row, body[data-report-page="person"] .weekday-row, body[data-report-page="people"] .day-grid, body[data-report-page="person"] .day-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--calendar-gap); width: 100%; } +body[data-report-page="people"] .weekday-row, body[data-report-page="person"] .weekday-row { margin-bottom: 6px; color: var(--oc-text-muted); font-size: 10px; text-align: center; text-transform: uppercase; } +body[data-report-page="people"] .day-grid, body[data-report-page="person"] .day-grid { align-items: center; } +body[data-report-page="people"] .day-spacer, body[data-report-page="person"] .day-spacer, body[data-report-page="people"] .day-cell, body[data-report-page="person"] .day-cell { width: 100%; aspect-ratio: 1; min-width: 0; } +body[data-report-page="people"] .day-cell, body[data-report-page="person"] .day-cell { display: grid; place-items: center; min-height: 24px; border: 1px solid var(--activity-0-border); border-radius: 6px; color: var(--oc-text-muted); font-size: 11px; font-weight: 760; } +body[data-report-page="people"] .day-cell:hover, body[data-report-page="person"] .day-cell:hover { border-color: var(--oc-accent-primary); color: var(--oc-text-primary); outline: 2px solid color-mix(in srgb, var(--oc-accent-primary) 24%, transparent); outline-offset: 1px; } +body[data-report-page="people"] .level-0, body[data-report-page="person"] .level-0 { background: var(--activity-0-bg); border-color: var(--activity-0-border); } +body[data-report-page="people"] .level-1, body[data-report-page="person"] .level-1, body[data-report-page="person"] .legend .level-1 { background: var(--activity-1-bg); border-color: var(--activity-1-border); color: var(--oc-text-primary); } +body[data-report-page="people"] .level-2, body[data-report-page="person"] .level-2, body[data-report-page="person"] .legend .level-2 { background: var(--activity-2-bg); border-color: var(--activity-2-border); color: var(--oc-text-primary); } +body[data-report-page="people"] .level-3, body[data-report-page="person"] .level-3, body[data-report-page="person"] .legend .level-3 { background: var(--activity-3-bg); border-color: var(--activity-3-border); color: var(--activity-3-text); } +body[data-report-page="people"] .level-4, body[data-report-page="person"] .level-4, body[data-report-page="person"] .legend .level-4 { background: var(--activity-4-bg); border-color: var(--activity-4-border); color: var(--activity-4-text); } +body[data-report-page="people"] .activity-list, body[data-report-page="person"] .activity-list { display: grid; gap: 10px; } +body[data-report-page="people"] .activity-row, body[data-report-page="person"] .activity-row { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 16px; padding: 14px; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-bg-elevated); } +body[data-report-page="people"] .activity-row:hover, body[data-report-page="person"] .activity-row:hover { border-color: var(--oc-accent-primary); } +body[data-report-page="people"] .activity-date, body[data-report-page="person"] .activity-date { color: var(--oc-text-primary); font-weight: 760; } +body[data-report-page="people"] .activity-row strong, body[data-report-page="person"] .activity-row strong, body[data-report-page="people"] .activity-row span span, body[data-report-page="person"] .activity-row span span { display: block; } +body[data-report-page="people"] .activity-row strong, body[data-report-page="person"] .activity-row strong { color: var(--oc-text-primary); } +body[data-report-page="people"] .activity-row span span, body[data-report-page="person"] .activity-row span span { color: var(--oc-text-muted); font-size: 13px; line-height: 1.45; } +body[data-report-page="people"] .activity-row p, body[data-report-page="person"] .activity-row p { margin-top: 6px; color: var(--oc-text-secondary); font-size: 13px; } +body[data-report-page="people"] .person-activity-panel, body[data-report-page="person"] .person-activity-panel { min-width: 0; } +body[data-report-page="people"] .person-activity-legend, body[data-report-page="person"] .person-activity-legend { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px 16px; margin: 4px 0 0; padding: 0; color: var(--oc-text-muted); font-size: 12px; line-height: 1.35; list-style: none; } +body[data-report-page="people"] .person-activity-legend li, body[data-report-page="person"] .person-activity-legend li { display: inline-flex; align-items: center; gap: 7px; } +body[data-report-page="people"] .person-activity-swatch, body[data-report-page="person"] .person-activity-swatch { width: 18px; height: 3px; flex: 0 0 auto; border-radius: 2px; } +body[data-report-page="people"] .person-activity-swatch.is-github, body[data-report-page="person"] .person-activity-swatch.is-github { background: var(--oc-status-success-fg); } +body[data-report-page="people"] .person-activity-swatch.is-discord, body[data-report-page="person"] .person-activity-swatch.is-discord { background: var(--oc-status-info-fg); } +body[data-report-page="people"] .person-activity-chart, body[data-report-page="person"] .person-activity-chart { min-width: 0; margin-top: 16px; border: 1px solid var(--oc-border-subtle); border-radius: var(--oc-radius-surface); background: var(--oc-bg-elevated); touch-action: pan-y; } +body[data-report-page="people"] .person-activity-chart:focus-visible, body[data-report-page="person"] .person-activity-chart:focus-visible { outline: 2px solid var(--oc-accent-primary); outline-offset: 2px; } +body[data-report-page="people"] .person-activity-svg, body[data-report-page="person"] .person-activity-svg { display: block; width: 100%; height: clamp(250px, 36vw, 390px); overflow: visible; } +body[data-report-page="people"] .person-activity-axis, body[data-report-page="person"] .person-activity-axis, body[data-report-page="people"] .person-activity-gridline, body[data-report-page="person"] .person-activity-gridline, body[data-report-page="people"] .person-activity-line, body[data-report-page="person"] .person-activity-line { vector-effect: non-scaling-stroke; } +body[data-report-page="people"] .person-activity-axis, body[data-report-page="person"] .person-activity-axis { fill: none; stroke: var(--oc-border-strong); stroke-width: 1; } +body[data-report-page="people"] .person-activity-gridline, body[data-report-page="person"] .person-activity-gridline { stroke: var(--oc-border-subtle); stroke-width: 1; } +body[data-report-page="people"] .person-activity-axis-tick, body[data-report-page="person"] .person-activity-axis-tick { fill: var(--oc-text-muted); font: 11px/1 var(--oc-font-mono); } +body[data-report-page="people"] .person-activity-axis-tick-left, body[data-report-page="person"] .person-activity-axis-tick-left { text-anchor: end; } +body[data-report-page="people"] .person-activity-axis-tick-right, body[data-report-page="person"] .person-activity-axis-tick-right { text-anchor: start; } +body[data-report-page="people"] .person-activity-axis-title, body[data-report-page="person"] .person-activity-axis-title { font: 800 12px/1 var(--oc-font-mono); } +body[data-report-page="people"] .person-activity-axis-title-github, body[data-report-page="person"] .person-activity-axis-title-github { fill: var(--oc-status-success-fg); } +body[data-report-page="people"] .person-activity-axis-title-discord, body[data-report-page="person"] .person-activity-axis-title-discord { fill: var(--oc-status-info-fg); } +body[data-report-page="people"] .person-activity-line, body[data-report-page="person"] .person-activity-line { fill: none; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; } +body[data-report-page="people"] .person-activity-line-github, body[data-report-page="person"] .person-activity-line-github { stroke: var(--oc-status-success-fg); } +body[data-report-page="people"] .person-activity-line-discord, body[data-report-page="person"] .person-activity-line-discord { stroke: var(--oc-status-info-fg); } +body[data-report-page="people"] .person-activity-point, body[data-report-page="person"] .person-activity-point { stroke: var(--oc-bg-elevated); stroke-width: 1; vector-effect: non-scaling-stroke; } +body[data-report-page="people"] .person-activity-point-github, body[data-report-page="person"] .person-activity-point-github { fill: var(--oc-status-success-fg); } +body[data-report-page="people"] .person-activity-point-discord, body[data-report-page="person"] .person-activity-point-discord { fill: var(--oc-status-info-fg); } +body[data-report-page="people"] .person-activity-quality-note, body[data-report-page="person"] .person-activity-quality-note { margin-top: 10px; font-size: 12px; line-height: 1.45; } +body[data-report-page="people"] .person-activity-values, body[data-report-page="person"] .person-activity-values { margin-top: 12px; border-top: 1px solid var(--oc-border-subtle); } +body[data-report-page="people"] .person-activity-values summary, body[data-report-page="person"] .person-activity-values summary { padding: 12px 0 4px; color: var(--oc-text-primary); font-weight: 760; cursor: pointer; } +body[data-report-page="people"] .person-activity-table-wrap, body[data-report-page="person"] .person-activity-table-wrap { max-width: 100%; overflow-x: auto; } +body[data-report-page="people"] .person-activity-table, body[data-report-page="person"] .person-activity-table { width: 100%; min-width: 700px; border-collapse: collapse; margin-top: 8px; } +body[data-report-page="people"] .person-activity-table th, body[data-report-page="person"] .person-activity-table th, body[data-report-page="people"] .person-activity-table td, body[data-report-page="person"] .person-activity-table td { padding: 9px 10px; border-bottom: 1px solid var(--oc-border-subtle); text-align: left; vertical-align: top; } +body[data-report-page="people"] .person-activity-table thead th, body[data-report-page="person"] .person-activity-table thead th { color: var(--oc-text-muted); font-size: 11px; text-transform: uppercase; } +body[data-report-page="people"] .person-activity-table tbody th, body[data-report-page="person"] .person-activity-table tbody th { color: var(--oc-text-primary); font: 760 12px/1.35 var(--oc-font-mono); } +body[data-report-page="people"] .person-activity-table td, body[data-report-page="person"] .person-activity-table td { color: var(--oc-text-secondary); font-size: 12px; line-height: 1.4; } +body[data-report-page="people"] .breadcrumbs, body[data-report-page="person"] .breadcrumbs { display: flex; gap: 8px; color: var(--oc-text-muted); font-size: 12px; margin-bottom: 12px; } +body[data-report-page="people"] .breadcrumbs a, body[data-report-page="person"] .breadcrumbs a { color: var(--oc-accent-primary); } +@media (max-width: 760px) { +body[data-report-page="people"] .people-header, body[data-report-page="person"] .people-header, body[data-report-page="people"] .month-row, body[data-report-page="person"] .month-row, body[data-report-page="people"] .activity-row, body[data-report-page="person"] .activity-row { grid-template-columns: 1fr; } +body[data-report-page="people"] .month-label, body[data-report-page="person"] .month-label { padding-top: 0; } +body[data-report-page="people"] .archive-panel, body[data-report-page="person"] .archive-panel { padding: 16px; } +body[data-report-page="people"] .calendar, body[data-report-page="person"] .calendar { width: 100%; } +body[data-report-page="people"] .day-cell, body[data-report-page="person"] .day-cell { font-size: 10px; } +body[data-report-page="people"] .person-activity-legend, body[data-report-page="person"] .person-activity-legend { justify-content: flex-start; } +body[data-report-page="people"] .person-activity-svg, body[data-report-page="person"] .person-activity-svg { height: auto; aspect-ratio: 8 / 3; } +body[data-report-page="people"] .person-activity-axis-tick, body[data-report-page="person"] .person-activity-axis-tick { font-size: 24px; } +body[data-report-page="people"] .person-activity-axis-title, body[data-report-page="person"] .person-activity-axis-title { display: none; } +} +@media print { +body[data-report-page="people"] .person-activity-chart, body[data-report-page="person"] .person-activity-chart { break-inside: avoid; } +body[data-report-page="people"] .person-activity-svg, body[data-report-page="person"] .person-activity-svg { height: 300px; } +body[data-report-page="people"] .person-activity-values, body[data-report-page="person"] .person-activity-values { break-inside: avoid; } +} + + +body[data-report-page="home"] .home-grid > .quick-card { box-shadow: none; } +body[data-report-page="home"] .home-card h2 { margin: 4px 0 0; font-size: 18px; } +body[data-report-page="home"] .home-card > p:not(.oc-eyebrow) { color: var(--oc-text-muted); font-size: 13px; line-height: 1.45; } +body[data-report-page="home"] .home-card > .panel-link { align-self: flex-start; } +body[data-report-page="home"] .home-grid .oc-summary-metric { min-width: 0; } +body[data-report-page="home"] .home-grid .oc-summary-metric + .oc-summary-metric { padding-left: var(--oc-space-3); border-left: 1px solid var(--oc-border-subtle); } +body[data-report-page="home"] .home-grid .oc-summary-metric-copy { gap: var(--oc-space-1); } +body[data-report-page="home"] .home-grid .oc-summary-metric-copy small { overflow: visible; white-space: normal; } +body[data-report-page="report"] .distribution-track { width: 100%; } +body[data-report-page="report"] .distribution-segment { fill: var(--oc-chart-color, var(--oc-accent-primary)); } +body[data-report-page="report"] header .oc-summary-metric { max-width: 27rem; } +body[data-report-page="report"] header .oc-summary-metric-copy small { white-space: normal; } +body[data-report-page="report"] .oc-banner-title { font-size: inherit; line-height: inherit; font-weight: 650; } +body[data-report-page="report"] main > .oc-banner { margin-block: var(--oc-space-3); } +body[data-report-page="report"] main > .oc-summary-strip { margin-top: var(--oc-space-5); } +body[data-report-page="report"] .alias-line, body[data-report-page="report"] .theme-kind { color: var(--oc-text-muted); font-size: var(--oc-font-size-xs); } +body[data-report-page="report"] .person-body details { min-width: 0; } +body[data-report-page="people"] .people-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin: -4px 0 18px; padding: 10px 12px; } +body[data-report-page="people"] .source-key { display: inline-flex; align-items: center; gap: 12px; margin-left: auto; color: var(--oc-text-muted); font-size: 12px; } +body[data-report-page="people"] .source-key span { display: inline-flex; align-items: center; gap: 5px; } +body[data-report-page="people"] .source-swatch { width: 10px; height: 10px; border-radius: 3px; border: 1px solid var(--oc-border-strong); } +body[data-report-page="people"] .source-swatch.github { background: var(--oc-status-success-fg); } +body[data-report-page="people"] .source-swatch.discord { background: var(--oc-status-info-fg); } +body[data-report-page="people"] .people-break.is-archived { margin-top: 18px; } +body[data-report-page="people"] .person-card.is-archived { border-style: dashed; opacity: .82; } +body[data-report-page="people"] .person-card-head .oc-avatar { width: 36px; height: 36px; } +body[data-report-page="people"] .person-card-days { flex-basis: 100%; } +body[data-report-page="people"] .person-card:hover { text-decoration: none; } +body[data-report-page="person"] .person-hero .oc-avatar { width: 72px; height: 72px; } +body[data-report-page="person"] .person-lifecycle, body[data-report-page="person"] .person-lifecycle-line { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; min-width: 0; color: var(--oc-status-warning-fg); font-size: 12px; font-weight: 800; line-height: 1.35; } +body[data-report-page="person"] .oc-summary-strip { margin-block: var(--oc-space-4) var(--oc-space-7); } +@media (max-width: 760px) { + body[data-report-page="people"] .people-toolbar { align-items: flex-start; flex-direction: column; } + body[data-report-page="people"] .source-key { margin-left: 0; } +} + + `; diff --git a/extensions/team-reports/src/render/theme.test.ts b/extensions/team-reports/src/render/theme.test.ts new file mode 100644 index 000000000000..89181bb79be2 --- /dev/null +++ b/extensions/team-reports/src/render/theme.test.ts @@ -0,0 +1,113 @@ +import { JSDOM } from "jsdom"; +import { afterEach, describe, expect, it } from "vitest"; +import { shell } from "./page.js"; + +const pages: JSDOM[] = []; +afterEach(() => { + for (const page of pages.splice(0)) { + page.window.close(); + } +}); + +async function openPage( + options: { + hash?: string; + stored?: string; + blockedStorage?: boolean; + systemLight?: boolean; + url?: string; + } = {}, +) { + const html = shell( + { + basePath: "/team/reports", + nonce: "fixture", + absoluteUrl: "https://public.example/team/reports/day/2026-09-07/?person=alice", + displayTimezone: "UTC", + }, + "Theme fixture", + `HistoryPeopleExternalOutside`, + "home", + ); + const page = new JSDOM(html, { + url: options.url ?? `https://gateway.example/team/reports/${options.hash ?? ""}`, + runScripts: "dangerously", + beforeParse(window) { + Object.defineProperty(window, "matchMedia", { + value: () => ({ matches: options.systemLight ?? false, addEventListener() {} }), + }); + if (options.blockedStorage) { + Object.defineProperty(window, "localStorage", { + get() { + throw new window.DOMException("Storage blocked by sandbox", "SecurityError"); + }, + }); + } else if (options.stored) { + window.localStorage.setItem("theme", options.stored); + } + }, + }); + pages.push(page); + // The head script must choose the theme before body parsing and enhancement. + const headTheme = page.window.document.documentElement.dataset.theme; + await new Promise((resolve) => { + page.window.addEventListener("load", () => resolve(), { once: true }); + }); + return { page, headTheme }; +} + +function link(page: JSDOM, selector: string): string | null | undefined { + return page.window.document.querySelector(selector)?.getAttribute("href"); +} + +function toggle(page: JSDOM): void { + page.window.document.querySelector("[data-theme-toggle]")?.click(); +} + +describe("Team Reports theme navigation", () => { + it.each([ + { hash: "#theme=light", stored: "dark", systemLight: false, expected: "light" }, + { hash: "#theme=dark", stored: "light", systemLight: true, expected: "dark" }, + { hash: "#theme=invalid", stored: "light", systemLight: false, expected: "light" }, + { hash: "", stored: "invalid", systemLight: true, expected: "light" }, + ])("resolves the head theme from fragment, storage, then OS ($hash/$stored)", async (options) => { + const { headTheme } = await openPage(options); + expect(headTheme).toBe(options.expected); + }); + + it("carries a sandboxed theme across internal navigation without changing external destinations", async () => { + const { page } = await openPage({ blockedStorage: true }); + toggle(page); + expect(page.window.document.documentElement.dataset.theme).toBe("light"); + expect(page.window.location.hash).toBe("#theme=light"); + expect(link(page, "#history")).toBe("/team/reports/day/2026-09-06/?person=alice#theme=light"); + expect(link(page, "#absolute")).toBe( + "https://gateway.example/team/reports/people/#theme=light", + ); + expect(link(page, 'a[aria-current="page"]')).toBe("/team/reports/#theme=light"); + expect(link(page, 'a[aria-label="Open in a new window"]')).toBe( + "https://public.example/team/reports/day/2026-09-07/?person=alice#theme=light", + ); + expect(link(page, "#external")).toBe("https://external.example/team/reports/"); + expect(link(page, "#outside")).toBe("/team/reports-other/"); + const next = await openPage({ + url: new URL(link(page, "#history") ?? "", page.window.location.href).href, + blockedStorage: true, + }); + expect(next.headTheme).toBe("light"); + expect(link(next.page, 'a[aria-current="page"]')).toBe("/team/reports/#theme=light"); + toggle(next.page); + expect(next.page.window.location.hash).toBe("#theme=dark"); + expect(link(next.page, "#history")).toBe( + "/team/reports/day/2026-09-06/?person=alice#theme=dark", + ); + }); + + it("persists a separate-window theme when browser storage is available", async () => { + const { page } = await openPage({ stored: "dark" }); + toggle(page); + expect(page.window.localStorage.getItem("theme")).toBe("light"); + const next = await openPage({ stored: page.window.localStorage.getItem("theme") ?? undefined }); + expect(next.headTheme).toBe("light"); + }); +}); diff --git a/extensions/team-reports/src/scheduler.test.ts b/extensions/team-reports/src/scheduler.test.ts index 32d4e30a0174..79660826591d 100644 --- a/extensions/team-reports/src/scheduler.test.ts +++ b/extensions/team-reports/src/scheduler.test.ts @@ -217,6 +217,41 @@ describe("Team Reports schedule boundaries", () => { }); describe("Team Reports scheduler lifecycle", () => { + it("reports the earliest due time and last completed run while another run is active", async () => { + const { scheduler, github } = setup({ + caughtUp: false, + schedule: { intradayEveryHours: 4 }, + }); + expect(scheduler.health()).toEqual({ running: false, warnings: 0 }); + scheduler.start(); + expect(scheduler.health()).toEqual({ + running: true, + nextDueMs: Date.parse("2026-08-20T12:01:00Z"), + warnings: 0, + }); + scheduler.generate(); + expect(scheduler.health().lastRun).toBeUndefined(); + await vi.advanceTimersByTimeAsync(60_000); + expect(scheduler.health()).toEqual({ + running: true, + lastRun: { status: "ok", kind: "manual", finishedAtMs: Date.parse("2026-08-20T12:00:00Z") }, + nextDueMs: Date.parse("2026-08-20T16:00:00Z"), + warnings: 0, + }); + const blocked = createDeferred>>(); + github.collect.mockImplementationOnce(() => blocked.promise); + scheduler.generate({ intraday: true }); + await vi.advanceTimersByTimeAsync(0); + expect(scheduler.health().lastRun).toEqual({ + status: "ok", + kind: "manual", + finishedAtMs: Date.parse("2026-08-20T12:00:00Z"), + }); + blocked.resolve({ items: [], status: healthy }); + await vi.advanceTimersByTimeAsync(0); + expect(scheduler.health().lastRun?.finishedAtMs).toBe(Date.parse("2026-08-20T12:01:00Z")); + }); + it("catches up yesterday once after the startup delay and also publishes today's partial", async () => { const { scheduler, store, github } = setup({ caughtUp: false }); scheduler.start(); @@ -438,11 +473,13 @@ describe("Team Reports scheduler lifecycle", () => { expect(stored?.summary?.warnings).toEqual([reason]); expect(stored?.markdown).toContain(`> ${reason}`); expect(scheduler.status().sourceWarnings).toEqual(["Roster coverage warning", reason]); + expect(scheduler.health().warnings).toBe(2); expect(context.logger.warn.mock.calls).toEqual([[reason]]); complete.mockResolvedValue(modelResponse()); scheduler.generate({ intraday: true }); await vi.advanceTimersByTimeAsync(0); expect(scheduler.status().sourceWarnings).toEqual(["Roster coverage warning"]); + expect(scheduler.health().warnings).toBe(1); }); it("reports source failures with redacted errors and clears health on the next successful run", async () => { @@ -456,6 +493,11 @@ describe("Team Reports scheduler lifecycle", () => { error: "Access failed for [redacted]", }); expect(context.serviceHealth.reportFailure).toHaveBeenCalledOnce(); + expect(scheduler.health().lastRun).toEqual({ + status: "error", + kind: "manual", + finishedAtMs: Date.now(), + }); expect(JSON.stringify(context.logger.error.mock.calls)).not.toContain("fixture-github-token"); const succeeded = scheduler.generate(); await vi.advanceTimersByTimeAsync(0); diff --git a/extensions/team-reports/src/scheduler.ts b/extensions/team-reports/src/scheduler.ts index 46aa4b3af6cd..06c4f7743c1f 100644 --- a/extensions/team-reports/src/scheduler.ts +++ b/extensions/team-reports/src/scheduler.ts @@ -19,6 +19,12 @@ const RUN_DEADLINE_MS = 45 * 60_000; const STOP_TIMEOUT_MS = 30_000; type RunKind = "closed-day" | "intraday" | "manual"; type ActiveRun = { id: string; controller: AbortController; done: Promise }; +export type TeamReportsHealth = { + running: boolean; + lastRun?: { status: "ok" | "error"; kind: RunKind; finishedAtMs: number }; + nextDueMs?: number; + warnings: number; +}; function nextClosedDayDue(nowMs: number, schedule: TeamReportsConfig["schedule"]): number { const random = Math.random(); @@ -97,6 +103,10 @@ export class TeamReportsScheduler { } } + orgs(): string[] { + return this.options.config.github.orgs; + } + people(): Person[] { return this.roster; } @@ -108,20 +118,45 @@ export class TeamReportsScheduler { nextDue: { ...this.due }, runs: this.options.store.listRuns(), periods: this.options.store.listPeriods(), - sourceWarnings: this.options.store - .listPeriods({ period: "day", limit: 1 }) - .flatMap((entry) => { - const stored = this.options.store.getPeriod("day", entry.key); - return stored - ? stored.report.sources.github.warnings.concat( - stored.report.sources.discord?.warnings ?? [], - stored.summary?.warnings ?? [], - ) - : []; - }), + sourceWarnings: this.sourceWarnings(), }; } + health(): TeamReportsHealth { + const finished = [ + ...this.options.store.listRuns(1, { status: "ok" }), + ...this.options.store.listRuns(1, { status: "error" }), + ].toSorted( + (a, b) => (b.finishedAtMs ?? 0) - (a.finishedAtMs ?? 0) || b.startedAtMs - a.startedAtMs, + )[0]; + const due = Object.values(this.due).filter((value) => value !== undefined); + return { + running: this.accepting, + ...(finished && finished.status !== "running" && finished.finishedAtMs !== null + ? { + lastRun: { + status: finished.status, + kind: finished.kind, + finishedAtMs: finished.finishedAtMs, + }, + } + : {}), + ...(due.length ? { nextDueMs: Math.min(...due) } : {}), + warnings: this.sourceWarnings().length, + }; + } + + private sourceWarnings(): string[] { + const latest = this.options.store.listPeriods({ period: "day", limit: 1 })[0]; + const stored = latest ? this.options.store.getPeriod("day", latest.key) : undefined; + return stored + ? stored.report.sources.github.warnings.concat( + stored.report.sources.discord?.warnings ?? [], + stored.summary?.warnings ?? [], + ) + : []; + } + generate(params: { date?: string; intraday?: boolean } = {}): string { const now = Date.now(); const day = describePeriod("day", params.date ?? now - (params.intraday ? 0 : DAY_MS)); diff --git a/extensions/team-reports/src/store.test.ts b/extensions/team-reports/src/store.test.ts index c8be25857d1e..bee0dc55a2bf 100644 --- a/extensions/team-reports/src/store.test.ts +++ b/extensions/team-reports/src/store.test.ts @@ -136,6 +136,88 @@ describe("Team Reports storage", () => { expect(store.listPersonDays("alice")).toHaveLength(1); }); + it("lists stored totals for each period kind and reflects regenerated documents", () => { + const { store } = openStore(); + for (const [period, key] of [ + ["day", "2026-08-20"], + ["week", "2026-W34"], + ["month", "2026-08"], + ] as const) { + const document = report(); + document.period = { ...document.period, period, key }; + document.activeMembers = 1; + document.totals.github = { + ...counts(21), + commits: 3, + prsOpened: 4, + prsMerged: 5, + securityAdvisories: 6, + }; + document.totals.discord.messages = 7; + store.upsertPeriod({ report: document, markdown: key }); + expect(store.listPeriods({ period })).toEqual([ + { + period, + key, + sinceMs: Date.parse("2026-08-20T00:00:00Z"), + untilMs: Date.parse("2026-08-21T00:00:00Z"), + generatedAtMs: Date.parse("2026-08-21T00:00:00Z"), + status: "closed", + activeMembers: 1, + memberCount: 2, + githubTotal: 21, + discordMessages: 7, + commits: 3, + prsOpened: 4, + prsMerged: 5, + securityAdvisories: 6, + }, + ]); + } + store.upsertPeriod({ report: report("2026-08-20", []), markdown: "refreshed" }); + expect(store.listPeriods({ period: "day" })[0]).toMatchObject({ + activeMembers: 0, + memberCount: 0, + githubTotal: 0, + discordMessages: 0, + commits: 0, + prsOpened: 0, + prsMerged: 0, + securityAdvisories: 0, + }); + }); + + it("lists all logins since an inclusive day without the individual timeline limit", () => { + const { store } = openStore(); + const logins = Array.from( + { length: 30 }, + (_, index) => `member-${String(index).padStart(2, "0")}`, + ); + store.upsertPeriod({ report: report("2026-08-18", ["older"]), markdown: "older" }); + store.upsertPeriod({ report: report("2026-08-19", logins), markdown: "boundary" }); + store.upsertPeriod({ report: report("2026-08-20", ["latest"]), markdown: "latest" }); + const days = store.listPersonDaysSince("2026-08-19"); + expect(days.map(({ dayKey, login }) => [dayKey, login])).toEqual([ + ["2026-08-20", "latest"], + ...logins.map((login) => ["2026-08-19", login]), + ]); + expect(days[1]).toEqual({ + dayKey: "2026-08-19", + login: "member-00", + githubTotal: 1, + commits: 1, + prsOpened: 0, + prsMerged: 0, + prsClosed: 0, + issuesOpened: 0, + issuesClosed: 0, + issueComments: 0, + reviewComments: 0, + discordMessages: 2, + }); + expect(store.listPersonDaysSince("2026-08-21")).toEqual([]); + }); + it("reads half-open day ranges and indexes newest first without projecting week rows onto people", () => { const { store } = openStore(); for (const key of ["2026-08-18", "2026-08-19", "2026-08-20"]) { diff --git a/extensions/team-reports/src/store.ts b/extensions/team-reports/src/store.ts index 5862497dd17c..bfe0ba68c7c8 100644 --- a/extensions/team-reports/src/store.ts +++ b/extensions/team-reports/src/store.ts @@ -36,6 +36,14 @@ export type PeriodListEntry = { untilMs: number; status: "partial" | "closed"; generatedAtMs: number; + activeMembers: number; + memberCount: number; + githubTotal: number; + discordMessages: number; + commits: number; + prsOpened: number; + prsMerged: number; + securityAdvisories: number; }; export type PersonDay = { dayKey: string; @@ -230,6 +238,29 @@ export class TeamReportsStore { "status", "generated_at_ms as generatedAtMs", ]) + // SQLite extracts only the chart totals instead of materializing every report in JavaScript. + .select((eb) => [ + eb.fn("json_extract", ["data_json", eb.val("$.activeMembers")]).as("activeMembers"), + eb.fn("json_extract", ["data_json", eb.val("$.memberCount")]).as("memberCount"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.github.total")]) + .as("githubTotal"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.discord.messages")]) + .as("discordMessages"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.github.commits")]) + .as("commits"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.github.prsOpened")]) + .as("prsOpened"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.github.prsMerged")]) + .as("prsMerged"), + eb + .fn("json_extract", ["data_json", eb.val("$.totals.github.securityAdvisories")]) + .as("securityAdvisories"), + ]) .orderBy("since_ms", "desc") .orderBy("period", "asc"); if (options.period) { @@ -260,7 +291,31 @@ export class TeamReportsStore { options: { since?: string; until?: string; limit?: number } = {}, ): PersonDay[] { this.assertOpen(); - let query = this.query + let query = this.selectPersonDays() + .where("login", "=", login.toLowerCase()) + .orderBy("day_key", "desc"); + if (options.since) { + query = query.where("day_key", ">=", options.since); + } + if (options.until) { + query = query.where("day_key", "<", options.until); + } + return executeSqliteQuerySync(this.db, query.limit(options.limit ?? 28)).rows; + } + + listPersonDaysSince(since: string): PersonDay[] { + this.assertOpen(); + return executeSqliteQuerySync( + this.db, + this.selectPersonDays() + .where("day_key", ">=", since) + .orderBy("day_key", "desc") + .orderBy("login", "asc"), + ).rows; + } + + private selectPersonDays() { + return this.query .selectFrom("team_reports_person_days") .select([ "day_key as dayKey", @@ -275,16 +330,7 @@ export class TeamReportsStore { "issue_comments as issueComments", "review_comments as reviewComments", "discord_messages as discordMessages", - ]) - .where("login", "=", login.toLowerCase()) - .orderBy("day_key", "desc"); - if (options.since) { - query = query.where("day_key", ">=", options.since); - } - if (options.until) { - query = query.where("day_key", "<", options.until); - } - return executeSqliteQuerySync(this.db, query.limit(options.limit ?? 28)).rows; + ]); } startRun(run: {