Files
IdeaSDK/scripts/check-manifest-tools.mjs
Blomios 8ff0f475de feat(sdk): contrat permissions.workspaceExec pour l'exécution contrôlée via l'hôte — #346
Cadrage capacités plugin SCM (#346): le manifeste plugin gagne
permissions.workspaceExec.allow — règles d'exécution contrôlée par l'hôte
(commande bare ASCII résolue sans shell, argv exact avec jeton `*` en
suffixe, cwd project-relative sûr, effect read/write/network/destructive,
64 règles max) — au lieu de lectures ad hoc du store interne .git.
Validation manifeste + exports runtime/index + docs README/manifest/
services + auto-check script étendu (règles valides acceptées, règles
unsafe rejetées).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-13 12:07:56 +02:00

62 lines
2.0 KiB
JavaScript

import assert from "node:assert/strict";
import { validatePluginManifest } from "../dist/index.js";
const base = {
ideaPluginManifestVersion: 1,
id: "dev.example.tools",
displayName: "Tools",
version: "1.0.0",
main: "dist/index.js",
trustLevel: "full",
capabilities: ["mcp"],
contributes: {
mcpServers: [
{
id: "server",
displayName: "Server",
command: "bin/server",
transport: "stdio"
}
]
}
};
assert.equal(validatePluginManifest(base).success, true, "tools metadata remains optional");
const withTools = structuredClone(base);
withTools.contributes.mcpServers[0].tools = [
{ name: "read_scene", description: "Read the active scene." },
{ name: "run_tests" }
];
assert.equal(validatePluginManifest(withTools).success, true, "valid tools metadata is accepted");
const duplicate = structuredClone(withTools);
duplicate.contributes.mcpServers[0].tools.push({ name: "read_scene" });
const duplicateResult = validatePluginManifest(duplicate);
assert.equal(duplicateResult.success, false, "duplicate tool metadata is rejected");
assert.ok(duplicateResult.errors.some((error) => error.includes("must be unique")));
const withWorkspaceExec = structuredClone(base);
withWorkspaceExec.permissions = {
workspaceExec: {
allow: [{ command: "tool", args: ["status", "*"], cwd: ".", effect: "read" }]
}
};
assert.equal(
validatePluginManifest(withWorkspaceExec).success,
true,
"valid generic workspace execution permissions are accepted"
);
for (const invalidRule of [
{ command: "sh -c", args: [], cwd: ".", effect: "read" },
{ command: "tool", args: ["sta*"], cwd: ".", effect: "read" },
{ command: "tool", args: [], cwd: "../outside", effect: "read" },
{ command: "tool", args: [], cwd: ".", effect: "git" }
]) {
const invalid = structuredClone(base);
invalid.permissions = { workspaceExec: { allow: [invalidRule] } };
assert.equal(validatePluginManifest(invalid).success, false, "unsafe workspace exec rule is rejected");
}