feat: add the two-tier dashboard (task 0017) #18

Merged
alexion merged 1 commits from task-0017-dashboard into main 2026-07-14 11:09:02 -04:00
Owner

Implements .claude/tasks/0017-dashboard.md.

Summary

Wires the bare gitea-axi command to the two-tier repository dashboard (ADR 0012):

  • Short tier (bare gitea-axi, also what the SessionStart hook runs): up to 3 open issues (number,title,state,author) and up to 3 open PRs (number,title,author,review), fetched in parallel at limit=3, with review computed client-side from a parallel per-PR reviews fetch. The help block always hints at --full.
  • Full tier (gitea-axi --full): the open-PR table (number,title,author,labels,review) capped at 20 rows with a count: 20 of T total line, plus open issue counts grouped by label — aggregated across every page of open issues (page size 50) up to a 1000-issue cap, suffixing each count with + when the cap is hit. Each issue counts under all its labels; a nonzero-only unlabeled bucket collects the rest.
  • Empty states are the raw strings prs: 0 open / issues: 0 open. Issue fetches pass type=issues. Outside a Gitea repo the dashboard errors with REPO_NOT_FOUND and -R/--login help. The SDK prepends the bin:/description: header.

Built test-first: 7 fixture-tier tests in test/dashboard.test.ts, a no-repo case in test/detection.test.ts, and a live-instance tier in test/e2e/dashboard.test.ts. Full suite green (371 fixture tests).

