11// noinspection ES6RedundantAwait
22
3- import { describe , expect , it , vi , beforeEach } from 'vitest' ;
3+ import { beforeEach , describe , expect , it , vi } from 'vitest' ;
44import type { CodexAuthRequest } from "../../CodexAuthMethod" ;
55import type * as acp from "@agentclientprotocol/sdk" ;
6- import { createTestFixture , createCodexMockTestFixture , createTestSessionState , type TestFixture } from "../acp-test-utils" ;
6+ import {
7+ createCodexMockTestFixture ,
8+ createTestFixture ,
9+ createTestSessionState ,
10+ type TestFixture
11+ } from "../acp-test-utils" ;
712import type { ServerNotification } from "../../app-server" ;
813import type { SessionState } from "../../CodexAcpServer" ;
914import { AgentMode } from "../../AgentMode" ;
10- import type { ListMcpServerStatusResponse , Model , SkillsListResponse , TurnStartParams } from "../../app-server/v2" ;
15+ import type { Model , TurnStartParams } from "../../app-server/v2" ;
1116import type { RateLimitsMap } from "../../RateLimitsMap" ;
1217import { ModelId } from "../../ModelId" ;
1318
@@ -736,28 +741,25 @@ describe('ACP server test', { timeout: 40_000 }, () => {
736741 } ) ;
737742
738743 it ( 'handles logout command' , async ( ) => {
739- const mockFixture = createCodexMockTestFixture ( ) ;
740- const codexAcpAgent = mockFixture . getCodexAcpAgent ( ) ;
741-
742- const sessionState : SessionState = createTestSessionState ( ) ;
744+ const codexAcpAgent = fixture . getCodexAcpAgent ( ) ;
745+ await codexAcpAgent . initialize ( { protocolVersion : 1 } ) ;
743746
744- const logoutSpy = vi . spyOn ( mockFixture . getCodexAcpClient ( ) , "logout" ) . mockResolvedValue ( ) ;
747+ fixture . getCodexAcpClient ( ) . authRequired = vi . fn ( ) . mockResolvedValue ( false ) ;
745748
746- // @ts -expect-error - exercising private helper
747- const handled = await codexAcpAgent . availableCommands . handleCommand ( { name : "logout" , input : null } , sessionState ) ;
749+ const newSessionResponse = await codexAcpAgent . newSession ( { cwd : "" , mcpServers : [ ] } ) ;
748750
749- expect ( handled ) . toBe ( true ) ;
750- expect ( logoutSpy ) . toHaveBeenCalledTimes ( 1 ) ;
751- await expect ( mockFixture . getAcpConnectionDump ( [ ] ) ) . toMatchFileSnapshot ( "data/command-logout.json" ) ;
751+ fixture . clearAcpConnectionDump ( ) ;
752+ const prompt : acp . ContentBlock [ ] = [ { type : "text" , text : "/logout " } ] ;
753+ await codexAcpAgent . prompt ( { sessionId : newSessionResponse . sessionId , prompt : prompt } ) ;
754+ await expect ( fixture . getAcpConnectionDump ( [ "sessionId" ] ) ) . toMatchFileSnapshot ( "data/command-logout.json" ) ;
752755 } ) ;
753756
754757 it ( 'handles skills command' , async ( ) => {
755- const mockFixture = createCodexMockTestFixture ( ) ;
756- const codexAcpAgent = mockFixture . getCodexAcpAgent ( ) ;
757-
758- const sessionState : SessionState = createTestSessionState ( ) ;
758+ const codexAcpAgent = fixture . getCodexAcpAgent ( ) ;
759+ await codexAcpAgent . initialize ( { protocolVersion : 1 } ) ;
759760
760- const skillsResponse : SkillsListResponse = {
761+ fixture . getCodexAcpClient ( ) . authRequired = vi . fn ( ) . mockResolvedValue ( false ) ;
762+ vi . spyOn ( fixture . getCodexAcpClient ( ) , "listSkills" ) . mockResolvedValue ( {
761763 data : [ {
762764 cwd : "/workspace" ,
763765 skills : [
@@ -766,29 +768,28 @@ describe('ACP server test', { timeout: 40_000 }, () => {
766768 ] ,
767769 errors : [ ]
768770 } ]
769- } ;
770- const skillsSpy = vi . spyOn ( mockFixture . getCodexAcpClient ( ) , "listSkills" ) . mockResolvedValue ( skillsResponse ) ;
771+ } ) ;
771772
772- // @ts -expect-error - exercising private helper
773- const handled = await codexAcpAgent . availableCommands . handleCommand ( { name : "skills" , input : null } , sessionState ) ;
773+ const newSessionResponse = await codexAcpAgent . newSession ( { cwd : "" , mcpServers : [ ] } ) ;
774774
775- expect ( handled ) . toBe ( true ) ;
776- expect ( skillsSpy ) . toHaveBeenCalledTimes ( 1 ) ;
777- await expect ( mockFixture . getAcpConnectionDump ( [ ] ) ) . toMatchFileSnapshot ( "data/command-skills.json" ) ;
775+ fixture . clearAcpConnectionDump ( ) ;
776+ const prompt : acp . ContentBlock [ ] = [ { type : "text" , text : "/skills " } ] ;
777+ await codexAcpAgent . prompt ( { sessionId : newSessionResponse . sessionId , prompt : prompt } ) ;
778+
779+ await expect ( fixture . getAcpConnectionDump ( [ "sessionId" ] ) ) . toMatchFileSnapshot ( "data/command-skills.json" ) ;
778780 } ) ;
779781
780782 it ( 'handles mcp command' , async ( ) => {
781- const mockFixture = createCodexMockTestFixture ( ) ;
782- const codexAcpAgent = mockFixture . getCodexAcpAgent ( ) ;
783-
784- const sessionState : SessionState = createTestSessionState ( ) ;
783+ const codexAcpAgent = fixture . getCodexAcpAgent ( ) ;
784+ await codexAcpAgent . initialize ( { protocolVersion : 1 } ) ;
785785
786- const mcpResponse : ListMcpServerStatusResponse = {
786+ fixture . getCodexAcpClient ( ) . authRequired = vi . fn ( ) . mockResolvedValue ( false ) ;
787+ vi . spyOn ( fixture . getCodexAcpClient ( ) , "listMcpServers" ) . mockResolvedValue ( {
787788 data : [
788789 {
789790 name : "fs" ,
790- tools : { listFiles : { name : "listFiles" , inputSchema : { type : "object" } } } ,
791- resources : [ { name : "workspace" , uri : "file:///workspace" } ] ,
791+ tools : { listFiles : { name : "listFiles" , inputSchema : { type : "object" } } } ,
792+ resources : [ { name : "workspace" , uri : "file:///workspace" } ] ,
792793 resourceTemplates : [ ] ,
793794 authStatus : "bearerToken"
794795 } ,
@@ -801,15 +802,37 @@ describe('ACP server test', { timeout: 40_000 }, () => {
801802 }
802803 ] ,
803804 nextCursor : null
804- } ;
805- const mcpSpy = vi . spyOn ( mockFixture . getCodexAcpClient ( ) , "listMcpServers" ) . mockResolvedValue ( mcpResponse ) ;
805+ } ) ;
806806
807- // @ts -expect-error - exercising private helper
808- const handled = await codexAcpAgent . availableCommands . handleCommand ( { name : "mcp" , input : null } , sessionState ) ;
807+ const newSessionResponse = await codexAcpAgent . newSession ( { cwd : "" , mcpServers : [ ] } ) ;
808+
809+ fixture . clearAcpConnectionDump ( ) ;
810+ const prompt : acp . ContentBlock [ ] = [ { type : "text" , text : "/mcp " } ] ;
811+ await codexAcpAgent . prompt ( { sessionId : newSessionResponse . sessionId , prompt : prompt } ) ;
812+ await expect ( fixture . getAcpConnectionDump ( [ "sessionId" ] ) ) . toMatchFileSnapshot ( "data/command-mcp.json" ) ;
813+ } ) ;
814+
815+ it ( 'handles builtin slash command locally when prompt has attachments' , async ( ) => {
816+ const codexAcpAgent = fixture . getCodexAcpAgent ( ) ;
817+ await codexAcpAgent . initialize ( { protocolVersion : 1 } ) ;
818+
819+ fixture . getCodexAcpClient ( ) . authRequired = vi . fn ( ) . mockResolvedValue ( false ) ;
820+
821+ const newSessionResponse = await codexAcpAgent . newSession ( { cwd : "" , mcpServers : [ ] } ) ;
822+ const prompt : acp . ContentBlock [ ] = [
823+ { type : "text" , text : "/status " } ,
824+ {
825+ type : "resource_link" ,
826+ name : "editor.xml" ,
827+ uri : "file:///editor.xml" ,
828+ description : "File that is opened in the IDE and is currently viewed by the user" ,
829+ } ,
830+ ] ;
809831
810- expect ( handled ) . toBe ( true ) ;
811- expect ( mcpSpy ) . toHaveBeenCalledTimes ( 1 ) ;
812- await expect ( mockFixture . getAcpConnectionDump ( [ ] ) ) . toMatchFileSnapshot ( "data/command-mcp.json" ) ;
832+ fixture . clearAcpConnectionDump ( ) ;
833+ await codexAcpAgent . prompt ( { sessionId : newSessionResponse . sessionId , prompt : prompt } ) ;
834+ const transportDump = fixture . getAcpConnectionDump ( [ ] ) ;
835+ expect ( transportDump ) . contain ( `**Session:** \`${ newSessionResponse . sessionId } \`` ) ;
813836 } ) ;
814837
815838 const mockModels : Model [ ] = [
0 commit comments