Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"packages/loopover-mcp": "3.15.2",
"packages/loopover-engine": "3.15.3",
"packages/loopover-engine": "3.16.0",
"packages/loopover-miner": "3.15.2",
"packages/loopover-ui-kit": "1.2.0"
}
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
"changelog:check:mcp": "node --experimental-strip-types scripts/check-changelog.ts --mcp",
"mcp:release-due": "tsx scripts/check-mcp-release-due.ts --json",
"mcp:release-candidate": "tsx scripts/check-mcp-release-candidate.ts",
"typecheck": "tsc --noEmit",
"typecheck": "npm run typecheck:root && npm run typecheck:packages",
"typecheck:root": "tsc --noEmit",
"typecheck:packages": "tsc -p packages/loopover-contract/tsconfig.json --noEmit && tsc -p packages/loopover-mcp/tsconfig.json --noEmit && tsc -p packages/loopover-miner/tsconfig.json --noEmit",
"check-node-version": "node --experimental-strip-types scripts/check-node-version.ts",
"pretest": "npm run check-node-version",
"test": "vitest run",
Expand Down
20 changes: 17 additions & 3 deletions packages/loopover-contract/src/tools/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,17 @@ export const ListPendingActionsOutput = z.looseObject({
status: z.string().optional(),
pendingActions: z.array(pendingActionEntrySchema).optional(),
});
/**
* The stdio server's narrowed variant, DERIVED rather than restated.
*
* `GET /agent/pending-actions` takes no query parameters and hardcodes status "pending", so the
* stdio server cannot honour the filter its remote counterpart offers. An agent reads the published
* schema to decide what to send, so advertising a filter that silently does nothing is worse than
* not advertising it -- this is the one place in the migration where a server deliberately serves
* LESS than the contract, and it says so in code rather than by omission.
*/
export const ListPendingActionsStdioInput = ListPendingActionsInput.omit({ status: true });

