Skip to content

Commit eb8baa4

Browse files
VoidChecksumVoidChecksum
andauthored
fix: strip shell comment lines before parsing claude_args (#1055)
shell-quote treats # as a shell comment character, swallowing all subsequent content including flags on new lines. Strip comment lines (lines starting with #) before passing input to shell-quote. Fixes #802 Co-authored-by: VoidChecksum <Admin@CyberNord>
1 parent f328a5c commit eb8baa4

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

base-action/src/parse-sdk-options.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ function mergeMcpConfigs(configValues: string[]): string {
7979
return JSON.stringify(merged);
8080
}
8181

82+
/**
83+
* Strip comment lines from a shell argument string.
84+
* Lines whose first non-whitespace character is `#` are removed entirely.
85+
* Inline `#` within a line (e.g. inside a quoted value) is left untouched
86+
* because shell-quote handles quoting — we only need to remove full comment lines
87+
* before shell-quote sees them.
88+
*/
89+
function stripShellComments(input: string): string {
90+
return input
91+
.split("\n")
92+
.filter((line) => !line.trim().startsWith("#"))
93+
.join("\n");
94+
}
95+
8296
/**
8397
* Parse claudeArgs string into extraArgs record for SDK pass-through
8498
* The SDK/CLI will handle --mcp-config, --json-schema, etc.
@@ -92,7 +106,7 @@ function parseClaudeArgsToExtraArgs(
92106
if (!claudeArgs?.trim()) return {};
93107

94108
const result: Record<string, string | null> = {};
95-
const args = parseShellArgs(claudeArgs).filter(
109+
const args = parseShellArgs(stripShellComments(claudeArgs)).filter(
96110
(arg): arg is string => typeof arg === "string",
97111
);
98112

base-action/test/parse-sdk-options.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,42 @@ describe("parseSdkOptions", () => {
313313
});
314314
});
315315

316+
describe("shell comment stripping", () => {
317+
test("should parse flags before and after a comment line", () => {
318+
const options: ClaudeOptions = {
319+
claudeArgs: "--model 'claude-haiku'\n# comment\n--allowed-tools 'Edit'",
320+
};
321+
322+
const result = parseSdkOptions(options);
323+
324+
expect(result.sdkOptions.extraArgs?.["model"]).toBe("claude-haiku");
325+
expect(result.sdkOptions.allowedTools).toEqual(["Edit"]);
326+
});
327+
328+
test("should parse flags correctly when no comments are present", () => {
329+
const options: ClaudeOptions = {
330+
claudeArgs: "--model 'claude-haiku'",
331+
};
332+
333+
const result = parseSdkOptions(options);
334+
335+
expect(result.sdkOptions.extraArgs?.["model"]).toBe("claude-haiku");
336+
});
337+
338+
test("should not strip inline # that appears inside a quoted value", () => {
339+
const options: ClaudeOptions = {
340+
claudeArgs: "--model 'claude-haiku' --prompt 'use color #ff0000'",
341+
};
342+
343+
const result = parseSdkOptions(options);
344+
345+
expect(result.sdkOptions.extraArgs?.["model"]).toBe("claude-haiku");
346+
expect(result.sdkOptions.extraArgs?.["prompt"]).toBe(
347+
"use color #ff0000",
348+
);
349+
});
350+
});
351+
316352
describe("environment variables passthrough", () => {
317353
test("should include OTEL environment variables in sdkOptions.env", () => {
318354
// Set up test environment variables

0 commit comments

Comments
 (0)