@clef-sh/ui 0.1.18 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,4 +35,4 @@ Error generating stack: `+e.message+`
35
35
  }`:u===`yaml`?`DB_HOST: localhost
36
36
  DB_PORT: '5432'`:`DB_HOST=localhost
37
37
  DB_PORT=5432
38
- # Comments are ignored`,rows:12,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:14,fontFamily:v.mono,fontSize:12,color:v.text,resize:`vertical`,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsx)(`div`,{style:{marginBottom:24,padding:`10px 14px`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,fontFamily:v.sans,fontSize:11,color:v.textMuted,lineHeight:1.5},children:`Values are sent directly to the local Clef server (127.0.0.1) and encrypted immediately. They are never stored in browser memory beyond this session.`}),(0,D.jsx)(M,{variant:`primary`,onClick:O,disabled:b||!c.trim(),children:b?`Previewing...`:`Next: Preview`})]}),n===2&&f&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,marginBottom:20},children:[`Importing to`,` `,(0,D.jsxs)(`span`,{style:{color:v.accent,fontWeight:600},children:[i,`/`,o]}),`. `,f.totalKeys,` key`,f.totalKeys===1?``:`s`,` parsed.`]}),f.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:f.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠ `,e]},t))}),f.wouldImport.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.green,children:[`New keys (`,f.wouldImport.length,`)`]}),f.wouldImport.map(e=>(0,D.jsx)(be,{icon:`\\u2192`,iconColor:v.green,label:e},e))]}),f.wouldSkip.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.yellow,children:[`Already exists (`,f.wouldSkip.length,`) — toggle to overwrite`]}),f.wouldSkip.map(({key:e,reason:t})=>{let n=m.includes(e);return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`6px 10px`,borderRadius:6,marginBottom:4,background:n?v.yellowDim:`transparent`,border:`1px solid ${n?v.yellow+`44`:v.border}`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:n,onChange:()=>N(e),style:{accentColor:v.yellow},id:`overwrite-${e}`}),(0,D.jsx)(`label`,{htmlFor:`overwrite-${e}`,style:{fontFamily:v.mono,fontSize:12,color:n?v.yellow:v.textMuted,flex:1,cursor:`pointer`},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:t})]},e)})]}),f.wouldImport.length===0&&f.wouldSkip.length===0&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,padding:`24px 0`,textAlign:`center`},children:`No importable keys found.`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:()=>r(1),children:`Back`}),(0,D.jsx)(M,{variant:`primary`,onClick:k,disabled:b||P===0,children:b?`Importing...`:`Import ${P} key${P===1?``:`s`}`})]})]}),n===3&&_&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:32},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:_.failed.length>0?v.redDim:v.greenDim,border:`1px solid ${_.failed.length>0?v.red+`44`:v.green+`44`}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:_.failed.length>0?v.red:v.green,marginBottom:16},children:_.failed.length>0?`⚠`:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:_.failed.length>0?v.yellow:v.green,marginBottom:8},children:_.failed.length>0?`Import completed with errors`:`Import complete`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[_.imported.length,` imported, `,_.skipped.length,` skipped,`,` `,_.failed.length,` failed`]})]}),_.imported.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.green,children:[`Imported (`,_.imported.length,`)`]}),_.imported.map(e=>(0,D.jsx)(be,{icon:`\\u2713`,iconColor:v.green,label:e},e))]}),_.failed.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.red,children:[`Failed (`,_.failed.length,`)`]}),_.failed.map(({key:e,error:t})=>(0,D.jsx)(be,{icon:`\\u2717`,iconColor:v.red,label:e,note:t},e))]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:j,children:`Import more`})]})]})]})})]})}function ge({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function _e({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim,marginBottom:4},children:e})}function ve({value:e,onChange:t,children:n}){return(0,D.jsx)(`select`,{value:e,onChange:t,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},children:n})}function ye({children:e,color:t}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,fontWeight:600,color:t,letterSpacing:`0.06em`,textTransform:`uppercase`,marginBottom:8},children:e})}function be({icon:e,iconColor:t,label:n,note:r}){return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`5px 10px`,borderRadius:6,marginBottom:3},children:[(0,D.jsx)(`span`,{style:{color:t,fontFamily:v.mono,fontSize:13},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:v.text,flex:1},children:n}),r&&(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:r})]})}function xe({manifest:e,reloadManifest:t}){let[n,r]=(0,g.useState)({kind:`none`}),[i,a]=(0,g.useState)(null),o=(0,g.useCallback)(()=>{r({kind:`none`}),a(null)},[]);if(!e)return(0,D.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`},children:(0,D.jsx)(A,{title:`Manifest`,subtitle:`Loading...`})});let s=e.namespaces,c=e.environments;return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Manifest`,subtitle:`${s.length} namespaces \u00B7 ${c.length} environments`}),(0,D.jsxs)(`div`,{style:{flex:1,overflow:`auto`,padding:28},children:[(0,D.jsx)(Se,{title:`Namespaces`,actionLabel:`+ Namespace`,onAction:()=>r({kind:`addNamespace`}),actionTestId:`add-namespace-btn`,children:s.length===0?(0,D.jsx)(Te,{message:`No namespaces declared yet.`}):(0,D.jsx)(Ce,{children:s.map(e=>(0,D.jsx)(we,{testId:`namespace-row-${e.name}`,name:e.name,description:e.description,badges:e.schema?[{label:`schema: ${e.schema}`,color:v.purple}]:[],onEdit:()=>r({kind:`editNamespace`,ns:e}),onDelete:()=>r({kind:`removeNamespace`,ns:e})},e.name))})}),(0,D.jsx)(`div`,{style:{marginTop:36},children:(0,D.jsx)(Se,{title:`Environments`,actionLabel:`+ Environment`,onAction:()=>r({kind:`addEnvironment`}),actionTestId:`add-environment-btn`,children:c.length===0?(0,D.jsx)(Te,{message:`No environments declared yet.`}):(0,D.jsx)(Ce,{children:c.map(e=>(0,D.jsx)(we,{testId:`environment-row-${e.name}`,name:e.name,description:e.description,badges:e.protected?[{label:`protected`,color:v.red}]:[],onEdit:()=>r({kind:`editEnvironment`,env:e}),onDelete:()=>r({kind:`removeEnvironment`,env:e})},e.name))})})})]}),n.kind===`addNamespace`&&(0,D.jsx)(Me,{onClose:o,onSubmit:async e=>{let n=await T(`/api/namespaces`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return n.ok?(t(),o(),!0):(a((await n.json()).error??`Failed to add namespace`),!1)},existingNames:s.map(e=>e.name),error:i,setError:a}),n.kind===`editNamespace`&&(0,D.jsx)(Ne,{ns:n.ns,existingNames:s.map(e=>e.name),onClose:o,onSubmit:async e=>{let r=await T(`/api/namespaces/${encodeURIComponent(n.ns.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return r.ok?(t(),o(),!0):(a((await r.json()).error??`Failed to edit namespace`),!1)},error:i,setError:a}),n.kind===`removeNamespace`&&(0,D.jsx)(Ie,{title:`Delete namespace`,subjectKind:`namespace`,subjectName:n.ns.name,impactDescription:`This will delete every encrypted cell file under '${n.ns.name}/' across all environments and remove '${n.ns.name}' from any service identity that references it.`,onClose:o,onConfirm:async()=>{let e=await T(`/api/namespaces/${encodeURIComponent(n.ns.name)}`,{method:`DELETE`});return e.ok?(t(),o(),!0):(a((await e.json()).error??`Failed to remove namespace`),!1)},error:i}),n.kind===`addEnvironment`&&(0,D.jsx)(Pe,{existingNames:c.map(e=>e.name),onClose:o,onSubmit:async e=>{let n=await T(`/api/environments`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return n.ok?(t(),o(),!0):(a((await n.json()).error??`Failed to add environment`),!1)},error:i,setError:a}),n.kind===`editEnvironment`&&(0,D.jsx)(Fe,{env:n.env,existingNames:c.map(e=>e.name),onClose:o,onSubmit:async e=>{let r=await T(`/api/environments/${encodeURIComponent(n.env.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return r.ok?(t(),o(),!0):(a((await r.json()).error??`Failed to edit environment`),!1)},error:i,setError:a}),n.kind===`removeEnvironment`&&(0,D.jsx)(Ie,{title:`Delete environment`,subjectKind:`environment`,subjectName:n.env.name,impactDescription:n.env.protected?`'${n.env.name}' is a protected environment and will be refused. Run "Edit" first and unprotect it before removing.`:`This will delete every encrypted cell file for '${n.env.name}' across all namespaces and remove the '${n.env.name}' entry from every service identity.`,onClose:o,onConfirm:async()=>{let e=await T(`/api/environments/${encodeURIComponent(n.env.name)}`,{method:`DELETE`});return e.ok?(t(),o(),!0):(a((await e.json()).error??`Failed to remove environment`),!1)},error:i})]})}function Se(e){return(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:14},children:[(0,D.jsx)(`h2`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.text,margin:0,letterSpacing:`-0.01em`},children:e.title}),(0,D.jsx)(M,{variant:`primary`,onClick:e.onAction,"data-testid":e.actionTestId,children:e.actionLabel})]}),e.children]})}function Ce(e){return(0,D.jsx)(`div`,{style:{border:`1px solid ${v.border}`,borderRadius:8,background:v.surface,overflow:`hidden`},children:e.children})}function we(e){return(0,D.jsxs)(`div`,{"data-testid":e.testId,style:{display:`flex`,alignItems:`center`,padding:`12px 16px`,borderBottom:`1px solid ${v.border}`,gap:12},children:[(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:13,fontWeight:600,color:v.text,display:`flex`,alignItems:`center`,gap:8},children:[e.name,e.badges.map(e=>(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:10,fontWeight:500,color:e.color,background:`${e.color}14`,border:`1px solid ${e.color}33`,borderRadius:10,padding:`1px 8px`},children:e.label},e.label))]}),e.description&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginTop:2},children:e.description})]}),(0,D.jsx)(M,{onClick:e.onEdit,"data-testid":`${e.testId}-edit`,children:`Edit`}),(0,D.jsx)(M,{onClick:e.onDelete,"data-testid":`${e.testId}-delete`,children:`Delete`})]})}function Te(e){return(0,D.jsx)(`div`,{style:{padding:24,border:`1px dashed ${v.border}`,borderRadius:8,textAlign:`center`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:e.message})}function Ee(e){return(0,D.jsx)(`div`,{"data-testid":`manifest-modal`,onClick:e.onClose,style:{position:`fixed`,inset:0,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`,zIndex:100},children:(0,D.jsxs)(`div`,{onClick:e=>e.stopPropagation(),style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:10,padding:24,width:480,maxWidth:`90vw`},children:[(0,D.jsx)(`h3`,{style:{fontFamily:v.sans,fontSize:16,fontWeight:600,color:v.text,margin:`0 0 16px`},children:e.title}),e.children]})})}function De(e){return(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(`label`,{style:{display:`block`,fontFamily:v.sans,fontSize:11,fontWeight:600,color:v.textMuted,marginBottom:4,textTransform:`uppercase`,letterSpacing:`0.05em`},children:e.label}),e.children,e.hint&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted,marginTop:4},children:e.hint})]})}function Oe(e){return(0,D.jsx)(`input`,{type:`text`,value:e.value,onChange:t=>e.onChange(t.target.value),placeholder:e.placeholder,"data-testid":e.testId,autoFocus:e.autoFocus,style:{width:`100%`,padding:`8px 12px`,background:v.bg,border:`1px solid ${v.border}`,borderRadius:6,color:v.text,fontFamily:v.mono,fontSize:13,boxSizing:`border-box`}})}function ke(e){return(0,D.jsx)(`div`,{"data-testid":`manifest-modal-error`,style:{padding:`8px 12px`,background:`${v.red}14`,border:`1px solid ${v.red}33`,borderRadius:6,color:v.red,fontFamily:v.sans,fontSize:12,marginBottom:12},children:e.message})}function Ae(e){return(0,D.jsx)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8,marginTop:8},children:e.children})}function je(e){return/^[A-Za-z0-9._-]+$/.test(e)}function Me(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(``),[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(!1),l=t.trim(),u=e.existingNames.includes(l),d=l.length>0&&je(l)&&!u,f=l?je(l)?u?`A namespace named '${l}' already exists.`:null:`Use letters, numbers, '.', '_', or '-' only.`:null;return(0,D.jsxs)(Ee,{title:`Add namespace`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:f??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},placeholder:`payments`,testId:`namespace-name-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,placeholder:`Payment processing secrets`,testId:`namespace-description-input`})}),(0,D.jsx)(De,{label:`Schema (optional)`,hint:`Path to a YAML schema file in the repo.`,children:(0,D.jsx)(Oe,{value:a,onChange:o,placeholder:`schemas/payments.yaml`,testId:`namespace-schema-input`})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`namespace-add-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!d||s,"data-testid":`namespace-add-submit`,onClick:async()=>{c(!0),await e.onSubmit({name:l,description:r.trim()||void 0,schema:a.trim()||void 0}),c(!1)},children:s?`Adding...`:`Add namespace`})]})]})}function Ne(e){let[t,n]=(0,g.useState)(e.ns.name),[r,i]=(0,g.useState)(e.ns.description??``),[a,o]=(0,g.useState)(e.ns.schema??``),[s,c]=(0,g.useState)(!1),l=t.trim(),u=l!==e.ns.name,d=u&&e.existingNames.includes(l),f=!u||je(l)&&!d,p=l?f?null:d?`A namespace named '${l}' already exists.`:`Use letters, numbers, '.', '_', or '-' only.`:`Name cannot be empty.`,m=u||r!==(e.ns.description??``)||a!==(e.ns.schema??``);return(0,D.jsxs)(Ee,{title:`Edit namespace '${e.ns.name}'`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:p??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},testId:`namespace-rename-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,testId:`namespace-description-input`})}),(0,D.jsx)(De,{label:`Schema (optional)`,hint:`Empty to clear.`,children:(0,D.jsx)(Oe,{value:a,onChange:o,testId:`namespace-schema-input`})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`namespace-edit-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!m||!!p||s,"data-testid":`namespace-edit-submit`,onClick:async()=>{c(!0);let t={};u&&(t.rename=l),r!==(e.ns.description??``)&&(t.description=r),a!==(e.ns.schema??``)&&(t.schema=a),await e.onSubmit(t),c(!1)},children:s?`Saving...`:`Save changes`})]})]})}function Pe(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(``),[a,o]=(0,g.useState)(!1),[s,c]=(0,g.useState)(!1),l=t.trim(),u=e.existingNames.includes(l),d=l.length>0&&je(l)&&!u,f=l?je(l)?u?`An environment named '${l}' already exists.`:null:`Use letters, numbers, '.', '_', or '-' only.`:null;return(0,D.jsxs)(Ee,{title:`Add environment`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:f??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},placeholder:`staging`,testId:`environment-name-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,placeholder:`Pre-production`,testId:`environment-description-input`})}),(0,D.jsx)(`div`,{style:{marginBottom:14},children:(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.sans,fontSize:12,color:v.text,cursor:`pointer`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(e.target.checked),"data-testid":`environment-protected-checkbox`}),`Mark as protected`]})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`environment-add-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!d||s,"data-testid":`environment-add-submit`,onClick:async()=>{c(!0),await e.onSubmit({name:l,description:r.trim()||void 0,protected:a||void 0}),c(!1)},children:s?`Adding...`:`Add environment`})]})]})}function Fe(e){let[t,n]=(0,g.useState)(e.env.name),[r,i]=(0,g.useState)(e.env.description??``),[a,o]=(0,g.useState)(e.env.protected===!0),[s,c]=(0,g.useState)(!1),l=t.trim(),u=l!==e.env.name,d=u&&e.existingNames.includes(l),f=!u||je(l)&&!d,p=l?f?null:d?`An environment named '${l}' already exists.`:`Use letters, numbers, '.', '_', or '-' only.`:`Name cannot be empty.`,m=a!==(e.env.protected===!0),h=u||r!==(e.env.description??``)||m;return(0,D.jsxs)(Ee,{title:`Edit environment '${e.env.name}'`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:p??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},testId:`environment-rename-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,testId:`environment-description-input`})}),(0,D.jsx)(`div`,{style:{marginBottom:14},children:(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.sans,fontSize:12,color:v.text,cursor:`pointer`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(e.target.checked),"data-testid":`environment-protected-checkbox`}),`Protected (write operations require confirmation)`]})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`environment-edit-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!h||!!p||s,"data-testid":`environment-edit-submit`,onClick:async()=>{c(!0);let t={};u&&(t.rename=l),r!==(e.env.description??``)&&(t.description=r),m&&(t.protected=a),await e.onSubmit(t),c(!1)},children:s?`Saving...`:`Save changes`})]})]})}function Ie(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(!1),a=t===e.subjectName;return(0,D.jsxs)(Ee,{title:e.title,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(`p`,{style:{fontFamily:v.sans,fontSize:12,color:v.text,margin:`0 0 12px`,lineHeight:1.5},children:e.impactDescription}),(0,D.jsx)(De,{label:`Type the ${e.subjectKind} name to confirm`,children:(0,D.jsx)(Oe,{value:t,onChange:n,placeholder:e.subjectName,testId:`${e.subjectKind}-remove-confirm-input`,autoFocus:!0})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`${e.subjectKind}-remove-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!a||r,"data-testid":`${e.subjectKind}-remove-submit`,onClick:async()=>{i(!0),await e.onConfirm(),i(!1)},children:r?`Deleting...`:`Delete ${e.subjectKind}`})]})]})}function Le({manifest:e,setView:t}){let[n,r]=(0,g.useState)([]),[i,a]=(0,g.useState)(0),[o,s]=(0,g.useState)(!1),[c,l]=(0,g.useState)(``),[u,d]=(0,g.useState)(``),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(!1),[_,y]=(0,g.useState)(null),[b,x]=(0,g.useState)(null),[S,C]=(0,g.useState)(0),[w,E]=(0,g.useState)(!1),[O,k]=(0,g.useState)(null),j=(0,g.useRef)(null),N=(0,g.useCallback)(async()=>{try{let e=await T(`/api/recipients`);if(e.ok){let t=await e.json();r(t.recipients),a(t.totalFiles)}}catch{}},[]);(0,g.useEffect)(()=>{N()},[N]),(0,g.useEffect)(()=>{if(!c.trim()){p(null);return}return j.current&&clearTimeout(j.current),j.current=setTimeout(async()=>{try{let e=await T(`/api/recipients/validate?key=${encodeURIComponent(c.trim())}`);e.ok&&p(await e.json())}catch{}},300),()=>{j.current&&clearTimeout(j.current)}},[c]);let P=async()=>{if(f?.valid){h(!0),y(null);try{let e=await T(`/api/recipients/add`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:c.trim(),label:u.trim()||void 0})});if(!e.ok){y((await e.json()).error??`Failed to add recipient`);return}r((await e.json()).recipients),s(!1),l(``),d(``),p(null)}catch(e){y(e instanceof Error?e.message:`Failed to add recipient`)}finally{h(!1)}}},F=e=>{x(e),C(1),E(!1)},I=()=>{x(null),C(0),E(!1)};return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Recipients`,subtitle:`clef recipients -- manage age encryption keys`,actions:!o&&S===0?(0,D.jsx)(M,{variant:`primary`,onClick:()=>s(!0),children:`+ Add recipient`}):void 0}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[_&&(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:_}),O&&(0,D.jsxs)(`div`,{"data-testid":`rotation-banner`,style:{background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:8,padding:`14px 18px`,marginBottom:20},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,fontWeight:600,color:v.yellow,marginBottom:8},children:`Rotation reminder`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,marginBottom:10,lineHeight:1.5},children:[(0,D.jsx)(`strong`,{children:O.name}),` has been removed and files re-encrypted. However, the removed key may still decrypt old versions of these files from git history. Rotate secret values in the following targets to complete revocation:`]}),O.targets.length>0&&(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,marginBottom:12,paddingLeft:12},children:O.targets.map(e=>(0,D.jsx)(`div`,{style:{marginBottom:2},children:e},e))}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`Go to Matrix to rotate`}),(0,D.jsx)(M,{variant:`ghost`,onClick:()=>k(null),children:`Dismiss`})]})]}),o&&(0,D.jsxs)(`div`,{"data-testid":`add-form`,style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.text,marginBottom:16},children:`Add recipient`}),(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(Re,{children:`Age public key`}),(0,D.jsx)(`input`,{type:`text`,value:c,onChange:e=>l(e.target.value),placeholder:`age1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq`,"data-testid":`add-key-input`,style:{width:`100%`,background:v.bg,border:`1px solid ${f?f.valid?v.green+`66`:v.red+`66`:v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`}}),f&&!f.valid&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.red,marginTop:4},children:f.error}),f?.valid&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.green,marginTop:4},children:`Valid age public key`})]}),(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(Re,{children:`Label (optional)`}),(0,D.jsx)(`input`,{type:`text`,value:u,onChange:e=>d(e.target.value),placeholder:`e.g. alice@example.com`,"data-testid":`add-label-input`,style:{width:`100%`,background:v.bg,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsxs)(`div`,{style:{marginBottom:16,padding:`10px 14px`,background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:6,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:[`Adding a recipient will re-encrypt `,i,` file`,i===1?``:`s`,`. This may take a moment.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:()=>{s(!1),l(``),d(``),p(null),y(null)},children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,onClick:P,disabled:m||!f?.valid,children:m?`Re-encrypting...`:`Add and re-encrypt`})]})]}),S===1&&b&&(0,D.jsxs)(`div`,{"data-testid":`remove-dialog`,style:{background:v.surface,border:`1px solid ${v.red}44`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.red,marginBottom:12},children:`Remove recipient`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,lineHeight:1.6,marginBottom:16},children:[`You are about to remove`,` `,(0,D.jsx)(`strong`,{style:{color:v.accent},children:b.label??b.preview}),` `,`(`,b.preview,`). All `,i,` encrypted file`,i===1?``:`s`,` will be re-encrypted without this key.`]}),(0,D.jsxs)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:6,padding:`12px 14px`,marginBottom:16,fontFamily:v.sans,fontSize:12,color:v.red,lineHeight:1.5},children:[`Re-encryption only removes `,(0,D.jsx)(`em`,{children:`future`}),` access. The removed key can still decrypt old versions from git history. You must rotate all secret values after removal.`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:v.text,marginBottom:16},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:w,onChange:e=>E(e.target.checked),"data-testid":`acknowledge-checkbox`,style:{accentColor:v.red,marginTop:2}}),`I understand — I will rotate secrets after removal`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Cancel`}),(0,D.jsx)(M,{variant:`danger`,onClick:()=>C(2),disabled:!w,children:`Continue`})]})]}),S===2&&b&&(0,D.jsxs)(`div`,{"data-testid":`remove-confirm-dialog`,style:{background:v.surface,border:`1px solid ${v.red}44`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.red,marginBottom:12},children:`Confirm removal`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,lineHeight:1.6,marginBottom:16},children:[`This will remove`,` `,(0,D.jsx)(`strong`,{style:{color:v.accent},children:b.label??b.preview}),` `,`and re-encrypt all `,i,` file`,i===1?``:`s`,`. This cannot be undone.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Cancel`}),(0,D.jsx)(M,{variant:`danger`,onClick:async()=>{if(b){h(!0),y(null);try{let e=await T(`/api/recipients/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:b.key})});if(!e.ok){y((await e.json()).error??`Failed to remove recipient`);return}let t=await e.json();r(t.recipients),k({name:b.label??b.preview,targets:t.rotationReminder??[]}),I()}catch(e){y(e instanceof Error?e.message:`Failed to remove recipient`)}finally{h(!1)}}},disabled:m,children:m?`Re-encrypting...`:`Remove and re-encrypt`})]})]}),n.length===0&&!o&&(0,D.jsx)(`div`,{style:{textAlign:`center`,paddingTop:40,fontFamily:v.sans,fontSize:14,color:v.textMuted},children:`No recipients configured. Add an age public key to get started.`}),n.length>0&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,letterSpacing:`0.05em`,textTransform:`uppercase`,marginBottom:10},children:[`Recipients (`,n.length,`)`]}),n.map(e=>(0,D.jsxs)(`div`,{"data-testid":`recipient-row`,style:{display:`flex`,alignItems:`center`,gap:14,padding:`12px 16px`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,marginBottom:8},children:[(0,D.jsx)(`div`,{style:{width:32,height:32,borderRadius:6,background:v.accentDim,border:`1px solid ${v.accent}44`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:14,flexShrink:0},children:`🔑`}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[e.label&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,fontWeight:600,color:v.text,marginBottom:2},children:e.label}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:e.preview})]}),(0,D.jsx)(M,{variant:`ghost`,onClick:()=>F(e),disabled:S!==0||m,children:`Remove`})]},e.key)),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textDim,marginTop:12},children:[i,` encrypted file`,i===1?``:`s`,` in the matrix`]})]})]})})]})}function Re({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function ze({manifest:e}){let[t,n]=(0,g.useState)(`list`),[r,i]=(0,g.useState)([]),[a,o]=(0,g.useState)(null),[s,c]=(0,g.useState)(``),[l,u]=(0,g.useState)(``),[d,f]=(0,g.useState)(``),[p,m]=(0,g.useState)(new Set),[h,_]=(0,g.useState)({}),[y,b]=(0,g.useState)(`ci`),[x,S]=(0,g.useState)(!0),[C,w]=(0,g.useState)(!1),[E,O]=(0,g.useState)(!1),[k,j]=(0,g.useState)(``),[P,F]=(0,g.useState)({}),[I,ee]=(0,g.useState)(``),[te,L]=(0,g.useState)(!1),[R,ne]=(0,g.useState)({}),[ie,ae]=(0,g.useState)(!1),[oe,se]=(0,g.useState)(``),[ce,le]=(0,g.useState)(void 0),[ue,de]=(0,g.useState)({}),[fe,pe]=(0,g.useState)(!1),[me,he]=(0,g.useState)(``),ge=(0,g.useCallback)(async()=>{try{let e=await T(`/api/service-identities`);e.ok&&i((await e.json()).identities)}catch{}},[]);(0,g.useEffect)(()=>{ge()},[ge]);let _e=r.find(e=>e.name===a),ve=(0,g.useCallback)(()=>{u(``),f(``),m(new Set);let t={};for(let n of e?.environments??[])t[n.name]={type:`age`,provider:`aws`,keyId:``};_(t),b(`ci`),S(!0),w(!1),j(``),n(`create`)},[e]),ye=(0,g.useCallback)(e=>{let t={};for(let[n,r]of Object.entries(e.environments)){let e=r.type===`kms`?`kms`:`age`;t[n]={type:e,provider:r.kms?.provider??`aws`,keyId:r.kms?.keyId??``,originalType:e,originalKeyId:r.kms?.keyId??``}}ne(t),se(``),n(`update`)},[]),be=(0,g.useCallback)(()=>{o(null),c(``),n(`list`)},[]),xe=(0,g.useCallback)(()=>{c(``),he(``),n(`detail`)},[]);async function Se(){O(!0),j(``);try{let e={};for(let[t,n]of Object.entries(h))n.type===`kms`&&(e[t]={provider:n.provider,keyId:n.keyId});let t={name:l.trim(),description:d.trim(),namespaces:Array.from(p)};y===`runtime`&&(t.packOnly=!0),x?t.sharedRecipient=!0:Object.keys(e).length>0&&(t.kmsEnvConfigs=e);let r=await T(`/api/service-identities`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}),i=await r.json();if(!r.ok){j(i.error??`Failed to create service identity.`);return}ee(i.identity.name),F(i.privateKeys??{}),L(i.sharedRecipient===!0),n(`keys`)}catch{j(`Network error. Check that the UI server is running.`)}finally{O(!1)}}async function Ce(){if(a){ae(!0),se(``);try{let e={};for(let[t,n]of Object.entries(R))n.type===`kms`&&(n.originalType!==`kms`||n.keyId!==n.originalKeyId)&&(e[t]={provider:n.provider,keyId:n.keyId});if(Object.keys(e).length===0){se(`No changes to apply.`);return}let t=await T(`/api/service-identities/${encodeURIComponent(a)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kmsEnvConfigs:e})}),n=await t.json();if(!t.ok){se(n.error??`Failed to update service identity.`);return}await ge(),xe()}catch{se(`Network error. Check that the UI server is running.`)}finally{ae(!1)}}}async function we(e){if(a){le(e),c(``);try{let t=await T(`/api/service-identities/${encodeURIComponent(a)}/rotate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({environment:e})}),r=await t.json();if(!t.ok){c(r.error??`Failed to rotate key.`);return}de(r.privateKeys??{}),await ge(),n(`rotate-keys`)}catch{c(`Network error. Check that the UI server is running.`)}finally{le(void 0)}}}async function Te(){if(a){pe(!0),he(``);try{let e=await T(`/api/service-identities/${encodeURIComponent(a)}`,{method:`DELETE`});if(!e.ok){he((await e.json()).error??`Failed to delete service identity.`);return}await ge(),be()}catch{he(`Network error. Check that the UI server is running.`)}finally{pe(!1)}}}if(t===`list`)return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Service Identities`,subtitle:`Per-service cryptographic access scoping`,actions:e&&(0,D.jsx)(M,{variant:`primary`,onClick:ve,children:`+ New identity`})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[s&&(0,D.jsx)(He,{children:s}),r.length===0&&(0,D.jsxs)(`div`,{style:{textAlign:`center`,padding:`48px 24px`,color:v.textMuted,fontFamily:v.sans,fontSize:13},children:[(0,D.jsx)(`div`,{style:{fontSize:28,marginBottom:12,opacity:.4},children:`🔑`}),`No service identities configured.`,e&&(0,D.jsx)(`div`,{style:{marginTop:16,display:`flex`,justifyContent:`center`},children:(0,D.jsx)(M,{variant:`primary`,onClick:ve,children:`Create the first one`})})]}),r.map(e=>(0,D.jsxs)(`div`,{role:`button`,tabIndex:0,"data-testid":`si-${e.name}`,onClick:()=>{o(e.name),c(``),n(`detail`)},onKeyDown:t=>{t.key===`Enter`&&(o(e.name),n(`detail`))},style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`16px 20px`,marginBottom:8,cursor:`pointer`,transition:`all 0.12s`},onMouseEnter:e=>{e.currentTarget.style.borderColor=v.borderLight},onMouseLeave:e=>{e.currentTarget.style.borderColor=v.border},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,marginBottom:8},children:[(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:14,color:v.text},children:e.name}),e.packOnly&&(0,D.jsx)(`span`,{"data-testid":`si-runtime-badge-${e.name}`,style:{fontFamily:v.mono,fontSize:9,color:v.yellow,background:`${v.yellow}15`,border:`1px solid ${v.yellow}33`,borderRadius:3,padding:`1px 6px`},children:`runtime`})]}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:[`Scoped to: `,(0,D.jsx)(`span`,{style:{color:v.text},children:e.namespaces.join(`, `)})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`},children:Object.entries(e.environments).map(([e,t])=>(0,D.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:4},children:[(0,D.jsx)(N,{env:e,small:!0}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:9,color:t.type===`kms`?v.purple:v.textDim},children:t.type===`kms`?`KMS`:`age`})]},e))})]},e.name))]})})]});if(t===`detail`)return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:_e?.name??a??``,subtitle:_e?.description,actions:(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[_e&&(0,D.jsx)(M,{"data-testid":`update-backends-btn`,variant:`ghost`,onClick:()=>ye(_e),children:`Update backends`}),(0,D.jsxs)(`button`,{"data-testid":`back-button`,onClick:be,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted,transition:`all 0.12s`},children:[`←`,` Back`]})]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[s&&(0,D.jsx)(He,{children:s}),_e&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Be,{children:`Scoped namespaces`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:6},children:_e.namespaces.map(e=>(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,background:v.accentDim,border:`1px solid ${v.accent}33`,borderRadius:4,padding:`2px 8px`},children:e},e))})]}),_e.packOnly&&(0,D.jsx)(`div`,{"data-testid":`runtime-info-banner`,style:{background:`${v.yellow}10`,border:`1px solid ${v.yellow}33`,borderRadius:8,padding:`10px 16px`,marginBottom:20,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:`Runtime identity — keys are not registered on encrypted files. This identity can only decrypt packed artifacts.`}),(0,D.jsx)(Be,{children:`Environment keys`}),e?.environments.map(e=>{let t=_e.environments[e.name];if(!t)return null;let n=t.protected??!1,r=ce===e.name;return(0,D.jsxs)(`div`,{"data-testid":`env-${e.name}`,style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`16px 20px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:12},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10},children:[(0,D.jsx)(N,{env:e.name}),n&&(0,D.jsx)(`span`,{style:{fontSize:12,color:v.red},children:`🔒`}),t.type===`kms`&&(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:10,color:v.purple,background:v.purpleDim,border:`1px solid ${v.purple}33`,borderRadius:3,padding:`1px 6px`},children:`KMS`})]}),t.type===`age`&&(0,D.jsx)(`button`,{"data-testid":`rotate-${e.name}`,disabled:r,onClick:()=>we(e.name),style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:5,padding:`3px 10px`,cursor:r?`default`:`pointer`,fontFamily:v.sans,fontSize:11,color:r?v.textDim:v.textMuted,opacity:r?.5:1},children:r?`Rotating…`:`Rotate key`})]}),t.type===`kms`&&t.kms&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[(0,D.jsxs)(`div`,{style:{marginBottom:8},children:[`Authentication: `,(0,D.jsx)(`span`,{style:{color:v.purple},children:`IAM + KMS`})]}),(0,D.jsxs)(`div`,{children:[`Provider:`,` `,(0,D.jsx)(`span`,{style:{color:v.text},children:t.kms.provider})]}),(0,D.jsxs)(`div`,{style:{marginTop:4},children:[`Key ID:`,` `,(0,D.jsx)(`span`,{style:{color:v.text,wordBreak:`break-all`},children:t.kms.keyId})]}),(0,D.jsx)(`div`,{style:{marginTop:10,padding:`8px 12px`,background:v.purpleDim,border:`1px solid ${v.purple}33`,borderRadius:4,fontSize:11,color:v.purple,fontFamily:v.sans},children:`No keys to provision. CI and runtime authenticate via IAM role with kms:Decrypt permission.`})]}),t.type===`age`&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[(0,D.jsxs)(`div`,{style:{marginBottom:8},children:[`Authentication: `,(0,D.jsx)(`span`,{style:{color:v.green},children:`age key`})]}),(0,D.jsxs)(`div`,{children:[`Public key:`,` `,(0,D.jsx)(`span`,{style:{color:v.text},children:t.publicKey?`${t.publicKey.slice(0,12)}...${t.publicKey.slice(-6)}`:`unknown`})]})]})]},e.name)}),(0,D.jsx)(`div`,{style:{marginTop:32,paddingTop:20,borderTop:`1px solid ${v.border}`,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{"data-testid":`delete-identity-btn`,variant:`danger`,onClick:()=>{he(``),n(`delete-confirm`)},children:`Delete identity`})})]})]})})]});if(t===`delete-confirm`)return(0,D.jsxs)(`div`,{"data-testid":`delete-confirm-view`,style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Delete service identity`,subtitle:`This action cannot be undone`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[me&&(0,D.jsx)(He,{children:me}),(0,D.jsxs)(`div`,{style:{background:`#1a0a0a`,border:`1px solid ${v.red}55`,borderRadius:8,padding:`16px 20px`,marginBottom:24,fontFamily:v.sans,fontSize:13,color:v.red},children:[(0,D.jsxs)(`div`,{style:{fontWeight:600,marginBottom:8},children:[`Delete `,(0,D.jsx)(`span`,{style:{fontFamily:v.mono},children:a}),`?`]}),(0,D.jsxs)(`div`,{style:{color:v.textMuted,fontSize:12,lineHeight:1.6},children:[`This will remove the identity from`,` `,(0,D.jsx)(`span`,{style:{fontFamily:v.mono},children:`clef.yaml`}),` and de-register its recipients from all scoped encrypted files. Any runtimes currently using this identity's private key will lose access on the next artifact refresh.`]})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{"data-testid":`cancel-delete-btn`,variant:`ghost`,onClick:xe,disabled:fe,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`confirm-delete-btn`,variant:`danger`,onClick:Te,disabled:fe,children:fe?`Deleting…`:`Delete identity`})]})]})})]});if(t===`rotate-keys`)return(0,D.jsxs)(`div`,{"data-testid":`rotate-keys-view`,style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Key rotated`,subtitle:`New keys for ${a}`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[(0,D.jsxs)(`div`,{style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.yellow,display:`flex`,gap:10,alignItems:`flex-start`},children:[(0,D.jsx)(`span`,{style:{fontSize:16,flexShrink:0},children:`⚠`}),(0,D.jsx)(`span`,{children:`Copy the new private key now — it will not be shown again. Provision it to the runtime and invalidate the old key.`})]}),(0,D.jsx)(Be,{children:`New private keys`}),Object.entries(ue).map(([e,t])=>(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsx)(N,{env:e}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]},e)),(0,D.jsx)(`div`,{style:{marginTop:8,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{"data-testid":`rotate-done-btn`,variant:`primary`,onClick:xe,children:`Done`})})]})})]});if(t===`update`){let t=e?.environments??[],n=Object.values(R).filter(e=>e.type===`kms`?e.originalType!==`kms`||e.keyId!==e.originalKeyId:!1).length>0&&Object.entries(R).every(([,e])=>e.type===`kms`?e.keyId.trim()!==``:!0);return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Update backends`,subtitle:`Environment backends for ${a}`,actions:(0,D.jsxs)(`button`,{onClick:xe,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:[`←`,` Cancel`]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[oe&&(0,D.jsx)(He,{children:oe}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:16,lineHeight:1.6},children:`Switch age environments to KMS, or update an existing KMS key ID. To revert KMS to age, delete and recreate the identity.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8,marginBottom:28},children:t.map(e=>{let t=R[e.name];return t?(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 16px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:t.type===`kms`?12:0},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(N,{env:e.name}),e.protected&&(0,D.jsx)(`span`,{style:{fontSize:11,color:v.red},children:`🔒`})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:4},children:[`age`,`kms`].map(n=>{let r=t.originalType===`kms`&&n===`age`;return(0,D.jsx)(`button`,{"data-testid":n===`kms`?`update-kms-toggle-${e.name}`:void 0,disabled:r,onClick:()=>{r||ne(r=>({...r,[e.name]:{...t,type:n}}))},title:r?`KMS → age requires delete and recreate`:void 0,style:{background:t.type===n?n===`kms`?v.purple:v.accent:`transparent`,border:`1px solid ${t.type===n?n===`kms`?v.purple:v.accent:v.border}`,borderRadius:4,padding:`3px 10px`,cursor:r?`not-allowed`:`pointer`,fontFamily:v.mono,fontSize:11,color:t.type===n?`#fff`:v.textMuted,opacity:r?.4:1,transition:`all 0.1s`},children:n.toUpperCase()},n)})})]}),t.type===`kms`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsxs)(`select`,{value:t.provider,onChange:n=>ne(r=>({...r,[e.name]:{...t,provider:n.target.value}})),style:{...Ue,width:90,flexShrink:0,padding:`7px 8px`},children:[(0,D.jsx)(`option`,{value:`aws`,children:`AWS`}),(0,D.jsx)(`option`,{value:`gcp`,children:`GCP`}),(0,D.jsx)(`option`,{value:`azure`,children:`Azure`})]}),(0,D.jsx)(`input`,{"data-testid":`update-keyid-${e.name}`,value:t.keyId,onChange:n=>ne(r=>({...r,[e.name]:{...t,keyId:n.target.value}})),placeholder:`arn:aws:kms:… or key resource ID`,style:{...Ue,flex:1}})]})]},e.name):null})}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{"data-testid":`update-cancel-btn`,variant:`ghost`,onClick:xe,disabled:ie,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`update-submit-btn`,variant:`primary`,onClick:Ce,disabled:!n||ie,children:ie?`Saving…`:`Save changes`})]})]})})]})}if(t===`keys`){let e=Object.keys(P).length>0,t=te?Object.values(P)[0]:void 0,n=te?Object.keys(P):[];return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`${I} created`,subtitle:`Service identity ready`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[e&&(0,D.jsxs)(`div`,{style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.yellow,display:`flex`,gap:10,alignItems:`flex-start`},children:[(0,D.jsx)(`span`,{style:{fontSize:16,flexShrink:0},children:`⚠`}),(0,D.jsx)(`span`,{children:te?`Copy this key now — it will not be shown again. Set it as CLEF_AGE_KEY in your CI. It decrypts: ${n.join(`, `)}.`:`Copy these private keys now — they will not be shown again. Store each key securely and provision it to the relevant runtime.`})]}),!e&&(0,D.jsx)(`div`,{style:{background:v.purpleDim,border:`1px solid ${v.purple}44`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.purple},children:`All environments use KMS. No private keys to provision — runtimes authenticate via IAM role.`}),(0,D.jsx)(Be,{children:`Private keys`}),te&&t?(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.accent}44`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,fontWeight:600},children:`CLEF_AGE_KEY`}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:`—`}),n.map(e=>(0,D.jsx)(N,{env:e,small:!0},e))]}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]}):Object.entries(P).map(([e,t])=>(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsx)(N,{env:e}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]},e)),(0,D.jsx)(`div`,{style:{marginTop:8,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{variant:`primary`,onClick:()=>{ge(),be()},children:`Done`})})]})})]})}let Ee=e?.namespaces??[],De=e?.environments??[],Oe=l.trim()&&r.some(e=>e.name===l.trim())?`A service identity with this name already exists.`:``,ke=l.trim()!==``&&!Oe&&p.size>0&&De.every(e=>{let t=h[e.name];return t?.type===`age`||t?.type===`kms`&&t.provider&&t.keyId.trim()});return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`New service identity`,subtitle:`Scope cryptographic access to specific namespaces`,actions:(0,D.jsxs)(`button`,{onClick:be,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:[`←`,` Cancel`]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[k&&(0,D.jsx)(He,{children:k}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Ve,{children:`Name`}),(0,D.jsx)(`input`,{"data-testid":`si-name-input`,value:l,onChange:e=>u(e.target.value),placeholder:`e.g. api-gateway`,style:Ue}),Oe&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.red,marginTop:6},children:Oe})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Description (optional)`}),(0,D.jsx)(`input`,{value:d,onChange:e=>f(e.target.value),placeholder:`e.g. API gateway service account`,style:Ue})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Role`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:0,borderRadius:6,overflow:`hidden`,border:`1px solid ${v.border}`,width:`fit-content`,marginBottom:8},children:[`ci`,`runtime`].map(e=>(0,D.jsx)(`button`,{"data-testid":`role-${e}`,onClick:()=>{b(e),S(e===`ci`),w(!1)},style:{background:y===e?v.accent:`transparent`,border:`none`,padding:`7px 18px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,fontWeight:y===e?600:400,color:y===e?`#fff`:v.textMuted,transition:`all 0.12s`},children:e===`ci`?`CI`:`Runtime`},e))}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,lineHeight:1.5},children:y===`ci`?`Decrypts files directly. Keys are registered on encrypted SOPS files. Use for CI pipelines and local tools.`:`Decrypts packed artifacts only. Keys are NOT added to encrypted files — smaller blast radius for deployment targets (Lambda, ECS, containers).`})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Namespaces`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:`This identity can decrypt secrets only from the selected namespaces.`}),Ee.length===0&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textDim},children:`No namespaces defined in manifest.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ee.map(e=>{let t=p.has(e.name);return(0,D.jsxs)(`label`,{"data-testid":`ns-checkbox-${e.name}`,style:{display:`flex`,alignItems:`center`,gap:10,padding:`10px 14px`,background:t?v.accentDim:v.surface,border:`1px solid ${t?v.accent+`55`:v.border}`,borderRadius:6,cursor:`pointer`,transition:`all 0.1s`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:t,onChange:t=>{let n=new Set(p);t.target.checked?n.add(e.name):n.delete(e.name),m(n)},style:{accentColor:v.accent}}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:t?v.accent:v.text},children:e.name}),e.description&&(0,D.jsxs)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted},children:[`— `,e.description]})]},e.name)})})]}),(0,D.jsxs)(`div`,{style:{marginBottom:28},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:6},children:[(0,D.jsx)(Ve,{children:`Environment backends`}),(0,D.jsxs)(`label`,{"data-testid":`shared-recipient-toggle`,style:{display:`flex`,alignItems:`center`,gap:7,cursor:`pointer`,fontFamily:v.sans,fontSize:11,color:x?v.accent:v.textMuted,userSelect:`none`},children:[(0,D.jsxs)(`div`,{style:{width:28,height:16,borderRadius:8,background:x?v.accent:v.border,position:`relative`,transition:`background 0.15s`,flexShrink:0},children:[(0,D.jsx)(`div`,{style:{position:`absolute`,top:2,left:x?14:2,width:12,height:12,borderRadius:`50%`,background:`#fff`,transition:`left 0.15s`}}),(0,D.jsx)(`input`,{type:`checkbox`,checked:x,onChange:e=>{S(e.target.checked);let t=y===`ci`;w(e.target.checked!==t)},style:{position:`absolute`,opacity:0,width:0,height:0}})]}),`Shared age key`]})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:x?`One age key pair for all environments — one CI secret, easier to provision.`:`Age generates a key pair per environment. KMS uses your cloud provider — no key material is provisioned.`}),C&&(0,D.jsx)(`div`,{"data-testid":`shared-recipient-warning`,style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:6,padding:`10px 14px`,marginBottom:10,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:y===`ci`&&!x?`Most CI pipelines use a single key. Per-environment keys are useful when your CI environments have separate secret access controls (e.g. GitHub environment protection rules).`:`Runtime workloads typically use per-environment keys for isolation. A shared key means a compromised key in any environment decrypts artifacts for all environments.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:x?(0,D.jsxs)(`div`,{style:{background:v.accentDim,border:`1px solid ${v.accent}44`,borderRadius:8,padding:`14px 16px`,display:`flex`,alignItems:`center`,gap:12},children:[(0,D.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`},children:De.map(e=>(0,D.jsx)(N,{env:e.name,small:!0},e.name))}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,marginLeft:`auto`},children:`age (shared)`})]}):De.map(e=>{let t=h[e.name]??{type:`age`,provider:`aws`,keyId:``};return(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 16px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:t.type===`kms`?12:0},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(N,{env:e.name}),e.protected&&(0,D.jsx)(`span`,{style:{fontSize:11,color:v.red},children:`🔒`})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:4},children:[`age`,`kms`].map(n=>(0,D.jsx)(`button`,{onClick:()=>_(r=>({...r,[e.name]:{...t,type:n}})),style:{background:t.type===n?n===`kms`?v.purple:v.accent:`transparent`,border:`1px solid ${t.type===n?n===`kms`?v.purple:v.accent:v.border}`,borderRadius:4,padding:`3px 10px`,cursor:`pointer`,fontFamily:v.mono,fontSize:11,color:t.type===n?`#fff`:v.textMuted,transition:`all 0.1s`},children:n.toUpperCase()},n))})]}),t.type===`kms`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsxs)(`select`,{value:t.provider,onChange:n=>_(r=>({...r,[e.name]:{...t,provider:n.target.value}})),style:{...Ue,width:90,flexShrink:0,padding:`7px 8px`},children:[(0,D.jsx)(`option`,{value:`aws`,children:`AWS`}),(0,D.jsx)(`option`,{value:`gcp`,children:`GCP`}),(0,D.jsx)(`option`,{value:`azure`,children:`Azure`})]}),(0,D.jsx)(`input`,{value:t.keyId,onChange:n=>_(r=>({...r,[e.name]:{...t,keyId:n.target.value}})),placeholder:`arn:aws:kms:… or key resource ID`,style:{...Ue,flex:1}})]})]},e.name)})})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:be,disabled:E,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`create-si-submit`,variant:`primary`,onClick:Se,disabled:!ke||E,children:E?`Creating…`:`Create identity`})]})]})})]})}function Be({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function Ve({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6},children:e})}function He({children:e}){return(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:e})}var Ue={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`},We={age:`age`,awskms:`AWS KMS`,gcpkms:`GCP KMS`,azurekv:`Azure Key Vault`,pgp:`PGP`},Ge={awskms:`arn:aws:kms:region:account:key/id`,gcpkms:`projects/.../locations/.../keyRings/.../cryptoKeys/...`,azurekv:`https://vault-name.vault.azure.net/keys/key-name/version`,pgp:`PGP fingerprint`},Ke=[`age`,`awskms`,`gcpkms`,`azurekv`,`pgp`];function qe({manifest:e,setView:t,reloadManifest:n}){let[r,i]=(0,g.useState)(1),[a,o]=(0,g.useState)(null),[s,c]=(0,g.useState)(`age`),[l,u]=(0,g.useState)(``),[d,f]=(0,g.useState)(`all`),[p,m]=(0,g.useState)(``),[h,_]=(0,g.useState)(null),[y,b]=(0,g.useState)(!1),[x,S]=(0,g.useState)(!1),[C,w]=(0,g.useState)(null),[E,O]=(0,g.useState)(!1),[k,j]=(0,g.useState)(null);(0,g.useEffect)(()=>{N()},[]),(0,g.useEffect)(()=>{e&&e.environments.length>0&&!p&&m(e.environments[0].name)},[e,p]);let N=async()=>{try{let e=await T(`/api/backend-config`);e.ok&&o(await e.json())}catch{}},P=async(e=!1)=>{O(!0),j(null);let t={target:{backend:s,key:s===`age`?void 0:l},environment:d===`single`?p:void 0,confirmed:e||void 0};try{let e=await T(`/api/migrate-backend/preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(e.status===409){b(!0),O(!1);return}if(!e.ok){j((await e.json()).error??`Preview failed`),O(!1);return}_(await e.json()),b(!1),S(!1),i(2)}catch(e){j(e instanceof Error?e.message:`Preview failed`)}finally{O(!1)}},F=async()=>{i(3),j(null);let e={target:{backend:s,key:s===`age`?void 0:l},environment:d===`single`?p:void 0,confirmed:!0};try{let t=await T(`/api/migrate-backend/apply`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){j((await t.json()).error??`Migration failed`),i(2);return}w(await t.json()),n(),i(4)}catch(e){j(e instanceof Error?e.message:`Migration failed`),i(2)}},I=()=>{i(1),_(null),w(null),b(!1),S(!1),j(null),N()},ee=e?.environments??[],te=h?.events.filter(e=>e.type===`info`&&e.message.startsWith(`Would`)).length??0;return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Backend`,subtitle:`clef migrate-backend — change encryption backend`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[(0,D.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:0,marginBottom:32},children:[1,2,3,4].map((e,t)=>(0,D.jsxs)(g.Fragment,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(`div`,{style:{width:24,height:24,borderRadius:`50%`,background:r>=e?v.accent:v.surface,border:`1px solid ${r>=e?v.accent:v.border}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontFamily:v.mono,fontSize:11,fontWeight:700,color:r>=e?`#000`:v.textDim},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:12,color:r>=e?v.text:v.textDim,fontWeight:r===e?600:400},children:e===1?`Configure`:e===2?`Preview`:e===3?`Migrate`:`Done`})]}),t<3&&(0,D.jsx)(`div`,{style:{flex:1,height:1,background:r>e?v.accent:v.border,margin:`0 12px`,minWidth:20}})]},e))}),k&&(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:k}),r===1&&(0,D.jsxs)(`div`,{children:[a&&(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Je,{children:`Current Configuration`}),(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:14},children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.text,marginBottom:8},children:[`Default backend:`,` `,(0,D.jsx)(`span`,{style:{color:v.accent,fontWeight:600},children:We[a.global.default_backend]})]}),a.environments.map(e=>(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.mono,fontSize:11,color:v.textMuted,marginBottom:2},children:[(0,D.jsxs)(`span`,{children:[e.protected?`🔒 `:``,e.name]}),(0,D.jsx)(`span`,{style:{color:v.textDim},children:`→`}),(0,D.jsxs)(`span`,{style:{color:e.hasOverride?v.yellow:v.textMuted},children:[We[e.effective.backend],e.hasOverride?` (override)`:``]})]},e.name))]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Je,{children:`Target Backend`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ke.map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:s===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`backend`,value:e,checked:s===e,onChange:()=>{c(e),u(``)},style:{accentColor:v.accent},"data-testid":`backend-radio-${e}`}),We[e]]},e))})]}),s!==`age`&&(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Je,{children:`Key Identifier`}),(0,D.jsx)(`input`,{type:`text`,value:l,onChange:e=>u(e.target.value),placeholder:Ge[s],"data-testid":`backend-key-input`,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Je,{children:`Scope`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:16,marginBottom:8},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===`all`?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`scope`,checked:d===`all`,onChange:()=>f(`all`),style:{accentColor:v.accent}}),`All environments`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===`single`?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`scope`,checked:d===`single`,onChange:()=>f(`single`),style:{accentColor:v.accent}}),`Single environment`]})]}),d===`single`&&(0,D.jsx)(`select`,{value:p,onChange:e=>m(e.target.value),"data-testid":`env-select`,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},children:ee.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))})]}),y&&(0,D.jsxs)(`div`,{style:{background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.yellow,marginBottom:8},children:`This migration affects protected environments.`}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.text},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:x,onChange:e=>S(e.target.checked),style:{accentColor:v.yellow},"data-testid":`protected-confirm`}),`I understand and want to proceed`]})]}),(0,D.jsx)(M,{variant:`primary`,onClick:()=>P(x),disabled:E||s!==`age`&&!l.trim(),children:E?`Loading...`:y&&x?`Confirm & Preview`:`Preview`})]}),r===2&&h&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,marginBottom:20},children:[`Migrating to`,` `,(0,D.jsx)(`span`,{style:{color:v.accent,fontWeight:600},children:We[s]}),d===`single`?` (${p} only)`:` (all environments)`]}),h.events.filter(e=>e.type===`info`).length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(Ye,{color:v.green,children:[`Files to migrate (`,h.events.filter(e=>e.type===`info`).length,`)`]}),h.events.filter(e=>e.type===`info`).map((e,t)=>(0,D.jsx)(Xe,{icon:`→`,iconColor:v.green,label:e.message},t))]}),h.events.filter(e=>e.type===`skip`).length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(Ye,{color:v.textDim,children:[`Already on target (`,h.events.filter(e=>e.type===`skip`).length,`)`]}),h.events.filter(e=>e.type===`skip`).map((e,t)=>(0,D.jsx)(Xe,{icon:`↷`,iconColor:v.textDim,label:e.message},t))]}),h.result.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:h.result.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠`,` `,e]},t))}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Back`}),(0,D.jsxs)(M,{variant:`primary`,onClick:F,disabled:te===0,"data-testid":`apply-button`,children:[`Migrate `,te,` file`,te===1?``:`s`]})]})]}),r===3&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:40},children:[(0,D.jsx)(`div`,{style:{width:40,height:40,border:`3px solid ${v.border}`,borderTopColor:v.accent,borderRadius:`50%`,animation:`spin 1s linear infinite`,marginBottom:16}}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,color:v.textMuted},children:`Migrating... this may take a moment`}),(0,D.jsx)(`style`,{children:`@keyframes spin { to { transform: rotate(360deg); } }`})]}),r===4&&C&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:32},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:C.result.rolledBack?v.redDim:v.greenDim,border:`1px solid ${C.result.rolledBack?v.red+`44`:v.green+`44`}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:C.result.rolledBack?v.red:v.green,marginBottom:16},children:C.result.rolledBack?`⚠`:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:C.result.rolledBack?v.red:v.green,marginBottom:8},children:C.result.rolledBack?`Migration failed`:`Migration complete`}),C.result.rolledBack&&C.result.error&&(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.red,marginBottom:8,textAlign:`center`},children:C.result.error}),C.result.rolledBack&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:8},children:`All changes have been rolled back.`}),!C.result.rolledBack&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[C.result.migratedFiles.length,` migrated,`,` `,C.result.skippedFiles.length,` skipped,`,` `,C.result.verifiedFiles.length,` verified`]})]}),C.result.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:C.result.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠`,` `,e]},t))}),!C.result.rolledBack&&(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`10px 14px`,marginBottom:24,fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[`git add clef.yaml .sops.yaml secrets/ && git commit -m "chore: migrate backend to`,` `,s,`"`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Migrate again`})]})]})]})})]})}function Je({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function Ye({children:e,color:t}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,fontWeight:600,color:t,letterSpacing:`0.06em`,textTransform:`uppercase`,marginBottom:8},children:e})}function Xe({icon:e,iconColor:t,label:n}){return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`5px 10px`,borderRadius:6,marginBottom:3},children:[(0,D.jsx)(`span`,{style:{color:t,fontFamily:v.mono,fontSize:13},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:v.text},children:n})]})}var Ze=[`age`,`awskms`,`gcpkms`,`azurekv`,`pgp`],Qe={age:`age`,awskms:`AWS KMS`,gcpkms:`GCP KMS`,azurekv:`Azure Key Vault`,pgp:`PGP`},$e={awskms:`arn:aws:kms:region:account:key/id`,gcpkms:`projects/.../locations/.../keyRings/.../cryptoKeys/...`,azurekv:`https://vault-name.vault.azure.net/keys/key-name/version`,pgp:`PGP fingerprint`};function et({manifest:e,setView:t,reloadManifest:n}){let r=e?.environments??[],i=e?.namespaces??[],a=r[0]?.name??``,o=i[0]?.name??``,[s,c]=(0,g.useState)(`idle`),[l,u]=(0,g.useState)(null),[d,f]=(0,g.useState)(`env`),[p,m]=(0,g.useState)(a),[h,_]=(0,g.useState)(o),[y,b]=(0,g.useState)(o),[x,S]=(0,g.useState)(a),[C,w]=(0,g.useState)(!1),[E,O]=(0,g.useState)(`age`),[k,j]=(0,g.useState)(``),[N,P]=(0,g.useState)(``),[F,I]=(0,g.useState)(``),[ee,te]=(0,g.useState)(null),L=d===`env`?p?{kind:`env`,name:p}:null:d===`namespace`?h?{kind:`namespace`,name:h}:null:y&&x?{kind:`cell`,namespace:y,environment:x}:null,R=L?L.kind===`env`?`env ${L.name}`:L.kind===`namespace`?`namespace ${L.name}`:`${L.namespace}/${L.environment}`:``,ne=C&&E!==`age`&&k.trim().length===0,re=F===R&&R.length>0,ie=L!==null&&re&&!ne&&s===`idle`,ae=ee?Object.values(ee.pendingKeysByCell).reduce((e,t)=>e+t.length,0):0,oe=async()=>{if(!L)return;c(`running`),u(null);let e=N.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),t={scope:L};C&&(t.backend=E,E!==`age`&&(t.key=k.trim())),e.length>0&&(t.keys=e);try{let e=await T(`/api/reset`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!e.ok){u((await e.json().catch(()=>({error:`Reset failed`}))).error??`Reset failed`),c(`idle`);return}te((await e.json()).result),n(),c(`done`)}catch(e){u(e instanceof Error?e.message:`Reset failed`),c(`idle`)}},se=()=>{c(`idle`),te(null),u(null),I(``)};return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Reset`,subtitle:`clef reset — destructively scaffold fresh placeholders`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[l&&(0,D.jsx)(`div`,{"data-testid":`reset-error`,style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:l}),s===`idle`&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(tt,{children:`Scope`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:16,marginBottom:10},children:[`env`,`namespace`,`cell`].map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`reset-scope-kind`,checked:d===e,onChange:()=>{f(e),I(``)},"data-testid":`reset-scope-${e}`,style:{accentColor:v.accent}}),e===`env`?`Environment`:e===`namespace`?`Namespace`:`Cell`]},e))}),d===`env`&&(0,D.jsx)(`select`,{value:p,onChange:e=>{m(e.target.value),I(``)},"data-testid":`reset-env-select`,style:nt,children:r.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))}),d===`namespace`&&(0,D.jsx)(`select`,{value:h,onChange:e=>{_(e.target.value),I(``)},"data-testid":`reset-namespace-select`,style:nt,children:i.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))}),d===`cell`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsx)(`select`,{value:y,onChange:e=>{b(e.target.value),I(``)},"data-testid":`reset-cell-namespace-select`,style:{...nt,flex:1},children:i.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))}),(0,D.jsx)(`select`,{value:x,onChange:e=>{S(e.target.value),I(``)},"data-testid":`reset-cell-env-select`,style:{...nt,flex:1},children:r.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))})]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:v.text},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:C,onChange:e=>w(e.target.checked),"data-testid":`reset-switch-backend`,style:{accentColor:v.accent}}),`Switch backend as part of reset`]}),C&&(0,D.jsxs)(`div`,{style:{marginTop:12,padding:14,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8},children:[(0,D.jsx)(tt,{children:`Target Backend`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ze.map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:E===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`reset-target-backend`,checked:E===e,onChange:()=>{O(e),j(``)},"data-testid":`reset-backend-radio-${e}`,style:{accentColor:v.accent}}),Qe[e]]},e))}),E!==`age`&&(0,D.jsxs)(`div`,{style:{marginTop:12},children:[(0,D.jsx)(tt,{children:`Key Identifier`}),(0,D.jsx)(`input`,{type:`text`,value:k,onChange:e=>j(e.target.value),placeholder:$e[E],"data-testid":`reset-backend-key-input`,style:rt})]})]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(tt,{children:`Explicit Keys (optional)`}),(0,D.jsx)(`input`,{type:`text`,value:N,onChange:e=>P(e.target.value),placeholder:`DB_URL, DB_PASSWORD`,"data-testid":`reset-keys-input`,style:rt}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted,marginTop:6},children:`Comma-separated. Ignored when the namespace has a schema — schema keys are authoritative.`})]}),(0,D.jsxs)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`14px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red,lineHeight:1.5},children:[`⚠`,` This will `,(0,D.jsx)(`strong`,{children:`ABANDON`}),` the current encrypted contents of the affected cells. Decryption will `,(0,D.jsx)(`strong`,{children:`NOT`}),` be attempted. This cannot be undone except via `,(0,D.jsx)(`code`,{children:`git revert`}),`.`]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsxs)(tt,{children:[`Type `,(0,D.jsx)(`code`,{style:{color:v.text},children:R||`<scope>`}),` to confirm`]}),(0,D.jsx)(`input`,{type:`text`,value:F,onChange:e=>I(e.target.value),placeholder:R,"data-testid":`reset-confirm-input`,disabled:!L,style:rt})]}),(0,D.jsxs)(M,{variant:`primary`,onClick:oe,disabled:!ie,"data-testid":`reset-submit`,children:[`Reset `,R||`<scope>`]})]}),s===`running`&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:40},"data-testid":`reset-running`,children:[(0,D.jsx)(`div`,{style:{width:40,height:40,border:`3px solid ${v.border}`,borderTopColor:v.accent,borderRadius:`50%`,animation:`spin 1s linear infinite`,marginBottom:16}}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:14,color:v.textMuted},children:[`Resetting `,R,`...`]}),(0,D.jsx)(`style`,{children:`@keyframes spin { to { transform: rotate(360deg); } }`})]}),s===`done`&&ee&&(0,D.jsxs)(`div`,{"data-testid":`reset-done`,children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:24},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:v.greenDim,border:`1px solid ${v.green}44`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:v.green,marginBottom:16},children:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:v.green,marginBottom:8},children:`Reset complete`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[ee.scaffoldedCells.length,` cell`,ee.scaffoldedCells.length===1?``:`s`,` scaffolded`,ae>0?`, ${ae} pending placeholder${ae===1?``:`s`}`:``]})]}),ee.backendChanged&&(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`10px 14px`,marginBottom:16,fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[`Backend override written for: `,ee.affectedEnvironments.join(`, `)]}),ae>0&&(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:16,lineHeight:1.5},children:[`Run `,(0,D.jsx)(`code`,{children:`clef set`}),` (or use the namespace editor) to replace placeholders with real values.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),"data-testid":`reset-view-matrix`,children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:se,"data-testid":`reset-start-over`,children:`Reset another`})]})]})]})})]})}function tt({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}var nt={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},rt={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`};function it({manifest:e}){let t=e?.namespaces??[],n=e?.environments??[],[r,i]=(0,g.useState)(t[0]?.name??``),[a,o]=(0,g.useState)(n[0]?.name??``),[s,c]=(0,g.useState)([]),[l,u]=(0,g.useState)(!1),[d,f]=(0,g.useState)(null);(0,g.useEffect)(()=>{t.length>0&&!r&&i(t[0].name),n.length>0&&!a&&o(n[0].name)},[t,n,r,a]);let p=(0,g.useCallback)(async()=>{if(!(!r||!a)){u(!0),f(null);try{let e=await T(`/api/git/log/${r}/${a}`);e.ok?c((await e.json()).log):(f((await e.json().catch(()=>({}))).error??`Failed to load history`),c([]))}catch{f(`Network error — could not load history`),c([])}finally{u(!1)}}},[r,a]);return(0,g.useEffect)(()=>{p()},[p]),(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`History`,subtitle:`Commit log per encrypted file`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,padding:`16px 24px`,borderBottom:`1px solid ${v.border}`},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[`Namespace`,(0,D.jsx)(`select`,{value:r,onChange:e=>i(e.target.value),style:{fontFamily:v.mono,fontSize:12,background:v.surface,color:v.text,border:`1px solid ${v.border}`,borderRadius:4,padding:`3px 8px`},children:t.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))})]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[`Environment`,(0,D.jsx)(`select`,{value:a,onChange:e=>o(e.target.value),style:{fontFamily:v.mono,fontSize:12,background:v.surface,color:v.text,border:`1px solid ${v.border}`,borderRadius:4,padding:`3px 8px`},children:n.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))})]})]}),(0,D.jsxs)(`div`,{style:{flex:1,overflow:`auto`,padding:`0 24px 24px`},children:[l&&(0,D.jsx)(`div`,{style:{padding:24,color:v.textMuted,fontFamily:v.mono,fontSize:12},children:`Loading…`}),!l&&d&&(0,D.jsx)(`div`,{style:{padding:24,color:v.red,fontFamily:v.mono,fontSize:12},children:d}),!l&&!d&&s.length===0&&(0,D.jsxs)(`div`,{style:{padding:24,color:v.textMuted,fontFamily:v.mono,fontSize:12},children:[`No commits found for `,r,`/`,a,`.`]}),!l&&!d&&s.length>0&&(0,D.jsxs)(`table`,{style:{width:`100%`,borderCollapse:`collapse`,fontFamily:v.mono,fontSize:12,marginTop:16},children:[(0,D.jsx)(`thead`,{children:(0,D.jsxs)(`tr`,{style:{borderBottom:`1px solid ${v.border}`,color:v.textDim},children:[(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px 6px 0`,fontWeight:600},children:`Hash`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px`,fontWeight:600},children:`Date`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px`,fontWeight:600},children:`Author`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 0`,fontWeight:600},children:`Message`})]})}),(0,D.jsx)(`tbody`,{children:s.map(e=>(0,D.jsxs)(`tr`,{style:{borderBottom:`1px solid ${v.border}22`},children:[(0,D.jsx)(`td`,{style:{padding:`8px 12px 8px 0`,color:v.accent},children:e.hash.slice(0,7)}),(0,D.jsx)(`td`,{style:{padding:`8px 12px`,color:v.textMuted,whiteSpace:`nowrap`},children:new Date(e.date).toLocaleDateString()}),(0,D.jsx)(`td`,{style:{padding:`8px 12px`,color:v.textMuted},children:e.author}),(0,D.jsx)(`td`,{style:{padding:`8px 0`,color:v.text},children:e.message})]},e.hash))})]})]})]})}function at(){let[e,t]=(0,g.useState)(`matrix`),[n,r]=(0,g.useState)(``),[i,a]=(0,g.useState)(``),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)([]),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(0),[_,y]=(0,g.useState)(0),[b,x]=(0,g.useState)(0),S=(0,g.useCallback)(async()=>{try{let e=await T(`/api/manifest`);if(e.ok){let t=await e.json();l(t),r(e=>e||(t.namespaces[0]?.name??``))}}catch{}finally{s(!1)}},[]),C=(0,g.useCallback)(async()=>{try{let e=await T(`/api/matrix`);e.ok&&d(await e.json())}catch{}},[]),w=(0,g.useCallback)(async()=>{try{let e=await T(`/api/git/status`);e.ok&&p(await e.json())}catch{}},[]),E=(0,g.useCallback)(async()=>{try{let e=await T(`/api/lint`);e.ok&&h((await e.json()).issues.filter(e=>e.severity===`error`).length)}catch{}},[]),k=(0,g.useCallback)(async()=>{try{let e=await T(`/api/scan/status`);if(e.ok){let t=await e.json();t.lastRun&&y((t.lastRun.matches?.length??0)+(t.lastRun.unencryptedMatrixFiles?.length??0))}}catch{}},[]),A=(0,g.useCallback)(async()=>{try{let e=await T(`/api/policy/check`);e.ok&&x((await e.json()).summary?.rotation_overdue??0)}catch{}},[]);return(0,g.useEffect)(()=>{S(),C(),w(),E(),k(),A()},[S,C,w,E,k,A]),(0,g.useEffect)(()=>{S(),C()},[e,S,C]),o?(0,D.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`center`,height:`100vh`,background:v.bg,color:v.textMuted,fontFamily:v.sans},children:(0,D.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,D.jsx)(`div`,{style:{fontSize:24,color:v.accent,marginBottom:12},children:`♪`}),(0,D.jsx)(`div`,{style:{fontSize:13},children:`Loading...`})]})}):(0,D.jsxs)(`div`,{style:{display:`flex`,height:`100vh`,background:v.bg,color:v.text,fontFamily:v.sans,overflow:`hidden`},children:[(0,D.jsx)(O,{activeView:e,setView:t,activeNs:n,setNs:r,manifest:c,matrixStatuses:u,gitStatus:f,lintErrorCount:m,scanIssueCount:_,policyOverdueCount:b}),(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[e===`matrix`&&(0,D.jsx)(R,{setView:t,setNs:r,setEnv:a,manifest:c,matrixStatuses:u,reloadMatrix:C}),e===`editor`&&(0,D.jsx)(ne,{ns:n,initialEnv:i,manifest:c}),e===`diff`&&(0,D.jsx)(ae,{manifest:c}),e===`lint`&&(0,D.jsx)(oe,{setView:t,setNs:r}),e===`scan`&&(0,D.jsx)(se,{}),e===`policy`&&(0,D.jsx)(me,{setView:t,setNs:r}),e===`import`&&(0,D.jsx)(he,{manifest:c,setView:t}),e===`recipients`&&(0,D.jsx)(Le,{manifest:c,setView:t}),e===`identities`&&(0,D.jsx)(ze,{manifest:c}),e===`backend`&&(0,D.jsx)(qe,{manifest:c,setView:t,reloadManifest:S}),e===`reset`&&(0,D.jsx)(et,{manifest:c,setView:t,reloadManifest:S}),e===`cloud`&&null,e===`history`&&(0,D.jsx)(it,{manifest:c}),e===`manifest`&&(0,D.jsx)(xe,{manifest:c,reloadManifest:S})]})]})}w();var ot=document.getElementById(`root`);ot&&_.createRoot(ot).render((0,D.jsx)(g.StrictMode,{children:(0,D.jsx)(at,{})}));
38
+ # Comments are ignored`,rows:12,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:14,fontFamily:v.mono,fontSize:12,color:v.text,resize:`vertical`,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsx)(`div`,{style:{marginBottom:24,padding:`10px 14px`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,fontFamily:v.sans,fontSize:11,color:v.textMuted,lineHeight:1.5},children:`Values are sent directly to the local Clef server (127.0.0.1) and encrypted immediately. They are never stored in browser memory beyond this session.`}),(0,D.jsx)(M,{variant:`primary`,onClick:O,disabled:b||!c.trim(),children:b?`Previewing...`:`Next: Preview`})]}),n===2&&f&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,marginBottom:20},children:[`Importing to`,` `,(0,D.jsxs)(`span`,{style:{color:v.accent,fontWeight:600},children:[i,`/`,o]}),`. `,f.totalKeys,` key`,f.totalKeys===1?``:`s`,` parsed.`]}),f.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:f.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠ `,e]},t))}),f.wouldImport.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.green,children:[`New keys (`,f.wouldImport.length,`)`]}),f.wouldImport.map(e=>(0,D.jsx)(be,{icon:`\\u2192`,iconColor:v.green,label:e},e))]}),f.wouldSkip.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.yellow,children:[`Already exists (`,f.wouldSkip.length,`) — toggle to overwrite`]}),f.wouldSkip.map(({key:e,reason:t})=>{let n=m.includes(e);return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`6px 10px`,borderRadius:6,marginBottom:4,background:n?v.yellowDim:`transparent`,border:`1px solid ${n?v.yellow+`44`:v.border}`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:n,onChange:()=>N(e),style:{accentColor:v.yellow},id:`overwrite-${e}`}),(0,D.jsx)(`label`,{htmlFor:`overwrite-${e}`,style:{fontFamily:v.mono,fontSize:12,color:n?v.yellow:v.textMuted,flex:1,cursor:`pointer`},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:t})]},e)})]}),f.wouldImport.length===0&&f.wouldSkip.length===0&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,padding:`24px 0`,textAlign:`center`},children:`No importable keys found.`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:()=>r(1),children:`Back`}),(0,D.jsx)(M,{variant:`primary`,onClick:k,disabled:b||P===0,children:b?`Importing...`:`Import ${P} key${P===1?``:`s`}`})]})]}),n===3&&_&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:32},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:_.failed.length>0?v.redDim:v.greenDim,border:`1px solid ${_.failed.length>0?v.red+`44`:v.green+`44`}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:_.failed.length>0?v.red:v.green,marginBottom:16},children:_.failed.length>0?`⚠`:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:_.failed.length>0?v.yellow:v.green,marginBottom:8},children:_.failed.length>0?`Import completed with errors`:`Import complete`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[_.imported.length,` imported, `,_.skipped.length,` skipped,`,` `,_.failed.length,` failed`]})]}),_.imported.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.green,children:[`Imported (`,_.imported.length,`)`]}),_.imported.map(e=>(0,D.jsx)(be,{icon:`\\u2713`,iconColor:v.green,label:e},e))]}),_.failed.length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(ye,{color:v.red,children:[`Failed (`,_.failed.length,`)`]}),_.failed.map(({key:e,error:t})=>(0,D.jsx)(be,{icon:`\\u2717`,iconColor:v.red,label:e,note:t},e))]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:j,children:`Import more`})]})]})]})})]})}function ge({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function _e({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim,marginBottom:4},children:e})}function ve({value:e,onChange:t,children:n}){return(0,D.jsx)(`select`,{value:e,onChange:t,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},children:n})}function ye({children:e,color:t}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,fontWeight:600,color:t,letterSpacing:`0.06em`,textTransform:`uppercase`,marginBottom:8},children:e})}function be({icon:e,iconColor:t,label:n,note:r}){return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`5px 10px`,borderRadius:6,marginBottom:3},children:[(0,D.jsx)(`span`,{style:{color:t,fontFamily:v.mono,fontSize:13},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:v.text,flex:1},children:n}),r&&(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:r})]})}function xe({manifest:e,reloadManifest:t}){let[n,r]=(0,g.useState)({kind:`none`}),[i,a]=(0,g.useState)(null),o=(0,g.useCallback)(()=>{r({kind:`none`}),a(null)},[]);if(!e)return(0,D.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`},children:(0,D.jsx)(A,{title:`Manifest`,subtitle:`Loading...`})});let s=e.namespaces,c=e.environments;return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Manifest`,subtitle:`${s.length} namespaces \u00B7 ${c.length} environments`}),(0,D.jsxs)(`div`,{style:{flex:1,overflow:`auto`,padding:28},children:[(0,D.jsx)(Se,{title:`Namespaces`,actionLabel:`+ Namespace`,onAction:()=>r({kind:`addNamespace`}),actionTestId:`add-namespace-btn`,children:s.length===0?(0,D.jsx)(Te,{message:`No namespaces declared yet.`}):(0,D.jsx)(Ce,{children:s.map(e=>(0,D.jsx)(we,{testId:`namespace-row-${e.name}`,name:e.name,description:e.description,badges:e.schema?[{label:`schema: ${e.schema}`,color:v.purple}]:[],onEdit:()=>r({kind:`editNamespace`,ns:e}),onDelete:()=>r({kind:`removeNamespace`,ns:e})},e.name))})}),(0,D.jsx)(`div`,{style:{marginTop:36},children:(0,D.jsx)(Se,{title:`Environments`,actionLabel:`+ Environment`,onAction:()=>r({kind:`addEnvironment`}),actionTestId:`add-environment-btn`,children:c.length===0?(0,D.jsx)(Te,{message:`No environments declared yet.`}):(0,D.jsx)(Ce,{children:c.map(e=>(0,D.jsx)(we,{testId:`environment-row-${e.name}`,name:e.name,description:e.description,badges:e.protected?[{label:`protected`,color:v.red}]:[],onEdit:()=>r({kind:`editEnvironment`,env:e}),onDelete:()=>r({kind:`removeEnvironment`,env:e})},e.name))})})})]}),n.kind===`addNamespace`&&(0,D.jsx)(Me,{onClose:o,onSubmit:async e=>{let n=await T(`/api/namespaces`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return n.ok?(t(),o(),!0):(a((await n.json()).error??`Failed to add namespace`),!1)},existingNames:s.map(e=>e.name),error:i,setError:a}),n.kind===`editNamespace`&&(0,D.jsx)(Ne,{ns:n.ns,existingNames:s.map(e=>e.name),onClose:o,onSubmit:async e=>{let r=await T(`/api/namespaces/${encodeURIComponent(n.ns.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return r.ok?(t(),o(),!0):(a((await r.json()).error??`Failed to edit namespace`),!1)},error:i,setError:a}),n.kind===`removeNamespace`&&(0,D.jsx)(Ie,{title:`Delete namespace`,subjectKind:`namespace`,subjectName:n.ns.name,impactDescription:`This will delete every encrypted cell file under '${n.ns.name}/' across all environments and remove '${n.ns.name}' from any service identity that references it.`,onClose:o,onConfirm:async()=>{let e=await T(`/api/namespaces/${encodeURIComponent(n.ns.name)}`,{method:`DELETE`});return e.ok?(t(),o(),!0):(a((await e.json()).error??`Failed to remove namespace`),!1)},error:i}),n.kind===`addEnvironment`&&(0,D.jsx)(Pe,{existingNames:c.map(e=>e.name),onClose:o,onSubmit:async e=>{let n=await T(`/api/environments`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return n.ok?(t(),o(),!0):(a((await n.json()).error??`Failed to add environment`),!1)},error:i,setError:a}),n.kind===`editEnvironment`&&(0,D.jsx)(Fe,{env:n.env,existingNames:c.map(e=>e.name),onClose:o,onSubmit:async e=>{let r=await T(`/api/environments/${encodeURIComponent(n.env.name)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});return r.ok?(t(),o(),!0):(a((await r.json()).error??`Failed to edit environment`),!1)},error:i,setError:a}),n.kind===`removeEnvironment`&&(0,D.jsx)(Ie,{title:`Delete environment`,subjectKind:`environment`,subjectName:n.env.name,impactDescription:n.env.protected?`'${n.env.name}' is a protected environment and will be refused. Run "Edit" first and unprotect it before removing.`:`This will delete every encrypted cell file for '${n.env.name}' across all namespaces and remove the '${n.env.name}' entry from every service identity.`,onClose:o,onConfirm:async()=>{let e=await T(`/api/environments/${encodeURIComponent(n.env.name)}`,{method:`DELETE`});return e.ok?(t(),o(),!0):(a((await e.json()).error??`Failed to remove environment`),!1)},error:i})]})}function Se(e){return(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:14},children:[(0,D.jsx)(`h2`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.text,margin:0,letterSpacing:`-0.01em`},children:e.title}),(0,D.jsx)(M,{variant:`primary`,onClick:e.onAction,"data-testid":e.actionTestId,children:e.actionLabel})]}),e.children]})}function Ce(e){return(0,D.jsx)(`div`,{style:{border:`1px solid ${v.border}`,borderRadius:8,background:v.surface,overflow:`hidden`},children:e.children})}function we(e){return(0,D.jsxs)(`div`,{"data-testid":e.testId,style:{display:`flex`,alignItems:`center`,padding:`12px 16px`,borderBottom:`1px solid ${v.border}`,gap:12},children:[(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:13,fontWeight:600,color:v.text,display:`flex`,alignItems:`center`,gap:8},children:[e.name,e.badges.map(e=>(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:10,fontWeight:500,color:e.color,background:`${e.color}14`,border:`1px solid ${e.color}33`,borderRadius:10,padding:`1px 8px`},children:e.label},e.label))]}),e.description&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginTop:2},children:e.description})]}),(0,D.jsx)(M,{onClick:e.onEdit,"data-testid":`${e.testId}-edit`,children:`Edit`}),(0,D.jsx)(M,{onClick:e.onDelete,"data-testid":`${e.testId}-delete`,children:`Delete`})]})}function Te(e){return(0,D.jsx)(`div`,{style:{padding:24,border:`1px dashed ${v.border}`,borderRadius:8,textAlign:`center`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:e.message})}function Ee(e){return(0,D.jsx)(`div`,{"data-testid":`manifest-modal`,onClick:e.onClose,style:{position:`fixed`,inset:0,background:`rgba(0,0,0,0.55)`,display:`flex`,alignItems:`center`,justifyContent:`center`,zIndex:100},children:(0,D.jsxs)(`div`,{onClick:e=>e.stopPropagation(),style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:10,padding:24,width:480,maxWidth:`90vw`},children:[(0,D.jsx)(`h3`,{style:{fontFamily:v.sans,fontSize:16,fontWeight:600,color:v.text,margin:`0 0 16px`},children:e.title}),e.children]})})}function De(e){return(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(`label`,{style:{display:`block`,fontFamily:v.sans,fontSize:11,fontWeight:600,color:v.textMuted,marginBottom:4,textTransform:`uppercase`,letterSpacing:`0.05em`},children:e.label}),e.children,e.hint&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted,marginTop:4},children:e.hint})]})}function Oe(e){return(0,D.jsx)(`input`,{type:`text`,value:e.value,onChange:t=>e.onChange(t.target.value),placeholder:e.placeholder,"data-testid":e.testId,autoFocus:e.autoFocus,style:{width:`100%`,padding:`8px 12px`,background:v.bg,border:`1px solid ${v.border}`,borderRadius:6,color:v.text,fontFamily:v.mono,fontSize:13,boxSizing:`border-box`}})}function ke(e){return(0,D.jsx)(`div`,{"data-testid":`manifest-modal-error`,style:{padding:`8px 12px`,background:`${v.red}14`,border:`1px solid ${v.red}33`,borderRadius:6,color:v.red,fontFamily:v.sans,fontSize:12,marginBottom:12},children:e.message})}function Ae(e){return(0,D.jsx)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8,marginTop:8},children:e.children})}function je(e){return/^[A-Za-z0-9._-]+$/.test(e)}function Me(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(``),[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(!1),l=t.trim(),u=e.existingNames.includes(l),d=l.length>0&&je(l)&&!u,f=l?je(l)?u?`A namespace named '${l}' already exists.`:null:`Use letters, numbers, '.', '_', or '-' only.`:null;return(0,D.jsxs)(Ee,{title:`Add namespace`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:f??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},placeholder:`payments`,testId:`namespace-name-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,placeholder:`Payment processing secrets`,testId:`namespace-description-input`})}),(0,D.jsx)(De,{label:`Schema (optional)`,hint:`Path to a YAML schema file in the repo.`,children:(0,D.jsx)(Oe,{value:a,onChange:o,placeholder:`schemas/payments.yaml`,testId:`namespace-schema-input`})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`namespace-add-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!d||s,"data-testid":`namespace-add-submit`,onClick:async()=>{c(!0),await e.onSubmit({name:l,description:r.trim()||void 0,schema:a.trim()||void 0}),c(!1)},children:s?`Adding...`:`Add namespace`})]})]})}function Ne(e){let[t,n]=(0,g.useState)(e.ns.name),[r,i]=(0,g.useState)(e.ns.description??``),[a,o]=(0,g.useState)(e.ns.schema??``),[s,c]=(0,g.useState)(!1),l=t.trim(),u=l!==e.ns.name,d=u&&e.existingNames.includes(l),f=!u||je(l)&&!d,p=l?f?null:d?`A namespace named '${l}' already exists.`:`Use letters, numbers, '.', '_', or '-' only.`:`Name cannot be empty.`,m=u||r!==(e.ns.description??``)||a!==(e.ns.schema??``);return(0,D.jsxs)(Ee,{title:`Edit namespace '${e.ns.name}'`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:p??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},testId:`namespace-rename-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,testId:`namespace-description-input`})}),(0,D.jsx)(De,{label:`Schema (optional)`,hint:`Empty to clear.`,children:(0,D.jsx)(Oe,{value:a,onChange:o,testId:`namespace-schema-input`})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`namespace-edit-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!m||!!p||s,"data-testid":`namespace-edit-submit`,onClick:async()=>{c(!0);let t={};u&&(t.rename=l),r!==(e.ns.description??``)&&(t.description=r),a!==(e.ns.schema??``)&&(t.schema=a),await e.onSubmit(t),c(!1)},children:s?`Saving...`:`Save changes`})]})]})}function Pe(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(``),[a,o]=(0,g.useState)(!1),[s,c]=(0,g.useState)(!1),l=t.trim(),u=e.existingNames.includes(l),d=l.length>0&&je(l)&&!u,f=l?je(l)?u?`An environment named '${l}' already exists.`:null:`Use letters, numbers, '.', '_', or '-' only.`:null;return(0,D.jsxs)(Ee,{title:`Add environment`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:f??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},placeholder:`staging`,testId:`environment-name-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,placeholder:`Pre-production`,testId:`environment-description-input`})}),(0,D.jsx)(`div`,{style:{marginBottom:14},children:(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.sans,fontSize:12,color:v.text,cursor:`pointer`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(e.target.checked),"data-testid":`environment-protected-checkbox`}),`Mark as protected`]})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`environment-add-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!d||s,"data-testid":`environment-add-submit`,onClick:async()=>{c(!0),await e.onSubmit({name:l,description:r.trim()||void 0,protected:a||void 0}),c(!1)},children:s?`Adding...`:`Add environment`})]})]})}function Fe(e){let[t,n]=(0,g.useState)(e.env.name),[r,i]=(0,g.useState)(e.env.description??``),[a,o]=(0,g.useState)(e.env.protected===!0),[s,c]=(0,g.useState)(!1),l=t.trim(),u=l!==e.env.name,d=u&&e.existingNames.includes(l),f=!u||je(l)&&!d,p=l?f?null:d?`An environment named '${l}' already exists.`:`Use letters, numbers, '.', '_', or '-' only.`:`Name cannot be empty.`,m=a!==(e.env.protected===!0),h=u||r!==(e.env.description??``)||m;return(0,D.jsxs)(Ee,{title:`Edit environment '${e.env.name}'`,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(De,{label:`Name`,hint:p??void 0,children:(0,D.jsx)(Oe,{value:t,onChange:t=>{n(t),e.setError(null)},testId:`environment-rename-input`,autoFocus:!0})}),(0,D.jsx)(De,{label:`Description`,children:(0,D.jsx)(Oe,{value:r,onChange:i,testId:`environment-description-input`})}),(0,D.jsx)(`div`,{style:{marginBottom:14},children:(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.sans,fontSize:12,color:v.text,cursor:`pointer`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(e.target.checked),"data-testid":`environment-protected-checkbox`}),`Protected (write operations require confirmation)`]})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`environment-edit-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!h||!!p||s,"data-testid":`environment-edit-submit`,onClick:async()=>{c(!0);let t={};u&&(t.rename=l),r!==(e.env.description??``)&&(t.description=r),m&&(t.protected=a),await e.onSubmit(t),c(!1)},children:s?`Saving...`:`Save changes`})]})]})}function Ie(e){let[t,n]=(0,g.useState)(``),[r,i]=(0,g.useState)(!1),a=t===e.subjectName;return(0,D.jsxs)(Ee,{title:e.title,onClose:e.onClose,children:[e.error&&(0,D.jsx)(ke,{message:e.error}),(0,D.jsx)(`p`,{style:{fontFamily:v.sans,fontSize:12,color:v.text,margin:`0 0 12px`,lineHeight:1.5},children:e.impactDescription}),(0,D.jsx)(De,{label:`Type the ${e.subjectKind} name to confirm`,children:(0,D.jsx)(Oe,{value:t,onChange:n,placeholder:e.subjectName,testId:`${e.subjectKind}-remove-confirm-input`,autoFocus:!0})}),(0,D.jsxs)(Ae,{children:[(0,D.jsx)(M,{onClick:e.onClose,"data-testid":`${e.subjectKind}-remove-cancel`,children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,disabled:!a||r,"data-testid":`${e.subjectKind}-remove-submit`,onClick:async()=>{i(!0),await e.onConfirm(),i(!1)},children:r?`Deleting...`:`Delete ${e.subjectKind}`})]})]})}function Le({manifest:e,setView:t}){let[n,r]=(0,g.useState)([]),[i,a]=(0,g.useState)(0),[o,s]=(0,g.useState)(!1),[c,l]=(0,g.useState)(``),[u,d]=(0,g.useState)(``),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(!1),[_,y]=(0,g.useState)(null),[b,x]=(0,g.useState)(null),[S,C]=(0,g.useState)(0),[w,E]=(0,g.useState)(!1),[O,k]=(0,g.useState)(null),j=(0,g.useRef)(null),N=(0,g.useCallback)(async()=>{try{let e=await T(`/api/recipients`);if(e.ok){let t=await e.json();r(t.recipients),a(t.totalFiles)}}catch{}},[]);(0,g.useEffect)(()=>{N()},[N]),(0,g.useEffect)(()=>{if(!c.trim()){p(null);return}return j.current&&clearTimeout(j.current),j.current=setTimeout(async()=>{try{let e=await T(`/api/recipients/validate?key=${encodeURIComponent(c.trim())}`);e.ok&&p(await e.json())}catch{}},300),()=>{j.current&&clearTimeout(j.current)}},[c]);let P=async()=>{if(f?.valid){h(!0),y(null);try{let e=await T(`/api/recipients/add`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:c.trim(),label:u.trim()||void 0})});if(!e.ok){y((await e.json()).error??`Failed to add recipient`);return}r((await e.json()).recipients),s(!1),l(``),d(``),p(null)}catch(e){y(e instanceof Error?e.message:`Failed to add recipient`)}finally{h(!1)}}},F=e=>{x(e),C(1),E(!1)},I=()=>{x(null),C(0),E(!1)};return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Recipients`,subtitle:`clef recipients -- manage age encryption keys`,actions:!o&&S===0?(0,D.jsx)(M,{variant:`primary`,onClick:()=>s(!0),children:`+ Add recipient`}):void 0}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[_&&(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:_}),O&&(0,D.jsxs)(`div`,{"data-testid":`rotation-banner`,style:{background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:8,padding:`14px 18px`,marginBottom:20},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,fontWeight:600,color:v.yellow,marginBottom:8},children:`Rotation reminder`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,marginBottom:10,lineHeight:1.5},children:[(0,D.jsx)(`strong`,{children:O.name}),` has been removed and files re-encrypted. However, the removed key may still decrypt old versions of these files from git history. Rotate secret values in the following targets to complete revocation:`]}),O.targets.length>0&&(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,marginBottom:12,paddingLeft:12},children:O.targets.map(e=>(0,D.jsx)(`div`,{style:{marginBottom:2},children:e},e))}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`Go to Matrix to rotate`}),(0,D.jsx)(M,{variant:`ghost`,onClick:()=>k(null),children:`Dismiss`})]})]}),o&&(0,D.jsxs)(`div`,{"data-testid":`add-form`,style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.text,marginBottom:16},children:`Add recipient`}),(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(Re,{children:`Age public key`}),(0,D.jsx)(`input`,{type:`text`,value:c,onChange:e=>l(e.target.value),placeholder:`age1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq`,"data-testid":`add-key-input`,style:{width:`100%`,background:v.bg,border:`1px solid ${f?f.valid?v.green+`66`:v.red+`66`:v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`}}),f&&!f.valid&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.red,marginTop:4},children:f.error}),f?.valid&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.green,marginTop:4},children:`Valid age public key`})]}),(0,D.jsxs)(`div`,{style:{marginBottom:14},children:[(0,D.jsx)(Re,{children:`Label (optional)`}),(0,D.jsx)(`input`,{type:`text`,value:u,onChange:e=>d(e.target.value),placeholder:`e.g. alice@example.com`,"data-testid":`add-label-input`,style:{width:`100%`,background:v.bg,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsxs)(`div`,{style:{marginBottom:16,padding:`10px 14px`,background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:6,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:[`Adding a recipient will re-encrypt `,i,` file`,i===1?``:`s`,`. This may take a moment.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:()=>{s(!1),l(``),d(``),p(null),y(null)},children:`Cancel`}),(0,D.jsx)(M,{variant:`primary`,onClick:P,disabled:m||!f?.valid,children:m?`Re-encrypting...`:`Add and re-encrypt`})]})]}),S===1&&b&&(0,D.jsxs)(`div`,{"data-testid":`remove-dialog`,style:{background:v.surface,border:`1px solid ${v.red}44`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.red,marginBottom:12},children:`Remove recipient`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,lineHeight:1.6,marginBottom:16},children:[`You are about to remove`,` `,(0,D.jsx)(`strong`,{style:{color:v.accent},children:b.label??b.preview}),` `,`(`,b.preview,`). All `,i,` encrypted file`,i===1?``:`s`,` will be re-encrypted without this key.`]}),(0,D.jsxs)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:6,padding:`12px 14px`,marginBottom:16,fontFamily:v.sans,fontSize:12,color:v.red,lineHeight:1.5},children:[`Re-encryption only removes `,(0,D.jsx)(`em`,{children:`future`}),` access. The removed key can still decrypt old versions from git history. You must rotate all secret values after removal.`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:v.text,marginBottom:16},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:w,onChange:e=>E(e.target.checked),"data-testid":`acknowledge-checkbox`,style:{accentColor:v.red,marginTop:2}}),`I understand — I will rotate secrets after removal`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Cancel`}),(0,D.jsx)(M,{variant:`danger`,onClick:()=>C(2),disabled:!w,children:`Continue`})]})]}),S===2&&b&&(0,D.jsxs)(`div`,{"data-testid":`remove-confirm-dialog`,style:{background:v.surface,border:`1px solid ${v.red}44`,borderRadius:10,padding:20,marginBottom:24},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,fontWeight:600,color:v.red,marginBottom:12},children:`Confirm removal`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.text,lineHeight:1.6,marginBottom:16},children:[`This will remove`,` `,(0,D.jsx)(`strong`,{style:{color:v.accent},children:b.label??b.preview}),` `,`and re-encrypt all `,i,` file`,i===1?``:`s`,`. This cannot be undone.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Cancel`}),(0,D.jsx)(M,{variant:`danger`,onClick:async()=>{if(b){h(!0),y(null);try{let e=await T(`/api/recipients/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:b.key})});if(!e.ok){y((await e.json()).error??`Failed to remove recipient`);return}let t=await e.json();r(t.recipients),k({name:b.label??b.preview,targets:t.rotationReminder??[]}),I()}catch(e){y(e instanceof Error?e.message:`Failed to remove recipient`)}finally{h(!1)}}},disabled:m,children:m?`Re-encrypting...`:`Remove and re-encrypt`})]})]}),n.length===0&&!o&&(0,D.jsx)(`div`,{style:{textAlign:`center`,paddingTop:40,fontFamily:v.sans,fontSize:14,color:v.textMuted},children:`No recipients configured. Add an age public key to get started.`}),n.length>0&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,letterSpacing:`0.05em`,textTransform:`uppercase`,marginBottom:10},children:[`Recipients (`,n.length,`)`]}),n.map(e=>(0,D.jsxs)(`div`,{"data-testid":`recipient-row`,style:{display:`flex`,alignItems:`center`,gap:14,padding:`12px 16px`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,marginBottom:8},children:[(0,D.jsx)(`div`,{style:{width:32,height:32,borderRadius:6,background:v.accentDim,border:`1px solid ${v.accent}44`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:14,flexShrink:0},children:`🔑`}),(0,D.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[e.label&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,fontWeight:600,color:v.text,marginBottom:2},children:e.label}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},children:e.preview})]}),(0,D.jsx)(M,{variant:`ghost`,onClick:()=>F(e),disabled:S!==0||m,children:`Remove`})]},e.key)),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textDim,marginTop:12},children:[i,` encrypted file`,i===1?``:`s`,` in the matrix`]})]})]})})]})}function Re({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function ze({manifest:e}){let[t,n]=(0,g.useState)(`list`),[r,i]=(0,g.useState)([]),[a,o]=(0,g.useState)(null),[s,c]=(0,g.useState)(``),[l,u]=(0,g.useState)(``),[d,f]=(0,g.useState)(``),[p,m]=(0,g.useState)(new Set),[h,_]=(0,g.useState)({}),[y,b]=(0,g.useState)(`ci`),[x,S]=(0,g.useState)(!0),[C,w]=(0,g.useState)(!1),[E,O]=(0,g.useState)(!1),[k,j]=(0,g.useState)(``),[P,F]=(0,g.useState)({}),[I,ee]=(0,g.useState)(``),[te,L]=(0,g.useState)(!1),[R,ne]=(0,g.useState)({}),[ie,ae]=(0,g.useState)(!1),[oe,se]=(0,g.useState)(``),[ce,le]=(0,g.useState)(void 0),[ue,de]=(0,g.useState)({}),[fe,pe]=(0,g.useState)(!1),[me,he]=(0,g.useState)(``),ge=(0,g.useCallback)(async()=>{try{let e=await T(`/api/service-identities`);e.ok&&i((await e.json()).identities)}catch{}},[]);(0,g.useEffect)(()=>{ge()},[ge]);let _e=r.find(e=>e.name===a),ve=(0,g.useCallback)(()=>{u(``),f(``),m(new Set);let t={};for(let n of e?.environments??[])t[n.name]={type:`age`,provider:`aws`,keyId:``};_(t),b(`ci`),S(!0),w(!1),j(``),n(`create`)},[e]),ye=(0,g.useCallback)(e=>{let t={};for(let[n,r]of Object.entries(e.environments)){let e=r.type===`kms`?`kms`:`age`;t[n]={type:e,provider:r.kms?.provider??`aws`,keyId:r.kms?.keyId??``,originalType:e,originalKeyId:r.kms?.keyId??``}}ne(t),se(``),n(`update`)},[]),be=(0,g.useCallback)(()=>{o(null),c(``),n(`list`)},[]),xe=(0,g.useCallback)(()=>{c(``),he(``),n(`detail`)},[]);async function Se(){O(!0),j(``);try{let e={};for(let[t,n]of Object.entries(h))n.type===`kms`&&(e[t]={provider:n.provider,keyId:n.keyId});let t={name:l.trim(),description:d.trim(),namespaces:Array.from(p)};y===`runtime`&&(t.packOnly=!0),x?t.sharedRecipient=!0:Object.keys(e).length>0&&(t.kmsEnvConfigs=e);let r=await T(`/api/service-identities`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}),i=await r.json();if(!r.ok){j(i.error??`Failed to create service identity.`);return}ee(i.identity.name),F(i.privateKeys??{}),L(i.sharedRecipient===!0),n(`keys`)}catch{j(`Network error. Check that the UI server is running.`)}finally{O(!1)}}async function Ce(){if(a){ae(!0),se(``);try{let e={};for(let[t,n]of Object.entries(R))n.type===`kms`&&(n.originalType!==`kms`||n.keyId!==n.originalKeyId)&&(e[t]={provider:n.provider,keyId:n.keyId});if(Object.keys(e).length===0){se(`No changes to apply.`);return}let t=await T(`/api/service-identities/${encodeURIComponent(a)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kmsEnvConfigs:e})}),n=await t.json();if(!t.ok){se(n.error??`Failed to update service identity.`);return}await ge(),xe()}catch{se(`Network error. Check that the UI server is running.`)}finally{ae(!1)}}}async function we(e){if(a){le(e),c(``);try{let t=await T(`/api/service-identities/${encodeURIComponent(a)}/rotate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({environment:e})}),r=await t.json();if(!t.ok){c(r.error??`Failed to rotate key.`);return}de(r.privateKeys??{}),await ge(),n(`rotate-keys`)}catch{c(`Network error. Check that the UI server is running.`)}finally{le(void 0)}}}async function Te(){if(a){pe(!0),he(``);try{let e=await T(`/api/service-identities/${encodeURIComponent(a)}`,{method:`DELETE`});if(!e.ok){he((await e.json()).error??`Failed to delete service identity.`);return}await ge(),be()}catch{he(`Network error. Check that the UI server is running.`)}finally{pe(!1)}}}if(t===`list`)return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Service Identities`,subtitle:`Per-service cryptographic access scoping`,actions:e&&(0,D.jsx)(M,{variant:`primary`,onClick:ve,children:`+ New identity`})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[s&&(0,D.jsx)(He,{children:s}),r.length===0&&(0,D.jsxs)(`div`,{style:{textAlign:`center`,padding:`48px 24px`,color:v.textMuted,fontFamily:v.sans,fontSize:13},children:[(0,D.jsx)(`div`,{style:{fontSize:28,marginBottom:12,opacity:.4},children:`🔑`}),`No service identities configured.`,e&&(0,D.jsx)(`div`,{style:{marginTop:16,display:`flex`,justifyContent:`center`},children:(0,D.jsx)(M,{variant:`primary`,onClick:ve,children:`Create the first one`})})]}),r.map(e=>(0,D.jsxs)(`div`,{role:`button`,tabIndex:0,"data-testid":`si-${e.name}`,onClick:()=>{o(e.name),c(``),n(`detail`)},onKeyDown:t=>{t.key===`Enter`&&(o(e.name),n(`detail`))},style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`16px 20px`,marginBottom:8,cursor:`pointer`,transition:`all 0.12s`},onMouseEnter:e=>{e.currentTarget.style.borderColor=v.borderLight},onMouseLeave:e=>{e.currentTarget.style.borderColor=v.border},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,marginBottom:8},children:[(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:14,color:v.text},children:e.name}),e.packOnly&&(0,D.jsx)(`span`,{"data-testid":`si-runtime-badge-${e.name}`,style:{fontFamily:v.mono,fontSize:9,color:v.yellow,background:`${v.yellow}15`,border:`1px solid ${v.yellow}33`,borderRadius:3,padding:`1px 6px`},children:`runtime`})]}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:[`Scoped to: `,(0,D.jsx)(`span`,{style:{color:v.text},children:e.namespaces.join(`, `)})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`},children:Object.entries(e.environments).map(([e,t])=>(0,D.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:4},children:[(0,D.jsx)(N,{env:e,small:!0}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:9,color:t.type===`kms`?v.purple:v.textDim},children:t.type===`kms`?`KMS`:`age`})]},e))})]},e.name))]})})]});if(t===`detail`)return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:_e?.name??a??``,subtitle:_e?.description,actions:(0,D.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[_e&&(0,D.jsx)(M,{"data-testid":`update-backends-btn`,variant:`ghost`,onClick:()=>ye(_e),children:`Update backends`}),(0,D.jsxs)(`button`,{"data-testid":`back-button`,onClick:be,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted,transition:`all 0.12s`},children:[`←`,` Back`]})]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[s&&(0,D.jsx)(He,{children:s}),_e&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Be,{children:`Scoped namespaces`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:6},children:_e.namespaces.map(e=>(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,background:v.accentDim,border:`1px solid ${v.accent}33`,borderRadius:4,padding:`2px 8px`},children:e},e))})]}),_e.packOnly&&(0,D.jsx)(`div`,{"data-testid":`runtime-info-banner`,style:{background:`${v.yellow}10`,border:`1px solid ${v.yellow}33`,borderRadius:8,padding:`10px 16px`,marginBottom:20,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:`Runtime identity — keys are not registered on encrypted files. This identity can only decrypt packed artifacts.`}),(0,D.jsx)(Be,{children:`Environment keys`}),e?.environments.map(e=>{let t=_e.environments[e.name];if(!t)return null;let n=t.protected??!1,r=ce===e.name;return(0,D.jsxs)(`div`,{"data-testid":`env-${e.name}`,style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`16px 20px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:12},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10},children:[(0,D.jsx)(N,{env:e.name}),n&&(0,D.jsx)(`span`,{style:{fontSize:12,color:v.red},children:`🔒`}),t.type===`kms`&&(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:10,color:v.purple,background:v.purpleDim,border:`1px solid ${v.purple}33`,borderRadius:3,padding:`1px 6px`},children:`KMS`})]}),t.type===`age`&&(0,D.jsx)(`button`,{"data-testid":`rotate-${e.name}`,disabled:r,onClick:()=>we(e.name),style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:5,padding:`3px 10px`,cursor:r?`default`:`pointer`,fontFamily:v.sans,fontSize:11,color:r?v.textDim:v.textMuted,opacity:r?.5:1},children:r?`Rotating…`:`Rotate key`})]}),t.type===`kms`&&t.kms&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[(0,D.jsxs)(`div`,{style:{marginBottom:8},children:[`Authentication: `,(0,D.jsx)(`span`,{style:{color:v.purple},children:`IAM + KMS`})]}),(0,D.jsxs)(`div`,{children:[`Provider:`,` `,(0,D.jsx)(`span`,{style:{color:v.text},children:t.kms.provider})]}),(0,D.jsxs)(`div`,{style:{marginTop:4},children:[`Key ID:`,` `,(0,D.jsx)(`span`,{style:{color:v.text,wordBreak:`break-all`},children:t.kms.keyId})]}),(0,D.jsx)(`div`,{style:{marginTop:10,padding:`8px 12px`,background:v.purpleDim,border:`1px solid ${v.purple}33`,borderRadius:4,fontSize:11,color:v.purple,fontFamily:v.sans},children:`No keys to provision. CI and runtime authenticate via IAM role with kms:Decrypt permission.`})]}),t.type===`age`&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[(0,D.jsxs)(`div`,{style:{marginBottom:8},children:[`Authentication: `,(0,D.jsx)(`span`,{style:{color:v.green},children:`age key`})]}),(0,D.jsxs)(`div`,{children:[`Public key:`,` `,(0,D.jsx)(`span`,{style:{color:v.text},children:t.publicKey?`${t.publicKey.slice(0,12)}...${t.publicKey.slice(-6)}`:`unknown`})]})]})]},e.name)}),(0,D.jsx)(`div`,{style:{marginTop:32,paddingTop:20,borderTop:`1px solid ${v.border}`,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{"data-testid":`delete-identity-btn`,variant:`danger`,onClick:()=>{he(``),n(`delete-confirm`)},children:`Delete identity`})})]})]})})]});if(t===`delete-confirm`)return(0,D.jsxs)(`div`,{"data-testid":`delete-confirm-view`,style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Delete service identity`,subtitle:`This action cannot be undone`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[me&&(0,D.jsx)(He,{children:me}),(0,D.jsxs)(`div`,{style:{background:`#1a0a0a`,border:`1px solid ${v.red}55`,borderRadius:8,padding:`16px 20px`,marginBottom:24,fontFamily:v.sans,fontSize:13,color:v.red},children:[(0,D.jsxs)(`div`,{style:{fontWeight:600,marginBottom:8},children:[`Delete `,(0,D.jsx)(`span`,{style:{fontFamily:v.mono},children:a}),`?`]}),(0,D.jsxs)(`div`,{style:{color:v.textMuted,fontSize:12,lineHeight:1.6},children:[`This will remove the identity from`,` `,(0,D.jsx)(`span`,{style:{fontFamily:v.mono},children:`clef.yaml`}),` and de-register its recipients from all scoped encrypted files. Any runtimes currently using this identity's private key will lose access on the next artifact refresh.`]})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{"data-testid":`cancel-delete-btn`,variant:`ghost`,onClick:xe,disabled:fe,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`confirm-delete-btn`,variant:`danger`,onClick:Te,disabled:fe,children:fe?`Deleting…`:`Delete identity`})]})]})})]});if(t===`rotate-keys`)return(0,D.jsxs)(`div`,{"data-testid":`rotate-keys-view`,style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Key rotated`,subtitle:`New keys for ${a}`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[(0,D.jsxs)(`div`,{style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.yellow,display:`flex`,gap:10,alignItems:`flex-start`},children:[(0,D.jsx)(`span`,{style:{fontSize:16,flexShrink:0},children:`⚠`}),(0,D.jsx)(`span`,{children:`Copy the new private key now — it will not be shown again. Provision it to the runtime and invalidate the old key.`})]}),(0,D.jsx)(Be,{children:`New private keys`}),Object.entries(ue).map(([e,t])=>(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsx)(N,{env:e}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]},e)),(0,D.jsx)(`div`,{style:{marginTop:8,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{"data-testid":`rotate-done-btn`,variant:`primary`,onClick:xe,children:`Done`})})]})})]});if(t===`update`){let t=e?.environments??[],n=Object.values(R).filter(e=>e.type===`kms`?e.originalType!==`kms`||e.keyId!==e.originalKeyId:!1).length>0&&Object.entries(R).every(([,e])=>e.type===`kms`?e.keyId.trim()!==``:!0);return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Update backends`,subtitle:`Environment backends for ${a}`,actions:(0,D.jsxs)(`button`,{onClick:xe,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:[`←`,` Cancel`]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[oe&&(0,D.jsx)(He,{children:oe}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:16,lineHeight:1.6},children:`Switch age environments to KMS, or update an existing KMS key ID. To revert KMS to age, delete and recreate the identity.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8,marginBottom:28},children:t.map(e=>{let t=R[e.name];return t?(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 16px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:t.type===`kms`?12:0},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(N,{env:e.name}),e.protected&&(0,D.jsx)(`span`,{style:{fontSize:11,color:v.red},children:`🔒`})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:4},children:[`age`,`kms`].map(n=>{let r=t.originalType===`kms`&&n===`age`;return(0,D.jsx)(`button`,{"data-testid":n===`kms`?`update-kms-toggle-${e.name}`:void 0,disabled:r,onClick:()=>{r||ne(r=>({...r,[e.name]:{...t,type:n}}))},title:r?`KMS → age requires delete and recreate`:void 0,style:{background:t.type===n?n===`kms`?v.purple:v.accent:`transparent`,border:`1px solid ${t.type===n?n===`kms`?v.purple:v.accent:v.border}`,borderRadius:4,padding:`3px 10px`,cursor:r?`not-allowed`:`pointer`,fontFamily:v.mono,fontSize:11,color:t.type===n?`#fff`:v.textMuted,opacity:r?.4:1,transition:`all 0.1s`},children:n.toUpperCase()},n)})})]}),t.type===`kms`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsxs)(`select`,{value:t.provider,onChange:n=>ne(r=>({...r,[e.name]:{...t,provider:n.target.value}})),style:{...Ue,width:90,flexShrink:0,padding:`7px 8px`},children:[(0,D.jsx)(`option`,{value:`aws`,children:`AWS`}),(0,D.jsx)(`option`,{value:`gcp`,children:`GCP`}),(0,D.jsx)(`option`,{value:`azure`,children:`Azure`})]}),(0,D.jsx)(`input`,{"data-testid":`update-keyid-${e.name}`,value:t.keyId,onChange:n=>ne(r=>({...r,[e.name]:{...t,keyId:n.target.value}})),placeholder:`arn:aws:kms:… or key resource ID`,style:{...Ue,flex:1}})]})]},e.name):null})}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{"data-testid":`update-cancel-btn`,variant:`ghost`,onClick:xe,disabled:ie,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`update-submit-btn`,variant:`primary`,onClick:Ce,disabled:!n||ie,children:ie?`Saving…`:`Save changes`})]})]})})]})}if(t===`keys`){let e=Object.keys(P).length>0,t=te?Object.values(P)[0]:void 0,n=te?Object.keys(P):[];return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`${I} created`,subtitle:`Service identity ready`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[e&&(0,D.jsxs)(`div`,{style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.yellow,display:`flex`,gap:10,alignItems:`flex-start`},children:[(0,D.jsx)(`span`,{style:{fontSize:16,flexShrink:0},children:`⚠`}),(0,D.jsx)(`span`,{children:te?`Copy this key now — it will not be shown again. Set it as CLEF_AGE_KEY in your CI. It decrypts: ${n.join(`, `)}.`:`Copy these private keys now — they will not be shown again. Store each key securely and provision it to the relevant runtime.`})]}),!e&&(0,D.jsx)(`div`,{style:{background:v.purpleDim,border:`1px solid ${v.purple}44`,borderRadius:8,padding:`14px 18px`,marginBottom:20,fontFamily:v.sans,fontSize:13,color:v.purple},children:`All environments use KMS. No private keys to provision — runtimes authenticate via IAM role.`}),(0,D.jsx)(Be,{children:`Private keys`}),te&&t?(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.accent}44`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,flexWrap:`wrap`},children:[(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,fontWeight:600},children:`CLEF_AGE_KEY`}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textDim},children:`—`}),n.map(e=>(0,D.jsx)(N,{env:e,small:!0},e))]}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]}):Object.entries(P).map(([e,t])=>(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 18px`,marginBottom:10},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:10},children:[(0,D.jsx)(N,{env:e}),(0,D.jsx)(re,{text:t})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.textMuted,wordBreak:`break-all`,background:v.bg,borderRadius:4,padding:`8px 10px`},children:t})]},e)),(0,D.jsx)(`div`,{style:{marginTop:8,display:`flex`,justifyContent:`flex-end`},children:(0,D.jsx)(M,{variant:`primary`,onClick:()=>{ge(),be()},children:`Done`})})]})})]})}let Ee=e?.namespaces??[],De=e?.environments??[],Oe=l.trim()&&r.some(e=>e.name===l.trim())?`A service identity with this name already exists.`:``,ke=l.trim()!==``&&!Oe&&p.size>0&&De.every(e=>{let t=h[e.name];return t?.type===`age`||t?.type===`kms`&&t.provider&&t.keyId.trim()});return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`New service identity`,subtitle:`Scope cryptographic access to specific namespaces`,actions:(0,D.jsxs)(`button`,{onClick:be,style:{background:`none`,border:`1px solid ${v.borderLight}`,borderRadius:6,padding:`4px 12px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.textMuted},children:[`←`,` Cancel`]})}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:560,margin:`0 auto`},children:[k&&(0,D.jsx)(He,{children:k}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Ve,{children:`Name`}),(0,D.jsx)(`input`,{"data-testid":`si-name-input`,value:l,onChange:e=>u(e.target.value),placeholder:`e.g. api-gateway`,style:Ue}),Oe&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.red,marginTop:6},children:Oe})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Description (optional)`}),(0,D.jsx)(`input`,{value:d,onChange:e=>f(e.target.value),placeholder:`e.g. API gateway service account`,style:Ue})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Role`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:0,borderRadius:6,overflow:`hidden`,border:`1px solid ${v.border}`,width:`fit-content`,marginBottom:8},children:[`ci`,`runtime`].map(e=>(0,D.jsx)(`button`,{"data-testid":`role-${e}`,onClick:()=>{b(e),S(e===`ci`),w(!1)},style:{background:y===e?v.accent:`transparent`,border:`none`,padding:`7px 18px`,cursor:`pointer`,fontFamily:v.sans,fontSize:12,fontWeight:y===e?600:400,color:y===e?`#fff`:v.textMuted,transition:`all 0.12s`},children:e===`ci`?`CI`:`Runtime`},e))}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,lineHeight:1.5},children:y===`ci`?`Decrypts files directly. Keys are registered on encrypted SOPS files. Use for CI pipelines and local tools.`:`Decrypts packed artifacts only. Keys are NOT added to encrypted files — smaller blast radius for deployment targets (Lambda, ECS, containers).`})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Ve,{children:`Namespaces`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:`This identity can decrypt secrets only from the selected namespaces.`}),Ee.length===0&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textDim},children:`No namespaces defined in manifest.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ee.map(e=>{let t=p.has(e.name);return(0,D.jsxs)(`label`,{"data-testid":`ns-checkbox-${e.name}`,style:{display:`flex`,alignItems:`center`,gap:10,padding:`10px 14px`,background:t?v.accentDim:v.surface,border:`1px solid ${t?v.accent+`55`:v.border}`,borderRadius:6,cursor:`pointer`,transition:`all 0.1s`},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:t,onChange:t=>{let n=new Set(p);t.target.checked?n.add(e.name):n.delete(e.name),m(n)},style:{accentColor:v.accent}}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:t?v.accent:v.text},children:e.name}),e.description&&(0,D.jsxs)(`span`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted},children:[`— `,e.description]})]},e.name)})})]}),(0,D.jsxs)(`div`,{style:{marginBottom:28},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:6},children:[(0,D.jsx)(Ve,{children:`Environment backends`}),(0,D.jsxs)(`label`,{"data-testid":`shared-recipient-toggle`,style:{display:`flex`,alignItems:`center`,gap:7,cursor:`pointer`,fontFamily:v.sans,fontSize:11,color:x?v.accent:v.textMuted,userSelect:`none`},children:[(0,D.jsxs)(`div`,{style:{width:28,height:16,borderRadius:8,background:x?v.accent:v.border,position:`relative`,transition:`background 0.15s`,flexShrink:0},children:[(0,D.jsx)(`div`,{style:{position:`absolute`,top:2,left:x?14:2,width:12,height:12,borderRadius:`50%`,background:`#fff`,transition:`left 0.15s`}}),(0,D.jsx)(`input`,{type:`checkbox`,checked:x,onChange:e=>{S(e.target.checked);let t=y===`ci`;w(e.target.checked!==t)},style:{position:`absolute`,opacity:0,width:0,height:0}})]}),`Shared age key`]})]}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:10},children:x?`One age key pair for all environments — one CI secret, easier to provision.`:`Age generates a key pair per environment. KMS uses your cloud provider — no key material is provisioned.`}),C&&(0,D.jsx)(`div`,{"data-testid":`shared-recipient-warning`,style:{background:`#1a1200`,border:`1px solid ${v.yellow}55`,borderRadius:6,padding:`10px 14px`,marginBottom:10,fontFamily:v.sans,fontSize:12,color:v.yellow,lineHeight:1.5},children:y===`ci`&&!x?`Most CI pipelines use a single key. Per-environment keys are useful when your CI environments have separate secret access controls (e.g. GitHub environment protection rules).`:`Runtime workloads typically use per-environment keys for isolation. A shared key means a compromised key in any environment decrypts artifacts for all environments.`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:x?(0,D.jsxs)(`div`,{style:{background:v.accentDim,border:`1px solid ${v.accent}44`,borderRadius:8,padding:`14px 16px`,display:`flex`,alignItems:`center`,gap:12},children:[(0,D.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`},children:De.map(e=>(0,D.jsx)(N,{env:e.name,small:!0},e.name))}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:11,color:v.accent,marginLeft:`auto`},children:`age (shared)`})]}):De.map(e=>{let t=h[e.name]??{type:`age`,provider:`aws`,keyId:``};return(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:`14px 16px`},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,marginBottom:t.type===`kms`?12:0},children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(N,{env:e.name}),e.protected&&(0,D.jsx)(`span`,{style:{fontSize:11,color:v.red},children:`🔒`})]}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:4},children:[`age`,`kms`].map(n=>(0,D.jsx)(`button`,{onClick:()=>_(r=>({...r,[e.name]:{...t,type:n}})),style:{background:t.type===n?n===`kms`?v.purple:v.accent:`transparent`,border:`1px solid ${t.type===n?n===`kms`?v.purple:v.accent:v.border}`,borderRadius:4,padding:`3px 10px`,cursor:`pointer`,fontFamily:v.mono,fontSize:11,color:t.type===n?`#fff`:v.textMuted,transition:`all 0.1s`},children:n.toUpperCase()},n))})]}),t.type===`kms`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsxs)(`select`,{value:t.provider,onChange:n=>_(r=>({...r,[e.name]:{...t,provider:n.target.value}})),style:{...Ue,width:90,flexShrink:0,padding:`7px 8px`},children:[(0,D.jsx)(`option`,{value:`aws`,children:`AWS`}),(0,D.jsx)(`option`,{value:`gcp`,children:`GCP`}),(0,D.jsx)(`option`,{value:`azure`,children:`Azure`})]}),(0,D.jsx)(`input`,{value:t.keyId,onChange:n=>_(r=>({...r,[e.name]:{...t,keyId:n.target.value}})),placeholder:`arn:aws:kms:… or key resource ID`,style:{...Ue,flex:1}})]})]},e.name)})})]}),(0,D.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:8},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:be,disabled:E,children:`Cancel`}),(0,D.jsx)(M,{"data-testid":`create-si-submit`,variant:`primary`,onClick:Se,disabled:!ke||E,children:E?`Creating…`:`Create identity`})]})]})})]})}function Be({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function Ve({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:6},children:e})}function He({children:e}){return(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:e})}var Ue={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`},We={age:`age`,awskms:`AWS KMS`,gcpkms:`GCP KMS`,azurekv:`Azure Key Vault`,pgp:`PGP`,hsm:`HSM (PKCS#11)`},Ge={awskms:`arn:aws:kms:region:account:key/id`,gcpkms:`projects/.../locations/.../keyRings/.../cryptoKeys/...`,azurekv:`https://vault-name.vault.azure.net/keys/key-name/version`,pgp:`PGP fingerprint`,hsm:`pkcs11:slot=0;label=clef-dek-wrapper`},Ke=[`age`,`awskms`,`gcpkms`,`azurekv`,`pgp`,`hsm`];function qe({manifest:e,setView:t,reloadManifest:n}){let[r,i]=(0,g.useState)(1),[a,o]=(0,g.useState)(null),[s,c]=(0,g.useState)(`age`),[l,u]=(0,g.useState)(``),[d,f]=(0,g.useState)(`all`),[p,m]=(0,g.useState)(``),[h,_]=(0,g.useState)(null),[y,b]=(0,g.useState)(!1),[x,S]=(0,g.useState)(!1),[C,w]=(0,g.useState)(null),[E,O]=(0,g.useState)(!1),[k,j]=(0,g.useState)(null);(0,g.useEffect)(()=>{N()},[]),(0,g.useEffect)(()=>{e&&e.environments.length>0&&!p&&m(e.environments[0].name)},[e,p]);let N=async()=>{try{let e=await T(`/api/backend-config`);e.ok&&o(await e.json())}catch{}},P=async(e=!1)=>{O(!0),j(null);let t={target:{backend:s,key:s===`age`?void 0:l},environment:d===`single`?p:void 0,confirmed:e||void 0};try{let e=await T(`/api/migrate-backend/preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(e.status===409){b(!0),O(!1);return}if(!e.ok){j((await e.json()).error??`Preview failed`),O(!1);return}_(await e.json()),b(!1),S(!1),i(2)}catch(e){j(e instanceof Error?e.message:`Preview failed`)}finally{O(!1)}},F=async()=>{i(3),j(null);let e={target:{backend:s,key:s===`age`?void 0:l},environment:d===`single`?p:void 0,confirmed:!0};try{let t=await T(`/api/migrate-backend/apply`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){j((await t.json()).error??`Migration failed`),i(2);return}w(await t.json()),n(),i(4)}catch(e){j(e instanceof Error?e.message:`Migration failed`),i(2)}},I=()=>{i(1),_(null),w(null),b(!1),S(!1),j(null),N()},ee=e?.environments??[],te=h?.events.filter(e=>e.type===`info`&&e.message.startsWith(`Would`)).length??0;return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Backend`,subtitle:`clef migrate-backend — change encryption backend`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[(0,D.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:0,marginBottom:32},children:[1,2,3,4].map((e,t)=>(0,D.jsxs)(g.Fragment,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,D.jsx)(`div`,{style:{width:24,height:24,borderRadius:`50%`,background:r>=e?v.accent:v.surface,border:`1px solid ${r>=e?v.accent:v.border}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontFamily:v.mono,fontSize:11,fontWeight:700,color:r>=e?`#000`:v.textDim},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.sans,fontSize:12,color:r>=e?v.text:v.textDim,fontWeight:r===e?600:400},children:e===1?`Configure`:e===2?`Preview`:e===3?`Migrate`:`Done`})]}),t<3&&(0,D.jsx)(`div`,{style:{flex:1,height:1,background:r>e?v.accent:v.border,margin:`0 12px`,minWidth:20}})]},e))}),k&&(0,D.jsx)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:k}),r===1&&(0,D.jsxs)(`div`,{children:[a&&(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Je,{children:`Current Configuration`}),(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:8,padding:14},children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.text,marginBottom:8},children:[`Default backend:`,` `,(0,D.jsx)(`span`,{style:{color:v.accent,fontWeight:600},children:We[a.global.default_backend]})]}),a.environments.map(e=>(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,fontFamily:v.mono,fontSize:11,color:v.textMuted,marginBottom:2},children:[(0,D.jsxs)(`span`,{children:[e.protected?`🔒 `:``,e.name]}),(0,D.jsx)(`span`,{style:{color:v.textDim},children:`→`}),(0,D.jsxs)(`span`,{style:{color:e.hasOverride?v.yellow:v.textMuted},children:[We[e.effective.backend],e.hasOverride?` (override)`:``]})]},e.name))]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Je,{children:`Target Backend`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ke.map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:s===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`backend`,value:e,checked:s===e,onChange:()=>{c(e),u(``)},style:{accentColor:v.accent},"data-testid":`backend-radio-${e}`}),We[e]]},e))})]}),s!==`age`&&(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(Je,{children:`Key Identifier`}),(0,D.jsx)(`input`,{type:`text`,value:l,onChange:e=>u(e.target.value),placeholder:Ge[s],"data-testid":`backend-key-input`,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`}})]}),(0,D.jsxs)(`div`,{style:{marginBottom:24},children:[(0,D.jsx)(Je,{children:`Scope`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:16,marginBottom:8},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===`all`?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`scope`,checked:d===`all`,onChange:()=>f(`all`),style:{accentColor:v.accent}}),`All environments`]}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===`single`?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`scope`,checked:d===`single`,onChange:()=>f(`single`),style:{accentColor:v.accent}}),`Single environment`]})]}),d===`single`&&(0,D.jsx)(`select`,{value:p,onChange:e=>m(e.target.value),"data-testid":`env-select`,style:{width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},children:ee.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))})]}),y&&(0,D.jsxs)(`div`,{style:{background:v.yellowDim,border:`1px solid ${v.yellow}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16},children:[(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.yellow,marginBottom:8},children:`This migration affects protected environments.`}),(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:12,color:v.text},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:x,onChange:e=>S(e.target.checked),style:{accentColor:v.yellow},"data-testid":`protected-confirm`}),`I understand and want to proceed`]})]}),(0,D.jsx)(M,{variant:`primary`,onClick:()=>P(x),disabled:E||s!==`age`&&!l.trim(),children:E?`Loading...`:y&&x?`Confirm & Preview`:`Preview`})]}),r===2&&h&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:13,color:v.textMuted,marginBottom:20},children:[`Migrating to`,` `,(0,D.jsx)(`span`,{style:{color:v.accent,fontWeight:600},children:We[s]}),d===`single`?` (${p} only)`:` (all environments)`]}),h.events.filter(e=>e.type===`info`).length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(Ye,{color:v.green,children:[`Files to migrate (`,h.events.filter(e=>e.type===`info`).length,`)`]}),h.events.filter(e=>e.type===`info`).map((e,t)=>(0,D.jsx)(Xe,{icon:`→`,iconColor:v.green,label:e.message},t))]}),h.events.filter(e=>e.type===`skip`).length>0&&(0,D.jsxs)(`div`,{style:{marginBottom:16},children:[(0,D.jsxs)(Ye,{color:v.textDim,children:[`Already on target (`,h.events.filter(e=>e.type===`skip`).length,`)`]}),h.events.filter(e=>e.type===`skip`).map((e,t)=>(0,D.jsx)(Xe,{icon:`↷`,iconColor:v.textDim,label:e.message},t))]}),h.result.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:h.result.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠`,` `,e]},t))}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10,marginTop:24},children:[(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Back`}),(0,D.jsxs)(M,{variant:`primary`,onClick:F,disabled:te===0,"data-testid":`apply-button`,children:[`Migrate `,te,` file`,te===1?``:`s`]})]})]}),r===3&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:40},children:[(0,D.jsx)(`div`,{style:{width:40,height:40,border:`3px solid ${v.border}`,borderTopColor:v.accent,borderRadius:`50%`,animation:`spin 1s linear infinite`,marginBottom:16}}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:14,color:v.textMuted},children:`Migrating... this may take a moment`}),(0,D.jsx)(`style`,{children:`@keyframes spin { to { transform: rotate(360deg); } }`})]}),r===4&&C&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:32},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:C.result.rolledBack?v.redDim:v.greenDim,border:`1px solid ${C.result.rolledBack?v.red+`44`:v.green+`44`}`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:C.result.rolledBack?v.red:v.green,marginBottom:16},children:C.result.rolledBack?`⚠`:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:C.result.rolledBack?v.red:v.green,marginBottom:8},children:C.result.rolledBack?`Migration failed`:`Migration complete`}),C.result.rolledBack&&C.result.error&&(0,D.jsx)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.red,marginBottom:8,textAlign:`center`},children:C.result.error}),C.result.rolledBack&&(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:8},children:`All changes have been rolled back.`}),!C.result.rolledBack&&(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[C.result.migratedFiles.length,` migrated,`,` `,C.result.skippedFiles.length,` skipped,`,` `,C.result.verifiedFiles.length,` verified`]})]}),C.result.warnings.length>0&&(0,D.jsx)(`div`,{style:{marginBottom:16},children:C.result.warnings.map((e,t)=>(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:11,color:v.yellow,marginBottom:4},children:[`⚠`,` `,e]},t))}),!C.result.rolledBack&&(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`10px 14px`,marginBottom:24,fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[`git add clef.yaml .sops.yaml secrets/ && git commit -m "chore: migrate backend to`,` `,s,`"`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:I,children:`Migrate again`})]})]})]})})]})}function Je({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}function Ye({children:e,color:t}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,fontWeight:600,color:t,letterSpacing:`0.06em`,textTransform:`uppercase`,marginBottom:8},children:e})}function Xe({icon:e,iconColor:t,label:n}){return(0,D.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`5px 10px`,borderRadius:6,marginBottom:3},children:[(0,D.jsx)(`span`,{style:{color:t,fontFamily:v.mono,fontSize:13},children:e}),(0,D.jsx)(`span`,{style:{fontFamily:v.mono,fontSize:12,color:v.text},children:n})]})}var Ze=[`age`,`awskms`,`gcpkms`,`azurekv`,`pgp`],Qe={age:`age`,awskms:`AWS KMS`,gcpkms:`GCP KMS`,azurekv:`Azure Key Vault`,pgp:`PGP`},$e={awskms:`arn:aws:kms:region:account:key/id`,gcpkms:`projects/.../locations/.../keyRings/.../cryptoKeys/...`,azurekv:`https://vault-name.vault.azure.net/keys/key-name/version`,pgp:`PGP fingerprint`};function et({manifest:e,setView:t,reloadManifest:n}){let r=e?.environments??[],i=e?.namespaces??[],a=r[0]?.name??``,o=i[0]?.name??``,[s,c]=(0,g.useState)(`idle`),[l,u]=(0,g.useState)(null),[d,f]=(0,g.useState)(`env`),[p,m]=(0,g.useState)(a),[h,_]=(0,g.useState)(o),[y,b]=(0,g.useState)(o),[x,S]=(0,g.useState)(a),[C,w]=(0,g.useState)(!1),[E,O]=(0,g.useState)(`age`),[k,j]=(0,g.useState)(``),[N,P]=(0,g.useState)(``),[F,I]=(0,g.useState)(``),[ee,te]=(0,g.useState)(null),L=d===`env`?p?{kind:`env`,name:p}:null:d===`namespace`?h?{kind:`namespace`,name:h}:null:y&&x?{kind:`cell`,namespace:y,environment:x}:null,R=L?L.kind===`env`?`env ${L.name}`:L.kind===`namespace`?`namespace ${L.name}`:`${L.namespace}/${L.environment}`:``,ne=C&&E!==`age`&&k.trim().length===0,re=F===R&&R.length>0,ie=L!==null&&re&&!ne&&s===`idle`,ae=ee?Object.values(ee.pendingKeysByCell).reduce((e,t)=>e+t.length,0):0,oe=async()=>{if(!L)return;c(`running`),u(null);let e=N.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),t={scope:L};C&&(t.backend=E,E!==`age`&&(t.key=k.trim())),e.length>0&&(t.keys=e);try{let e=await T(`/api/reset`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!e.ok){u((await e.json().catch(()=>({error:`Reset failed`}))).error??`Reset failed`),c(`idle`);return}te((await e.json()).result),n(),c(`done`)}catch(e){u(e instanceof Error?e.message:`Reset failed`),c(`idle`)}},se=()=>{c(`idle`),te(null),u(null),I(``)};return(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`Reset`,subtitle:`clef reset — destructively scaffold fresh placeholders`}),(0,D.jsx)(`div`,{style:{flex:1,overflow:`auto`,padding:24},children:(0,D.jsxs)(`div`,{style:{maxWidth:620,margin:`0 auto`},children:[l&&(0,D.jsx)(`div`,{"data-testid":`reset-error`,style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`12px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red},children:l}),s===`idle`&&(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(tt,{children:`Scope`}),(0,D.jsx)(`div`,{style:{display:`flex`,gap:16,marginBottom:10},children:[`env`,`namespace`,`cell`].map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:6,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:d===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`reset-scope-kind`,checked:d===e,onChange:()=>{f(e),I(``)},"data-testid":`reset-scope-${e}`,style:{accentColor:v.accent}}),e===`env`?`Environment`:e===`namespace`?`Namespace`:`Cell`]},e))}),d===`env`&&(0,D.jsx)(`select`,{value:p,onChange:e=>{m(e.target.value),I(``)},"data-testid":`reset-env-select`,style:nt,children:r.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))}),d===`namespace`&&(0,D.jsx)(`select`,{value:h,onChange:e=>{_(e.target.value),I(``)},"data-testid":`reset-namespace-select`,style:nt,children:i.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))}),d===`cell`&&(0,D.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,D.jsx)(`select`,{value:y,onChange:e=>{b(e.target.value),I(``)},"data-testid":`reset-cell-namespace-select`,style:{...nt,flex:1},children:i.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))}),(0,D.jsx)(`select`,{value:x,onChange:e=>{S(e.target.value),I(``)},"data-testid":`reset-cell-env-select`,style:{...nt,flex:1},children:r.map(e=>(0,D.jsxs)(`option`,{value:e.name,children:[e.name,e.protected?` (protected)`:``]},e.name))})]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:v.text},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:C,onChange:e=>w(e.target.checked),"data-testid":`reset-switch-backend`,style:{accentColor:v.accent}}),`Switch backend as part of reset`]}),C&&(0,D.jsxs)(`div`,{style:{marginTop:12,padding:14,background:v.surface,border:`1px solid ${v.border}`,borderRadius:8},children:[(0,D.jsx)(tt,{children:`Target Backend`}),(0,D.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6},children:Ze.map(e=>(0,D.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:8,cursor:`pointer`,fontFamily:v.sans,fontSize:13,color:E===e?v.text:v.textMuted},children:[(0,D.jsx)(`input`,{type:`radio`,name:`reset-target-backend`,checked:E===e,onChange:()=>{O(e),j(``)},"data-testid":`reset-backend-radio-${e}`,style:{accentColor:v.accent}}),Qe[e]]},e))}),E!==`age`&&(0,D.jsxs)(`div`,{style:{marginTop:12},children:[(0,D.jsx)(tt,{children:`Key Identifier`}),(0,D.jsx)(`input`,{type:`text`,value:k,onChange:e=>j(e.target.value),placeholder:$e[E],"data-testid":`reset-backend-key-input`,style:rt})]})]})]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsx)(tt,{children:`Explicit Keys (optional)`}),(0,D.jsx)(`input`,{type:`text`,value:N,onChange:e=>P(e.target.value),placeholder:`DB_URL, DB_PASSWORD`,"data-testid":`reset-keys-input`,style:rt}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:11,color:v.textMuted,marginTop:6},children:`Comma-separated. Ignored when the namespace has a schema — schema keys are authoritative.`})]}),(0,D.jsxs)(`div`,{style:{background:v.redDim,border:`1px solid ${v.red}44`,borderRadius:8,padding:`14px 16px`,marginBottom:16,fontFamily:v.sans,fontSize:13,color:v.red,lineHeight:1.5},children:[`⚠`,` This will `,(0,D.jsx)(`strong`,{children:`ABANDON`}),` the current encrypted contents of the affected cells. Decryption will `,(0,D.jsx)(`strong`,{children:`NOT`}),` be attempted. This cannot be undone except via `,(0,D.jsx)(`code`,{children:`git revert`}),`.`]}),(0,D.jsxs)(`div`,{style:{marginBottom:20},children:[(0,D.jsxs)(tt,{children:[`Type `,(0,D.jsx)(`code`,{style:{color:v.text},children:R||`<scope>`}),` to confirm`]}),(0,D.jsx)(`input`,{type:`text`,value:F,onChange:e=>I(e.target.value),placeholder:R,"data-testid":`reset-confirm-input`,disabled:!L,style:rt})]}),(0,D.jsxs)(M,{variant:`primary`,onClick:oe,disabled:!ie,"data-testid":`reset-submit`,children:[`Reset `,R||`<scope>`]})]}),s===`running`&&(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:40},"data-testid":`reset-running`,children:[(0,D.jsx)(`div`,{style:{width:40,height:40,border:`3px solid ${v.border}`,borderTopColor:v.accent,borderRadius:`50%`,animation:`spin 1s linear infinite`,marginBottom:16}}),(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:14,color:v.textMuted},children:[`Resetting `,R,`...`]}),(0,D.jsx)(`style`,{children:`@keyframes spin { to { transform: rotate(360deg); } }`})]}),s===`done`&&ee&&(0,D.jsxs)(`div`,{"data-testid":`reset-done`,children:[(0,D.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,alignItems:`center`,paddingTop:20,paddingBottom:24},children:[(0,D.jsx)(`div`,{style:{width:56,height:56,borderRadius:`50%`,background:v.greenDim,border:`1px solid ${v.green}44`,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:24,color:v.green,marginBottom:16},children:`✓`}),(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontWeight:600,fontSize:16,color:v.green,marginBottom:8},children:`Reset complete`}),(0,D.jsxs)(`div`,{style:{fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[ee.scaffoldedCells.length,` cell`,ee.scaffoldedCells.length===1?``:`s`,` scaffolded`,ae>0?`, ${ae} pending placeholder${ae===1?``:`s`}`:``]})]}),ee.backendChanged&&(0,D.jsxs)(`div`,{style:{background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`10px 14px`,marginBottom:16,fontFamily:v.mono,fontSize:11,color:v.textMuted},children:[`Backend override written for: `,ee.affectedEnvironments.join(`, `)]}),ae>0&&(0,D.jsxs)(`div`,{style:{fontFamily:v.sans,fontSize:12,color:v.textMuted,marginBottom:16,lineHeight:1.5},children:[`Run `,(0,D.jsx)(`code`,{children:`clef set`}),` (or use the namespace editor) to replace placeholders with real values.`]}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:10},children:[(0,D.jsx)(M,{variant:`primary`,onClick:()=>t(`matrix`),"data-testid":`reset-view-matrix`,children:`View in Matrix`}),(0,D.jsx)(M,{variant:`ghost`,onClick:se,"data-testid":`reset-start-over`,children:`Reset another`})]})]})]})})]})}function tt({children:e}){return(0,D.jsx)(`div`,{style:{fontFamily:v.sans,fontSize:12,fontWeight:600,color:v.textMuted,marginBottom:8,letterSpacing:`0.05em`,textTransform:`uppercase`},children:e})}var nt={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`7px 10px`,fontFamily:v.sans,fontSize:13,color:v.text,outline:`none`,cursor:`pointer`},rt={width:`100%`,background:v.surface,border:`1px solid ${v.border}`,borderRadius:6,padding:`8px 12px`,fontFamily:v.mono,fontSize:12,color:v.text,outline:`none`,boxSizing:`border-box`};function it({manifest:e}){let t=e?.namespaces??[],n=e?.environments??[],[r,i]=(0,g.useState)(t[0]?.name??``),[a,o]=(0,g.useState)(n[0]?.name??``),[s,c]=(0,g.useState)([]),[l,u]=(0,g.useState)(!1),[d,f]=(0,g.useState)(null);(0,g.useEffect)(()=>{t.length>0&&!r&&i(t[0].name),n.length>0&&!a&&o(n[0].name)},[t,n,r,a]);let p=(0,g.useCallback)(async()=>{if(!(!r||!a)){u(!0),f(null);try{let e=await T(`/api/git/log/${r}/${a}`);e.ok?c((await e.json()).log):(f((await e.json().catch(()=>({}))).error??`Failed to load history`),c([]))}catch{f(`Network error — could not load history`),c([])}finally{u(!1)}}},[r,a]);return(0,g.useEffect)(()=>{p()},[p]),(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[(0,D.jsx)(A,{title:`History`,subtitle:`Commit log per encrypted file`}),(0,D.jsxs)(`div`,{style:{display:`flex`,gap:12,padding:`16px 24px`,borderBottom:`1px solid ${v.border}`},children:[(0,D.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[`Namespace`,(0,D.jsx)(`select`,{value:r,onChange:e=>i(e.target.value),style:{fontFamily:v.mono,fontSize:12,background:v.surface,color:v.text,border:`1px solid ${v.border}`,borderRadius:4,padding:`3px 8px`},children:t.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))})]}),(0,D.jsxs)(`label`,{style:{display:`flex`,gap:8,alignItems:`center`,fontFamily:v.mono,fontSize:12,color:v.textMuted},children:[`Environment`,(0,D.jsx)(`select`,{value:a,onChange:e=>o(e.target.value),style:{fontFamily:v.mono,fontSize:12,background:v.surface,color:v.text,border:`1px solid ${v.border}`,borderRadius:4,padding:`3px 8px`},children:n.map(e=>(0,D.jsx)(`option`,{value:e.name,children:e.name},e.name))})]})]}),(0,D.jsxs)(`div`,{style:{flex:1,overflow:`auto`,padding:`0 24px 24px`},children:[l&&(0,D.jsx)(`div`,{style:{padding:24,color:v.textMuted,fontFamily:v.mono,fontSize:12},children:`Loading…`}),!l&&d&&(0,D.jsx)(`div`,{style:{padding:24,color:v.red,fontFamily:v.mono,fontSize:12},children:d}),!l&&!d&&s.length===0&&(0,D.jsxs)(`div`,{style:{padding:24,color:v.textMuted,fontFamily:v.mono,fontSize:12},children:[`No commits found for `,r,`/`,a,`.`]}),!l&&!d&&s.length>0&&(0,D.jsxs)(`table`,{style:{width:`100%`,borderCollapse:`collapse`,fontFamily:v.mono,fontSize:12,marginTop:16},children:[(0,D.jsx)(`thead`,{children:(0,D.jsxs)(`tr`,{style:{borderBottom:`1px solid ${v.border}`,color:v.textDim},children:[(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px 6px 0`,fontWeight:600},children:`Hash`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px`,fontWeight:600},children:`Date`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 12px`,fontWeight:600},children:`Author`}),(0,D.jsx)(`th`,{style:{textAlign:`left`,padding:`6px 0`,fontWeight:600},children:`Message`})]})}),(0,D.jsx)(`tbody`,{children:s.map(e=>(0,D.jsxs)(`tr`,{style:{borderBottom:`1px solid ${v.border}22`},children:[(0,D.jsx)(`td`,{style:{padding:`8px 12px 8px 0`,color:v.accent},children:e.hash.slice(0,7)}),(0,D.jsx)(`td`,{style:{padding:`8px 12px`,color:v.textMuted,whiteSpace:`nowrap`},children:new Date(e.date).toLocaleDateString()}),(0,D.jsx)(`td`,{style:{padding:`8px 12px`,color:v.textMuted},children:e.author}),(0,D.jsx)(`td`,{style:{padding:`8px 0`,color:v.text},children:e.message})]},e.hash))})]})]})]})}function at(){let[e,t]=(0,g.useState)(`matrix`),[n,r]=(0,g.useState)(``),[i,a]=(0,g.useState)(``),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)([]),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(0),[_,y]=(0,g.useState)(0),[b,x]=(0,g.useState)(0),S=(0,g.useCallback)(async()=>{try{let e=await T(`/api/manifest`);if(e.ok){let t=await e.json();l(t),r(e=>e||(t.namespaces[0]?.name??``))}}catch{}finally{s(!1)}},[]),C=(0,g.useCallback)(async()=>{try{let e=await T(`/api/matrix`);e.ok&&d(await e.json())}catch{}},[]),w=(0,g.useCallback)(async()=>{try{let e=await T(`/api/git/status`);e.ok&&p(await e.json())}catch{}},[]),E=(0,g.useCallback)(async()=>{try{let e=await T(`/api/lint`);e.ok&&h((await e.json()).issues.filter(e=>e.severity===`error`).length)}catch{}},[]),k=(0,g.useCallback)(async()=>{try{let e=await T(`/api/scan/status`);if(e.ok){let t=await e.json();t.lastRun&&y((t.lastRun.matches?.length??0)+(t.lastRun.unencryptedMatrixFiles?.length??0))}}catch{}},[]),A=(0,g.useCallback)(async()=>{try{let e=await T(`/api/policy/check`);e.ok&&x((await e.json()).summary?.rotation_overdue??0)}catch{}},[]);return(0,g.useEffect)(()=>{S(),C(),w(),E(),k(),A()},[S,C,w,E,k,A]),(0,g.useEffect)(()=>{S(),C()},[e,S,C]),o?(0,D.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`center`,height:`100vh`,background:v.bg,color:v.textMuted,fontFamily:v.sans},children:(0,D.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,D.jsx)(`div`,{style:{fontSize:24,color:v.accent,marginBottom:12},children:`♪`}),(0,D.jsx)(`div`,{style:{fontSize:13},children:`Loading...`})]})}):(0,D.jsxs)(`div`,{style:{display:`flex`,height:`100vh`,background:v.bg,color:v.text,fontFamily:v.sans,overflow:`hidden`},children:[(0,D.jsx)(O,{activeView:e,setView:t,activeNs:n,setNs:r,manifest:c,matrixStatuses:u,gitStatus:f,lintErrorCount:m,scanIssueCount:_,policyOverdueCount:b}),(0,D.jsxs)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,overflow:`hidden`},children:[e===`matrix`&&(0,D.jsx)(R,{setView:t,setNs:r,setEnv:a,manifest:c,matrixStatuses:u,reloadMatrix:C}),e===`editor`&&(0,D.jsx)(ne,{ns:n,initialEnv:i,manifest:c}),e===`diff`&&(0,D.jsx)(ae,{manifest:c}),e===`lint`&&(0,D.jsx)(oe,{setView:t,setNs:r}),e===`scan`&&(0,D.jsx)(se,{}),e===`policy`&&(0,D.jsx)(me,{setView:t,setNs:r}),e===`import`&&(0,D.jsx)(he,{manifest:c,setView:t}),e===`recipients`&&(0,D.jsx)(Le,{manifest:c,setView:t}),e===`identities`&&(0,D.jsx)(ze,{manifest:c}),e===`backend`&&(0,D.jsx)(qe,{manifest:c,setView:t,reloadManifest:S}),e===`reset`&&(0,D.jsx)(et,{manifest:c,setView:t,reloadManifest:S}),e===`history`&&(0,D.jsx)(it,{manifest:c}),e===`manifest`&&(0,D.jsx)(xe,{manifest:c,reloadManifest:S})]})]})}w();var ot=document.getElementById(`root`);ot&&_.createRoot(ot).render((0,D.jsx)(g.StrictMode,{children:(0,D.jsx)(at,{})}));
@@ -42,7 +42,7 @@
42
42
  color: #3d4455;
