@@ -65,6 +65,43 @@ public void Upsert_WritesOverlayFileAndReturnsSavedAgent()
6565 Assert . True ( File . Exists ( Path . Combine ( fixture . AgentsDirectory , "custom-agent" , "AGENT.md" ) ) ) ;
6666 }
6767
68+ [ Fact ]
69+ public void Upsert_WhenWritableAgentDirectoryDiffers_WritesOverlayFileAndReloadsSavedAgent ( )
70+ {
71+ using var fixture = new AgentRegistryFixture ( useWritableOverlay : true ) ;
72+ var controller = fixture . CreateController ( ) ;
73+
74+ var result = controller . Upsert ( "business-analyst" , new UpsertAgentRequest (
75+ AgentId : "business-analyst" ,
76+ Name : "Business Analyst" ,
77+ Description : "Turns issues into requirements." ,
78+ Category : "analysis" ,
79+ Runner : "agent-model" ,
80+ Skills :
81+ [
82+ new AgentSkillBinding (
83+ "requirements" ,
84+ "Requirements" ,
85+ "Shape requirements." ,
86+ [ "requirement-design" ] ,
87+ "test-driven-development" )
88+ ] ,
89+ SupportedActions : [ "requirement-design" ] ,
90+ SupportedEnvironments : [ "all" ] ,
91+ SupportedPolicyTags : [ "requirement-design" ] ,
92+ SystemPrompt : "Write crisp requirements." ) ) ;
93+
94+ var ok = Assert . IsType < OkObjectResult > ( result ) ;
95+ var detail = Assert . IsType < AgentDetail > ( ok . Value ) ;
96+
97+ var sourcePath = Path . Combine ( fixture . AgentsDirectory , "business-analyst" , "AGENT.md" ) ;
98+ var overlayPath = Path . Combine ( fixture . WritableAgentsDirectory , "business-analyst" , "AGENT.md" ) ;
99+ Assert . False ( File . Exists ( sourcePath ) ) ;
100+ Assert . True ( File . Exists ( overlayPath ) ) ;
101+ Assert . Equal ( "test-driven-development" , Assert . Single ( detail . Skills ) . SkillManifestId ) ;
102+ Assert . Equal ( Path . GetFullPath ( overlayPath ) , detail . EffectiveFilePath ) ;
103+ }
104+
68105 [ Fact ]
69106 public void Upload_ParsesAgentMarkdownAndCreatesAgentFile ( )
70107 {
@@ -167,12 +204,14 @@ public void Upsert_WhenSandboxProfileIsKnown_PersistsAndReturnsIt()
167204
168205 private sealed class AgentRegistryFixture : IDisposable
169206 {
170- public AgentRegistryFixture ( )
207+ public AgentRegistryFixture ( bool useWritableOverlay = false )
171208 {
172209 Root = Path . Combine ( Path . GetTempPath ( ) , $ "agent_registry_{ Guid . NewGuid ( ) : N} ") ;
173210 AgentsDirectory = Path . Combine ( Root , "agents" ) ;
211+ WritableAgentsDirectory = useWritableOverlay ? Path . Combine ( Root , "agent-overlays" ) : AgentsDirectory ;
174212 SkillsDirectory = Path . Combine ( Root , "skills" ) ;
175213 Directory . CreateDirectory ( AgentsDirectory ) ;
214+ Directory . CreateDirectory ( WritableAgentsDirectory ) ;
176215 Directory . CreateDirectory ( Path . Combine ( SkillsDirectory , "test-driven-development" ) ) ;
177216 File . WriteAllText ( Path . Combine ( SkillsDirectory , "test-driven-development" , "SKILL.md" ) , """
178217 ---
@@ -183,8 +222,11 @@ public AgentRegistryFixture()
183222 Skill body.
184223 """ ) ;
185224
186- Paths = new AgentRegistryPaths ( AgentsDirectory , SkillsDirectory ) ;
187- Registry = new FileAgentRegistry ( AgentsDirectory ) ;
225+ Paths = new AgentRegistryPaths ( AgentsDirectory , SkillsDirectory )
226+ {
227+ WritableAgentsDirectory = WritableAgentsDirectory
228+ } ;
229+ Registry = new FileAgentRegistry ( Paths ) ;
188230 Skills = new SkillRepository ( SkillsDirectory ) ;
189231 Editor = new FileAgentRegistryEditor ( Paths , Registry ) ;
190232 }
@@ -193,6 +235,8 @@ Skill body.
193235
194236 public string AgentsDirectory { get ; }
195237
238+ public string WritableAgentsDirectory { get ; }
239+
196240 public string SkillsDirectory { get ; }
197241
198242 public AgentRegistryPaths Paths { get ; }
0 commit comments