Skip to content

Commit 17dcbd1

Browse files
fix: reject unexpected args on codemap skill and rule (#120)
Parse skill/rule argv like other subcommands; only bare verb or --help/-h succeed.
1 parent cf0532b commit 17dcbd1

4 files changed

Lines changed: 81 additions & 6 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stainless-code/codemap": patch
3+
---
4+
5+
Reject unexpected arguments on `codemap skill` and `codemap rule` instead of silently printing bundled content.

src/cli/cmd-skill.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,38 @@ import {
88
checkConsumerPointers,
99
EXPECTED_POINTER_VERSION,
1010
} from "../application/agent-content";
11+
import { parseAgentContentRest } from "./cmd-skill";
12+
13+
describe("parseAgentContentRest", () => {
14+
it("returns help on --help / -h", () => {
15+
expect(parseAgentContentRest(["skill", "--help"]).kind).toBe("help");
16+
expect(parseAgentContentRest(["rule", "-h"]).kind).toBe("help");
17+
});
18+
19+
it("runs with no extra arguments", () => {
20+
expect(parseAgentContentRest(["skill"])).toEqual({
21+
kind: "run",
22+
verb: "skill",
23+
});
24+
expect(parseAgentContentRest(["rule"])).toEqual({
25+
kind: "run",
26+
verb: "rule",
27+
});
28+
});
29+
30+
it("errors on unexpected flags or positionals", () => {
31+
const skillJson = parseAgentContentRest(["skill", "--json"]);
32+
expect(skillJson.kind).toBe("error");
33+
if (skillJson.kind === "error") {
34+
expect(skillJson.message).toContain("unexpected argument");
35+
}
36+
const ruleExtra = parseAgentContentRest(["rule", "extra"]);
37+
expect(ruleExtra.kind).toBe("error");
38+
if (ruleExtra.kind === "error") {
39+
expect(ruleExtra.message).toContain("unexpected argument");
40+
}
41+
});
42+
});
1143

1244
describe("agent content fetch surfaces", () => {
1345
it("assembles the skill from section files", () => {

src/cli/cmd-skill.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,37 @@ import type { AgentContentKind } from "../application/agent-content";
1313
*/
1414
export type { AgentContentKind };
1515

16+
export type AgentContentRest =
17+
| { kind: "help"; verb: AgentContentKind }
18+
| { kind: "run"; verb: AgentContentKind }
19+
| { kind: "error"; message: string };
20+
21+
/** Parse `codemap skill` / `codemap rule` argv after bootstrap strips global flags. */
22+
export function parseAgentContentRest(rest: string[]): AgentContentRest {
23+
const verb = rest[0];
24+
if (verb !== "skill" && verb !== "rule") {
25+
throw new Error(
26+
`parseAgentContentRest: expected first token skill|rule, got ${String(verb)}`,
27+
);
28+
}
29+
const args = rest.slice(1);
30+
if (args.length === 0) return { kind: "run", verb };
31+
if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
32+
return { kind: "help", verb };
33+
}
34+
const bad = args.find((a) => a !== "--help" && a !== "-h");
35+
if (bad !== undefined) {
36+
return {
37+
kind: "error",
38+
message: `codemap ${verb}: unexpected argument "${bad}". Run \`codemap ${verb} --help\` for usage.`,
39+
};
40+
}
41+
return {
42+
kind: "error",
43+
message: `codemap ${verb}: unexpected extra arguments. Run \`codemap ${verb} --help\` for usage.`,
44+
};
45+
}
46+
1647
export function printAgentContentCmdHelp(kind: AgentContentKind): void {
1748
const verb = kind;
1849
const source = `templates/agent-content/${kind}/*.md (assembled)`;

src/cli/main.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,21 @@ Copies bundled agent templates into .agents/ under the project root.
9898
}
9999

100100
if (rest[0] === "skill" || rest[0] === "rule") {
101-
const kind = rest[0];
102-
const { printAgentContentCmdHelp, runAgentContentCmd } =
103-
await import("./cmd-skill.js");
104-
if (rest.includes("--help") || rest.includes("-h")) {
105-
printAgentContentCmdHelp(kind);
101+
const {
102+
parseAgentContentRest,
103+
printAgentContentCmdHelp,
104+
runAgentContentCmd,
105+
} = await import("./cmd-skill.js");
106+
const parsed = parseAgentContentRest(rest);
107+
if (parsed.kind === "help") {
108+
printAgentContentCmdHelp(parsed.verb);
106109
return;
107110
}
108-
runAgentContentCmd(kind);
111+
if (parsed.kind === "error") {
112+
console.error(parsed.message);
113+
process.exit(1);
114+
}
115+
runAgentContentCmd(parsed.verb);
109116
return;
110117
}
111118

0 commit comments

Comments
 (0)