diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 4a8ce1c1..fe2ae5e1 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed +- Fixed prompt-template defaults for all arguments (`${@:-default}` and `${ARGUMENTS:-default}`) ([#6695](https://github.com/earendil-works/pi/issues/6695)). - Fixed obsolete custom UI, custom tool, and custom editor examples in the extension documentation ([#6735](https://github.com/earendil-works/pi/issues/6735)). - Fixed Kimi Coding sessions to show API-equivalent implied costs with the subscription indicator. - Fixed OpenAI Responses early stream endings to trigger automatic retry instead of ending the agent run ([#6727](https://github.com/earendil-works/pi/issues/6727)). diff --git a/packages/coding-agent/docs/prompt-templates.md b/packages/coding-agent/docs/prompt-templates.md index d8990bea..073b9f00 100644 --- a/packages/coding-agent/docs/prompt-templates.md +++ b/packages/coding-agent/docs/prompt-templates.md @@ -69,6 +69,7 @@ Templates support positional arguments, defaults, and simple slicing: - `$1`, `$2`, ... positional args - `$@` or `$ARGUMENTS` for all args joined - `${1:-default}` uses arg 1 when present/non-empty, otherwise `default` +- `${@:-default}` or `${ARGUMENTS:-default}` uses all arguments when present/non-empty, otherwise `default` - `${@:N}` for args from the Nth position (1-indexed) - `${@:N:L}` for `L` args starting at N diff --git a/packages/coding-agent/src/core/prompt-templates.ts b/packages/coding-agent/src/core/prompt-templates.ts index 6b5b1e24..e0fe89e5 100644 --- a/packages/coding-agent/src/core/prompt-templates.ts +++ b/packages/coding-agent/src/core/prompt-templates.ts @@ -60,6 +60,7 @@ export function parseCommandArgs(argsString: string): string[] { * - $1, $2, ... for positional args * - $@ and $ARGUMENTS for all args * - ${N:-default} for positional arg N with default when missing/empty + * - ${@:-default} and ${ARGUMENTS:-default} for all args with a default when empty * - ${@:N} for args from Nth onwards (bash-style slicing) * - ${@:N:L} for L args starting from Nth * @@ -70,11 +71,11 @@ export function substituteArgs(content: string, args: string[]): string { const allArgs = args.join(" "); return content.replace( - /\$\{(\d+):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g, - (_match, defaultNum, defaultValue, sliceStart, sliceLength, simple) => { - if (defaultNum) { - const index = parseInt(defaultNum, 10) - 1; - const value = args[index]; + /\$\{(\d+|ARGUMENTS|@):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g, + (_match, defaultTarget, defaultValue, sliceStart, sliceLength, simple) => { + if (defaultTarget) { + const value = + defaultTarget === "@" || defaultTarget === "ARGUMENTS" ? allArgs : args[parseInt(defaultTarget, 10) - 1]; return value ? value : defaultValue; } diff --git a/packages/coding-agent/test/prompt-templates.test.ts b/packages/coding-agent/test/prompt-templates.test.ts index 681a7c62..97bfe985 100644 --- a/packages/coding-agent/test/prompt-templates.test.ts +++ b/packages/coding-agent/test/prompt-templates.test.ts @@ -199,6 +199,15 @@ describe("substituteArgs - positional defaults", () => { expect(substituteArgs(`List exactly \${1:-7} next steps`, [])).toBe("List exactly 7 next steps"); }); + test("should support defaults for all arguments", () => { + const template = `\${@:-default}\n\${ARGUMENTS:-default}`; + + expect(substituteArgs(template, [])).toBe("default\ndefault"); + expect(substituteArgs(template, ["This", "would", "be", "the", "arguments"])).toBe( + "This would be the arguments\nThis would be the arguments", + ); + }); + test("should use positional arg when present", () => { expect(substituteArgs(`List exactly \${1:-7} next steps`, ["3"])).toBe("List exactly 3 next steps"); });