Skip to content

feat(miner-portfolio): read-only portfolio dashboard view (CLI + extension panel) #4287

Description

@JSONbored

Two adjacent things already exist with "miner dashboard" in the name — worth naming explicitly so this issue isn't mistaken for either. src/services/miner-dashboard-recommendations.ts and apps/gittensory-ui/src/lib/miner-commands.ts (tested by test/unit/miner-dashboard-recommendations.test.ts and test/unit/miner-dashboard-commands.test.ts) are the HOSTED web app's decision-pack-driven "what should I pursue" view and copyable-CLI-command builder — server-side recommendations computed from live GitHub signals, rendered inside apps/gittensory-ui. That's unrelated to this issue, which is a read-only view of the miner's OWN local SQLite backlog (packages/gittensory-miner/lib/portfolio-queue.js) — 100% client-side, per that module's own header (portfolio-queue.js:6-10).

Nothing aggregates the portfolio queue today. gittensory-miner queue list (packages/gittensory-miner/lib/portfolio-queue-cli.js:105-124, renderQueueTable) prints raw individual rows only — no counts-by-status, no per-repo summary. The closest existing pattern to extend is packages/gittensory-miner/lib/manage-status.js: collectManageStatus (manage-status.js:59) is a pure builder that composes the PortfolioQueueStore and EventLedger into ManageStatusRow[], renderManageStatusTable (manage-status.js:114) renders it as a plain-text table, and runManageStatus (manage-status.js:152) is the CLI glue registered as gittensory-miner manage status (bin/gittensory-miner.js:37-39) — but that view is scoped to per-PR CI/gate-verdict state (the Phase 4 "manage/loop" domain), not the backlog/queue itself. This issue is the same three-layer shape (pure collect → pure render → thin CLI glue), applied to the portfolio queue instead.

The extension-panel half needs correcting, not just scoping down. This repo is NOT starting from zero on a browser extension: apps/gittensory-extension already exists — a shipped Manifest V3 extension ("Gittensory Maintainer Overlay", apps/gittensory-extension/manifest.json) that content-scripts onto github.com/*/*/pull/* and .../issues/* pages (manifest.json:12-19) and mounts a private-context panel (content.js, mountOverlay). But it is maintainer-facing PR-review context, not miner/contributor content — a grep for "miner" or "portfolio" across every file in that directory returns zero hits — and, more importantly, its host_permissions only cover https://github.com/* and https://gittensory-api.aethereal.dev/* (manifest.json:7); there is no localhost/loopback permission and no native-messaging config anywhere in it. The miner's portfolio queue is a local SQLite file on the contributor's own machine (portfolio-queue.js:6-10, "the database only lives on this machine; this module never uploads, syncs, or phones home"), which a GitHub-page content script has no channel to reach today. So "add a miner panel to the extension" isn't a small follow-on to existing infrastructure — it needs a new local-reachable channel (e.g. a loopback server the CLI runs, or native messaging) that doesn't exist anywhere in this repo yet, and that is a materially bigger, cross-cutting piece of work than this S-sized item. The parent tracker's own Phase 6 still lists feat(miner-extension): scaffold browser extension surface and feat(miner-extension): add read-only issue-page opportunity badge as unchecked/unfiled (confirmed no such issue exists via title search), so there's no sibling issue yet to lean on either.

Given that, this issue delivers the CLI view now, with its pure data builder factored so it's directly reusable once a local-reachable channel exists — the extension half is recorded as a forward dependency here, not a blocking deliverable.

This is a read-only view — it never mutates queue state, and it doesn't gate or enforce anything; it is unrelated to the fail-closed Governor chokepoint work in #2340 (milestone 13, maintainer-only).

Deliverables

  • New packages/gittensory-miner/lib/portfolio-dashboard.js (+ .d.ts) exporting a pure collectPortfolioDashboard(sources) — same shape as collectManageStatus (manage-status.js:59) — that aggregates listQueue() (portfolio-queue.js:184) into summary stats: counts by status (queued/in_progress/done) globally and per repo, and oldest-queued-item age
  • A renderPortfolioDashboardTable-style plain-text renderer plus --json output, mirroring renderManageStatusTable (manage-status.js:114) and runManageStatus's (manage-status.js:152) CLI-glue conventions
  • New gittensory-miner queue dashboard subcommand (extends the existing queue dispatch at bin/gittensory-miner.js:41-43, alongside list/next/done) — read-only, no state mutation
  • Unit tests for the pure builder (empty queue, multi-repo/multi-status mix) and the CLI glue (--json vs. table output), mirroring the existing portfolio-queue-cli.js test conventions
  • Doc comment distinguishing this from the unrelated hosted-web-app "miner dashboard" (src/services/miner-dashboard-recommendations.ts, apps/gittensory-ui/src/lib/miner-commands.ts) so future readers don't conflate the two
  • Note (not a code deliverable): record in the module's doc comment that the extension-panel half is blocked on a local-reachable channel between apps/gittensory-extension and the miner's local SQLite state (no such channel exists today — the extension's host_permissions cover only github.com and the hosted API), not merely on the extension existing — do not attempt that channel in this issue

References

  • packages/gittensory-miner/lib/manage-status.js:59 (collectManageStatus), :114 (renderManageStatusTable), :152 (runManageStatus) — the three-layer pattern to mirror
  • packages/gittensory-miner/lib/portfolio-queue.js:6-10 (client-side-only header), :184 (listQueue)
  • packages/gittensory-miner/lib/portfolio-queue-cli.js:105-124 (renderQueueTable, the existing raw-row view this issue adds a summary alongside)
  • packages/gittensory-miner/bin/gittensory-miner.js:37-39 (manage status dispatch), :41-43 (queue dispatch)
  • apps/gittensory-extension/manifest.json (whole file, esp. :7 host_permissions, :12-19 content-script matches) — the existing extension scaffold, confirmed maintainer-facing with no miner content and no local-channel permissions
  • src/services/miner-dashboard-recommendations.ts, apps/gittensory-ui/src/lib/miner-commands.ts — the unrelated existing "miner dashboard" surfaces to disambiguate from
  • Parent tracker 🧩 Wave 2 — Analyze, Plan, Create & Deploy (HELD tracker) #2353, Phase 6 — feat(miner-extension): scaffold browser extension surface and feat(miner-extension): add read-only issue-page opportunity badge, both still open/unfiled

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.gittensor:priorityMaintainer-selected Gittensor priority — scores a 1.5x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions