Skip to content

feat(api): add POST /v1/repos/:owner/:repo/repo-docs/refresh + CLI mirror - #6973

Merged
loopover-orb[bot] merged 3 commits into
JSONbored:mainfrom
galuis116:feat/refresh-repo-docs-rest-cli-mirror
Jul 17, 2026
Merged

feat(api): add POST /v1/repos/:owner/:repo/repo-docs/refresh + CLI mirror#6973
loopover-orb[bot] merged 3 commits into
JSONbored:mainfrom
galuis116:feat/refresh-repo-docs-rest-cli-mirror

Conversation

@galuis116

Copy link
Copy Markdown
Contributor

Summary

  • The MCP tool loopover_refresh_repo_docs (opens or finds the already-open AGENTS.md/CLAUDE.md generation PR via performRepoDocRefresh) had no REST or CLI counterpart.
  • Adds POST /v1/repos/:owner/:repo/repo-docs/refresh in src/api/routes.ts, gated the same way as the pending-actions decision route (requireRepoWriteAccess — real per-repo write access, not just maintainer-data visibility).
  • Adds the path to the session coarse-path allowlist (canSessionAccessPath/isRepoDocRefreshPath) — without this, a browser maintainer session would 403 with insufficient_role at the global gate before ever reaching the route's own write-access check.
  • Adds a maintain refresh-docs CLI subcommand (packages/loopover-mcp/bin/loopover-mcp.js), proxying the new route.
  • Both the REST route and the MCP tool trim the runner's internal claudeMode field from the response, so all three surfaces (MCP/REST/CLI) expose the identical public shape.
  • Registers RepoDocRefreshResultSchema and the route in the OpenAPI spec; regenerated apps/loopover-ui/public/openapi.json.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves.

