@@ -222,6 +222,83 @@ ${systemEnv}
222222Current Date: ${ timeInfo . date } ` ;
223223}
224224
225+ /**
226+ * Read raw content of the active ROLE file IF it is marked as "override system prompt".
227+ * Priority: project > global. Returns null if no active role is marked as override
228+ * or if the role file is missing/empty.
229+ */
230+ export function getOverrideRoleContent ( ) : string | null {
231+ const tryReadRole = ( rolePath : string ) : string | null => {
232+ try {
233+ if ( ! fs . existsSync ( rolePath ) ) return null ;
234+ const content = fs . readFileSync ( rolePath , 'utf-8' ) . trim ( ) ;
235+ return content || null ;
236+ } catch {
237+ return null ;
238+ }
239+ } ;
240+
241+ const resolveActiveOverride = (
242+ location : 'project' | 'global' ,
243+ ) : { path : string ; isOverride : boolean } | null => {
244+ try {
245+ const baseDir =
246+ location === 'project'
247+ ? process . cwd ( )
248+ : path . join ( os . homedir ( ) , '.snow' ) ;
249+ const configPath =
250+ location === 'project'
251+ ? path . join ( baseDir , '.snow' , 'role.json' )
252+ : path . join ( baseDir , 'role.json' ) ;
253+
254+ let activeRoleId : string | undefined ;
255+ let overrideRoleIds : string [ ] = [ ] ;
256+ if ( fs . existsSync ( configPath ) ) {
257+ try {
258+ const raw = fs . readFileSync ( configPath , 'utf-8' ) ;
259+ const parsed = JSON . parse ( raw ) as {
260+ activeRoleId ?: string ;
261+ overrideRoleIds ?: string [ ] ;
262+ } ;
263+ activeRoleId = parsed . activeRoleId ;
264+ overrideRoleIds = parsed . overrideRoleIds || [ ] ;
265+ } catch {
266+ // ignore
267+ }
268+ }
269+
270+ const resolvedActiveId =
271+ ! activeRoleId || activeRoleId === 'active' ? 'active' : activeRoleId ;
272+ const isOverride = overrideRoleIds . includes ( resolvedActiveId ) ;
273+ const filePath =
274+ resolvedActiveId === 'active'
275+ ? path . join ( baseDir , 'ROLE.md' )
276+ : path . join ( baseDir , `ROLE-${ resolvedActiveId } .md` ) ;
277+ return { path : filePath , isOverride} ;
278+ } catch {
279+ return null ;
280+ }
281+ } ;
282+
283+ try {
284+ const projectInfo = resolveActiveOverride ( 'project' ) ;
285+ if ( projectInfo && projectInfo . isOverride ) {
286+ const content = tryReadRole ( projectInfo . path ) ;
287+ if ( content ) return content ;
288+ }
289+
290+ const globalInfo = resolveActiveOverride ( 'global' ) ;
291+ if ( globalInfo && globalInfo . isOverride ) {
292+ const content = tryReadRole ( globalInfo . path ) ;
293+ if ( content ) return content ;
294+ }
295+ } catch ( error ) {
296+ console . error ( 'Failed to read override ROLE configuration:' , error ) ;
297+ }
298+
299+ return null ;
300+ }
301+
225302/**
226303 * Get the tool discovery section based on whether tool search is disabled
227304 */
0 commit comments