43
43
  }
44
44
  </style>
45
- <script type="module" crossorigin src="/assets/index-DA0UG2qb.js"></script>
45
+ <script type="module" crossorigin src="/assets/index-BvjtHXyF.js"></script>
46
46
  </head>
47
47
  <body>
48
48
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clef-sh/ui",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Local web UI for Clef — git-native secrets management",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,14 +27,14 @@
27
27
  "scripts": {
28
28
  "build": "npm run build:client && npm run build:server && npm run build:client-lib",
29
29
  "build:client": "vite build",
30
- "build:server": "tsc",
30
+ "build:server": "tsc -p tsconfig.build.json",
31
31
  "build:client-lib": "tsc -p tsconfig.client.json",
32
32
  "dev": "vite",
33
33
  "test": "jest",
34
34
  "test:coverage": "jest --coverage"
35
35
  },
36
36
  "dependencies": {
37
- "@clef-sh/core": "*",
37
+ "@clef-sh/core": "0.1.19",
38
38
  "express": "^5.1.0",
39
39
  "express-rate-limit": "^7.0.0",
40
40
  "yaml": "^2.8.3"
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useCallback } from "react";
1
+ import { useState, useEffect, useCallback } from "react";
2
2
  import { theme } from "./theme";
3
3
  import { apiFetch } from "./api";
