Skip to content

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

Closed
galuis116 wants to merge 2 commits into
JSONbored:mainfrom
galuis116:feat/refresh-repo-docs-rest-cli-mirror
Closed

feat(api): add POST /v1/repos/:owner/:repo/repo-docs/refresh + CLI mirror#6971
galuis116 wants to merge 2 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. Caught by testing a real session request end-to-end rather than only unit-testing the route handler in isolation.
  • 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 — ran; passed
  • 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 (which exercises every changed file end-to-end and would fail on a real type error at the module-load boundary) as the local proxy, and CI's isolated runner for the authoritative tsc --noEmit.
  • npm run test:coverage — full vitest run of every touched/related test file: test/unit/routes-repo-doc-refresh.test.ts (new, 3 tests), test/unit/mcp-refresh-repo-docs.test.ts (5, unmodified — pins the underlying runner's behavior is untouched), test/unit/mcp-cli-maintain.test.ts (19, incl. 3 new refresh-docs cases), test/unit/access-boundary.test.ts (9, the coarse-path-allowlist regression suite) — 73/73 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 and committed
  • npm run ui:openapi:settings-parity — passed
  • npm run command-reference — ran; no drift
  • npm run ui:lint / npm run ui:typecheck — this PR only touches src/, packages/loopover-mcp/, and test/, no apps/loopover-ui/** surface; ran npm run ui:lint anyway as a sanity check (0 errors, only pre-existing unrelated warnings)
  • 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

  • Caught and fixed a real gap 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:43
@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 87.03%. Comparing base (4966070) to head (13ba666).

❗ There is a different number of reports uploaded between BASE (4966070) and HEAD (13ba666). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (4966070) HEAD (13ba666)
shard-6 1 0
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6971      +/-   ##
==========================================
- Coverage   93.71%   87.03%   -6.68%     
==========================================
  Files         686      686              
  Lines       68392    68403      +11     
  Branches    18730    18732       +2     
==========================================
- Hits        64093    59537    -4556     
- Misses       3302     7176    +3874     
- Partials      997     1690     +693     
Flag Coverage Δ
shard-1 43.75% <36.36%> (-0.01%) ⬇️
shard-2 36.92% <27.27%> (-0.01%) ⬇️
shard-3 33.07% <100.00%> (+0.27%) ⬆️
shard-4 33.85% <36.36%> (+<0.01%) ⬆️
shard-5 32.13% <27.27%> (-0.01%) ⬇️
shard-6 ?

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

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

... and 119 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 17, 2026
@loopover-orb

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-17 16:50:14 UTC

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

🛑 Suggested Action - Fix Blockers

Review summary
This PR adds a REST route (POST /v1/repos/:owner/:repo/repo-docs/refresh) and CLI mirror for the existing MCP tool loopover_refresh_repo_docs, wired through requireRepoWriteAccess and the session coarse-path allowlist, with matching OpenAPI schema/spec registration and tests covering opened, not-enabled, and forbidden-access cases plus CLI plain/json output parity. The wiring looks correct: the route trims claudeMode the same way the MCP tool does, the coarse-path allowlist addition is necessary (documented in the description as caught via end-to-end session testing) and matches the pattern of the existing pending-actions route, and the discriminated-union schema mirrors the runtime shape. The PR closes issue #6743 as required and stays narrowly scoped to this one feature mirror.

Nits — 5 non-blocking
  • src/api/routes.ts: the /* v8 ignore next */ comment on the gate-check line assumes auth middleware always rejects before reaching the handler — worth double-checking that assumption holds for every auth path (e.g. bearer token vs session cookie) since a future refactor could silently invalidate the ignore.
  • test/unit/support/mcp-cli-harness.ts: the repoDocRefresh fixture default duplicates the same literal PR/response shape used in mcp-cli-maintain.test.ts's first test — minor duplication but harmless.
  • src/openapi/spec.ts:714 introduces a bare 200 status code literal alongside the rest of the file's existing convention of inline literals, so this is consistent with existing style rather than a new smell.
  • Consider adding a short JSDoc-style note above isRepoDocRefreshPath referencing requireRepoWriteAccess explicitly (already done) — this is good practice already followed, no change needed.
  • If there's a shared helper for the openapi.json regeneration diff size, no action needed here since it's a generated artifact.

CI checks failing

  • validate
  • validate-tests (6)

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 · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds the REST route POST /v1/repos/:owner/:repo/repo-docs/refresh gated by requireRepoWriteAccess and calling performRepoDocRefresh, adds a maintain refresh-docs CLI subcommand mirroring it, and includes unit tests covering the route (open/reuse/not-enabled/403) and CLI (parity of opened/reused/not-opened outputs). This directly fulfills all stated deliverables including the parity test req

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 2 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 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (CI is failing (validate, validate-tests (6))). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

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

REST + CLI mirror for loopover_refresh_repo_docs

1 participant