diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e7b4546 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,28 @@ +version: 2 + +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: friday + time: "13:00" + timezone: Europe/Berlin + groups: + minor-and-patch: + update-types: + - minor + - patch + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: friday + time: "13:00" + timezone: Europe/Berlin + groups: + minor-and-patch: + update-types: + - minor + - patch diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000..13f05d1 --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,21 @@ +name: Dependabot Auto-Merge + +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - uses: dependabot/fetch-metadata@v2 + id: metadata + + - if: steps.metadata.outputs.update-type != 'version-update:semver-major' + run: gh pr merge "$PR_URL" --auto --squash + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/playwright.config.ts b/playwright.config.ts index ff7028a..13e44cf 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,6 +1,8 @@ import { defineConfig } from "@playwright/test" +import { tmpdir } from "node:os" +import { join } from "node:path" -const testDbPath = "/var/folders/p2/0gbt1nps4m1_t9np42sx_kl00000gn/T/opencode/opencode-usage-stats-e2e.db" +const testDbPath = join(tmpdir(), "opencode", "opencode-usage-stats-e2e.db") const port = 43434 export default defineConfig({ diff --git a/src/dashboard.ts b/src/dashboard.ts index a877a42..2588090 100644 --- a/src/dashboard.ts +++ b/src/dashboard.ts @@ -63,8 +63,8 @@ interface ModeStats { provider_id: string | null; } -function getStats(repos: Repos): SessionStats[] { - const rootSessions = repos.sessions.getRootSessions(); +function getStats(repos: Repos, directory?: string): SessionStats[] { + const rootSessions = repos.sessions.getRootSessions(directory ?? undefined); const childSessions = repos.sessions.getChildSessions(); const agentCalls = repos.toolCalls.getAgentCalls(); const modeRows = repos.messages.getModeStats(); @@ -266,9 +266,21 @@ export function renderTokens( return html; } +function recencyClass(lastSeen: string | null | undefined): string { + if (!lastSeen) return ""; + const iso = `${lastSeen.replace(" ", "T")}Z`; + const ageSec = (Date.now() - Date.parse(iso)) / 1000; + if (Number.isNaN(ageSec) || ageSec < 0) return ""; + if (ageSec < 30) return "session-card--active"; + if (ageSec < 120) return "session-card--recent"; + if (ageSec < 600) return "session-card--idle"; + return ""; +} + function renderSessionCard(s: SessionStats): string { const title = s.title || s.directory?.split("/").pop() || s.session_id; const time = s.last_seen?.replace("T", " ").slice(0, 16) ?? ""; + const recency = recencyClass(s.last_seen); const agentRows = s.agents .map((a) => { @@ -327,7 +339,7 @@ function renderSessionCard(s: SessionStats): string { .join(""); return ` -