@@ -53,46 +53,86 @@ function getSystemDirectory(): string {
5353}
5454
5555/**
56- * Read instruction set from a workspace using the runtime abstraction.
57- * This supports both local workspaces and remote SSH workspaces.
56+ * Read the first available file from a list using runtime.
5857 *
5958 * @param runtime - Runtime instance (may be local or SSH)
60- * @param workspacePath - Path to workspace directory
61- * @returns Combined instruction content, or null if no base file exists
59+ * @param directory - Directory to search in
60+ * @param filenames - List of filenames to try, in priority order
61+ * @returns Content of the first file found, or null if none exist
6262 */
63- async function readInstructionSetFromRuntime (
63+ async function readFirstAvailableFileFromRuntime (
6464 runtime : Runtime ,
65- workspacePath : string
65+ directory : string ,
66+ filenames : readonly string [ ]
6667) : Promise < string | null > {
67- const LOCAL_INSTRUCTION_FILENAME = "AGENTS.local.md" ;
68-
69- // Try to read base instruction file
70- let baseContent : string | null = null ;
71- for ( const filename of INSTRUCTION_FILE_NAMES ) {
68+ for ( const filename of filenames ) {
7269 try {
73- const filePath = path . join ( workspacePath , filename ) ;
74- baseContent = await readFileString ( runtime , filePath ) ;
75- break ; // Found one, stop searching
70+ const filePath = path . join ( directory , filename ) ;
71+ return await readFileString ( runtime , filePath ) ;
7672 } catch {
7773 // File doesn't exist or can't be read, try next
7874 continue ;
7975 }
8076 }
77+ return null ;
78+ }
79+
80+ /**
81+ * Read a file with optional local variant using runtime.
82+ * Follows the same pattern as readFileWithLocalVariant but uses Runtime.
83+ *
84+ * @param runtime - Runtime instance (may be local or SSH)
85+ * @param directory - Directory to search
86+ * @param baseFilenames - Base filenames to try in priority order
87+ * @param localFilename - Optional local filename to append if present
88+ * @returns Combined content or null if no base file exists
89+ */
90+ async function readFileWithLocalVariantFromRuntime (
91+ runtime : Runtime ,
92+ directory : string ,
93+ baseFilenames : readonly string [ ] ,
94+ localFilename ?: string
95+ ) : Promise < string | null > {
96+ const baseContent = await readFirstAvailableFileFromRuntime ( runtime , directory , baseFilenames ) ;
8197
8298 if ( ! baseContent ) {
8399 return null ;
84100 }
85101
86- // Try to read local variant
102+ if ( ! localFilename ) {
103+ return baseContent ;
104+ }
105+
87106 try {
88- const localFilePath = path . join ( workspacePath , LOCAL_INSTRUCTION_FILENAME ) ;
107+ const localFilePath = path . join ( directory , localFilename ) ;
89108 const localContent = await readFileString ( runtime , localFilePath ) ;
90109 return `${ baseContent } \n\n${ localContent } ` ;
91110 } catch {
92111 return baseContent ;
93112 }
94113}
95114
115+ /**
116+ * Read instruction set from a workspace using the runtime abstraction.
117+ * This supports both local workspaces and remote SSH workspaces.
118+ *
119+ * @param runtime - Runtime instance (may be local or SSH)
120+ * @param workspacePath - Path to workspace directory
121+ * @returns Combined instruction content, or null if no base file exists
122+ */
123+ async function readInstructionSetFromRuntime (
124+ runtime : Runtime ,
125+ workspacePath : string
126+ ) : Promise < string | null > {
127+ const LOCAL_INSTRUCTION_FILENAME = "AGENTS.local.md" ;
128+ return readFileWithLocalVariantFromRuntime (
129+ runtime ,
130+ workspacePath ,
131+ INSTRUCTION_FILE_NAMES ,
132+ LOCAL_INSTRUCTION_FILENAME
133+ ) ;
134+ }
135+
96136/**
97137 * Builds a system message for the AI model by combining multiple instruction sources.
98138 *
0 commit comments