Skip to content

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

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#7870
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 (generateIssuePlanDrafts, src/services/issue-plan-draft.ts) 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:

  • REST routePOST /v1/repos/:owner/:repo/issue-plan-drafts/generate in src/api/routes.ts, calling generateIssuePlanDrafts (required goal from the body), gated identically to the contributor sibling, plus the canSessionAccessPath matcher and the OpenAPI registerPath.
  • CLI commandloopover-mcp maintain plan-issues, POSTing to the new route (dry-run by default; --create opts in).
  • Local stdio MCP toolloopover_plan_repo_issues, calling the new CLI logic.

generateIssuePlanDrafts, the remote tool, and src/services/** are unchanged. Rebased onto latest main (incl. #7705, which stopped committing the compiled bin .js — this PR touches only the tracked .ts).

Tests

  • test/unit/routes-issue-plan-draft.test.ts (mirrors the contributor route test): success, both auth-gate branches incl. write-granted create fall-through, invalid-JSON, invalid-body, explicit-create guard, cross-repo/forbidden — the new routes.ts lines are 100% statement + branch covered.
  • test/unit/mcp-cli-plan-issues.test.ts (mirrors mcp-generate-contributor-issue-drafts): in-process coverage of the CLI command + stdio tool via the .ts source (an entrypoint guard makes the bin importable without hijacking argv; subprocess launch unchanged).

UI Evidence

N/A — no UI/frontend changes. The only apps/loopover-ui/** change is the regenerated public/openapi.json API-spec artifact (required by ui:openapi:check for the new backend route); no rendered component, route, or style changes.

Validation

  • Root tsc --noEmit clean (my files); new route/CLI/stdio + mcp-cli-completion-spec (CLI_COMMAND_SPEC parity) tests pass; ui:openapi:check, command-reference:check, docs:drift-check green; OpenAPI regenerated; rebased on latest main.
  • Auth/CORS negative-path tests included (forbidden / cross-repo / unauthorized). No wallet/hotkey/trust-score/reward terms in route output or CLI text.

Closes #7764

…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:33
@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

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
527 2 525 0
View the top 2 failed test(s) by shortest run time
test/unit/mcp-tool-rename-aliases.test.ts > MCP legacy alias retirement (#4777) — discovery invariants > lists exactly 79 loopover_ tools and zero gittensory_-prefixed aliases
Stack Traces | 1.73s run time
AssertionError: expected 80 to be 79 // Object.is equality

- Expected
+ Received

- 79
+ 80

 ❯ test/unit/mcp-tool-rename-aliases.test.ts:76:28
test/unit/mcp-tool-rename-aliases.test.ts > MCP legacy alias retirement (#4777) — discovery invariants > `loopover-mcp tools --json` reports the same 79-tool count the live server registers
Stack Traces | 3.12s run time
AssertionError: expected 80 to be 79 // Object.is equality

- Expected
+ Received

- 79
+ 80

 ❯ test/unit/mcp-tool-rename-aliases.test.ts:97:27

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@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:48:00 UTC

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

🛑 Suggested Action - Fix Blockers

Review summary
This PR extends the existing loopover_plan_repo_issues MCP tool with a REST route, CLI subcommand (maintain plan-issues), and local stdio tool proxy, closely mirroring the already-shipped loopover_generate_contributor_issue_drists surfaces. The route's auth/gating (requireAppRole -> per-repo requireSessionRepoAccess -> explicit_create_requires_dry_run_false -> requireRepoWriteAccess) matches the sibling pattern, the CLI always forces dryRun:!create so a bare invocation can never write, and the new isProcessEntrypoint guard correctly lets tests import the bin module without hijacking argv or binding the shared stdio transport. Test coverage (routes-issue-plan-draft.test.ts, mcp-cli-plan-issues.test.ts, updated mcp-cli-maintain.test.ts) exercises both auth branches, the create-safety guard, and the CLI/stdio proxy paths against a real fixture server.

Nits — 6 non-blocking
  • The security-scan flag on test/unit/mcp-cli-plan-issues.test.ts:31 is a false positive — that's a hardcoded test fixture token ("in-process-token"), not a real secret.
  • The stdio tool's planRepoIssuesShape defaults dryRun:true/create:false independently, so a caller passing only create:true (without also flipping dryRun:false) will bounce off the route's explicit_create_requires_dry_run_false guard instead of the CLI's automatic dryRun:!create behavior — worth a one-line doc note on the asymmetry between the CLI (auto-derives dryRun) and the stdio tool (requires both flags explicitly).
  • New magic numbers (2000ms timeout, limit caps of 5/10, 2000-char goal max) are inline literals rather than named constants, consistent with existing style in this file but still worth a constant if these caps are meant to be tuned later.
  • No explicit 'Closes #NNNN' in the PR description despite the extensive inline 'loopover_plan_repo_issues has no REST route, CLI command, or local stdio MCP tool #7764' references — worth confirming the linked issue explicitly per repo convention.
  • Consider extracting the repeated goal-max-length (2000) and limit-max (10) into a shared constant between src/api/routes.ts and packages/loopover-mcp/bin/loopover-mcp.ts so the two schemas can't silently drift.
  • Possible secret-shaped assignment in the diff (generic_secret_assignment) — Verify the value is not a real credential.

CI checks failing

  • validate
  • validate-tests (2)

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 a POST /v1/repos/:owner/:repo/issue-plan-drafts/generate route calling generateIssuePlanDrafts gated the same way as the contributor sibling, a CLI 'maintain plan-issues' command in loopover-mcp.ts, and a registerStdioTool block for loopover_plan_repo_issues proxying the new route, matching the requested three-surface parity pattern.

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: JavaScript, TypeScript
  • 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 <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> 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.

@loopover-orb loopover-orb Bot closed this Jul 21, 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.

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