export const listPendingActionsTool = defineTool({
name: "loopover_list_pending_actions",
title: "List pending actions",
Expand Down Expand Up @@ -644,12 +655,15 @@ export const GetAgentAuditFeedOutput = z.looseObject({
repoFullName: z.string().optional(),
events: z
.array(
// `.nullish()`, not `.nullable()`: the REST route this proxies OMITS these for an event that
// has none rather than sending an explicit null, and modelling them as merely nullable made
// every real audit feed fail output validation (#9537).
z.looseObject({
eventType: z.string(),
pullNumber: z.number().nullable(),
pullNumber: z.number().nullish(),
outcome: z.string(),
actor: z.string().nullable(),
detail: z.string().nullable(),
actor: z.string().nullish(),
detail: z.string().nullish(),
createdAt: z.string(),
}),
)
Expand Down
4 changes: 4 additions & 0 deletions packages/loopover-contract/src/tools/branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ const validationEntrySchema = z.strictObject({
// ── preflight local diff (input + output: no transform) ─────────────────────────────────────────

export const PreflightLocalDiffInput = PreflightPrInput.extend({
// #9537: `cwd`/`baseRef` name a checkout only the stdio server can read; the remote server
// ignores them. Widening the shared input is the safe direction.
cwd: z.string().optional(),
baseRef: z.string().optional(),
changedLineCount: z.number().int().min(0).optional(),
testFiles: z.array(z.string().max(PREFLIGHT_LIMITS.changedFileChars)).max(PREFLIGHT_LIMITS.changedFiles).optional(),
commitMessage: z.string().max(PREFLIGHT_LIMITS.bodyChars).optional(),
Expand Down
38 changes: 36 additions & 2 deletions packages/loopover-contract/src/tools/discovery-utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,46 @@ export const validateConfigTool = defineTool({
output: ValidateConfigOutput,
});

export const LocalStatusInput = noInput;
/**
* A THIRD divergence, found while migrating the stdio server (#9537) -- one the issue did not name,
* because it is not a payload that drifted but two different tools that collided on one name:
*
* - the remote server answers "what does this MCP endpoint support" (reachability, the supported
* endpoint, the tool surface it advertises);
* - the stdio server answers "what is the state of THIS CLI on THIS machine" (api url, package
* version, token/session presence, workspace roots, and the local git checkout).
*
* Neither can answer the other's question -- the remote has no checkout to inspect, and the CLI has
* no endpoint surface to report -- so unlike get_repo_context and get_pr_reviewability there is no
* payload to converge on. The real fix is a rename, which breaks every caller of whichever side
* loses the name, so it is filed rather than done in flight. The union below keeps both wires
* working, gives both a validated schema instead of none, and keeps the collision visible.
*
* `cwd`/`baseRef`/`repoFullName` on the input are the stdio side's; the remote server ignores them.
* Widening an input is always the safe direction.
*/
export const LocalStatusInput = z.object({
cwd: z.string().optional(),
baseRef: z.string().optional(),
repoFullName: z.string().min(3).optional(),
});
export const LocalStatusOutput = z.looseObject({
// Remote fields.
apiAvailable: z.boolean().optional(),
sourceUploadDefault: z.boolean().optional(),
supportedEndpoint: z.string().optional(),
supportedTools: z.unknown().optional(),
// Shared.
sourceUploadDefault: z.boolean().optional(),
// stdio fields.
apiUrl: z.string().optional(),
package: z.looseObject({ name: z.string(), version: z.string() }).optional(),
hasToken: z.boolean().optional(),
profile: z.record(z.string(), z.unknown()).optional(),
authLogin: z.string().nullable().optional(),
sessionExpiresAt: z.string().nullable().optional(),
sourceUploadSupported: z.boolean().optional(),
workspaceRoots: z.unknown().optional(),
git: z.record(z.string(), z.unknown()).optional(),
});
export const localStatusTool = defineTool({
name: "loopover_local_status",
Expand Down
41 changes: 41 additions & 0 deletions packages/loopover-contract/src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,27 @@ import {
agentStartRunTool,
agentGetRunTool,
} from "./agent.js";
import {
preflightCurrentBranchTool,
previewCurrentBranchScoreTool,
rankLocalNextActionsTool,
explainLocalBlockersTool,
remediationPlanTool,
preparePrPacketTool,
agentPreparePrPacketTool,
reviewPrBeforePushTool,
draftPrBodyTool,
compareLocalVariantsTool,
previewLocalPrScoreTool,
getEligibilityPlanTool,
comparePrVariantsTool,
feasibilityGateTool,
markNotificationsReadTool,
watchIssuesTool,
findOpportunitiesTool,
retrieveIssueContextTool,
simulateOpenPrPressureTool,
} from "./local-branch.js";

/**
* #9517's pilot batch, the full AMS miner server (#9536, all 11 tools), and the remote server's
Expand Down Expand Up @@ -218,6 +239,25 @@ export const TOOL_CONTRACTS: readonly ToolContract[] = [
agentExplainNextActionTool,
agentStartRunTool,
agentGetRunTool,
preflightCurrentBranchTool,
previewCurrentBranchScoreTool,
rankLocalNextActionsTool,
explainLocalBlockersTool,
remediationPlanTool,
preparePrPacketTool,
agentPreparePrPacketTool,
reviewPrBeforePushTool,
draftPrBodyTool,
compareLocalVariantsTool,
previewLocalPrScoreTool,
getEligibilityPlanTool,
comparePrVariantsTool,
feasibilityGateTool,
markNotificationsReadTool,
watchIssuesTool,
findOpportunitiesTool,
retrieveIssueContextTool,
simulateOpenPrPressureTool,
minerPingTool,
minerPortfolioDashboardTool,
minerManageStatusTool,
Expand Down Expand Up @@ -259,4 +299,5 @@ export * from "./review.js";
export * from "./branch.js";
export * from "./discovery-utility.js";
export * from "./agent.js";
export * from "./local-branch.js";
export * from "./miner.js";
Loading
Loading