4
4
  import { Sidebar, ViewName } from "./components/Sidebar";
@@ -209,7 +209,6 @@ export default function App() {
209
209
  {view === "reset" && (
210
210
  <ResetScreen manifest={manifest} setView={setView} reloadManifest={loadManifest} />
211
211
  )}
212
- {view === "cloud" && null}
213
212
  {view === "history" && <GitLogView manifest={manifest} />}
214
213
  {view === "manifest" && (
215
214
  <ManifestScreen manifest={manifest} reloadManifest={loadManifest} />
@@ -45,6 +45,7 @@ const BACKEND_LABELS: Record<BackendType, string> = {
45
45
  gcpkms: "GCP KMS",
46
46
  azurekv: "Azure Key Vault",
47
47
  pgp: "PGP",
48
+ hsm: "HSM (PKCS#11)",
48
49
  };
49
50
 
50
51
  const KEY_PLACEHOLDERS: Record<string, string> = {
@@ -52,9 +53,10 @@ const KEY_PLACEHOLDERS: Record<string, string> = {
52
53
  gcpkms: "projects/.../locations/.../keyRings/.../cryptoKeys/...",
53
54
  azurekv: "https://vault-name.vault.azure.net/keys/key-name/version",
54
55
  pgp: "PGP fingerprint",
56
+ hsm: "pkcs11:slot=0;label=clef-dek-wrapper",
55
57
  };
56
58
 
57
- const ALL_BACKENDS: BackendType[] = ["age", "awskms", "gcpkms", "azurekv", "pgp"];
59
+ const ALL_BACKENDS: BackendType[] = ["age", "awskms", "gcpkms", "azurekv", "pgp", "hsm"];
58
60
  export function BackendScreen({ manifest, setView, reloadManifest }: BackendScreenProps) {
59
61
  const [step, setStep] = useState<1 | 2 | 3 | 4>(1);
60
62
  const [config, setConfig] = useState<BackendConfigResponse | null>(null);