@@ -281,29 +281,44 @@ type EnvLookup = {
281281 personalEnvCache : Map < string , Record < string , string > >
282282}
283283
284+ type KeySource = 'plaintext' | 'workspace' | 'personal'
285+
286+ const KEY_SOURCE_PRIORITY : Record < KeySource , number > = {
287+ plaintext : 0 ,
288+ workspace : 1 ,
289+ personal : 2 ,
290+ }
291+
284292async function resolveKey (
285293 ref : RawKeyRef ,
286294 context : string ,
287295 env : EnvLookup
288- ) : Promise < { key : string | null ; envVarFailed : boolean } > {
289- if ( ! isEnvVarReference ( ref . rawValue ) ) return { key : ref . rawValue , envVarFailed : false }
296+ ) : Promise < { key : string | null ; source : KeySource ; envVarFailed : boolean } > {
297+ if ( ! isEnvVarReference ( ref . rawValue ) ) {
298+ return { key : ref . rawValue , source : 'plaintext' , envVarFailed : false }
299+ }
290300
291301 const varName = extractEnvVarName ( ref . rawValue )
292- if ( ! varName ) return { key : null , envVarFailed : true }
302+ if ( ! varName ) return { key : null , source : 'personal' , envVarFailed : true }
293303
294304 const personalVars = env . personalEnvCache . get ( ref . userId )
295- const encryptedValue = env . wsEnvVars [ varName ] ?? personalVars ?. [ varName ]
305+
306+ const wsValue = env . wsEnvVars [ varName ]
307+ const personalValue = personalVars ?. [ varName ]
308+ const encryptedValue = wsValue ?? personalValue
309+ const source : KeySource = wsValue ? 'workspace' : 'personal'
310+
296311 if ( ! encryptedValue ) {
297312 console . warn ( ` [WARN] Env var "${ varName } " not found (${ context } )` )
298- return { key : null , envVarFailed : true }
313+ return { key : null , source , envVarFailed : true }
299314 }
300315
301316 try {
302317 const decrypted = await decryptSecret ( encryptedValue )
303- return { key : decrypted , envVarFailed : false }
318+ return { key : decrypted , source , envVarFailed : false }
304319 } catch ( error ) {
305320 console . warn ( ` [WARN] Failed to decrypt env var "${ varName } " (${ context } ): ${ error } ` )
306- return { key : null , envVarFailed : true }
321+ return { key : null , source , envVarFailed : true }
307322 }
308323}
309324
@@ -488,31 +503,34 @@ async function run() {
488503
489504 for ( const [ providerId , refs ] of providerKeys ) {
490505 // Resolve all keys for this provider to check for conflicts
491- const resolved : { ref : RawKeyRef ; key : string } [ ] = [ ]
506+ const resolved : { ref : RawKeyRef ; key : string ; source : KeySource } [ ] = [ ]
492507 for ( const ref of refs ) {
493508 const context = `"${ ref . blockName } " in "${ ref . workflowName } "`
494- const { key, envVarFailed } = await resolveKey ( ref , context , envLookup )
509+ const { key, source , envVarFailed } = await resolveKey ( ref , context , envLookup )
495510 if ( envVarFailed ) stats . envVarFailures ++
496- if ( key ?. trim ( ) ) resolved . push ( { ref, key } )
511+ if ( key ?. trim ( ) ) resolved . push ( { ref, key : key . trim ( ) , source } )
497512 }
498513
499514 if ( resolved . length === 0 ) continue
500515
516+ // Sort by priority: plaintext > workspace > personal
517+ resolved . sort ( ( a , b ) => KEY_SOURCE_PRIORITY [ a . source ] - KEY_SOURCE_PRIORITY [ b . source ] )
518+
501519 // Detect conflicting values
502520 const distinctKeys = new Set ( resolved . map ( ( r ) => r . key ) )
503521 if ( distinctKeys . size > 1 ) {
504522 stats . conflicts ++
505523 console . log ( ` [CONFLICT] provider "${ providerId } ": ${ distinctKeys . size } distinct keys` )
506- for ( const { ref, key } of resolved ) {
524+ for ( const { ref, key, source } of resolved ) {
507525 const display = isEnvVarReference ( ref . rawValue )
508526 ? `${ ref . rawValue } -> ${ maskKey ( key ) } `
509527 : maskKey ( ref . rawValue )
510- console . log ( ` "${ ref . blockName } " in "${ ref . workflowName } ": ${ display } ` )
528+ console . log ( ` [ ${ source } ] "${ ref . blockName } " in "${ ref . workflowName } ": ${ display } ` )
511529 }
512- console . log ( ' Using first resolved key' )
530+ console . log ( ` Using highest-priority key ( ${ resolved [ 0 ] . source } )` )
513531 }
514532
515- // Use the first resolved key
533+ // Use the highest-priority resolved key
516534 const chosen = resolved [ 0 ]
517535
518536 if ( DRY_RUN ) {
0 commit comments