@@ -1972,6 +1972,83 @@ test("wellknown URL with trailing slash is normalized", async () => {
19721972 }
19731973} )
19741974
1975+ test ( "wellknown remote_config supports templated env vars in headers" , async ( ) => {
1976+ const originalFetch = globalThis . fetch
1977+ const originalToken = process . env . TEST_TOKEN
1978+ let wellknownFetchedUrl : string | undefined
1979+ let remoteFetchedUrl : string | undefined
1980+ let remoteHeaders : HeadersInit | undefined
1981+ globalThis . fetch = mock ( ( url : string | URL | Request , init ?: RequestInit ) => {
1982+ const urlStr = url instanceof Request ? url . url : url instanceof URL ? url . href : url
1983+ if ( urlStr . includes ( ".well-known/opencode" ) ) {
1984+ wellknownFetchedUrl = urlStr
1985+ return Promise . resolve (
1986+ new Response (
1987+ JSON . stringify ( {
1988+ remote_config : {
1989+ url : "https://config.example.com/opencode.json" ,
1990+ headers : {
1991+ Authorization : "Bearer {env:TEST_TOKEN}" ,
1992+ } ,
1993+ } ,
1994+ } ) ,
1995+ { status : 200 } ,
1996+ ) ,
1997+ )
1998+ }
1999+ if ( urlStr . includes ( "config.example.com" ) ) {
2000+ remoteFetchedUrl = urlStr
2001+ remoteHeaders = init ?. headers
2002+ return Promise . resolve (
2003+ new Response (
2004+ JSON . stringify ( {
2005+ mcp : { confluence : { type : "remote" , url : "https://confluence.example.com/mcp" , enabled : true } } ,
2006+ } ) ,
2007+ { status : 200 } ,
2008+ ) ,
2009+ )
2010+ }
2011+ return originalFetch ( url , init )
2012+ } ) as unknown as typeof fetch
2013+
2014+ const fakeAuth = Layer . mock ( Auth . Service ) ( {
2015+ all : ( ) =>
2016+ Effect . succeed ( {
2017+ "https://example.com" : new Auth . WellKnown ( { type : "wellknown" , key : "TEST_TOKEN" , token : "test-token" } ) ,
2018+ } ) ,
2019+ } )
2020+
2021+ const layer = Config . layer . pipe (
2022+ Layer . provide ( testFlock ) ,
2023+ Layer . provide ( AppFileSystem . defaultLayer ) ,
2024+ Layer . provide ( Env . defaultLayer ) ,
2025+ Layer . provide ( fakeAuth ) ,
2026+ Layer . provide ( emptyAccount ) ,
2027+ Layer . provideMerge ( infra ) ,
2028+ Layer . provide ( noopNpm ) ,
2029+ )
2030+
2031+ try {
2032+ await provideTmpdirInstance (
2033+ ( ) =>
2034+ Config . Service . use ( ( svc ) =>
2035+ Effect . gen ( function * ( ) {
2036+ const config = yield * svc . get ( )
2037+ expect ( wellknownFetchedUrl ) . toBe ( "https://example.com/.well-known/opencode" )
2038+ expect ( remoteFetchedUrl ) . toBe ( "https://config.example.com/opencode.json" )
2039+ expect ( remoteHeaders ) . toEqual ( { Authorization : "Bearer test-token" } )
2040+ expect ( config . mcp ?. confluence ?. enabled ) . toBe ( true )
2041+ } ) ,
2042+ ) ,
2043+ { git : true } ,
2044+ ) . pipe ( Effect . scoped , Effect . provide ( layer ) , Effect . runPromise )
2045+ } finally {
2046+ globalThis . fetch = originalFetch
2047+ if ( originalToken === undefined ) delete process . env . TEST_TOKEN
2048+ else process . env . TEST_TOKEN = originalToken
2049+ }
2050+ } )
2051+
19752052describe ( "resolvePluginSpec" , ( ) => {
19762053 test ( "keeps package specs unchanged" , async ( ) => {
19772054 await using tmp = await tmpdir ( )
0 commit comments