Skip to content

feat(api): add GET /v1/repos/:owner/:repo/automation-state + CLI mirror - #6964

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/automation-state-route-6742
Jul 17, 2026
Merged

feat(api): add GET /v1/repos/:owner/:repo/automation-state + CLI mirror#6964
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/automation-state-route-6742

Conversation

@luciferlive112116

Copy link
Copy Markdown
Contributor

Summary

The MCP tool loopover_get_automation_state computes a derived view — mode / permissionReadiness / actingActionClasses / pendingActionCount — that GET /v1/repos/:owner/:repo/settings does not return (settings returns only the raw resolved row). It was reachable only over MCP; the CLI had write-side mirrors (maintain pause/resume/set-level) but no read-side counterpart.

This adds both halves the issue asks for:

  • GET /v1/repos/:owner/:repo/automation-state in src/api/routes.ts, maintainer-gated exactly like /settings.
  • maintain automation-state CLI subcommand proxying it.
  • Regenerated OpenAPI spec (AutomationState schema).

Single source of truth — the part worth reviewing

Rather than duplicate the computation into the route (which would drift from the MCP tool the moment either changed), I extracted it into src/services/automation-state.ts (buildAutomationState) and refactored the MCP tool to call it. So all three surfaces — REST, MCP, CLI — compute the derived view one way. The MCP tool's own test suite (mcp-automation-state.test.ts, 37 tests) passes unchanged against the refactor, which is the evidence the extraction preserved behavior exactly.

The service performs no authorization itself — every caller gates first (the route via requireRepoMaintainer, the MCP tool via its own requireRepoAccess), preserving the pre-refactor gating.

Tests

  • Route (integration, api.test.ts) — asserts 401 unauthenticated, 200 for a maintainer, and every derived field with its exact enum shape (mode, permissionReadiness). This is src/**, so it's under the 99% patch gate.
  • CLI (mcp-cli-maintain.test.ts) — drives the real CLI against a fixture, asserting the rendered summary + output parity (--json returns the same derived fields).
  • Completion spec, help text, and the pinned PowerShell completer assertion updated for the new subcommand.

Validation

  • Patch coverage 100%, measured from the v8 JSON report across every changed src/** file: automation-state.ts (9/9 stmts, 6/6 branches, 3/3 funcs), plus the route/refactor/openapi lines in routes.ts, server.ts, spec.ts, schemas.ts — zero uncovered, zero partial. The one structurally-unreachable line (if (gate instanceof Response) — the auth middleware rejects before the handler) carries the same /* v8 ignore next */ pragma its sibling routes use.
  • 144/144 pass across the integration + MCP + CLI suites this touches.
  • npm run typecheck — 0 · npm run ui:openapi:check (drift) — clean · ui:openapi:settings-parity — clean · eslint — 0/0 · node --check — ok · git diff --check — clean · rebased on latest main.

Deliberately does not touch mcp-tool-rename-aliases.test.ts: a maintain subcommand is not a registerStdioTool, so it doesn't change the pinned stdio tool count — avoiding the count-pin that has been a recurring base-conflict hotspot.

Scope & safety

  • Read-only GET + a shared read-only service. No write path, no new capability; the route exposes only what the MCP tool already did, under the same maintainer gate.
  • Regenerated openapi.json is committed (CI fails on drift); the spec adds one path + one named schema.
  • No secrets; no changelog/site//CNAME/lovable changes.

Closes #6742

…or (JSONbored#6742)

The derived automation view (mode / permissionReadiness / actingActionClasses /
pendingActionCount) that loopover_get_automation_state computes was reachable only over
MCP -- GET /settings returns just the raw resolved row. This adds the read-side REST
route and a `maintain automation-state` CLI subcommand, symmetric with the existing
write-side PUT /settings and maintain pause/resume/set-level.

The computation is extracted into src/services/automation-state.ts (buildAutomationState)
and the MCP tool refactored to call it, so the three surfaces share one implementation
and cannot drift. Route is maintainer-gated like /settings; OpenAPI spec regenerated
with an AutomationState schema.

Closes JSONbored#6742
@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 (484c9c8) to head (9e420c1).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6964   +/-   ##
=======================================
  Coverage   93.71%   93.71%           
=======================================
  Files         685      686    +1     
  Lines       68379    68392   +13     
  Branches    18730    18730           
=======================================
+ Hits        64080    64093   +13     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.75% <30.00%> (+<0.01%) ⬆️
shard-2 36.80% <20.00%> (+0.01%) ⬆️
shard-3 32.93% <30.00%> (+0.18%) ⬆️
shard-4 34.26% <30.00%> (-0.21%) ⬇️
shard-5 31.88% <20.00%> (-0.29%) ⬇️
shard-6 45.76% <100.00%> (+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.82% <100.00%> (+<0.01%) ⬆️
src/mcp/server.ts 96.28% <100.00%> (-0.02%) ⬇️
src/openapi/schemas.ts 100.00% <100.00%> (ø)
src/openapi/spec.ts 99.45% <100.00%> (+<0.01%) ⬆️
src/services/automation-state.ts 100.00% <100.00%> (ø)

@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 16:13:02 UTC

11 files · 1 AI reviewer · no blockers · readiness 80/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR extracts the derived automation-state computation from the MCP tool into a shared `buildAutomationState` service, then wires it up as a new maintainer-gated REST route, a CLI subcommand, and regenerated OpenAPI schema — a clean single-source-of-truth refactor. The MCP tool is refactored to call the shared function and its existing test suite passes unchanged, which is solid evidence the extraction preserved behavior. Tests cover the route (401/200 + full shape) and the CLI (plain + --json parity), and the completion spec/help text are updated consistently.

Nits — 5 non-blocking
  • src/openapi/schemas.ts: AutomationStateSchema uses z.record for autonomy while RepositorySettingsSchema likely has a more specific shape elsewhere — worth confirming they stay in parity if autonomy's shape ever changes.
  • packages/loopover-mcp/bin/loopover-mcp.js: the new automation-state branch duplicates the summary string already generated by automationStateSummary in src/services/automation-state.ts; consider having the API response include a pre-formatted summary or accept the duplication is intentional for CLI-side rendering.
  • src/mcp/server.ts: `return { summary: automationStateSummary(state), data: { ...state } }` spreads state into a plain object — fine, but a one-line comment already explains why, so this is just noting it's a reasonable pattern.
  • Consider whether AGENT_ACTION_CLASS_VALUES / AUTONOMY_LEVEL_VALUES in src/openapi/schemas.ts could import from the same source (AGENT_ACTION_CLASSES in settings/autonomy) instead of being redeclared as a parallel literal tuple, to avoid future drift between the runtime constant and the OpenAPI schema.
  • The route's `/* v8 ignore next */` comment for the auth-rejection branch is a reasonable pattern already used elsewhere in the file — no action needed.

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 #6742
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: 171 registered-repo PR(s), 103 merged, 28 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 171 PR(s), 28 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds GET /v1/repos/:owner/:repo/automation-state gated by requireRepoMaintainer, a maintain automation-state CLI subcommand mirroring it, and updates openapi.json/spec.ts with an AutomationState schema, plus unit/integration tests covering both surfaces.

Review context
  • Author: luciferlive112116
  • 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: 171 PR(s), 28 issue(s).
  • Related work: Titles/paths share 8 meaningful terms. (issue #6744, issue #6742)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6747, issue #6742)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6746, issue #6742)
  • 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 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 c566906 into JSONbored:main Jul 17, 2026
16 checks passed
This was referenced 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_get_automation_state

1 participant