Skip to content

feat(mcp): add REST + CLI + stdio surfaces for loopover_plan_repo_issues - #7856

Closed
xfodev wants to merge 1 commit into
JSONbored:mainfrom
xfodev:feat/plan-repo-issues-three-surfaces-7764
Closed

feat(mcp): add REST + CLI + stdio surfaces for loopover_plan_repo_issues#7856
xfodev wants to merge 1 commit into
JSONbored:mainfrom
xfodev:feat/plan-repo-issues-three-surfaces-7764

Conversation

@xfodev

@xfodev xfodev commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

loopover_plan_repo_issues (backed by generateIssuePlanDrafts) shipped only as a remote MCP tool (via Epic #7424, after the MCP-parity milestone closed), so it never got the REST + CLI + local-stdio mirror every other repo-scoped tool has. This adds all three:

  • REST: POST /v1/repos/:owner/:repo/issue-plan-drafts/generate (src/api/routes.ts + src/openapi/spec.ts), gated by requireAppRole + requireSessionRepoAccess, with the explicit_create_requires_dry_run_false create-safety guard (a bare create is rejected; only {create:true, dryRun:false} reaches the write path).
  • CLI: loopover-mcp maintain plan-issues --goal "..." (dry-run by default; --create/--limit/--json).
  • stdio tool: loopover_plan_repo_issues, proxying the REST mirror.

Coverage / testability

packages/loopover-mcp/bin/loopover-mcp.ts is a CLI dispatcher otherwise only exercised via subprocess spawn (which v8 can't instrument). It adds an isProcessEntrypoint() guard + runAsCliEntrypoint flag so a unit test can import the module and drive runCli/maintainCli in-process without hijacking argv or binding stdin (the untestable server.connect(new StdioServerTransport()) carries a /* v8 ignore */). test/unit/mcp-cli-plan-issues.test.ts drives both the maintain plan-issues CLI (incl. --help) and the stdio tool in-process against both the built .js and .ts; test/unit/routes-issue-plan-draft.test.ts covers the REST route (session + static-token, cross-repo rejection, create-safety); and test/unit/mcp-tool-rename-aliases.test.ts's tool-count invariant is bumped 79 → 80.

Verified on latest main: mcp-cli + routes + openapi + tool-count tests pass, tsc --noEmit clean, ui:openapi:check / command-reference:check / test:mcp-pack clean, git diff --check clean, and every changed line in routes.ts / spec.ts / loopover-mcp.ts is Codecov-covered.

Closes #7764

(Supersedes #7834 and #7846. #7834 was gate-closed on a base conflict — the bin migration removed the committed loopover-mcp.js from main, making its .js edit a modify/delete conflict; this branch is .ts-only. #7846 was gate-closed because the new tool takes the registered count 79 → 80, which the mcp-tool-rename-aliases invariant asserts — now updated.)

…lan_repo_issues

loopover_plan_repo_issues (generateIssuePlanDrafts) shipped only as a remote MCP
tool and never got the REST + CLI + local-stdio mirror surfaces its repo-scoped,
requireRepoManageAccess-gated siblings all have. Mirrors
loopover_generate_contributor_issue_drafts exactly: a POST
/v1/repos/:owner/:repo/issue-plan-drafts/generate route (same gate), a
maintain plan-issues CLI command calling it, and a loopover_plan_repo_issues
stdio tool. generateIssuePlanDrafts and the remote tool are unchanged.

Closes JSONbored#7764
@xfodev
xfodev requested a review from JSONbored as a code owner July 21, 2026 15:12
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.25%. Comparing base (fa21f3e) to head (4cebe58).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7856      +/-   ##
==========================================
- Coverage   91.40%   83.25%   -8.15%     
==========================================
  Files         730       91     -639     
  Lines       74763    26027   -48736     
  Branches    22815     5325   -17490     
==========================================
- Hits        68335    21669   -46666     
+ Misses       5385     4051    -1334     
+ Partials     1043      307     -736     
Flag Coverage Δ
shard-1 18.51% <6.12%> (-37.75%) ⬇️
shard-2 33.03% <57.14%> (-18.10%) ⬇️
shard-3 40.36% <48.97%> (-13.49%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/loopover-mcp/bin/loopover-mcp.ts 13.20% <100.00%> (+13.20%) ⬆️
src/api/routes.ts 95.16% <100.00%> (+0.04%) ⬆️
src/openapi/spec.ts 99.48% <100.00%> (+<0.01%) ⬆️

... and 639 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 21, 2026
@loopover-orb

loopover-orb Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-21 15:24:08 UTC

10 files · 1 AI reviewer · no blockers · CI failing · blocked

🛑 Suggested Action - Fix Blockers

Review summary
This PR adds a REST route, CLI subcommand, and stdio tool for `loopover_plan_repo_issues`, mirroring the existing `contributor-issue-drafts` pattern closely (same auth gate ordering, same create-safety guard shape, same file-layout conventions). The `isProcessEntrypoint()` guard is a reasonable, minimally invasive way to make the CLI dispatcher unit-testable without subprocess spawn, and it correctly gates both the CLI dispatch and the stdio `server.connect()` so an in-process import can't hijack test argv or bind stdin. The route wiring (`requireAppRole` → `requireSessionRepoAccess` → create-safety check → `requireRepoWriteAccess`) matches the sibling route exactly, and the CLI's `--create` maps to the literal `{create:true, dryRun:false}` shape the route's guard demands. The tool-count bump (79→80) and OpenAPI/spec additions are consistent and covered by the added tests.

Nits — 6 non-blocking
  • The 'generic_secret_assignment' flag on test/unit/mcp-cli-plan-issues.test.ts:31 is almost certainly a false positive — it's `process.env.LOOPOVER_API_TOKEN = "in-process-token"`, a hardcoded test fixture token, not a real credential; still worth a quick look to confirm nothing sensitive slipped in.
  • packages/loopover-mcp/bin/loopover-mcp.ts: the new `planRepoIssuesShape`/CLI `--limit` cap of 10 (vs. the sibling `generate-issue-drafts`' 20) is explained in the comment (LLM cost) but consider extracting a shared named constant instead of repeating the literal `10`/`2000` across routes.ts and the bin file.
  • test/unit/routes-issue-plan-draft.test.ts and mcp-cli-plan-issues.test.ts are thorough but somewhat verbose given how closely they mirror the sibling contributor-issue-draft tests — acceptable given the coverage bar, but worth noting for future reviewers scanning for genuine novel logic.
  • The `any` annotations at loopover-mcp.ts:2651/3282/3527 are consistent with existing patterns in this file (loosely-typed CLI options plumbing) but still a nit worth tightening opportunistically.
  • Consider factoring the repeated `goal`/`limit` schema shape (z.string().min(1).max(2000), limit min(1).max(10).optional().default(5)) shared between src/api/routes.ts's issuePlanDraftGenerateSchema and the bin's planRepoIssuesShape into one exported source of truth to prevent future drift between the two independently-hand-synced schemas.
  • Possible secret-shaped assignment in the diff (generic_secret_assignment) — Verify the value is not a real credential.

CI checks failing

  • validate
  • validate-tests-merge

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #7764
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low 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: 80 registered-repo PR(s), 46 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor xfodev; Gittensor profile; 80 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds all three required mirror surfaces: a REST route `/v1/repos/:owner/:repo/issue-plan-drafts/generate` in routes.ts gated by requireAppRole/requireSessionRepoAccess/requireRepoWriteAccess mirroring the contributor-issue-drafts route, a `maintain plan-issues` CLI command, and a `loopover_plan_repo_issues` registerStdioTool block proxying the new route, plus corresponding regression test

Review context
  • Author: xfodev
  • 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: 80 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
diff /
diff /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy · Diff highlights exactly what changed.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)
after / (scroll)
after / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb

loopover-orb Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

This pull request changes UI/visual code but its screenshot evidence is incomplete. Every required viewport × theme combination needs its own before/after image pair in a labeled table row (e.g. "Desktop · Light | before | after"). Still missing: Desktop · Dark, Tablet · Dark, Mobile · Dark.

Please resubmit with the remaining rows filled in.

See https://github.com/JSONbored/loopover/blob/main/.claude/skills/contributing-to-loopover/SKILL.md for the exact format and examples. This is an automated maintenance action.

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loopover_plan_repo_issues has no REST route, CLI command, or local stdio MCP tool

1 participant