Context
packages/loopover-miner/lib/manage-status.js (loopover-miner manage status [--json], #2325) is an explicitly-documented read-only aggregation: its own header comment says "Aggregate managed PR rows from the local portfolio queue and append-only event ledger. Read-only — never calls GitHub or mutates local stores." It combines three local stores — portfolio-queue.js, event-ledger.js (via the manage_pr_update event vocabulary), and run-state.js — into two distinct views via collectManageStatus (per-managed-PR rows: branch, CI state, gate verdict, outcome, last-polled-at) and collectRunPortfolio (a run-level portfolio view).
This is a genuinely different aggregation from what's already exposed. The existing loopover_miner_get_portfolio_dashboard MCP tool wraps collectPortfolioDashboard — status counts (queued/in_progress/done totals + oldest-queued age) from the portfolio queue alone. loopover_miner_get_run_state wraps run-state.js directly — per-repo run-state only. Neither returns the per-managed-PR detail rows (collectManageStatus) or the run-portfolio view (collectRunPortfolio) that manage status produces by joining all three stores together — an MCP client currently has no way to ask "what's the live status of each PR my miner is managing, and what does it look like across the whole run?" without shelling out to loopover-miner manage status --json.
Requirements
- Add a new tool
loopover_miner_get_manage_status to packages/loopover-miner/bin/loopover-miner-mcp.js, alongside the existing loopover_miner_get_portfolio_dashboard tool it's a sibling of.
- Input schema: no arguments (the CLI command itself takes only
--json, no filters).
- Implementation: open
portfolio-queue.js, event-ledger.js, and run-state.js (respecting the same options.init* injection-seam convention the file already uses for loopover_miner_get_portfolio_dashboard/loopover_miner_get_run_state), call the EXISTING exported collectManageStatus({ portfolioQueue, eventLedger }) and collectRunPortfolio({ portfolioQueue, eventLedger, runStateStore }) functions unchanged — do not reimplement the join logic that already lives in manage-status.js. Close every store this tool itself opened in a finally block, matching runManageStatus's own three-way finally.
- Return shape:
{ rows, runPortfolio } — the identical additive JSON shape runManageStatus's --json output already uses (per manage-status.js's own comment: "rows keeps its existing shape unchanged; runPortfolio is a new key").
- Description text must state this is read-only, never calls GitHub, never mutates local stores (mirroring
manage-status.js's own header comment verbatim in spirit), and reuses the existing aggregator with no new logic.
Deliverables
Test Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch in packages/loopover-miner/bin/loopover-miner-mcp.js, including the store-ownership invariant and both the populated and empty aggregation cases.
Expected Outcome
An MCP client connected to the miner's stdio server can call loopover_miner_get_manage_status and get the same per-PR managed-status rows and run-portfolio view that loopover-miner manage status --json prints today, without shelling out to the CLI.
Links & Resources
Context
packages/loopover-miner/lib/manage-status.js(loopover-miner manage status [--json], #2325) is an explicitly-documented read-only aggregation: its own header comment says "Aggregate managed PR rows from the local portfolio queue and append-only event ledger. Read-only — never calls GitHub or mutates local stores." It combines three local stores —portfolio-queue.js,event-ledger.js(via themanage_pr_updateevent vocabulary), andrun-state.js— into two distinct views viacollectManageStatus(per-managed-PR rows: branch, CI state, gate verdict, outcome, last-polled-at) andcollectRunPortfolio(a run-level portfolio view).This is a genuinely different aggregation from what's already exposed. The existing
loopover_miner_get_portfolio_dashboardMCP tool wrapscollectPortfolioDashboard— status counts (queued/in_progress/done totals + oldest-queued age) from the portfolio queue alone.loopover_miner_get_run_statewrapsrun-state.jsdirectly — per-repo run-state only. Neither returns the per-managed-PR detail rows (collectManageStatus) or the run-portfolio view (collectRunPortfolio) thatmanage statusproduces by joining all three stores together — an MCP client currently has no way to ask "what's the live status of each PR my miner is managing, and what does it look like across the whole run?" without shelling out toloopover-miner manage status --json.Requirements
loopover_miner_get_manage_statustopackages/loopover-miner/bin/loopover-miner-mcp.js, alongside the existingloopover_miner_get_portfolio_dashboardtool it's a sibling of.--json, no filters).portfolio-queue.js,event-ledger.js, andrun-state.js(respecting the sameoptions.init*injection-seam convention the file already uses forloopover_miner_get_portfolio_dashboard/loopover_miner_get_run_state), call the EXISTING exportedcollectManageStatus({ portfolioQueue, eventLedger })andcollectRunPortfolio({ portfolioQueue, eventLedger, runStateStore })functions unchanged — do not reimplement the join logic that already lives inmanage-status.js. Close every store this tool itself opened in afinallyblock, matchingrunManageStatus's own three-wayfinally.{ rows, runPortfolio }— the identical additive JSON shaperunManageStatus's--jsonoutput already uses (permanage-status.js's own comment: "rowskeeps its existing shape unchanged;runPortfoliois a new key").manage-status.js's own header comment verbatim in spirit), and reuses the existing aggregator with no new logic.Deliverables
loopover_miner_get_manage_statustool registration inpackages/loopover-miner/bin/loopover-miner-mcp.jswith matching injection seamsrowsandrunPortfolio), the empty case (no managed PRs recorded yet), and the store-ownership open/close invariantTest Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch in
packages/loopover-miner/bin/loopover-miner-mcp.js, including the store-ownership invariant and both the populated and empty aggregation cases.Expected Outcome
An MCP client connected to the miner's stdio server can call
loopover_miner_get_manage_statusand get the same per-PR managed-status rows and run-portfolio view thatloopover-miner manage status --jsonprints today, without shelling out to the CLI.Links & Resources
loopover_miner_get_portfolio_dashboardandloopover_miner_get_run_stateinpackages/loopover-miner/bin/loopover-miner-mcp.js(same multi-store-open, injection-seam, close-on-finally pattern)packages/loopover-miner/lib/manage-status.js(collectManageStatus,collectRunPortfolio,runManageStatus)manage status), feat(miner-manage-ui): manage-phase dashboard panel for run portfolio #4279 (the dashboard-panel UI consumer of the same data), Expose AMS portfolio-queue dashboard as a read-only MCP tool (gittensory_miner_get_portfolio_dashboard) #5155/Expose AMS per-repo run-state as a read-only MCP tool (gittensory_miner_get_run_state) #5160 (the sibling miner-mcp tool issues this follows the pattern of)