Closes #6743

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck — the whole-repo tsc --noEmit reliably OOMs on this shared, memory-constrained sandbox regardless of what changed (confirmed via a clean-checkout rerun); relied on npm run build --workspace @loopover/engine (passed) plus the full targeted vitest run below as the local proxy, and CI's isolated runner for the authoritative tsc --noEmit.
  • npm run test:coverage — full targeted vitest run: test/unit/routes-repo-doc-refresh.test.ts (new, 3 tests), test/unit/mcp-refresh-repo-docs.test.ts (5, unmodified), test/unit/mcp-cli-maintain.test.ts (19, incl. 3 new refresh-docs cases), test/unit/mcp-cli-basics.test.ts (21, incl. the fixed PowerShell completion snapshot), test/unit/access-boundary.test.ts (9) — 94/94 passing.
  • npm run test:workers (not applicable — no Cloudflare Worker binding/queue changes)
  • npm run build:mcp / npm run test:mcp-pack (not applicable — no MCP server packaging changes)
  • npm run ui:openapi — regenerated (no drift this revision)
  • npm run ui:openapi:settings-parity — passed
  • npm run command-reference — ran; no drift
  • npm run ui:lint — 0 errors (only pre-existing unrelated warnings; this PR touches no apps/loopover-ui/** files)
  • npm audit --audit-level=moderate (no dependency changes in this PR)
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • The whole-repo npm run typecheck OOMs on this specific sandbox under current memory pressure (independently reproduced on a clean main checkout with no diff at all), so it was not run standalone; npm run build --workspace @loopover/engine plus the full targeted test run above stand in as the local proxy, and CI's isolated runner performs the real tsc --noEmit. npm run test:workers and the MCP packaging checks have no surface to exercise for a change scoped to one REST route + one CLI subcommand.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. This PR adds a new session-reachable maintainer route; test/unit/routes-repo-doc-refresh.test.ts covers the write-access-denied (403) path, and test/unit/access-boundary.test.ts continues to pass unmodified.
  • API/OpenAPI/MCP behavior is updated and tested where needed. New route registered in the OpenAPI spec; RepoDocRefreshResultSchema matches the trimmed response shape both mirrors actually return.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (N/A — no UI changes in this PR.)
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots. (N/A — this is a backend REST route + CLI subcommand with no UI surface.)
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes

  • A prior attempt at this same change (superseded by this PR) was auto-closed by CI: it missed updating a hand-maintained PowerShell-completion snapshot test (test/unit/mcp-cli-basics.test.ts) that hardcodes the full maintain subcommand list, so the new refresh-docs entry broke that assertion. Fixed here.
  • Also caught and fixed during testing: the new route wasn't initially reachable by a session-authenticated maintainer at all (insufficient_role from the global coarse-path allowlist, independent of the route's own per-repo write check), discovered only because the negative-path test exercised the real app.request(...) flow end-to-end rather than mocking the gate. Fixed by adding isRepoDocRefreshPath to canSessionAccessPath, mirroring the existing isRepoAgentAuditFeedPath/isRepoAgentPendingActionsPath precedent.

…rror

The MCP tool loopover_refresh_repo_docs (opens or finds the already-open
AGENTS.md/CLAUDE.md generation PR) had no REST or CLI counterpart. Adds
the write-access-gated REST route, a `maintain refresh-docs` CLI
subcommand, and admits the new path through the session coarse-path
allowlist so a browser maintainer session can actually reach it (the
route's own requireRepoWriteAccess still enforces real per-repo write
authority). Both mirrors trim the runner's internal claudeMode field the
same way the MCP tool's own response already does, keeping all three
surfaces' public shape identical.
@galuis116
galuis116 requested a review from JSONbored as a code owner July 17, 2026 16:57
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.71%. Comparing base (ad8536e) to head (d157001).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6973   +/-   ##
=======================================
  Coverage   93.71%   93.71%           
=======================================
  Files         687      687           
  Lines       68404    68415   +11     
  Branches    18730    18732    +2     
=======================================
+ Hits        64105    64116   +11     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.74% <36.36%> (-0.01%) ⬇️
shard-2 36.98% <27.27%> (+0.05%) ⬆️
shard-3 33.10% <100.00%> (+0.20%) ⬆️
shard-4 34.25% <36.36%> (+<0.01%) ⬆️
shard-5 31.89% <27.27%> (-0.01%) ⬇️
shard-6 45.75% <45.45%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
src/api/routes.ts 94.84% <100.00%> (+0.01%) ⬆️
src/openapi/schemas.ts 100.00% <100.00%> (ø)
src/openapi/spec.ts 99.46% <100.00%> (+<0.01%) ⬆️

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

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-17 17:09:55 UTC

9 files · 1 AI reviewer · no blockers · readiness 77/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR adds a REST route and CLI command mirroring the existing MCP tool loopover_refresh_repo_docs, gating it with requireRepoWriteAccess and the coarse-path session allowlist consistent with the existing pending-actions decision route pattern. The route correctly trims the runner's internal claudeMode field before returning, tests cover the opened/not-enabled/forbidden branches, and OpenAPI schema/spec/generated JSON are all updated in lockstep. The change is narrow, well-tested, and closes the linked issue #6743 as described.

Nits — 5 non-blocking
  • src/api/routes.ts: the comment block above the route is quite long (5 lines) relative to repo convention seen elsewhere in the diff; could be trimmed to the essential 'why' about the coarse-path allowlist.
  • test/unit/routes-repo-doc-refresh.test.ts relies on mocked getRepositoryCollaboratorPermission and fixture GitHub responses rather than exercising performRepoDocRefresh's own branch logic, but that's explicitly delegated to mcp-refresh-repo-docs.test.ts per the comment, which is reasonable.
  • The size-smell flags on routes.ts/loopover-mcp.js are pre-existing file sizes, not something this diff meaningfully worsens beyond the ~23 and ~13 line additions respectively.
  • Consider whether the /* v8 ignore next */ comment in src/api/routes.ts:2748 area is still accurate — confirm the auth middleware truly rejects unauthorized requests before this line is ever reached for coverage purposes.
  • No functional changes needed; the PR is a clean, config-consistent mirror of an existing pattern.

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 #6743
Related work ⚠️ 3 scoped overlaps 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: 1957 registered-repo PR(s), 1287 merged, 52 issue(s).
Contributor context ✅ Confirmed Gittensor contributor galuis116; Gittensor profile; 1957 PR(s), 52 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: galuis116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: JavaScript, Python, Dart, TypeScript, HTML, MDX, Rust, C++
  • Official Gittensor activity: 1957 PR(s), 52 issue(s).
  • Related work: Titles/paths share 7 meaningful terms. (PR #6967)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6744, issue #6743)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6743, issue #6747)
  • Additional title-only matches omitted; title-only overlap does not block.
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 3 steps in the Signals table above.
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 /
/ 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.

🟩 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 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.

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

@loopover-orb
loopover-orb Bot merged commit f1e9632 into JSONbored:main Jul 17, 2026
16 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 17, 2026
12 tasks
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.

REST + CLI mirror for loopover_refresh_repo_docs

1 participant