fix(managed): validate CLI type selections with the member contract (#2125)

`inspect-managed-members --type` accepted repeated and empty names that
the MCP contract rejects. The provider's contract parse then threw, and
the CLI reported execution_failure with advice to run `rea doctor`.
Reuse the contract's type_names schema so the CLI rejects them as a
validation error on --type.

Fixes #2121

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822andClaude Opus 5.5 authored and GitHub committed 2026-10-12 19:26:32 +08:00
1 parent 672bdea21f
commit 60259a91d9
2 files changed
+36 -6

No files matched your search

+4 -6
View File
@@ -16,6 +16,7 @@ import { logCliCommand } from "../cliLogging.js";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
import { registerProjectManagedApplicationGraph } from "./managedProjectGraphCommand.js";
import { managedMembersInputSchema } from "../contracts/managed/managedToolContracts.js";
export const registerManagedCommands = (
cli: CliInstance,
@@ -60,12 +61,9 @@ const registerInspectManagedMembers = (
path: z.string().describe("Managed PE executable or assembly path"),
}),
options: z.object({
type: z
.array(z.string())
.optional()
.describe(
"Inspect only members declared by this exact type full name, such as System.Threading.Monitor; a nested type is named by its bare name, which selects every nested type of that name (repeatable)",
),
type: managedMembersInputSchema.shape.type_names.describe(
"Inspect only members declared by this exact type full name, such as System.Threading.Monitor; a nested type is named by its bare name, which selects every nested type of that name (repeatable)",
),
}),
run: ({ args, options }) =>
logCliCommand(logger, "inspect-managed-members", () =>
+32
View File
@@ -177,6 +177,38 @@ cliTest(
},
);
cliTest(
"managed CLI rejects repeated or empty type selections as invalid input",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-managed-cli-types-");
const path = join(root, "fixture.dll");
await writeFile(path, buildManagedPeFixture());
for (const [types, message] of [
[["Fixture.Empty0", "Fixture.Empty0"], "must not repeat a name"],
[[""], ">=1 characters"],
] as const) {
const result = await cli.run({
arguments: [
"inspect-managed-members",
path,
...types.flatMap((type) => ["--type", type]),
"--json",
],
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "VALIDATION_ERROR",
fieldErrors: [
expect.objectContaining({
path: expect.stringMatching(/^type/u),
message: expect.stringContaining(message),
}),
],
});
}
},
);
cliTest(
"managed CLI bounds CIL claims by section virtual ranges",
async ({ cli }) => {