Skip to content

feat(miner-portfolio): read-only portfolio dashboard view (#4287) - #4482

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:feat/gittensory-portfolio-dashboard
Jul 9, 2026
Merged

feat(miner-portfolio): read-only portfolio dashboard view (#4287)#4482
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:feat/gittensory-portfolio-dashboard

Conversation

@davion-knight

Copy link
Copy Markdown
Contributor

Adds packages/gittensory-miner/lib/portfolio-dashboard.js — a read-only aggregate view of the miner's own local portfolio-queue backlog, in the same three-layer shape as manage-status.js (pure collect → pure render → thin CLI glue), scoped to the queue rather than per-PR manage state.

API

  • collectPortfolioDashboard(sources, { nowMs }) — a pure aggregator over an injected portfolio-queue store (mirrors collectManageStatus). Read-only — never mutates queue state. Returns counts by status (queued/in_progress/done) globally and per repo, plus the oldest queued item's age in ms when a clock is supplied (null otherwise). Robust to unknown statuses, non-string repos, and malformed timestamps.
  • renderPortfolioDashboardTable + a --json path (mirrors renderManageStatusTable).
  • runPortfolioDashboard — CLI glue wired as gittensory-miner queue dashboard via one new case in runQueueCli's dispatch (alongside list/next/done; no bin edit needed).

Scope

The extension-panel half is a forward dependency, not delivered here: the miner's queue is a local SQLite file with no local-reachable channel a GitHub-page content script can read today (per portfolio-queue.js's "never uploads, syncs, or phones home" header). The pure collector is factored to be directly reusable once such a channel exists. This is read-only — it doesn't gate or enforce anything (unrelated to the maintainer-only Governor chokepoint work).

Tests

test/unit/miner-portfolio-dashboard.test.ts: the collector (invalid-source throw, multi-status/multi-repo aggregation, oldest-queued age, null-age when no clock / nothing queued, unknown-status + non-string-repo + malformed-timestamp handling), the renderer (empty, with/without age), the arg parser, and the CLI runner (table + --json + bad-arg error). Pure collector/renderer/parser fully covered; typecheck clean; the existing queue-CLI + miner-package skeleton suites stay green. Adds the hand-written .d.ts.

Closes #4287

…4287)

Add packages/gittensory-miner/lib/portfolio-dashboard.js: a read-only aggregate
view of the miner's OWN local portfolio-queue backlog, in the same three-layer
shape as manage-status.js (pure collect -> pure render -> thin CLI glue) but
scoped to the queue rather than per-PR manage state.

- collectPortfolioDashboard(sources, { nowMs }): a pure aggregator over an
  injected portfolio-queue store (mirrors collectManageStatus). Read-only —
  never mutates queue state. Returns counts by status (queued/in_progress/done)
  globally and per repo, plus the oldest queued item's age when a clock is given.
- renderPortfolioDashboardTable + a --json path (mirrors renderManageStatusTable).
- runPortfolioDashboard: CLI glue wired as 'gittensory-miner queue dashboard'
  (one new case in runQueueCli's dispatch, alongside list/next/done).

The extension-panel half is a forward dependency, not delivered here: the miner's
queue is a local SQLite file with no local-reachable channel a GitHub-page content
script can read today; the pure collector is factored to be reusable once one
exists. Adds the hand-written .d.ts.

Closes JSONbored#4287
@davion-knight
davion-knight requested a review from JSONbored as a code owner July 9, 2026 21:29
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.03%. Comparing base (453c5d4) to head (aceb029).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4482   +/-   ##
=======================================
  Coverage   94.03%   94.03%           
=======================================
  Files         420      420           
  Lines       37521    37521           
  Branches    13701    13701           
=======================================
  Hits        35282    35282           
  Misses       1583     1583           
  Partials      656      656           
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. labels Jul 9, 2026
@loopover-orb

loopover-orb Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-09 21:41:17 UTC

4 files · 1 AI reviewer · no blockers · readiness 82/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This is a clean, narrowly-scoped read-only aggregator (collectPortfolioDashboard) plus render/CLI glue, added in the same three-layer shape as the existing manage-status.js pattern and wired into runQueueCli's dispatch as a new `queue dashboard` subcommand. The aggregation logic (counts by status/repo, oldest-queued age, malformed-timestamp and non-string-repo handling) is correct and traced end-to-end in the file content shown, and the test suite exercises both arms of every conditional (nowMs present/absent, queued/not-queued, valid/malformed enqueuedAt, string/non-string repoFullName). Duplicating the ownsQueue/close pattern locally in portfolio-dashboard.js rather than importing it from portfolio-queue-cli.js is the right call, since portfolio-queue-cli.js already imports runPortfolioDashboard and reusing the helper would create a circular import. The PR explicitly documents that it delivers only the CLI half of issue #4287 (the extension-panel half is called out as a forward dependency blocked on a not-yet-existing local-read channel), which is a legitimate scope call rather than scope creep.

Nits — 5 non-blocking
  • portfolio-dashboard.js:61-69 hardcodes column widths (28/7/8/6/6) and the 60000 ms-to-minutes divisor inline — pulling these into named constants (mirroring however manage-status.js does it, if it does) would make the render function easier to scan.
  • collectPortfolioDashboard (portfolio-dashboard.js:24) sits at cyclomatic complexity 11 against the repo's threshold of 10 — consider factoring the per-entry repo-bucket upsert (lines ~40-47) into a small helper to bring it back under threshold.
  • The nested `if (status === "queued") { const ms = ...; if (...) ... }` block (portfolio-dashboard.js:81) reaches depth 5 against a threshold of 4; still readable as-is, but an early `continue` for non-queued entries before the repo bucketing would flatten it.
  • parsePortfolioDashboardArgs returns the generic usage error on the *first* stray positional without noting which token was unexpected — minor UX nit, consistent with the sibling parsers though so not worth blocking on.
  • Consider extracting the repo width/format string used in renderPortfolioDashboardTable into a shared table-formatting helper if a third CLI table view is added later, but not worth doing preemptively for two call sites.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4287
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 89 registered-repo PR(s), 53 merged, 3 issue(s).
Contributor context ✅ Confirmed Gittensor contributor davion-knight; Gittensor profile; 89 PR(s), 3 issue(s).
Gate result ✅ Passing No configured blocker found.
Linked issue satisfaction

Addressed
The PR adds portfolio-dashboard.js/.d.ts with a pure collectPortfolioDashboard mirroring collectManageStatus (status counts globally/per-repo, oldest-queued age), a plain-text renderer plus --json output, a new 'queue dashboard' CLI subcommand wired through runQueueCli, and unit tests covering empty/multi-repo/multi-status cases and CLI table/--json/error paths, matching essentially every listed d

Review context
  • Author: davion-knight
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 89 PR(s), 3 issue(s).
  • Related work: Titles/paths share 6 meaningful terms. (issue #4261, issue #4307)
Contributor next steps
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Check active issues and PRs before submitting.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gittensory approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 953fdef into JSONbored:main Jul 9, 2026
10 checks passed
@loopover-orb loopover-orb Bot added gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. and removed gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. labels Jul 9, 2026
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. and removed gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants