Skip to content

feat(api): REST + CLI mirror for loopover_intake_idea - #6916

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
lourincedaging0-commits:feat/rest-cli-intake-idea-6755
Jul 17, 2026
Merged

feat(api): REST + CLI mirror for loopover_intake_idea#6916
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
lourincedaging0-commits:feat/rest-cli-intake-idea-6755

Conversation

@lourincedaging0-commits

Copy link
Copy Markdown
Contributor

The loopover_intake_idea MCP tool (src/mcp/server.ts) is explicitly described as "deterministic and source-free" and is rate-limit-only gated, but has neither a REST route nor a CLI mirror — unlike its same-tier sibling loopover_check_slop_risk (/v1/lint/slop-risk + stdio tool), which has both.

Changes

  • POST /v1/loop/intake-idea — reproduces the tool's handler exactly: validate the submission, then assemble the task-graph from the optional caller-supplied decomposition (else the single-issue baseline), delegating to the same pure validateIdeaSubmission/buildTaskGraph and adding no logic of its own. Placed alongside its source-free /v1/loop/* and /v1/lint/* siblings.
  • loopover_intake_idea stdio tool — computed in-process from @loopover/engine, so idea intake works fully offline with no API round-trip (same posture as the check_slop_risk local mirror).
  • A malformed or empty submission returns the engine's actionable error list, not a silent failure — mirroring the existing find-opportunities route's semantic-validation shape (the payload, with 400).
  • Both surfaces mirror intakeIdeaShape verbatim, including its deliberate looseness, so the engine — not the schema — keeps owning the real bounds and error list. An out-of-range priority is still a string, so it reaches the engine and comes back as priority_invalid, exactly as on the tool.

Tests

  • test/unit/routes-intake-idea.test.ts — pins the ROUTE contract across all three arms: a valid submission returns the scored graph (single-issue baseline, or the supplied decomposition preserved in order); every engine-rejected shape (id_required, title_required, body_required, target_repo_required, target_repo_malformed, title_too_long, priority_invalid) returns the actionable list, with an empty submission reporting every missing field at once; schema-invalid and unparseable bodies are rejected before reaching the engine. Also asserts the maintainer-only gittensor:priority label is never emitted.
  • test/unit/mcp-cli-intake-idea-tool.test.ts — cross-surface PARITY: the stdio tool returns exactly what the pure bridge returns for identical input, proven offline against a black-holed API URL, including the error-list arm.
  • Tool-count invariant bumped 68 → 69 in the same commit.

Closes #6755

The loopover_intake_idea MCP tool (src/mcp/server.ts) is explicitly described as
deterministic and source-free and is rate-limit-only gated, but had neither a REST
route nor a CLI mirror -- unlike its same-tier sibling loopover_check_slop_risk,
which has both.

Add POST /v1/loop/intake-idea and register the matching in-process
loopover_intake_idea stdio tool, so idea intake is available over REST/CLI and
works fully offline. Both reproduce the tool's handler exactly: validate the
submission, then assemble the task-graph from the optional caller-supplied
decomposition (else the single-issue baseline), delegating to the same pure
validateIdeaSubmission/buildTaskGraph and adding no logic of their own. A
malformed or empty submission returns the engine's actionable error list rather
than a silent failure, mirroring the existing find-opportunities route's
semantic-validation shape.

Both surfaces mirror intakeIdeaShape verbatim, including its deliberate looseness,
so the engine -- not the schema -- keeps owning the real bounds and error list.

Closes JSONbored#6755
@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.70%. Comparing base (b1a2bbd) to head (efe8fff).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6916   +/-   ##
=======================================
  Coverage   93.70%   93.70%           
=======================================
  Files         685      685           
  Lines       68331    68340    +9     
  Branches    18723    18725    +2     
=======================================
+ Hits        64032    64041    +9     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.65% <22.22%> (-0.01%) ⬇️
shard-2 36.86% <22.22%> (+0.05%) ⬆️
shard-3 32.81% <100.00%> (+0.13%) ⬆️
shard-4 34.88% <22.22%> (+0.06%) ⬆️
shard-5 31.90% <22.22%> (-0.01%) ⬇️
shard-6 45.45% <22.22%> (-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.75% <100.00%> (+0.02%) ⬆️

@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 13:12:38 UTC

5 files · 1 AI reviewer · no blockers · readiness 82/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR adds a REST route (`POST /v1/loop/intake-idea`) and a stdio CLI mirror for the existing `loopover_intake_idea` MCP tool, following the exact same pattern already established for `loopover_check_slop_risk` and `buildResultsPayload` (#6752). Both new surfaces delegate to the same pure `validateIdeaSubmission`/`buildTaskGraph` functions from `@​loopover/engine`/`src/idea-intake`, add no new logic, and the zod schemas are verbatim (deliberately loose) mirrors of `intakeIdeaShape` in `src/mcp/server.ts`, preserving the engine as the source of truth for validation. Tests are thorough — they pin route/tool parity against the pure functions directly rather than hardcoding expected output, and the tool-count bump (68→69) is correctly updated in the alias-retirement test.

Nits — 4 non-blocking
  • The magic number `50` (max array length) is repeated four times across `loopover-mcp.js` and `routes.ts` without a shared named constant, unlike a single source of truth — consider exporting a `MAX_DECOMPOSITION_ITEMS` constant from `src/idea-intake` and importing it in both places.
  • `src/api/routes.ts:3341` uses `.catch(() => null)` for JSON parsing which is consistent with existing routes in this file, but worth confirming this pattern is intentional repo-wide rather than something to consolidate.
  • Export the `50` bound as a named constant from `src/idea-intake` (alongside `IDEA_TITLE_MAX_CHARS`) and reuse it in both `intakeIdeaShape` and `intakeIdeaSchema` to guarantee they can't drift.
  • Confirm the issue link (REST + CLI mirror for loopover_intake_idea #6755) fully scopes this work, since the external brief flags 'partial' issue coverage — worth a one-line confirmation from the author that CLI+REST parity is the complete ask.

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 #6755
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: 113 registered-repo PR(s), 55 merged, 5 issue(s).
Contributor context ✅ Confirmed Gittensor contributor lourincedaging0-commits; Gittensor profile; 113 PR(s), 5 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds POST /v1/loop/intake-idea delegating to validateIdeaSubmission/buildTaskGraph, a matching loopover_intake_idea stdio CLI tool computed in-process from the same engine functions, and unit tests (routes-intake-idea.test.ts, mcp-cli-intake-idea-tool.test.ts) that directly assert output parity between the REST and CLI surfaces for identical inputs, fulfilling all listed deliverables.

Review context
  • Author: lourincedaging0-commits
  • 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: 113 PR(s), 5 issue(s).
  • Related work: Titles/paths share 5 meaningful terms. (issue #6756)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6735, issue #6747)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6735, 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.

🟩 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 f1fb812 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_intake_idea

1 participant