fix(codex): let plugin remove take the same spec plugin add and list use

This commit is contained in:
2026-09-08 21:37:41 +07:00
parent 56bf5bbf4d
commit 4d4449866b
2 changed files with 11 additions and 4 deletions
+5 -1
View File
@@ -52,7 +52,8 @@ describe("codex-cli argument validation", () => {
it("refuses a name that could be read as a flag or a path", async () => {
await assert.rejects(() => cli.mcpRemove("--force"), /name/i);
await assert.rejects(() => cli.mcpRemove("../../etc"), /name/i);
await assert.rejects(() => cli.pluginRemove("--force"), /name/i);
await assert.rejects(() => cli.pluginRemove("--force"), /spec/i);
await assert.rejects(() => cli.pluginRemove("../../etc"), /spec/i);
await assert.rejects(() => cli.marketplaceRemove("--force"), /name/i);
await assert.rejects(() => cli.mcpAdd({ name: "--force", command: "node" }), /name/i);
});
@@ -178,6 +179,9 @@ describe("codex-cli argv construction", () => {
assert.deepEqual(argvOf(await cli.pluginList()), ["plugin", "list", "--json"]);
assert.deepEqual(argvOf(await cli.pluginAdd("demo@sg")), ["plugin", "add", "demo@sg"]);
assert.deepEqual(argvOf(await cli.pluginRemove("demo")), ["plugin", "remove", "demo"]);
// `plugin list` reports marketplace-scoped plugins as `<name>@<marketplace>`,
// and `plugin add` takes that form — so remove has to accept it back.
assert.deepEqual(argvOf(await cli.pluginRemove("demo@sg")), ["plugin", "remove", "demo@sg"]);
} finally {
restore();
}
+6 -3
View File
@@ -239,9 +239,12 @@ async function pluginAdd(spec) {
return serialize(() => runCodex(["plugin", "add", s]));
}
async function pluginRemove(name) {
const n = assertName(name);
return serialize(() => runCodex(["plugin", "remove", n]));
async function pluginRemove(spec) {
// A spec, not a bare name: `plugin add` accepts `<name>@<marketplace>`, so
// `plugin remove` has to accept back what `plugin list` hands out.
// cc-plugin-cli.js validates every plugin verb the same way.
const s = assertPluginSpec(spec);
return serialize(() => runCodex(["plugin", "remove", s]));
}
// ── Marketplaces ───────────────────────────────────────────────────────