You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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-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
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.tsandapps/gittensory-ui/src/lib/miner-commands.ts(tested bytest/unit/miner-dashboard-recommendations.test.tsandtest/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 insideapps/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 ispackages/gittensory-miner/lib/manage-status.js:collectManageStatus(manage-status.js:59) is a pure builder that composes thePortfolioQueueStoreandEventLedgerintoManageStatusRow[],renderManageStatusTable(manage-status.js:114) renders it as a plain-text table, andrunManageStatus(manage-status.js:152) is the CLI glue registered asgittensory-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-extensionalready exists — a shipped Manifest V3 extension ("Gittensory Maintainer Overlay",apps/gittensory-extension/manifest.json) that content-scripts ontogithub.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, itshost_permissionsonly coverhttps://github.com/*andhttps://gittensory-api.aethereal.dev/*(manifest.json:7); there is nolocalhost/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 thisS-sized item. The parent tracker's own Phase 6 still listsfeat(miner-extension): scaffold browser extension surfaceandfeat(miner-extension): add read-only issue-page opportunity badgeas 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
packages/gittensory-miner/lib/portfolio-dashboard.js(+.d.ts) exporting a purecollectPortfolioDashboard(sources)— same shape ascollectManageStatus(manage-status.js:59) — that aggregateslistQueue()(portfolio-queue.js:184) into summary stats: counts by status (queued/in_progress/done) globally and per repo, and oldest-queued-item agerenderPortfolioDashboardTable-style plain-text renderer plus--jsonoutput, mirroringrenderManageStatusTable(manage-status.js:114) andrunManageStatus's (manage-status.js:152) CLI-glue conventionsgittensory-miner queue dashboardsubcommand (extends the existingqueuedispatch atbin/gittensory-miner.js:41-43, alongsidelist/next/done) — read-only, no state mutation--jsonvs. table output), mirroring the existingportfolio-queue-cli.jstest conventionssrc/services/miner-dashboard-recommendations.ts,apps/gittensory-ui/src/lib/miner-commands.ts) so future readers don't conflate the twoapps/gittensory-extensionand the miner's local SQLite state (no such channel exists today — the extension'shost_permissionscover onlygithub.comand the hosted API), not merely on the extension existing — do not attempt that channel in this issueReferences
packages/gittensory-miner/lib/manage-status.js:59(collectManageStatus),:114(renderManageStatusTable),:152(runManageStatus) — the three-layer pattern to mirrorpackages/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 statusdispatch),:41-43(queuedispatch)apps/gittensory-extension/manifest.json(whole file, esp.:7host_permissions,:12-19content-script matches) — the existing extension scaffold, confirmed maintainer-facing with no miner content and no local-channel permissionssrc/services/miner-dashboard-recommendations.ts,apps/gittensory-ui/src/lib/miner-commands.ts— the unrelated existing "miner dashboard" surfaces to disambiguate fromfeat(miner-extension): scaffold browser extension surfaceandfeat(miner-extension): add read-only issue-page opportunity badge, both still open/unfiled