Context
collectPortfolioDashboard (packages/loopover-miner/lib/portfolio-dashboard.js:25-57) groups queue rows into perRepo keyed purely by repoFullName (lines 38-47), with no apiBaseUrl anywhere in the per-repo entry shape ({ repoFullName, byStatus, total }, line 43). Verified empirically: feeding it 2 queued + 1 done row on acme/widgets split across https://api.github.com and https://ghe.example.com/api/v3 produces one repos entry with { queued: 2, done: 1, total: 3 } — the two hosts' independent backlogs are silently merged, in both the object result and its --json output (there's no host field to recover the split even in JSON mode). renderPortfolioDashboardTable (lines 60-79) then prints this merged count with no indication two hosts are involved.
Separately, renderQueueTable (packages/loopover-miner/lib/portfolio-queue-cli.js:200-219, queue list's human-readable output) prints only repo, identifier, status, pri, enqueued-at — no apiBaseUrl column — even though queue done/release/requeue all require an explicit --api-base-url (lines 147-155) to disambiguate two rows that legitimately share the same repoFullName+identifier post-#5563. (The --json variant of queue list does retain apiBaseUrl per row via rowToEntry, so this half is display-only; the dashboard half is a genuine data-loss bug since the aggregation itself discards the host before either output format sees it.)
Requirements
collectPortfolioDashboard's perRepo map must key by (apiBaseUrl, repoFullName), and each repo summary entry must include its apiBaseUrl.
renderPortfolioDashboardTable must show which host each row belongs to.
renderQueueTable must add an apiBaseUrl (or shortened host) column so a human reading queue list's plain-text output can determine the --api-base-url value needed for a follow-up queue done/release/requeue call.
- Single-host installs (the default/common case) must render identically to today modulo the new column/field.
Deliverables
Test Coverage Requirements
Both touched files are under packages/loopover-miner/lib/**/*.js, in Codecov's 99% patch-coverage gate. Pure, synchronous rendering/aggregation functions — full line+branch coverage is achievable with the two regression tests plus existing single-host tests (test/unit/miner-portfolio-dashboard.test.ts, test/unit/miner-portfolio-queue-cli.test.ts) continuing to pass.
Expected Outcome
An operator running queue dashboard or queue list against a portfolio spanning multiple forge hosts sees accurate, host-separated counts and can tell which host a given row belongs to without falling back to --json and manually inspecting apiBaseUrl.
Links & Resources
packages/loopover-miner/lib/portfolio-dashboard.js:25-79
packages/loopover-miner/lib/portfolio-queue-cli.js:200-219
Context
collectPortfolioDashboard(packages/loopover-miner/lib/portfolio-dashboard.js:25-57) groups queue rows intoperRepokeyed purely byrepoFullName(lines 38-47), with noapiBaseUrlanywhere in the per-repo entry shape ({ repoFullName, byStatus, total }, line 43). Verified empirically: feeding it 2 queued + 1 done row onacme/widgetssplit acrosshttps://api.github.comandhttps://ghe.example.com/api/v3produces onereposentry with{ queued: 2, done: 1, total: 3 }— the two hosts' independent backlogs are silently merged, in both the object result and its--jsonoutput (there's no host field to recover the split even in JSON mode).renderPortfolioDashboardTable(lines 60-79) then prints this merged count with no indication two hosts are involved.Separately,
renderQueueTable(packages/loopover-miner/lib/portfolio-queue-cli.js:200-219,queue list's human-readable output) prints onlyrepo,identifier,status,pri,enqueued-at— noapiBaseUrlcolumn — even thoughqueue done/release/requeueall require an explicit--api-base-url(lines 147-155) to disambiguate two rows that legitimately share the samerepoFullName+identifierpost-#5563. (The--jsonvariant ofqueue listdoes retainapiBaseUrlper row viarowToEntry, so this half is display-only; the dashboard half is a genuine data-loss bug since the aggregation itself discards the host before either output format sees it.)Requirements
collectPortfolioDashboard'sperRepomap must key by(apiBaseUrl, repoFullName), and each repo summary entry must include itsapiBaseUrl.renderPortfolioDashboardTablemust show which host each row belongs to.renderQueueTablemust add anapiBaseUrl(or shortened host) column so a human readingqueue list's plain-text output can determine the--api-base-urlvalue needed for a follow-upqueue done/release/requeuecall.Deliverables
collectPortfolioDashboardgroups by(apiBaseUrl, repoFullName)and includesapiBaseUrlin each repo entryrenderPortfolioDashboardTabledisplays host per rowrenderQueueTablegains anapiBaseUrlcolumnrepoFullNameproduce two distinct dashboard repo entries with correct, non-merged countsqueue list's plain-text table distinguishes two same-named-repo rows on different hostsTest Coverage Requirements
Both touched files are under
packages/loopover-miner/lib/**/*.js, in Codecov's 99% patch-coverage gate. Pure, synchronous rendering/aggregation functions — full line+branch coverage is achievable with the two regression tests plus existing single-host tests (test/unit/miner-portfolio-dashboard.test.ts,test/unit/miner-portfolio-queue-cli.test.ts) continuing to pass.Expected Outcome
An operator running
queue dashboardorqueue listagainst a portfolio spanning multiple forge hosts sees accurate, host-separated counts and can tell which host a given row belongs to without falling back to--jsonand manually inspectingapiBaseUrl.Links & Resources
packages/loopover-miner/lib/portfolio-dashboard.js:25-79packages/loopover-miner/lib/portfolio-queue-cli.js:200-219