@@ -174,6 +174,12 @@ describe('AdditionalContextProvider', () => {
174174 workspaceFolder : mockWorkspaceFolder ,
175175 }
176176
177+ // Mock path.join to simulate Unix behavior
178+ sinon . stub ( path , 'join' ) . callsFake ( ( ...args ) => {
179+ // Simulate Unix path.join behavior
180+ return args . join ( '/' ) . replace ( / \\ / g, '/' )
181+ } )
182+
177183 const explicitContext = [
178184 {
179185 id : 'explicit-file' ,
@@ -208,6 +214,9 @@ describe('AdditionalContextProvider', () => {
208214 assert . strictEqual ( result . length , 1 )
209215 assert . strictEqual ( result [ 0 ] . name , 'Explicit File' )
210216 assert . strictEqual ( result [ 0 ] . pinned , false )
217+
218+ // Restore original path.join
219+ ; ( path . join as sinon . SinonStub ) . restore ( )
211220 } )
212221
213222 it ( 'should avoid duplicates between explicit and pinned context' , async ( ) => {
@@ -220,6 +229,12 @@ describe('AdditionalContextProvider', () => {
220229 workspaceFolder : mockWorkspaceFolder ,
221230 }
222231
232+ // Mock path.join to simulate Unix behavior
233+ sinon . stub ( path , 'join' ) . callsFake ( ( ...args ) => {
234+ // Simulate Unix path.join behavior
235+ return args . join ( '/' ) . replace ( / \\ / g, '/' )
236+ } )
237+
223238 const sharedContext = {
224239 id : 'shared-file' ,
225240 command : 'Shared File' ,
@@ -255,6 +270,9 @@ describe('AdditionalContextProvider', () => {
255270 assert . strictEqual ( result . length , 1 )
256271 assert . strictEqual ( result [ 0 ] . name , 'Shared File' )
257272 assert . strictEqual ( result [ 0 ] . pinned , false ) // Should be marked as explicit, not pinned
273+
274+ // Restore original path.join
275+ ; ( path . join as sinon . SinonStub ) . restore ( )
258276 } )
259277
260278 it ( 'should handle Active File context correctly' , async ( ) => {
@@ -358,6 +376,105 @@ describe('AdditionalContextProvider', () => {
358376 assert . strictEqual ( triggerContext . contextInfo ?. pinnedContextCount . codeContextCount , 1 )
359377 assert . strictEqual ( triggerContext . contextInfo ?. pinnedContextCount . promptContextCount , 1 )
360378 } )
379+
380+ it ( 'should handle Unix path separators correctly' , async ( ) => {
381+ const mockWorkspaceFolder = { uri : URI . file ( '/workspace' ) . toString ( ) , name : 'test' }
382+ sinon . stub ( workspaceUtils , 'getWorkspaceFolderPaths' ) . returns ( [ '/workspace' ] )
383+
384+ // Mock path.join to simulate Unix behavior
385+ sinon . stub ( path , 'join' ) . callsFake ( ( ...args ) => {
386+ // Simulate Unix path.join behavior
387+ return args . join ( '/' ) . replace ( / \\ / g, '/' )
388+ } )
389+
390+ const explicitContext = [
391+ {
392+ id : 'unix-prompt' ,
393+ command : 'Unix Prompt' ,
394+ label : 'file' as any ,
395+ route : [ '/Users/test/.aws/amazonq/prompts' , 'hello.md' ] ,
396+ } ,
397+ ]
398+
399+ fsExistsStub . callsFake ( ( path : string ) => path . includes ( '.amazonq/rules' ) )
400+ fsReadDirStub . resolves ( [ ] )
401+
402+ // Reset stub - return data for first call (explicit context), empty for second call (pinned context)
403+ getContextCommandPromptStub . reset ( )
404+ getContextCommandPromptStub . onFirstCall ( ) . resolves ( [
405+ {
406+ // promptContextCommands - explicit context
407+ name : 'Unix Prompt' ,
408+ content : 'content' ,
409+ filePath : '/Users/test/.aws/amazonq/prompts/hello.md' , // Proper Unix path
410+ relativePath : 'hello.md' ,
411+ startLine : 1 ,
412+ endLine : 10 ,
413+ } ,
414+ ] )
415+ getContextCommandPromptStub . onSecondCall ( ) . resolves ( [ ] ) // pinnedContextCommands - empty
416+
417+ const result = await provider . getAdditionalContext (
418+ { workspaceFolder : mockWorkspaceFolder } ,
419+ 'tab1' ,
420+ explicitContext
421+ )
422+ assert . strictEqual ( result . length , 1 )
423+ assert . strictEqual ( result [ 0 ] . name , 'Unix Prompt' )
424+
425+ // Restore original path.join
426+ ; ( path . join as sinon . SinonStub ) . restore ( )
427+ } )
428+
429+ it ( 'should handle Windows path separators correctly' , async ( ) => {
430+ const mockWorkspaceFolder = { uri : URI . file ( '/workspace' ) . toString ( ) , name : 'test' }
431+ sinon . stub ( workspaceUtils , 'getWorkspaceFolderPaths' ) . returns ( [ '/workspace' ] )
432+
433+ // Mock path.join to simulate Windows behavior
434+ const originalPathJoin = path . join
435+ sinon . stub ( path , 'join' ) . callsFake ( ( ...args ) => {
436+ // Simulate Windows path.join behavior
437+ return args . join ( '\\' ) . replace ( / \/ / g, '\\' )
438+ } )
439+
440+ const explicitContext = [
441+ {
442+ id : 'windows-prompt' ,
443+ command : 'Windows Prompt' ,
444+ label : 'file' as any ,
445+ route : [ 'C:\\Users\\test\\.aws\\amazonq\\prompts' , 'hello.md' ] ,
446+ } ,
447+ ]
448+
449+ fsExistsStub . callsFake ( ( path : string ) => path . includes ( '.amazonq/rules' ) )
450+ fsReadDirStub . resolves ( [ ] )
451+
452+ // Reset stub - return data for first call (explicit context), empty for second call (pinned context)
453+ getContextCommandPromptStub . reset ( )
454+ getContextCommandPromptStub . onFirstCall ( ) . resolves ( [
455+ {
456+ // promptContextCommands - explicit context
457+ name : 'Windows Prompt' ,
458+ content : 'content' ,
459+ filePath : 'C:\\Users\\test\\.aws\\amazonq\\prompts\\hello.md' , // Proper Windows path
460+ relativePath : 'hello.md' ,
461+ startLine : 1 ,
462+ endLine : 10 ,
463+ } ,
464+ ] )
465+ getContextCommandPromptStub . onSecondCall ( ) . resolves ( [ ] ) // pinnedContextCommands - empty
466+
467+ const result = await provider . getAdditionalContext (
468+ { workspaceFolder : mockWorkspaceFolder } ,
469+ 'tab1' ,
470+ explicitContext
471+ )
472+ assert . strictEqual ( result . length , 1 )
473+ assert . strictEqual ( result [ 0 ] . name , 'Windows Prompt' )
474+
475+ // Restore original path.join
476+ ; ( path . join as sinon . SinonStub ) . restore ( )
477+ } )
361478 } )
362479
363480 describe ( 'getFileListFromContext' , ( ) => {
0 commit comments