@@ -587,9 +587,7 @@ function NewApiKeyDialog({
587587 presets ?. find ( ( preset ) => preset . available ) ?. id ??
588588 "FULL_ACCESS" ;
589589 const additionalPresetIds =
590- presets
591- ?. filter ( ( preset ) => ! KNOWN_PRESET_IDS . has ( preset . id ) )
592- . map ( ( preset ) => preset . id ) ?? [ ] ;
590+ presets ?. filter ( ( preset ) => ! KNOWN_PRESET_IDS . has ( preset . id ) ) . map ( ( preset ) => preset . id ) ?? [ ] ;
593591 const expiresAt = expirationDate ( expiration ) ;
594592 const [ presetId , setPresetId ] = useState ( defaultPresetId ) ;
595593 const [ taskScope , setTaskScope ] = useState < "all" | "selected" > ( "all" ) ;
@@ -860,13 +858,7 @@ const API_KEY_EXPIRATIONS = [
860858 { value : "never" , label : "Never" } ,
861859] ;
862860
863- type CapId =
864- | "tasks"
865- | "runs"
866- | "batches"
867- | "queues"
868- | "deployments"
869- | "envvars" ;
861+ type CapId = "tasks" | "runs" | "batches" | "queues" | "deployments" | "envvars" ;
870862
871863// Capability rows shown in the scope pane, in a fixed order so two presets read
872864// as a diff of the same list rather than a reshuffled one.
@@ -936,9 +928,7 @@ function scopeDetailForPreset(preset?: ApiKeyPreset): PresetScopeDetail | undefi
936928
937929 return {
938930 scopable : preset . usesTaskSelection ,
939- taskLabel : scopes . some ( ( scope ) => scope . split ( ":" ) [ 1 ] === "tasks" )
940- ? "All tasks"
941- : "No tasks" ,
931+ taskLabel : scopes . some ( ( scope ) => scope . split ( ":" ) [ 1 ] === "tasks" ) ? "All tasks" : "No tasks" ,
942932 caps,
943933 } ;
944934}
@@ -1077,72 +1067,74 @@ function ApiKeyScopePanel({
10771067 </ div >
10781068 </ div >
10791069
1080- { detail . admin ? (
1081- < div className = "rounded-md border border-amber-500/25 bg-amber-500/[0.08] p-3" >
1082- < code className = "font-mono text-xs text-amber-400" > admin</ code >
1083- < p className = "mt-1.5 text-xs text-text-dimmed" >
1084- A single scope that grants everything below, including anything added to the API
1085- later.
1086- </ p >
1087- </ div >
1088- ) : null }
1089-
1090- < ul className = "flex flex-col" >
1091- { SCOPE_CAPABILITIES . map ( ( [ key , label ] ) => {
1092- const cap = detail . admin ? undefined : detail . caps [ key ] ;
1093- const level = detail . admin ? 4 : cap ? cap [ 0 ] : 0 ;
1094- const rawScopes = cap ?. [ 1 ] ;
1095- const tone : ScopeTone = SCOPE_LEVEL_TONES [ level ] ?? "none" ;
1096- const rows = rawScopes ?. flatMap ( ( raw ) => expandScopeString ( raw , scoped , selectedTasks ) ) ;
1097-
1098- return (
1099- < li key = { key } className = "border-t border-grid-dimmed py-2.5 first:border-t-0" >
1100- < div className = "flex items-baseline gap-2.5" >
1101- < span
1102- className = { cn (
1103- "mt-1.5 size-1.5 shrink-0 rounded-[2px]" ,
1104- tone === "read"
1105- ? "bg-blue-500"
1106- : tone === "write"
1107- ? "bg-amber-500"
1108- : "bg-charcoal-600"
1109- ) }
1110- />
1111- < span
1112- className = { cn (
1113- "min-w-0 flex-1 text-sm" ,
1114- level === 0 ? "text-text-dimmed" : "text-text-bright"
1115- ) }
1116- >
1117- { label }
1118- </ span >
1119- < span className = "whitespace-nowrap text-xs text-text-dimmed" >
1120- { SCOPE_LEVEL_WORDS [ level ] ?? "No access" }
1121- </ span >
1122- </ div >
1123- { rows && rows . length > 0 ? (
1124- < div className = "ml-4 mt-1 flex flex-col gap-0.5" >
1125- { rows . map ( ( row ) => (
1126- < code
1127- key = { row }
1128- className = { cn (
1129- "break-all font-mono text-xxs leading-relaxed" ,
1130- row . startsWith ( "…" )
1131- ? "text-text-dimmed"
1132- : tone === "read"
1133- ? "text-blue-400/80"
1134- : "text-amber-400/80"
1135- ) }
1136- >
1137- { row }
1138- </ code >
1139- ) ) }
1070+ { detail . admin ? (
1071+ < div className = "rounded-md border border-amber-500/25 bg-amber-500/[0.08] p-3" >
1072+ < code className = "font-mono text-xs text-amber-400" > admin</ code >
1073+ < p className = "mt-1.5 text-xs text-text-dimmed" >
1074+ A single scope that grants everything below, including anything added to the API
1075+ later.
1076+ </ p >
1077+ </ div >
1078+ ) : null }
1079+
1080+ < ul className = "flex flex-col" >
1081+ { SCOPE_CAPABILITIES . map ( ( [ key , label ] ) => {
1082+ const cap = detail . admin ? undefined : detail . caps [ key ] ;
1083+ const level = detail . admin ? 4 : cap ? cap [ 0 ] : 0 ;
1084+ const rawScopes = cap ?. [ 1 ] ;
1085+ const tone : ScopeTone = SCOPE_LEVEL_TONES [ level ] ?? "none" ;
1086+ const rows = rawScopes ?. flatMap ( ( raw ) =>
1087+ expandScopeString ( raw , scoped , selectedTasks )
1088+ ) ;
1089+
1090+ return (
1091+ < li key = { key } className = "border-t border-grid-dimmed py-2.5 first:border-t-0" >
1092+ < div className = "flex items-baseline gap-2.5" >
1093+ < span
1094+ className = { cn (
1095+ "mt-1.5 size-1.5 shrink-0 rounded-[2px]" ,
1096+ tone === "read"
1097+ ? "bg-blue-500"
1098+ : tone === "write"
1099+ ? "bg-amber-500"
1100+ : "bg-charcoal-600"
1101+ ) }
1102+ />
1103+ < span
1104+ className = { cn (
1105+ "min-w-0 flex-1 text-sm" ,
1106+ level === 0 ? "text-text-dimmed" : "text-text-bright"
1107+ ) }
1108+ >
1109+ { label }
1110+ </ span >
1111+ < span className = "whitespace-nowrap text-xs text-text-dimmed" >
1112+ { SCOPE_LEVEL_WORDS [ level ] ?? "No access" }
1113+ </ span >
11401114 </ div >
1141- ) : null }
1142- </ li >
1143- ) ;
1144- } ) }
1145- </ ul >
1115+ { rows && rows . length > 0 ? (
1116+ < div className = "ml-4 mt-1 flex flex-col gap-0.5" >
1117+ { rows . map ( ( row ) => (
1118+ < code
1119+ key = { row }
1120+ className = { cn (
1121+ "break-all font-mono text-xxs leading-relaxed" ,
1122+ row . startsWith ( "…" )
1123+ ? "text-text-dimmed"
1124+ : tone === "read"
1125+ ? "text-blue-400/80"
1126+ : "text-amber-400/80"
1127+ ) }
1128+ >
1129+ { row }
1130+ </ code >
1131+ ) ) }
1132+ </ div >
1133+ ) : null }
1134+ </ li >
1135+ ) ;
1136+ } ) }
1137+ </ ul >
11461138 </ div >
11471139 < ApiKeyScopeUpgradeCta show = { showUpgradeCta } />
11481140 </ div >
0 commit comments