@@ -13,6 +13,7 @@ import {
1313} from './utils.js' ;
1414import type { Config } from '../config/config.js' ;
1515import type { ToolRegistry } from '../tools/tool-registry.js' ;
16+ import * as snippets from './snippets.js' ;
1617
1718vi . mock ( '../utils/paths.js' , ( ) => ( {
1819 homedir : vi . fn ( ) . mockReturnValue ( '/mock/home' ) ,
@@ -312,4 +313,40 @@ describe('applySubstitutions', () => {
312313 ) ;
313314 expect ( result ) . toBe ( 'A plain prompt with no variables.' ) ;
314315 } ) ;
316+
317+ it ( 'should preserve dollar sequences in ${AgentSkills} verbatim' , ( ) => {
318+ const result = applySubstitutions (
319+ 'Skills: ${AgentSkills} | Tail' ,
320+ mockConfig ,
321+ "echo $'a\\nb' and $$ and $& and $VAR" ,
322+ ) ;
323+ expect ( result ) . toBe ( "Skills: echo $'a\\nb' and $$ and $& and $VAR | Tail" ) ;
324+ } ) ;
325+
326+ it ( 'should preserve dollar sequences in ${SubAgents} verbatim' , ( ) => {
327+ vi . mocked ( snippets . renderSubAgents ) . mockReturnValueOnce (
328+ "echo $'a\\nb' and $$ and $&" ,
329+ ) ;
330+ const result = applySubstitutions (
331+ 'Agents: ${SubAgents} | Tail' ,
332+ mockConfig ,
333+ '' ,
334+ true ,
335+ ) ;
336+ expect ( result ) . toBe ( "Agents: echo $'a\\nb' and $$ and $& | Tail" ) ;
337+ } ) ;
338+
339+ it ( 'should preserve dollar sequences in ${AvailableTools} verbatim' , ( ) => {
340+ ( mockConfig as unknown as { toolRegistry : ToolRegistry } ) . toolRegistry = {
341+ getAllToolNames : vi . fn ( ) . mockReturnValue ( [ "echo $'a\\nb'" , '$$' , '$&' ] ) ,
342+ getAllTools : vi . fn ( ) . mockReturnValue ( [ ] ) ,
343+ } as unknown as ToolRegistry ;
344+
345+ const result = applySubstitutions (
346+ 'Tools: ${AvailableTools} | Tail' ,
347+ mockConfig ,
348+ '' ,
349+ ) ;
350+ expect ( result ) . toContain ( "- echo $'a\\nb'\n- $$\n- $& | Tail" ) ;
351+ } ) ;
315352} ) ;
0 commit comments