@@ -292,6 +292,72 @@ describe("Config", () => {
292292 ) ,
293293 )
294294
295+ it . live ( "substitutes environment variables and relative file contents" , ( ) =>
296+ Effect . acquireUseRelease (
297+ Effect . sync ( ( ) => {
298+ const previous = {
299+ token : process . env . OPENCODE_TEST_MCP_TOKEN ,
300+ missing : process . env . OPENCODE_TEST_MISSING ,
301+ }
302+ process . env . OPENCODE_TEST_MCP_TOKEN = "secret"
303+ delete process . env . OPENCODE_TEST_MISSING
304+ return previous
305+ } ) ,
306+ ( ) =>
307+ Effect . acquireUseRelease (
308+ Effect . promise ( ( ) => tmpdir ( ) ) ,
309+ ( tmp ) =>
310+ Effect . gen ( function * ( ) {
311+ yield * Effect . promise ( ( ) =>
312+ Promise . all ( [
313+ fs . writeFile ( path . join ( tmp . path , "token.txt" ) , 'file\n"token"\n' ) ,
314+ fs . writeFile (
315+ path . join ( tmp . path , "opencode.jsonc" ) ,
316+ `{
317+ // Ignored reference: {file:missing.txt}
318+ "username": "user-{env:OPENCODE_TEST_MISSING}",
319+ "mcp": {
320+ "servers": {
321+ "remote": {
322+ "type": "remote",
323+ "url": "https://example.com/mcp",
324+ "headers": {
325+ "Authorization": "Bearer {env:OPENCODE_TEST_MCP_TOKEN}",
326+ "X-Token": "{file:token.txt}"
327+ }
328+ }
329+ }
330+ }
331+ }` ,
332+ ) ,
333+ ] ) ,
334+ )
335+
336+ return yield * Effect . gen ( function * ( ) {
337+ const config = yield * Config . Service
338+ const document = ( yield * config . entries ( ) ) . find ( ( entry ) => entry . type === "document" )
339+ expect ( document ?. info . username ) . toBe ( "user-" )
340+ const remote = document ?. info . mcp ?. servers ?. remote
341+ expect ( remote ?. type ) . toBe ( "remote" )
342+ if ( remote ?. type !== "remote" ) return
343+ expect ( remote . headers ) . toEqual ( {
344+ Authorization : "Bearer secret" ,
345+ "X-Token" : 'file\n"token"' ,
346+ } )
347+ } ) . pipe ( Effect . provide ( testLayer ( tmp . path ) ) )
348+ } ) ,
349+ ( tmp ) => Effect . promise ( ( ) => tmp [ Symbol . asyncDispose ] ( ) ) ,
350+ ) ,
351+ ( previous ) =>
352+ Effect . sync ( ( ) => {
353+ if ( previous . token === undefined ) delete process . env . OPENCODE_TEST_MCP_TOKEN
354+ else process . env . OPENCODE_TEST_MCP_TOKEN = previous . token
355+ if ( previous . missing === undefined ) delete process . env . OPENCODE_TEST_MISSING
356+ else process . env . OPENCODE_TEST_MISSING = previous . missing
357+ } ) ,
358+ ) ,
359+ )
360+
295361 it . live ( "does not load legacy config.json files" , ( ) =>
296362 Effect . acquireRelease (
297363 Effect . promise ( ( ) => tmpdir ( ) ) ,
0 commit comments