@@ -10,21 +10,28 @@ import { SSHRuntime } from "@/runtime/SSHRuntime";
1010
1111describe ( "buildSystemMessage" , ( ) => {
1212 let tempDir : string ;
13+ let projectDir : string ;
1314 let workspaceDir : string ;
1415 let globalDir : string ;
1516 let mockHomedir : Mock < typeof os . homedir > ;
17+ let runtime : LocalRuntime ;
1618
1719 beforeEach ( async ( ) => {
1820 // Create temp directory for test
1921 tempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "systemMessage-test-" ) ) ;
22+ projectDir = path . join ( tempDir , "project" ) ;
2023 workspaceDir = path . join ( tempDir , "workspace" ) ;
2124 globalDir = path . join ( tempDir , ".cmux" ) ;
25+ await fs . mkdir ( projectDir , { recursive : true } ) ;
2226 await fs . mkdir ( workspaceDir , { recursive : true } ) ;
2327 await fs . mkdir ( globalDir , { recursive : true } ) ;
2428
2529 // Mock homedir to return our test directory (getSystemDirectory will append .cmux)
2630 mockHomedir = spyOn ( os , "homedir" ) ;
2731 mockHomedir . mockReturnValue ( tempDir ) ;
32+
33+ // Create a local runtime for tests
34+ runtime = new LocalRuntime ( tempDir ) ;
2835 } ) ;
2936
3037 afterEach ( async ( ) => {
@@ -35,9 +42,9 @@ describe("buildSystemMessage", () => {
3542 } ) ;
3643
3744 test ( "includes mode-specific section when mode is provided" , async ( ) => {
38- // Write instruction file with mode section
45+ // Write instruction file with mode section to projectDir
3946 await fs . writeFile (
40- path . join ( workspaceDir , "AGENTS.md" ) ,
47+ path . join ( projectDir , "AGENTS.md" ) ,
4148 `# General Instructions
4249Always be helpful.
4350
@@ -51,10 +58,9 @@ Use diagrams where appropriate.
5158 id : "test-workspace" ,
5259 name : "test-workspace" ,
5360 projectName : "test-project" ,
54- projectPath : tempDir ,
61+ projectPath : projectDir ,
5562 } ;
5663
57- const runtime = new LocalRuntime ( tempDir ) ;
5864 const systemMessage = await buildSystemMessage ( metadata , runtime , workspaceDir , "plan" ) ;
5965
6066 // Should include the mode-specific content
@@ -68,9 +74,9 @@ Use diagrams where appropriate.
6874 } ) ;
6975
7076 test ( "excludes mode-specific section when mode is not provided" , async ( ) => {
71- // Write instruction file with mode section
77+ // Write instruction file with mode section to projectDir
7278 await fs . writeFile (
73- path . join ( workspaceDir , "AGENTS.md" ) ,
79+ path . join ( projectDir , "AGENTS.md" ) ,
7480 `# General Instructions
7581Always be helpful.
7682
@@ -83,10 +89,9 @@ Focus on planning and design.
8389 id : "test-workspace" ,
8490 name : "test-workspace" ,
8591 projectName : "test-project" ,
86- projectPath : tempDir ,
92+ projectPath : projectDir ,
8793 } ;
8894
89- const runtime = new LocalRuntime ( tempDir ) ;
9095 const systemMessage = await buildSystemMessage ( metadata , runtime , workspaceDir ) ;
9196
9297 // Should NOT include the <plan> mode-specific tag
@@ -98,7 +103,7 @@ Focus on planning and design.
98103 expect ( systemMessage ) . toContain ( "Focus on planning and design" ) ;
99104 } ) ;
100105
101- test ( "prefers workspace mode section over global mode section" , async ( ) => {
106+ test ( "prefers project mode section over global mode section" , async ( ) => {
102107 // Write global instruction file with mode section
103108 await fs . writeFile (
104109 path . join ( globalDir , "AGENTS.md" ) ,
@@ -109,34 +114,33 @@ Global plan instructions.
109114`
110115 ) ;
111116
112- // Write workspace instruction file with mode section
117+ // Write project instruction file with mode section
113118 await fs . writeFile (
114- path . join ( workspaceDir , "AGENTS.md" ) ,
115- `# Workspace Instructions
119+ path . join ( projectDir , "AGENTS.md" ) ,
120+ `# Project Instructions
116121
117122## Mode: Plan
118- Workspace plan instructions (should win).
123+ Project plan instructions (should win).
119124`
120125 ) ;
121126
122127 const metadata : WorkspaceMetadata = {
123128 id : "test-workspace" ,
124129 name : "test-workspace" ,
125130 projectName : "test-project" ,
126- projectPath : tempDir ,
131+ projectPath : projectDir ,
127132 } ;
128133
129- const runtime = new LocalRuntime ( tempDir ) ;
130134 const systemMessage = await buildSystemMessage ( metadata , runtime , workspaceDir , "plan" ) ;
131135
132- // Should include workspace mode section in the <plan> tag (workspace wins)
133- expect ( systemMessage ) . toMatch ( / < p l a n > \s * W o r k s p a c e p l a n i n s t r u c t i o n s \( s h o u l d w i n \) \. / s) ;
136+ // Should include project mode section in the <plan> tag (project wins)
137+ expect ( systemMessage ) . toMatch ( / < p l a n > \s * P r o j e c t p l a n i n s t r u c t i o n s \( s h o u l d w i n \) \. / s) ;
134138 // Global instructions are still present in <custom-instructions> section (that's correct)
135- // But the mode-specific <plan> section should only have workspace content
139+ // But the mode-specific <plan> section should only have project content
136140 expect ( systemMessage ) . not . toMatch ( / < p l a n > [ ^ < ] * G l o b a l p l a n i n s t r u c t i o n s / s) ;
137141 } ) ;
138142
139- test ( "falls back to global mode section when workspace has none" , async ( ) => {
143+ test ( "falls back to global mode section when project has none" , async ( ) => {
140144 // Write global instruction file with mode section
141145 await fs . writeFile (
142146 path . join ( globalDir , "AGENTS.md" ) ,
@@ -147,22 +151,21 @@ Global plan instructions.
147151`
148152 ) ;
149153
150- // Write workspace instruction file WITHOUT mode section
154+ // Write project instruction file WITHOUT mode section
151155 await fs . writeFile (
152- path . join ( workspaceDir , "AGENTS.md" ) ,
153- `# Workspace Instructions
154- Just general workspace stuff.
156+ path . join ( projectDir , "AGENTS.md" ) ,
157+ `# Project Instructions
158+ Just general project stuff.
155159`
156160 ) ;
157161
158162 const metadata : WorkspaceMetadata = {
159163 id : "test-workspace" ,
160164 name : "test-workspace" ,
161165 projectName : "test-project" ,
162- projectPath : tempDir ,
166+ projectPath : projectDir ,
163167 } ;
164168
165- const runtime = new LocalRuntime ( tempDir ) ;
166169 const systemMessage = await buildSystemMessage ( metadata , runtime , workspaceDir , "plan" ) ;
167170
168171 // Should include global mode section as fallback
@@ -171,7 +174,7 @@ Just general workspace stuff.
171174
172175 test ( "handles mode with special characters by sanitizing tag name" , async ( ) => {
173176 await fs . writeFile (
174- path . join ( workspaceDir , "AGENTS.md" ) ,
177+ path . join ( projectDir , "AGENTS.md" ) ,
175178 `## Mode: My-Special_Mode!
176179Special mode instructions.
177180`
@@ -181,10 +184,9 @@ Special mode instructions.
181184 id : "test-workspace" ,
182185 name : "test-workspace" ,
183186 projectName : "test-project" ,
184- projectPath : tempDir ,
187+ projectPath : projectDir ,
185188 } ;
186189
187- const runtime = new LocalRuntime ( tempDir ) ;
188190 const systemMessage = await buildSystemMessage (
189191 metadata ,
190192 runtime ,
@@ -197,30 +199,30 @@ Special mode instructions.
197199 expect ( systemMessage ) . toContain ( "Special mode instructions" ) ;
198200 expect ( systemMessage ) . toContain ( "</my-special_mode->" ) ;
199201 } ) ;
202+ } ) ;
200203
201- test ( "environment context differs between LocalRuntime and SSHRuntime" , async ( ) => {
202- const metadata : WorkspaceMetadata = {
203- id : "test-workspace" ,
204- name : "test-workspace" ,
205- projectName : "test-project" ,
206- projectPath : tempDir ,
207- } ;
208-
209- // Test with LocalRuntime
210- const localRuntime = new LocalRuntime ( tempDir ) ;
211- const localMessage = await buildSystemMessage ( metadata , localRuntime , workspaceDir ) ;
212-
213- // Should mention "git worktree" and include worktree-specific warnings
214- expect ( localMessage ) . toContain ( "git worktree" ) ;
215- expect ( localMessage ) . toContain ( "Do not modify or visit other worktrees" ) ;
216-
217- // Test with SSHRuntime
218- const sshRuntime = new SSHRuntime ( { host : "test-host" , srcBaseDir : "/remote/path" } ) ;
219- const sshMessage = await buildSystemMessage ( metadata , sshRuntime , workspaceDir ) ;
220-
221- // Should mention "git repository" but not "worktree"
222- expect ( sshMessage ) . toContain ( "git repository" ) ;
223- expect ( sshMessage ) . not . toContain ( "git worktree" ) ;
224- expect ( sshMessage ) . not . toContain ( "Do not modify or visit other worktrees" ) ;
225- } ) ;
204+ test ( "environment context differs between LocalRuntime and SSHRuntime" , async ( ) => {
205+ const metadata : WorkspaceMetadata = {
206+ id : "test-workspace" ,
207+ name : "test-workspace" ,
208+ projectName : "test-project" ,
209+ projectPath : tempDir ,
210+ } ;
211+
212+ // Test with LocalRuntime
213+ const localRuntime = new LocalRuntime ( tempDir ) ;
214+ const localMessage = await buildSystemMessage ( metadata , localRuntime , workspaceDir ) ;
215+
216+ // Should mention "git worktree" and include worktree-specific warnings
217+ expect ( localMessage ) . toContain ( "git worktree" ) ;
218+ expect ( localMessage ) . toContain ( "Do not modify or visit other worktrees" ) ;
219+
220+ // Test with SSHRuntime
221+ const sshRuntime = new SSHRuntime ( { host : "test-host" , srcBaseDir : "/remote/path" } ) ;
222+ const sshMessage = await buildSystemMessage ( metadata , sshRuntime , workspaceDir ) ;
223+
224+ // Should mention "git repository" but not "worktree"
225+ expect ( sshMessage ) . toContain ( "git repository" ) ;
226+ expect ( sshMessage ) . not . toContain ( "git worktree" ) ;
227+ expect ( sshMessage ) . not . toContain ( "Do not modify or visit other worktrees" ) ;
226228} ) ;
0 commit comments