Deviations / decisions (see the task's Implementation Notes)

  • --full is extracted in runCli before SDK dispatch (the SDK rejects pre-command flags), only when it is the sole remaining argument.
  • paginate.ts's PaginatedResult gained a backward-compatible capped flag to drive the + suffix.
  • Beyond the literal spec, kept deliberately: deterministic label-count ordering (count desc, name asc, unlabeled last); a defensive slice of the PR page to the requested limit; the full-tier count line is always emitted; a short dashboard/--full note added to top-level --help.

Review

Three-axis /review-uncommitted (task file as spec source).

Risk

Overall: Medium

  • Blast radius: Medium — touches cli.ts dispatch and adds a capped field to shared paginate.ts, but mostly a self-contained new dashboard.ts.
  • Reversibility: Low — pure additive CLI output; no migrations, deletions, or persisted schema.
  • Test coverage: Low — fixture unit tests plus an e2e tier cover both tiers, empty states, caps, and label aggregation.
  • Sensitive domain: Low — read-only issue/PR listing; no auth, permissions, or mutation.
  • Size & complexity: Medium — ~280-line new module with parallel fetches, two tiers, per-PR review folding, and the --full argv extraction.
  • Runtime criticality: Medium — the bare command runs in a SessionStart hook path with a timeout, so latency/errors are user-facing (dev tooling, not production).

Standards — unaddressed findings (all judgement-call smells; no hard violations)

  • Duplicated single-page fetch try/catch across fetchOpenPulls/fetchOpenIssues/fetchAllOpenIssues. Left as-is: this classifyHttpError wrapper is the established house shape (mirrors pr.ts/issue.ts fetch helpers).
  • Review-column handling conceptually shared with pr list. Left as-is: pr list also merges --fields extras into the same row, so it is not the same operation; the dashboard's version is localized in prRowsWithReview (ADR 0006).
  • OpenPulls { pulls, total } vs PaginatedResult { items, total } data clump. Left as-is: fetchOpenPulls does a single-page fetch, so reusing PaginatedResult would force a meaningless capped field.
  • --full bespoke argv parsing outside SDK dispatch. Left as-is: correct and documented; the SDK genuinely rejects pre-command flags, so this is the right place to handle the overload.

Spec

Contract fully satisfied — no missing, partial, or wrong requirements. The only unrequested behavior is the deterministic label ordering and the defensive PR slice, both kept (noted above).

Implements `.claude/tasks/0017-dashboard.md`. ## Summary Wires the bare `gitea-axi` command to the two-tier repository dashboard (ADR 0012): - **Short tier** (bare `gitea-axi`, also what the SessionStart hook runs): up to 3 open issues (`number,title,state,author`) and up to 3 open PRs (`number,title,author,review`), fetched in parallel at `limit=3`, with `review` computed client-side from a parallel per-PR reviews fetch. The help block always hints at `--full`. - **Full tier** (`gitea-axi --full`): the open-PR table (`number,title,author,labels,review`) capped at 20 rows with a `count: 20 of T total` line, plus open issue counts grouped by label — aggregated across every page of open issues (page size 50) up to a 1000-issue cap, suffixing each count with `+` when the cap is hit. Each issue counts under all its labels; a nonzero-only `unlabeled` bucket collects the rest. - Empty states are the raw strings `prs: 0 open` / `issues: 0 open`. Issue fetches pass `type=issues`. Outside a Gitea repo the dashboard errors with `REPO_NOT_FOUND` and `-R`/`--login` help. The SDK prepends the `bin:`/`description:` header. Built test-first: 7 fixture-tier tests in `test/dashboard.test.ts`, a no-repo case in `test/detection.test.ts`, and a live-instance tier in `test/e2e/dashboard.test.ts`. Full suite green (371 fixture tests). ## Deviations / decisions (see the task's Implementation Notes) - `--full` is extracted in `runCli` before SDK dispatch (the SDK rejects pre-command flags), only when it is the sole remaining argument. - `paginate.ts`'s `PaginatedResult` gained a backward-compatible `capped` flag to drive the `+` suffix. - Beyond the literal spec, kept deliberately: deterministic label-count ordering (count desc, name asc, `unlabeled` last); a defensive slice of the PR page to the requested limit; the full-tier count line is always emitted; a short dashboard/`--full` note added to top-level `--help`. ## Review Three-axis `/review-uncommitted` (task file as spec source). ### Risk **Overall: Medium** - Blast radius: Medium — touches `cli.ts` dispatch and adds a `capped` field to shared `paginate.ts`, but mostly a self-contained new `dashboard.ts`. - Reversibility: Low — pure additive CLI output; no migrations, deletions, or persisted schema. - Test coverage: Low — fixture unit tests plus an e2e tier cover both tiers, empty states, caps, and label aggregation. - Sensitive domain: Low — read-only issue/PR listing; no auth, permissions, or mutation. - Size & complexity: Medium — ~280-line new module with parallel fetches, two tiers, per-PR review folding, and the `--full` argv extraction. - Runtime criticality: Medium — the bare command runs in a SessionStart hook path with a timeout, so latency/errors are user-facing (dev tooling, not production). ### Standards — unaddressed findings (all judgement-call smells; no hard violations) - **Duplicated single-page fetch `try/catch`** across `fetchOpenPulls`/`fetchOpenIssues`/`fetchAllOpenIssues`. Left as-is: this `classifyHttpError` wrapper is the established house shape (mirrors `pr.ts`/`issue.ts` fetch helpers). - **Review-column handling conceptually shared with `pr list`.** Left as-is: `pr list` also merges `--fields` extras into the same row, so it is not the same operation; the dashboard's version is localized in `prRowsWithReview` (ADR 0006). - **`OpenPulls { pulls, total }` vs `PaginatedResult { items, total }` data clump.** Left as-is: `fetchOpenPulls` does a single-page fetch, so reusing `PaginatedResult` would force a meaningless `capped` field. - **`--full` bespoke argv parsing outside SDK dispatch.** Left as-is: correct and documented; the SDK genuinely rejects pre-command flags, so this is the right place to handle the overload. ### Spec Contract fully satisfied — no missing, partial, or wrong requirements. The only unrequested behavior is the deterministic label ordering and the defensive PR slice, both kept (noted above).
alexion added 1 commit 2026-07-14 11:02:00 -04:00
feat: add the two-tier dashboard (task 0017)
All checks were successful
CI / test (pull_request) Successful in 47s
CI / test (push) Successful in 50s
5b6a9b4917
Wire the bare `gitea-axi` home command to a two-tier repository
dashboard (ADR 0012): the short tier shows up to 3 open issues and 3
open PRs with the client-side `review` decision, and `--full` shows the
20-row open-PR table plus open issue counts grouped by label, aggregated
across every page of open issues up to the 1000-issue cap with a `+`
suffix when capped. Empty states render the raw `prs: 0 open` /
`issues: 0 open` strings; issue fetches pass `type=issues`; outside a
Gitea repo the dashboard errors with REPO_NOT_FOUND.

`paginate.ts` now reports whether pagination stopped at the cap, which
drives the label-count `+` suffix.
alexion merged commit 5b6a9b4917 into main 2026-07-14 11:09:02 -04:00
alexion deleted branch task-0017-dashboard 2026-07-14 11:09:02 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alexion/gitea-axi#18