@humwick/server 0.130.3 → 0.130.4
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.
- package/docs/openapi.json +103 -1
- package/package.json +6 -6
- package/public/assets/{MessageBubble-Bq9kr21N.js → MessageBubble-BOkmEvgZ.js} +2 -2
- package/public/assets/{PlanGraphPanel-Dqiroy06.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
- package/public/assets/{TraceView-DYU962-H.js → TraceView-B99Uu2yT.js} +2 -2
- package/public/assets/{VaultDecisionCard-DhPfzioE.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
- package/public/assets/{activity-DzCcQTee.js → activity-ZIX0N1El.js} +2 -2
- package/public/assets/{agent-lineage-SgDt9i3T.js → agent-lineage-kq9TPYFw.js} +2 -2
- package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
- package/public/assets/{agent-name-CcY3Aijy.js → agent-name-C_7F4DFR.js} +2 -2
- package/public/assets/{agent-profiles-cxtRBn6O.js → agent-profiles-BNOcrGcY.js} +2 -2
- package/public/assets/{agent-project-badge-DGYbIhaI.js → agent-project-badge-B6yAh70a.js} +2 -2
- package/public/assets/{agent-tools-DHbftV0N.js → agent-tools-CcrhmOzF.js} +2 -2
- package/public/assets/{agent-type-icon-CY113sp-.js → agent-type-icon-CXSLrKiq.js} +2 -2
- package/public/assets/{agents-BPzY7IlQ.js → agents-DIZG97_X.js} +2 -2
- package/public/assets/{analytics-DENFPv_a.js → analytics-rasmoPjR.js} +2 -2
- package/public/assets/{artifact-viewer-KRvSc7sl.js → artifact-viewer-tBpTrEPb.js} +2 -2
- package/public/assets/{artifacts-C9gSmL3s.js → artifacts-BNkrynP1.js} +2 -2
- package/public/assets/{artifacts-DT-HkI5O.js → artifacts-Bjq-ZyBA.js} +2 -2
- package/public/assets/{automation-BsmjQhKD.js → automation-Cx422L3L.js} +2 -2
- package/public/assets/{backlog-8NYH_62t.js → backlog-RuFQ8PUu.js} +2 -2
- package/public/assets/{busy-health-D3hwvYb4.js → busy-health-BvNQ9g5x.js} +2 -2
- package/public/assets/{channels-DCJ5WL7O.js → channels-DNbKAS0I.js} +2 -2
- package/public/assets/{chat-DAIl357U.js → chat-Bp3Fx73h.js} +2 -2
- package/public/assets/{code-preview-CzrZfr9U.js → code-preview-KIRZA6cz.js} +2 -2
- package/public/assets/{connectors-xTxtlyou.js → connectors-k7vO4vvc.js} +2 -2
- package/public/assets/{cosmos-BpebFLK2.js → cosmos-BuVoq1aw.js} +2 -2
- package/public/assets/{crate-agent-BHvI5wXC.js → crate-agent-irqlt4NH.js} +2 -2
- package/public/assets/{dependency-graph-DGT0o3wJ.js → dependency-graph-D_rurNBz.js} +2 -2
- package/public/assets/{deploys-hqWOHSHE.js → deploys-yzZqIpxE.js} +2 -2
- package/public/assets/{display-CDeH4I8T.js → display-BemJG1f_.js} +2 -2
- package/public/assets/{files-BTeGVmTg.js → files-DXWcrxOz.js} +2 -2
- package/public/assets/{fleet-DgXtNgCa.js → fleet-TEuOCZXE.js} +2 -2
- package/public/assets/{fleet-metrics-BHEt5yc_.js → fleet-metrics-BGoDAFI-.js} +2 -2
- package/public/assets/{formatted-body-impl-CAe664Z8.js → formatted-body-impl-BB9eq9nN.js} +2 -2
- package/public/assets/{formatted-body-MLtodyPp.js → formatted-body-qy2nTD_1.js} +3 -3
- package/public/assets/{host-providers-dialog-mapF4Fj9.js → host-providers-dialog-BGPHxuwT.js} +2 -2
- package/public/assets/{index-CqqgOI5R.js → index-BC5XZc0z.js} +5 -5
- package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
- package/public/assets/{insights-DNyf7IzF.js → insights-C-KQG0h-.js} +2 -2
- package/public/assets/{integrations-DlYOHq7T.js → integrations-ClPRPyKU.js} +2 -2
- package/public/assets/{issue-ref-chip-CeWBNWn7.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
- package/public/assets/{log-viewer-Cib8nqdE.js → log-viewer-PH4zVn24.js} +2 -2
- package/public/assets/{maintenance-DSn1cPm7.js → maintenance-5lV43uTL.js} +2 -2
- package/public/assets/{managed-agents-C3CkM81m.js → managed-agents-BdgU35aX.js} +2 -2
- package/public/assets/{markdown-preview-W4VQQPAv.js → markdown-preview-DNT4OUwQ.js} +3 -3
- package/public/assets/{markdown-preview-impl-CMsTdhjq.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
- package/public/assets/{memory-BV17qtO4.js → memory--GgWH1gH.js} +2 -2
- package/public/assets/{messages-Bm_1AqSA.js → messages-CzFl_97O.js} +2 -2
- package/public/assets/{orchestrators-Dg-vfP09.js → orchestrators-CVvJVkzv.js} +2 -2
- package/public/assets/overview-DsrZvE86.js +2 -0
- package/public/assets/{pairs-8o9nuG3V.js → pairs-D2d0d2py.js} +2 -2
- package/public/assets/{profile-icon-BsRyBMea.js → profile-icon-_SMuSbYF.js} +2 -2
- package/public/assets/{project-profile-instructions-DETKFn_E.js → project-profile-instructions-Apn15y43.js} +2 -2
- package/public/assets/{projects-M_m6AHws.js → projects-D3B6kto5.js} +2 -2
- package/public/assets/{prompt-settings-C_mNCgeL.js → prompt-settings-DnPB6Ez6.js} +2 -2
- package/public/assets/provider-display-bWwiuedV.js +2 -0
- package/public/assets/{registry-DDHHHE5N.js → registry-D790cIhN.js} +2 -2
- package/public/assets/{run-card-Dt4I4jaP.js → run-card-BCro-Odj.js} +2 -2
- package/public/assets/{secrets-BkVwxI5O.js → secrets-CVXvfvbU.js} +2 -2
- package/public/assets/{service-access-settings-Crq-6a-B.js → service-access-settings-D3Xxqb9w.js} +2 -2
- package/public/assets/{settings-CYcavMFu.js → settings-CoUC7Jci.js} +2 -2
- package/public/assets/{shipping-H6gzEeZB.js → shipping-D_Lp9n_J.js} +2 -2
- package/public/assets/{stats-BJVeWkpV.js → stats-CXiNjB9S.js} +2 -2
- package/public/assets/{status-dot-BcHyw1Vw.js → status-dot-C703YIy1.js} +2 -2
- package/public/assets/store-BgDALGIX.js +9 -0
- package/public/assets/{tasks-qJjlQPpx.js → tasks-DO0WpJCx.js} +2 -2
- package/public/assets/{teams-Cd5Sk1uX.js → teams-FGkdi_tL.js} +2 -2
- package/public/assets/{terminal-viewer-CpY5_m7W.js → terminal-viewer-Dh8dSC7e.js} +3 -3
- package/public/assets/{terminal-viewer-impl-DI_2llFR.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
- package/public/assets/{use-agent-terminal-0yJA_buM.js → use-agent-terminal-CRUVDvLC.js} +2 -2
- package/public/assets/{use-decisions-uJXHf34W.js → use-decisions-CoaqRh4l.js} +2 -2
- package/public/assets/{use-project-list-CpWl6eHQ.js → use-project-list-X-BgT53X.js} +2 -2
- package/public/assets/{use-selectors-BdxBW8mL.js → use-selectors-0X_UZkk-.js} +2 -2
- package/public/assets/{user-avatar-3IndfpOc.js → user-avatar-CkLhVBGu.js} +2 -2
- package/public/assets/{versioned-prompt-editor-CIVg7XB1.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
- package/public/assets/{work-queue-B9rnLwHZ.js → work-queue-DDOLEyKo.js} +2 -2
- package/public/assets/{workflow-marker-X8wxyhzC.js → workflow-marker-CzOsB8BM.js} +2 -2
- package/public/assets/{workflows-o5YyMFW7.js → workflows-DJilvmRM.js} +2 -2
- package/public/assets/{workspaces-CzEGoAng.js → workspaces-CHcfbLR3.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +29 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/adapters/claude-api.ts +1 -1
- package/runner/src/provider-setup.ts +2 -2
- package/src/auth/login-link.ts +35 -0
- package/src/cli/index.ts +7 -1
- package/src/cli/init.ts +53 -0
- package/src/cli/orchestrator.ts +1 -7
- package/src/cli/setup.ts +6 -4
- package/src/db/spawn-delegation.ts +2 -1
- package/src/db/workflow-execution.ts +3 -3
- package/src/dev.ts +4 -13
- package/src/init.ts +299 -0
- package/src/invite-link.ts +16 -9
- package/src/routes/auth.ts +30 -2
- package/src/routes/host-providers.ts +18 -0
- package/src/routes/index.ts +5 -2
- package/src/routes/orchestrator-bootstrap.ts +2 -0
- package/src/routes/secrets-backup.ts +2 -3
- package/src/routes/secrets-import.ts +2 -3
- package/src/routes/secrets-vault.ts +5 -7
- package/src/runtime-install.ts +30 -0
- package/src/server.ts +4 -4
- package/src/services/auth-context.ts +6 -0
- package/src/services/provider-api-key.ts +73 -0
- package/src/setup.ts +47 -8
- package/src/utils.ts +7 -0
- package/public/assets/agent-liveness-Bq-s73jW.js +0 -2
- package/public/assets/overview-DcYCrvlr.js +0 -2
- package/public/assets/provider-display-BEeLXC_D.js +0 -2
- package/public/assets/store-DKPDIZBe.js +0 -9
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{p as t,u as n}from"./dist-DeW2Y1R5.js";import{$ as r,B as i,Ct as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,P as h,Q as g,R as _,U as v,V as y,W as b,X as x,Y as S,Z as C,at as w,et as T,it as E,j as D,nt as O,rt as k,t as A,tt as j,z as M}from"./store-DKPDIZBe.js";import{M as N}from"./provider-display-BEeLXC_D.js";import{et as P,f as F,v as I}from"./display-CDeH4I8T.js";import{s as L,t as R}from"./api-CIIVBtAV.js";import{t as z}from"./archive-CIuPSvmx.js";import{t as B}from"./external-link-BRfu-fHG.js";import{n as V,t as ee}from"./shield-alert-B9jCWcKW.js";import{t as te}from"./key-round-CcSxl5qr.js";import{t as H}from"./loader-circle-BfPd4kOD.js";import{t as U}from"./lock-BW8MPKw_.js";import{t as ne}from"./pencil-B1Hf2V_J.js";import{t as W}from"./plus-D5Ek4e2S.js";import{t as re}from"./refresh-cw-CfpvQcUn.js";import{t as ie}from"./rotate-cw-FPtkDewA.js";import{t as ae}from"./trash-2-FbcSq927.js";import{t as oe}from"./triangle-alert-BBNhfgMi.js";import{t as G}from"./button-Do6Z3vvn.js";import{t as K}from"./badge-DqJRtj_p.js";import{t as q}from"./input-CsTB6jIx.js";import{t as se}from"./textarea-hs6Mpyfl.js";import{t as ce}from"./VaultDecisionCard-DhPfzioE.js";var J=e(t(),1),Y=n();function le({url:e}){return(0,Y.jsxs)(`a`,{"data-testid":`source-link`,href:e,target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex min-h-9 max-w-full items-center gap-1 text-xs text-primary underline-offset-2 hover:underline sm:min-h-0`,children:[(0,Y.jsx)(B,{className:`h-3 w-3 shrink-0`}),(0,Y.jsxs)(`span`,{className:`min-w-0 break-all`,children:[`Open the source page: `,e]})]})}function ue({rotate:e,projectId:t,environment:n=`prod`,sourceUrl:r,disabled:i,onClose:a}){let o=A(e=>e.fetchOpenDecisions),[s,c]=(0,J.useState)(e??``),[l,u]=(0,J.useState)(e?`Rotate ${e}`:``),[d,f]=(0,J.useState)(!1),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(null),v=y.test(s),b=v&&l.trim().length>0&&!i&&!d;async function S(){if(b){f(!0),m(``);try{let e=await _(s,l.trim(),t,n);g({name:e.name,formUrl:e.formUrl}),o()}catch(e){m(N(e))}finally{f(!1)}}}return(0,Y.jsx)(`div`,{"data-testid":`secret-request-panel`,className:`rounded-lg border border-border bg-card/60 p-3 text-sm`,children:h?(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`p`,{children:[`Request filed for `,(0,Y.jsx)(`code`,{className:`break-all`,children:h.name}),`. Open the form and enter the value there. The link works once, until it expires or the request is withdrawn. The form has optional expiry, revision and source URL fields, and shows the fingerprint after you save.`]}),h.formUrl?(0,Y.jsxs)(`a`,{href:x(h.formUrl,L()),target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 sm:h-8 sm:w-auto`,children:[(0,Y.jsx)(B,{className:`h-3.5 w-3.5`}),`Open secure form`]}):(0,Y.jsx)(`p`,{className:`text-xs text-tone-warning-fg`,children:`The form link is only shown to the operator token.`}),(0,Y.jsx)(`div`,{children:(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:a,children:`Close`})})]}):(0,Y.jsxs)(`form`,{className:`space-y-2`,onSubmit:e=>{e.preventDefault(),S()},children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:e?`Rotate ${e}`:`Request a new secret`}),!e&&(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(q,{"aria-label":`Secret name`,"aria-invalid":s!==``&&!v,placeholder:`NAME or NAME@environment`,autoComplete:`off`,spellCheck:!1,value:s,onChange:e=>c(e.target.value),className:`font-mono`}),s!==``&&!v&&(0,Y.jsx)(`p`,{className:`mt-1 text-[11px] text-tone-danger-fg`,children:`Start with a letter or underscore; then letters, digits, _ . - (up to 256). Optional @environment: 1–32 lowercase letters, digits or hyphens.`})]}),r&&(0,Y.jsx)(le,{url:r}),(0,Y.jsx)(se,{"aria-label":`Reason`,rows:2,placeholder:`Why is it needed?`,value:l,maxLength:4096,onChange:e=>u(e.target.value)}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`You enter the value on the next page. Do not paste it here.`]}),p&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:p}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!b,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[d&&(0,Y.jsx)(H,{className:`animate-spin`}),e?`Request rotation`:`Request secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:a,className:`h-9 sm:h-8`,children:`Cancel`})]})]})})}function de({projects:e,defaultProjectId:t=``,onClose:n}){let r=A(e=>e.fetchVault),[i,a]=(0,J.useState)(`infisical`),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(`prod`),[u,d]=(0,J.useState)(`/`),[f,p]=(0,J.useState)(``),[m,h]=(0,J.useState)(`codex`),[g,_]=(0,J.useState)(t),[v,y]=(0,J.useState)(`prod`),[b,x]=(0,J.useState)(null),[S,C]=(0,J.useState)(!1),[w,T]=(0,J.useState)(``),[E,D]=(0,J.useState)(null),O=i===`infisical`?{kind:i,project:o,environment:c,path:u}:{kind:i,host:f,provider:m},k=b&&JSON.stringify(b.source)===JSON.stringify(O)?b:null;async function j(){C(!0),T(``),x(null);try{let{names:e}=await R(`POST`,`/secrets/import/preview`,{source:O});x({source:O,names:e,picked:[]})}catch(e){T(N(e))}finally{C(!1)}}async function M(){if(!k?.picked.length)return;C(!0),T(``);let e={source:k.source,names:k.picked,environment:v,scope:g?`project`:`global`,...g?{project:g}:{}};try{D(await R(`POST`,`/secrets/import`,e)),r()}catch(e){T(N(e))}finally{C(!1)}}return(0,Y.jsx)(`section`,{"data-testid":`secret-import-panel`,"aria-label":`Import secrets`,className:`space-y-3 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:E?(0,Y.jsxs)(Y.Fragment,{children:[E.secrets.map(e=>(0,Y.jsxs)(`p`,{children:[`Imported `,e.name,` v`,e.version]},e.name)),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`p`,{className:`font-medium`,children:`Import secrets`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Choose existing names. Relay moves the values directly into encrypted storage. Import selected approves the whole batch.`}),(0,Y.jsxs)(`fieldset`,{disabled:S,className:`space-y-2`,children:[(0,Y.jsxs)(`select`,{"aria-label":`Import source`,value:i,onChange:e=>a(e.target.value),className:`h-9 w-full rounded-md border border-input bg-background px-3`,children:[(0,Y.jsx)(`option`,{value:`infisical`,children:`Infisical path`}),(0,Y.jsx)(`option`,{value:`provider-config`,children:`Provider config`})]}),i===`infisical`?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(q,{"aria-label":`Infisical project`,placeholder:`Infisical project ID, slug or name`,value:o,onChange:e=>s(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source environment`,placeholder:`Source environment`,value:c,onChange:e=>l(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source path`,placeholder:`/path`,value:u,onChange:e=>d(e.target.value)})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(q,{"aria-label":`Source host`,placeholder:`Host ID or hostname`,value:f,onChange:e=>p(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source provider`,placeholder:`Provider`,value:m,onChange:e=>h(e.target.value)}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Imported env entries are replaced with secret: references.`})]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,onClick:()=>void j(),children:`Load names`}),k&&(0,Y.jsx)(`div`,{className:`space-y-1`,children:k.names.length===0?(0,Y.jsx)(`p`,{children:`No importable names at this source.`}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:()=>x({...k,picked:k.names}),children:`Select all`}),k.names.map(e=>(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 break-all`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,checked:k.picked.includes(e),onChange:t=>x({...k,picked:t.target.checked?[...k.picked,e]:k.picked.filter(t=>t!==e)})}),e]},e))]})}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Target scope`,(0,Y.jsxs)(`select`,{"aria-label":`Target scope`,value:g,onChange:e=>_(e.target.value),className:`mt-1 h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,children:[(0,Y.jsx)(`option`,{value:``,children:`Global`}),e.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[`Project: `,e.title||e.slug||e.id]},e.id))]})]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Target environment`,(0,Y.jsx)(q,{"aria-label":`Target environment`,value:v,onChange:e=>y(e.target.value)})]})]}),w&&(0,Y.jsx)(`p`,{role:`alert`,className:`break-words text-xs text-tone-danger-fg`,children:w}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(G,{size:`sm`,disabled:S||!k?.picked.length||!v,onClick:()=>void M(),children:`Import selected`}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,disabled:S,onClick:n,children:`Cancel`})]})]})})}var fe={"no-recipient":`No backup recipient is set, so no backup is written. Add your age public key in Settings → Secrets → Vault backup.`,stale:`The last successful backup is more than 48 hours old.`};function pe({status:e,disabled:t}){let n=A(e=>e.fetchVault),r=a(),[i,o]=(0,J.useState)(!1),[s,c]=(0,J.useState)(``),l=e.lastSuccess;async function u(){o(!0),c(``);try{await D()}catch(e){c(N(e))}finally{o(!1),n()}}return(0,Y.jsxs)(`section`,{"data-testid":`vault-backup`,"aria-label":`Vault backup`,className:`space-y-1.5 rounded-lg border px-3 py-2.5 text-sm ${e.warning?`border-tone-warning/40 bg-tone-warning/10`:`border-border bg-card`}`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 font-medium`,children:[(0,Y.jsx)(z,{className:`h-4 w-4 shrink-0 text-muted-foreground`}),` Backup`]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,disabled:t||i||!e.recipientFingerprint,onClick:()=>void u(),children:i?`Backing up…`:`Back up now`})]}),(0,Y.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`dt`,{children:`Last backup`}),(0,Y.jsx)(`dd`,{"data-testid":`vault-backup-last`,className:`min-w-0 break-words text-foreground`,children:l?(0,Y.jsxs)(`span`,{title:I(l.at),children:[P(r,l.at),` · `,l.secrets,` secret`,l.secrets===1?``:`s`]}):`Never`}),(0,Y.jsx)(`dt`,{children:`Recipient`}),(0,Y.jsx)(`dd`,{"data-testid":`vault-backup-recipient`,className:`min-w-0 break-all font-mono text-foreground`,children:e.recipientFingerprint??`Not set`}),(0,Y.jsx)(`dt`,{children:`Kept`}),(0,Y.jsxs)(`dd`,{className:`min-w-0 break-all`,children:[e.files,` of `,e.keep,` in `,e.directory]})]}),e.warning&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs text-tone-warning-fg`,children:fe[e.warning]}),e.lastError&&(!l||e.lastError.at>l.at)&&(0,Y.jsxs)(`p`,{className:`break-words text-xs text-tone-danger-fg`,children:[`Last attempt failed `,P(r,e.lastError.at),`: `,e.lastError.message]}),s&&(0,Y.jsx)(`p`,{role:`alert`,className:`break-words text-xs text-tone-danger-fg`,children:s})]})}function X({draft:e,onChange:t,collapsible:n=!0}){let r=(0,Y.jsxs)(`div`,{"data-testid":`metadata-fields`,className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`space-y-1 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`Expires on`}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(q,{"aria-label":`Expires on`,type:`date`,value:e.expiresDate,onChange:n=>t({...e,expiresDate:n.target.value,expiresBad:n.target.validity.badInput}),className:`text-foreground`}),(0,Y.jsx)(q,{"aria-label":`Expiry time (optional)`,type:`time`,value:e.expiresTime,onChange:n=>t({...e,expiresTime:n.target.value}),className:`w-32 shrink-0 text-foreground`})]}),(0,Y.jsx)(`p`,{className:`text-[11px]`,children:`In your time zone. Without a time it expires at the end of that day.`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Revision`,(0,Y.jsx)(q,{"aria-label":`Revision`,maxLength:500,autoComplete:`off`,placeholder:`Vendor revision or number`,value:e.revision,onChange:n=>t({...e,revision:n.target.value}),className:`text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Source URL`,(0,Y.jsx)(q,{"aria-label":`Source URL`,type:`url`,inputMode:`url`,maxLength:2048,autoComplete:`off`,spellCheck:!1,placeholder:`https://vendor.example/keys`,value:e.sourceUrl,onChange:n=>t({...e,sourceUrl:n.target.value}),className:`font-mono text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`flex min-h-9 items-center gap-2 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,"aria-label":`Show last four characters`,checked:e.hintEnabled,onChange:n=>t({...e,hintEnabled:n.target.checked}),className:`h-4 w-4`}),`Show the last four characters as a hint`]}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`Stored as plain text, readable by agents. Never put a credential here.`})]});return n?(0,Y.jsxs)(`details`,{className:`rounded-md border border-border/60 px-2.5 py-1.5`,children:[(0,Y.jsx)(`summary`,{className:`cursor-pointer text-xs font-medium text-muted-foreground`,children:`Optional metadata`}),(0,Y.jsx)(`div`,{className:`mt-2`,children:r})]}):r}var me=e=>e.title||e.slug||e.id;function he({projects:e,defaultProjectId:t=``,onClose:n}){let i=A(e=>e.fetchVault),[a,o]=(0,J.useState)(``),[s,c]=(0,J.useState)(t),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(``),[m,h]=(0,J.useState)(r),[g,_]=(0,J.useState)(!1),[v,b]=(0,J.useState)(``),[x,S]=(0,J.useState)(null),C=y.test(a),w=O(m),T=C&&d.length>0&&!w&&!g;async function D(){if(T){_(!0),b(``);try{let[t,n=`prod`]=a.split(`@`),r=await p({name:t,environment:n,value:d,projectId:s||void 0,description:l.trim()||void 0,metadata:k(m)}),o=e.find(e=>e.id===s);S({name:a,where:o?me(o):`global`,signature:E(r.fingerprint,r.hint)}),f(``),i()}catch(e){b(N(e))}finally{_(!1)}}}return x?(0,Y.jsxs)(`div`,{"data-testid":`secret-new-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:[(0,Y.jsxs)(`p`,{children:[`Saved `,(0,Y.jsx)(`code`,{className:`break-all`,children:x.name}),` (`,x.where,`). Agents use it as `,(0,Y.jsxs)(`code`,{className:`break-all`,children:[`secret:`,x.name]}),`. The value is not shown again.`]}),x.signature&&(0,Y.jsxs)(`p`,{"data-testid":`saved-signature`,className:`text-xs text-muted-foreground`,children:[`Fingerprint `,(0,Y.jsx)(`code`,{children:x.signature}),`. Compare it with the key where you copied it from.`]}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(`form`,{"data-testid":`secret-new-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),D()},children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:`New secret`}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(q,{"aria-label":`Secret name`,"aria-invalid":a!==``&&!C,placeholder:`NAME or NAME@environment`,autoComplete:`off`,spellCheck:!1,value:a,onChange:e=>o(e.target.value),className:`font-mono`}),a!==``&&!C&&(0,Y.jsx)(`p`,{className:`mt-1 text-[11px] text-tone-danger-fg`,children:`Start with a letter or underscore; then letters, digits, _ . - (up to 256). Optional @environment: 1–32 lowercase letters, digits or hyphens.`})]}),(0,Y.jsxs)(`select`,{"aria-label":`Scope`,value:s,onChange:e=>c(e.target.value),className:`h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,children:[(0,Y.jsx)(`option`,{value:``,children:`Global (all projects)`}),e.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[`Project: `,me(e)]},e.id))]}),(0,Y.jsx)(q,{"aria-label":`Description`,placeholder:`Description (optional)`,maxLength:500,autoComplete:`off`,value:l,onChange:e=>u(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Value`,type:`password`,placeholder:`Value`,autoComplete:`new-password`,spellCheck:!1,value:d,onChange:e=>f(e.target.value),className:`font-mono`}),(0,Y.jsx)(X,{draft:m,onChange:h}),w&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:w}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`Stored encrypted. It is never shown again, only replaced with Rotate.`]}),v&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:v}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!T,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[g&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:n,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ge({secret:e,scopedRef:t,onClose:n}){let{name:r,projectId:i,environment:a}=e,o=A(e=>e.fetchVault),[s,c]=(0,J.useState)(``),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(()=>T(e.metadata,e.hintEnabled)),[p,m]=(0,J.useState)(!1),[h,g]=(0,J.useState)(``),[_,v]=(0,J.useState)(null),[y,b]=(0,J.useState)(!1),x=O(d,e),S=s.length>0&&!x&&!p;async function C(){if(S){m(!0),g(``);try{let n=await M(t,s,l.trim()||void 0,k(d,e));v({version:n.version,signature:E(n.fingerprint,n.hint)}),c(``),o()}catch(e){g(N(e))}finally{m(!1)}}}return y?(0,Y.jsx)(ue,{rotate:r,projectId:i,environment:a,sourceUrl:e.metadata.sourceUrl,onClose:n}):_?(0,Y.jsxs)(`div`,{"data-testid":`secret-rotate-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:[(0,Y.jsxs)(`p`,{children:[(0,Y.jsx)(`code`,{className:`break-all`,children:r}),` is now v`,_.version,`. The value is not shown again.`]}),_.signature&&(0,Y.jsxs)(`p`,{"data-testid":`saved-signature`,className:`text-xs text-muted-foreground`,children:[`Fingerprint `,(0,Y.jsx)(`code`,{children:_.signature}),`. Compare it with the key where you copied it from.`]}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(`form`,{"data-testid":`secret-rotate-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),C()},children:[(0,Y.jsxs)(`div`,{className:`text-xs font-medium text-foreground`,children:[`Rotate `,r]}),e.metadata.sourceUrl&&(0,Y.jsx)(le,{url:e.metadata.sourceUrl}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`New value`,(0,Y.jsx)(q,{"aria-label":`New value`,type:`password`,autoComplete:`new-password`,spellCheck:!1,value:s,onChange:e=>c(e.target.value),className:`font-mono text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Reason (optional)`,(0,Y.jsx)(q,{"aria-label":`Reason (optional)`,maxLength:500,autoComplete:`off`,value:l,onChange:e=>u(e.target.value),className:`text-foreground`})]}),(0,Y.jsx)(X,{draft:d,onChange:f}),x&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:x}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`Stored encrypted as the next version. It is never shown again.`]}),h&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:h}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!S,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[p&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save new value`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:n,className:`h-9 sm:h-8`,children:`Cancel`})]}),(0,Y.jsx)(`button`,{type:`button`,onClick:()=>b(!0),className:`text-xs text-primary underline-offset-2 hover:underline`,children:`Ask someone else to provide it`})]})}function Z({actor:e,labels:t}){let n=A(t=>t.agentsById[e]),r=A(e=>e.openAgentDetail),i=c(e)??(n?e.replace(/^agent-/,``):null);if(!i)return(0,Y.jsx)(`span`,{className:`break-all`,children:e});let a=n?F(n):t?.[e],o=a?`${a} · ${i}`:`agent · ${i}`;return n?(0,Y.jsx)(`button`,{type:`button`,"data-testid":`vault-actor`,"data-agent":`live`,title:e,onClick:()=>r(n),className:`min-w-0 break-words text-left text-primary underline-offset-2 hover:underline`,children:o}):(0,Y.jsx)(`span`,{"data-testid":`vault-actor`,"data-agent":`gone`,title:e,className:`min-w-0 break-words`,children:o})}function _e({secret:e,onClose:t,onDeleted:n}){let r=A(e=>e.fetchVault),i=a(),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(!1),[u,d]=(0,J.useState)(``),f=o===e.name&&!c;async function p(){if(f){l(!0),d(``);try{await m(g(e)),n(),r()}catch(e){d(N(e)),l(!1)}}}return(0,Y.jsxs)(`form`,{"data-testid":`secret-delete-panel`,className:`space-y-2 rounded-lg border border-tone-danger/40 bg-tone-danger/10 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),p()},children:[(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs font-medium text-tone-danger-fg`,children:[(0,Y.jsx)(oe,{className:`mt-0.5 h-3.5 w-3.5 shrink-0`}),`Delete `,e.name,` and all `,e.version,` version`,e.version===1?``:`s`]}),(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`This cannot be undone. Agents that use `,(0,Y.jsxs)(`code`,{className:`break-all`,children:[`secret:`,e.name,e.environment===`prod`?``:`@${e.environment}`]}),` will fail with “not found”.`]}),e.lastResolved&&(0,Y.jsxs)(`p`,{"data-testid":`delete-in-use`,className:`text-xs text-tone-warning-fg`,children:[`In use: last used `,P(i,e.lastResolved.at),` by `,(0,Y.jsx)(Z,{actor:e.lastResolved.actor}),`.`]}),(0,Y.jsx)(q,{"aria-label":`Type ${e.name} to confirm`,placeholder:`Type ${e.name} to confirm`,autoComplete:`off`,spellCheck:!1,value:o,onChange:e=>s(e.target.value),className:`font-mono`}),u&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:u}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,variant:`destructive`,disabled:!f,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[c&&(0,Y.jsx)(H,{className:`animate-spin`}),`Delete secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:t,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ve({secret:e,onClose:t,onSaved:n}){let r=A(e=>e.fetchVault),[i,a]=(0,J.useState)(()=>T(e.metadata,e.hintEnabled)),[o,s]=(0,J.useState)(!1),[c,l]=(0,J.useState)(``),u=O(i,e),d=u?void 0:k(i,e);async function f(){if(!(!d||o)){s(!0),l(``);try{await h(g(e),d),r(),n()}catch(e){l(N(e)),s(!1)}}}return(0,Y.jsxs)(`form`,{"data-testid":`secret-metadata-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),f()},children:[(0,Y.jsxs)(`div`,{className:`text-xs font-medium text-foreground`,children:[`Edit metadata of `,e.name]}),(0,Y.jsx)(X,{draft:i,onChange:a,collapsible:!1}),u&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:u}),c&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:c}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!d||o,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[o&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save metadata`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:t,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ye({history:e}){return e.error?(0,Y.jsx)(`p`,{role:`alert`,className:`mt-2 text-xs text-tone-danger-fg break-words`,children:e.error}):e.rows?e.rows.length?(0,Y.jsx)(`ul`,{"data-testid":`audit-list`,className:`mt-2 divide-y divide-border/60 rounded-md border border-border/60 text-xs`,"aria-label":`History of ${e.name}`,children:e.rows.map(t=>(0,Y.jsxs)(`li`,{"data-testid":`audit-row`,className:`flex flex-wrap items-baseline gap-x-2 gap-y-0.5 px-2.5 py-1.5`,children:[(0,Y.jsx)(`span`,{className:`shrink-0 whitespace-nowrap text-muted-foreground`,children:I(t.createdAt)}),(0,Y.jsx)(K,{variant:t.outcome===`ok`?`secondary`:`destructive`,className:`h-4 px-1 text-[10px]`,children:v(t.action)}),t.version!==void 0&&(0,Y.jsxs)(`span`,{className:`text-muted-foreground`,children:[`v`,t.version]}),t.version!==void 0&&(t.action===`set`||t.action===`rotated`)&&e.versions?.[t.version]&&(0,Y.jsx)(`code`,{"data-testid":`audit-signature`,className:`text-[11px] text-muted-foreground`,children:e.versions[t.version]}),(0,Y.jsx)(Z,{actor:t.actor,labels:e.labels}),t.outcome!==`ok`&&(0,Y.jsx)(`span`,{className:`text-tone-danger-fg`,children:t.outcome}),(0,Y.jsx)(be,{row:t,labels:e.labels})]},t.id))}):(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`No audit rows yet.`}):(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`Loading history…`})}function be({row:e,labels:t}){let{decisionId:n,requestedBy:r}=s(e),i=A(e=>n!==void 0&&e.openDecisions.some(e=>e.id===n));if(r)return(0,Y.jsxs)(`span`,{className:`min-w-0 break-words text-muted-foreground`,children:[`requested by `,(0,Y.jsx)(Z,{actor:r,labels:t})]});if(n!==void 0)return i?(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>document.querySelector(`[data-testid="decision-card-${n}"]`)?.scrollIntoView({block:`center`}),className:`text-primary underline-offset-2 hover:underline`,children:[`decision #`,n]}):(0,Y.jsxs)(`span`,{className:`text-muted-foreground`,children:[`decision #`,n]});let a=b(e);return a?(0,Y.jsx)(`span`,{className:`min-w-0 break-all text-muted-foreground`,children:a}):null}var xe=`humwick-vault-filter`;function Se(){try{let e=JSON.parse(localStorage.getItem(xe)??`null`);return{tab:e?.tab===`project`?`project`:`global`,projectId:typeof e?.projectId==`string`?e.projectId:``}}catch{return{tab:`global`,projectId:``}}}function Ce(e){try{localStorage.setItem(xe,JSON.stringify(e))}catch{}}var Q=e=>e.title||e.slug||e.id;function we(e,t,n){let r=new Map(e.map(e=>[e.id,e]));for(let e of t)e.projectId&&!r.has(e.projectId)&&r.set(e.projectId,{id:e.projectId,title:e.projectName??``,slug:``});return n&&!r.has(n)&&r.set(n,{id:n,title:``,slug:``}),[...r.values()].sort((e,t)=>Q(e).localeCompare(Q(t)))}function Te(){let e=A(e=>e.vault),t=A(e=>e.vaultProjects),n=A(e=>e.vaultBackup),r=A(e=>e.fetchVault),p=A(e=>e.agentsById),m=A(e=>e.openDecisions),h=a(),[_,v]=(0,J.useState)(null),[y,b]=(0,J.useState)(null),[x,w]=(0,J.useState)(Se),T=e.status===`key-problem`,D=e.status===`ready`?e.secrets:[],O=D.some(e=>e.environment&&e.environment!==`prod`),k=we(t,D,x.projectId),j=x.tab===`project`&&!x.projectId&&k[0]?{tab:`project`,projectId:k[0].id}:x,M=D.filter(e=>S(e,j)),P=m.filter(u).filter(e=>S(C(e.title),j)),F=D.filter(e=>e.projectId).length,I=j.tab===`project`?j.projectId:void 0;function L(e){w(e),Ce(e),v(null),b(null)}function R(e){b(t=>t?.name===e&&t.rows?t:{name:e}),f(e).then(t=>b(n=>n?.name===e?{...n,versions:Object.fromEntries(t.map(e=>[e.version,E(e.fingerprint,e.hint)]))}:n)).catch(()=>{}),l(e).then(t=>{b(n=>n?.name===e?{...n,rows:t}:n);let n=[...new Set(t.flatMap(e=>[e.actor,s(e).requestedBy??``]))].filter(e=>c(e)&&!p[e]);n.length&&o(n).then(t=>b(n=>n?.name===e?{...n,labels:t}:n))},t=>b(n=>n?.name===e?{name:e,error:N(t)}:n))}function z(e){y?.name===e?b(null):R(e)}function B(e){v(t=>t&&t.kind===e.kind&&(!(`ref`in t)||`ref`in e&&t.ref===e.ref)?null:e)}function V(){r(),y&&R(y.name)}return(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(te,{className:`h-5 w-5 text-muted-foreground`}),(0,Y.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Secrets`}),e.status===`ready`&&(0,Y.jsx)(K,{variant:`secondary`,children:M.length})]}),(e.status===`ready`||T)&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,onClick:V,children:[(0,Y.jsx)(re,{className:`h-3.5 w-3.5`}),` Refresh`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,disabled:T,onClick:()=>B({kind:`request`}),children:[(0,Y.jsx)(W,{className:`h-3.5 w-3.5`}),` Request secret`]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,disabled:T,onClick:()=>B({kind:`import`}),children:`Import`}),(0,Y.jsxs)(G,{size:`sm`,disabled:T,onClick:()=>B({kind:`new`}),children:[(0,Y.jsx)(W,{className:`h-3.5 w-3.5`}),` New secret`]})]})]}),e.status===`ready`&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsxs)(`div`,{role:`tablist`,"aria-label":`Secret scope`,className:`inline-flex rounded-md border border-border p-0.5`,children:[(0,Y.jsx)(Ee,{selected:x.tab===`global`,onClick:()=>L({...x,tab:`global`}),children:`Global`}),(0,Y.jsxs)(Ee,{selected:x.tab===`project`,onClick:()=>L({...x,tab:`project`}),children:[`Project`,F>0?` (${F})`:``]})]}),x.tab===`project`&&(0,Y.jsxs)(`select`,{"aria-label":`Project`,value:j.projectId,onChange:e=>L({tab:`project`,projectId:e.target.value}),className:`h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm sm:h-8 sm:max-w-xs`,children:[k.length===0&&(0,Y.jsx)(`option`,{value:``,children:`No projects`}),k.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:Q(e)},e.id))]})]}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Names and versions only. Values are never shown, here or anywhere else in Relay.`}),e.status===`unknown`&&(0,Y.jsx)($,{children:`Loading…`}),e.status===`off`&&(0,Y.jsxs)($,{testId:`vault-off`,title:`The secrets vault is off`,children:[`The vault is on by default. Remove `,(0,Y.jsx)(`code`,{children:`AGENT_RELAY_SECRETS_VAULT=0`}),` from the hub environment and restart Relay to turn it on. This page needs an operator token with the secrets scope.`]}),e.status===`error`&&(0,Y.jsx)($,{testId:`vault-error`,title:`Could not read the vault`,tone:`danger`,children:e.message}),e.status===`key-problem`&&(0,Y.jsxs)($,{testId:`vault-key-problem`,title:i[e.code].title,tone:`danger`,children:[i[e.code].body,` Setting and using secrets is paused until then.`]}),n&&(e.status===`ready`||T)&&(0,Y.jsx)(pe,{status:n,disabled:T}),_?.kind===`request`&&(0,Y.jsx)(ue,{disabled:T,projectId:I,onClose:()=>v(null)}),_?.kind===`import`&&!T&&(0,Y.jsx)(de,{projects:k,defaultProjectId:I,onClose:()=>v(null)}),_?.kind===`new`&&!T&&(0,Y.jsx)(he,{projects:k,defaultProjectId:I,onClose:()=>v(null)}),P.length>0&&(0,Y.jsxs)(`section`,{className:`space-y-2`,"aria-label":`Pending requests`,children:[(0,Y.jsxs)(`h3`,{className:`text-sm font-medium text-tone-warning-fg`,children:[`Waiting for a value (`,d(P,h),`)`]}),P.map(e=>(0,Y.jsx)(ce,{decision:e},`${e.id}:${e.updatedAt}`))]}),e.status===`ready`&&(M.length===0?(0,Y.jsx)($,{testId:`vault-empty`,children:j.tab===`project`?`No secrets in this project yet. Create one, request one, or let an agent ask for it.`:`No global secrets yet. Create one, request one, or let an agent ask for it.`}):(0,Y.jsx)(`ul`,{className:`space-y-2`,"aria-label":`Secrets`,children:M.map(e=>{let t=g(e);return(0,Y.jsx)(De,{secret:e,showEnvironment:O,open:y?.name===t?y:null,panel:_&&`ref`in _&&_.ref===t?_.kind:null,onRotate:()=>B({kind:`rotate`,ref:t}),onEditMetadata:()=>B({kind:`metadata`,ref:t}),onMetadataSaved:()=>{v(null),y?.name===t&&R(t)},onDelete:()=>B({kind:`delete`,ref:t}),onHistory:()=>z(t),onClosePanel:()=>v(null),onDeleted:()=>{v(null),y?.name===t&&b(null)}},t)})}))]})}function Ee({selected:e,onClick:t,children:n}){return(0,Y.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":e,onClick:t,className:`h-8 rounded px-3 text-sm font-medium sm:h-7 ${e?`bg-secondary text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:n})}function $({title:e,tone:t,testId:n,children:r}){return(0,Y.jsxs)(`div`,{"data-testid":n,role:t===`danger`?`alert`:void 0,className:t===`danger`?`rounded-md border border-tone-danger/40 bg-tone-danger/10 px-3 py-3 text-sm text-tone-danger-fg`:`rounded-md border border-border px-3 py-6 text-center text-sm text-muted-foreground`,children:[e&&(0,Y.jsxs)(`div`,{className:`mb-1 flex items-center gap-1.5 font-medium`,children:[(0,Y.jsx)(ee,{className:`h-4 w-4 shrink-0`}),e]}),(0,Y.jsx)(`div`,{className:`break-words`,children:r})]})}function De({secret:e,showEnvironment:t,open:n,panel:r,onRotate:i,onEditMetadata:o,onMetadataSaved:s,onDelete:c,onHistory:l,onClosePanel:u,onDeleted:d}){let f=a();return(0,Y.jsxs)(`li`,{"data-testid":`secret-row`,"data-secret":e.name,"data-environment":e.environment??`prod`,"data-scope":e.projectId?`project`:`global`,className:`rounded-lg border border-border bg-card px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,Y.jsx)(`code`,{className:`break-all text-sm font-medium`,children:e.name}),(0,Y.jsx)(K,{variant:`outline`,className:`h-4 px-1 text-[10px]`,children:e.projectId?`project: ${e.projectName??e.projectId}`:`global`}),(0,Y.jsxs)(K,{variant:`secondary`,className:`h-4 px-1 text-[10px]`,children:[`v`,e.version]}),e.metadata?.expiresAt&&Date.parse(e.metadata.expiresAt)<=f&&(0,Y.jsx)(K,{variant:`destructive`,className:`h-4 px-1 text-[10px]`,children:`Expired`}),t&&(0,Y.jsx)(K,{"data-testid":`secret-environment`,variant:`outline`,className:`h-4 px-1 text-[10px]`,children:e.environment??`prod`})]}),(0,Y.jsxs)(`div`,{className:`mt-0.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsxs)(`span`,{title:I(e.updatedAt),children:[e.version>1?`Rotated`:`Set`,` `,P(f,e.updatedAt)]}),(0,Y.jsx)(`span`,{children:` · `}),e.lastResolved?(0,Y.jsxs)(`span`,{title:I(e.lastResolved.at),children:[`Last used `,P(f,e.lastResolved.at),` by `,(0,Y.jsx)(Z,{actor:e.lastResolved.actor})]}):(0,Y.jsx)(`span`,{children:`Not used yet`})]}),(0,Y.jsx)(Oe,{secret:e,now:f})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap gap-1.5`,children:[(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,"aria-expanded":r===`rotate`,onClick:i,className:`h-8`,children:[(0,Y.jsx)(ie,{className:`h-3.5 w-3.5`}),`Rotate`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":r===`metadata`,onClick:o,className:`h-8`,children:[(0,Y.jsx)(ne,{className:`h-3.5 w-3.5`}),`Edit metadata`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":!!n,onClick:l,className:`h-8`,children:[(0,Y.jsx)(V,{className:`h-3.5 w-3.5`}),`History`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":r===`delete`,onClick:c,className:`h-8 text-tone-danger-fg`,children:[(0,Y.jsx)(ae,{className:`h-3.5 w-3.5`}),`Delete`]})]})]}),r===`rotate`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(ge,{secret:e,scopedRef:g(e),onClose:u})}),r===`metadata`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(ve,{secret:e,onClose:u,onSaved:s})}),r===`delete`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(_e,{secret:e,onClose:u,onDeleted:d})}),n&&(0,Y.jsx)(ye,{history:n})]})}function Oe({secret:e,now:t}){let{expiresAt:n,revision:r,sourceUrl:i}=e.metadata,a=w(n,t),o=E(e.fingerprint,e.hint);return!o&&!a&&!r&&!i?null:(0,Y.jsxs)(`div`,{className:`mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-muted-foreground`,children:[o&&(0,Y.jsx)(`code`,{"data-testid":`secret-signature`,title:`Fingerprint (first 6 of SHA-256) and last 4 characters`,children:o}),a&&(a.expired?(0,Y.jsxs)(K,{"data-testid":`secret-expiry`,"data-expired":`true`,variant:`destructive`,title:I(new Date(n).getTime()),className:`h-4 px-1 text-[10px]`,children:[`Expired · `,a.label.replace(/^expired /,``),` (`,j(n),`)`]}):(0,Y.jsxs)(`span`,{"data-testid":`secret-expiry`,"data-expired":`false`,title:I(new Date(n).getTime()),children:[a.label,` (`,j(n),`)`]})),r&&(0,Y.jsxs)(`span`,{"data-testid":`secret-revision`,className:`break-all`,children:[`rev `,r]}),i&&(0,Y.jsxs)(`a`,{"data-testid":`source-link`,href:i,target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex min-h-6 items-center gap-0.5 text-primary underline-offset-2 hover:underline`,children:[(0,Y.jsx)(B,{className:`h-3 w-3 shrink-0`}),`Source`]})]})}export{Te as SecretsView};
|
|
2
|
-
//# sourceMappingURL=secrets-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{p as t,u as n}from"./dist-DeW2Y1R5.js";import{$ as r,B as i,Ct as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,P as h,Q as g,R as _,U as v,V as y,W as b,X as x,Y as S,Z as C,at as w,et as T,it as E,j as D,nt as O,rt as k,t as A,tt as j,z as M}from"./store-BgDALGIX.js";import{M as N}from"./provider-display-bWwiuedV.js";import{et as P,f as F,v as I}from"./display-BemJG1f_.js";import{s as L,t as R}from"./api-CIIVBtAV.js";import{t as z}from"./archive-CIuPSvmx.js";import{t as B}from"./external-link-BRfu-fHG.js";import{n as V,t as ee}from"./shield-alert-B9jCWcKW.js";import{t as te}from"./key-round-CcSxl5qr.js";import{t as H}from"./loader-circle-BfPd4kOD.js";import{t as U}from"./lock-BW8MPKw_.js";import{t as ne}from"./pencil-B1Hf2V_J.js";import{t as W}from"./plus-D5Ek4e2S.js";import{t as re}from"./refresh-cw-CfpvQcUn.js";import{t as ie}from"./rotate-cw-FPtkDewA.js";import{t as ae}from"./trash-2-FbcSq927.js";import{t as oe}from"./triangle-alert-BBNhfgMi.js";import{t as G}from"./button-Do6Z3vvn.js";import{t as K}from"./badge-DqJRtj_p.js";import{t as q}from"./input-CsTB6jIx.js";import{t as se}from"./textarea-hs6Mpyfl.js";import{t as ce}from"./VaultDecisionCard-DUIfTTFF.js";var J=e(t(),1),Y=n();function le({url:e}){return(0,Y.jsxs)(`a`,{"data-testid":`source-link`,href:e,target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex min-h-9 max-w-full items-center gap-1 text-xs text-primary underline-offset-2 hover:underline sm:min-h-0`,children:[(0,Y.jsx)(B,{className:`h-3 w-3 shrink-0`}),(0,Y.jsxs)(`span`,{className:`min-w-0 break-all`,children:[`Open the source page: `,e]})]})}function ue({rotate:e,projectId:t,environment:n=`prod`,sourceUrl:r,disabled:i,onClose:a}){let o=A(e=>e.fetchOpenDecisions),[s,c]=(0,J.useState)(e??``),[l,u]=(0,J.useState)(e?`Rotate ${e}`:``),[d,f]=(0,J.useState)(!1),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(null),v=y.test(s),b=v&&l.trim().length>0&&!i&&!d;async function S(){if(b){f(!0),m(``);try{let e=await _(s,l.trim(),t,n);g({name:e.name,formUrl:e.formUrl}),o()}catch(e){m(N(e))}finally{f(!1)}}}return(0,Y.jsx)(`div`,{"data-testid":`secret-request-panel`,className:`rounded-lg border border-border bg-card/60 p-3 text-sm`,children:h?(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`p`,{children:[`Request filed for `,(0,Y.jsx)(`code`,{className:`break-all`,children:h.name}),`. Open the form and enter the value there. The link works once, until it expires or the request is withdrawn. The form has optional expiry, revision and source URL fields, and shows the fingerprint after you save.`]}),h.formUrl?(0,Y.jsxs)(`a`,{href:x(h.formUrl,L()),target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 sm:h-8 sm:w-auto`,children:[(0,Y.jsx)(B,{className:`h-3.5 w-3.5`}),`Open secure form`]}):(0,Y.jsx)(`p`,{className:`text-xs text-tone-warning-fg`,children:`The form link is only shown to the operator token.`}),(0,Y.jsx)(`div`,{children:(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:a,children:`Close`})})]}):(0,Y.jsxs)(`form`,{className:`space-y-2`,onSubmit:e=>{e.preventDefault(),S()},children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:e?`Rotate ${e}`:`Request a new secret`}),!e&&(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(q,{"aria-label":`Secret name`,"aria-invalid":s!==``&&!v,placeholder:`NAME or NAME@environment`,autoComplete:`off`,spellCheck:!1,value:s,onChange:e=>c(e.target.value),className:`font-mono`}),s!==``&&!v&&(0,Y.jsx)(`p`,{className:`mt-1 text-[11px] text-tone-danger-fg`,children:`Start with a letter or underscore; then letters, digits, _ . - (up to 256). Optional @environment: 1–32 lowercase letters, digits or hyphens.`})]}),r&&(0,Y.jsx)(le,{url:r}),(0,Y.jsx)(se,{"aria-label":`Reason`,rows:2,placeholder:`Why is it needed?`,value:l,maxLength:4096,onChange:e=>u(e.target.value)}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`You enter the value on the next page. Do not paste it here.`]}),p&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:p}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!b,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[d&&(0,Y.jsx)(H,{className:`animate-spin`}),e?`Request rotation`:`Request secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:a,className:`h-9 sm:h-8`,children:`Cancel`})]})]})})}function de({projects:e,defaultProjectId:t=``,onClose:n}){let r=A(e=>e.fetchVault),[i,a]=(0,J.useState)(`infisical`),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(`prod`),[u,d]=(0,J.useState)(`/`),[f,p]=(0,J.useState)(``),[m,h]=(0,J.useState)(`codex`),[g,_]=(0,J.useState)(t),[v,y]=(0,J.useState)(`prod`),[b,x]=(0,J.useState)(null),[S,C]=(0,J.useState)(!1),[w,T]=(0,J.useState)(``),[E,D]=(0,J.useState)(null),O=i===`infisical`?{kind:i,project:o,environment:c,path:u}:{kind:i,host:f,provider:m},k=b&&JSON.stringify(b.source)===JSON.stringify(O)?b:null;async function j(){C(!0),T(``),x(null);try{let{names:e}=await R(`POST`,`/secrets/import/preview`,{source:O});x({source:O,names:e,picked:[]})}catch(e){T(N(e))}finally{C(!1)}}async function M(){if(!k?.picked.length)return;C(!0),T(``);let e={source:k.source,names:k.picked,environment:v,scope:g?`project`:`global`,...g?{project:g}:{}};try{D(await R(`POST`,`/secrets/import`,e)),r()}catch(e){T(N(e))}finally{C(!1)}}return(0,Y.jsx)(`section`,{"data-testid":`secret-import-panel`,"aria-label":`Import secrets`,className:`space-y-3 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:E?(0,Y.jsxs)(Y.Fragment,{children:[E.secrets.map(e=>(0,Y.jsxs)(`p`,{children:[`Imported `,e.name,` v`,e.version]},e.name)),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`p`,{className:`font-medium`,children:`Import secrets`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Choose existing names. Relay moves the values directly into encrypted storage. Import selected approves the whole batch.`}),(0,Y.jsxs)(`fieldset`,{disabled:S,className:`space-y-2`,children:[(0,Y.jsxs)(`select`,{"aria-label":`Import source`,value:i,onChange:e=>a(e.target.value),className:`h-9 w-full rounded-md border border-input bg-background px-3`,children:[(0,Y.jsx)(`option`,{value:`infisical`,children:`Infisical path`}),(0,Y.jsx)(`option`,{value:`provider-config`,children:`Provider config`})]}),i===`infisical`?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(q,{"aria-label":`Infisical project`,placeholder:`Infisical project ID, slug or name`,value:o,onChange:e=>s(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source environment`,placeholder:`Source environment`,value:c,onChange:e=>l(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source path`,placeholder:`/path`,value:u,onChange:e=>d(e.target.value)})]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(q,{"aria-label":`Source host`,placeholder:`Host ID or hostname`,value:f,onChange:e=>p(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Source provider`,placeholder:`Provider`,value:m,onChange:e=>h(e.target.value)}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Imported env entries are replaced with secret: references.`})]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,onClick:()=>void j(),children:`Load names`}),k&&(0,Y.jsx)(`div`,{className:`space-y-1`,children:k.names.length===0?(0,Y.jsx)(`p`,{children:`No importable names at this source.`}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:()=>x({...k,picked:k.names}),children:`Select all`}),k.names.map(e=>(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 break-all`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,checked:k.picked.includes(e),onChange:t=>x({...k,picked:t.target.checked?[...k.picked,e]:k.picked.filter(t=>t!==e)})}),e]},e))]})}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Target scope`,(0,Y.jsxs)(`select`,{"aria-label":`Target scope`,value:g,onChange:e=>_(e.target.value),className:`mt-1 h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,children:[(0,Y.jsx)(`option`,{value:``,children:`Global`}),e.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[`Project: `,e.title||e.slug||e.id]},e.id))]})]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Target environment`,(0,Y.jsx)(q,{"aria-label":`Target environment`,value:v,onChange:e=>y(e.target.value)})]})]}),w&&(0,Y.jsx)(`p`,{role:`alert`,className:`break-words text-xs text-tone-danger-fg`,children:w}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(G,{size:`sm`,disabled:S||!k?.picked.length||!v,onClick:()=>void M(),children:`Import selected`}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,disabled:S,onClick:n,children:`Cancel`})]})]})})}var fe={"no-recipient":`No backup recipient is set, so no backup is written. Add your age public key in Settings → Secrets → Vault backup.`,stale:`The last successful backup is more than 48 hours old.`};function pe({status:e,disabled:t}){let n=A(e=>e.fetchVault),r=a(),[i,o]=(0,J.useState)(!1),[s,c]=(0,J.useState)(``),l=e.lastSuccess;async function u(){o(!0),c(``);try{await D()}catch(e){c(N(e))}finally{o(!1),n()}}return(0,Y.jsxs)(`section`,{"data-testid":`vault-backup`,"aria-label":`Vault backup`,className:`space-y-1.5 rounded-lg border px-3 py-2.5 text-sm ${e.warning?`border-tone-warning/40 bg-tone-warning/10`:`border-border bg-card`}`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 font-medium`,children:[(0,Y.jsx)(z,{className:`h-4 w-4 shrink-0 text-muted-foreground`}),` Backup`]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,disabled:t||i||!e.recipientFingerprint,onClick:()=>void u(),children:i?`Backing up…`:`Back up now`})]}),(0,Y.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`dt`,{children:`Last backup`}),(0,Y.jsx)(`dd`,{"data-testid":`vault-backup-last`,className:`min-w-0 break-words text-foreground`,children:l?(0,Y.jsxs)(`span`,{title:I(l.at),children:[P(r,l.at),` · `,l.secrets,` secret`,l.secrets===1?``:`s`]}):`Never`}),(0,Y.jsx)(`dt`,{children:`Recipient`}),(0,Y.jsx)(`dd`,{"data-testid":`vault-backup-recipient`,className:`min-w-0 break-all font-mono text-foreground`,children:e.recipientFingerprint??`Not set`}),(0,Y.jsx)(`dt`,{children:`Kept`}),(0,Y.jsxs)(`dd`,{className:`min-w-0 break-all`,children:[e.files,` of `,e.keep,` in `,e.directory]})]}),e.warning&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs text-tone-warning-fg`,children:fe[e.warning]}),e.lastError&&(!l||e.lastError.at>l.at)&&(0,Y.jsxs)(`p`,{className:`break-words text-xs text-tone-danger-fg`,children:[`Last attempt failed `,P(r,e.lastError.at),`: `,e.lastError.message]}),s&&(0,Y.jsx)(`p`,{role:`alert`,className:`break-words text-xs text-tone-danger-fg`,children:s})]})}function X({draft:e,onChange:t,collapsible:n=!0}){let r=(0,Y.jsxs)(`div`,{"data-testid":`metadata-fields`,className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`space-y-1 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`Expires on`}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(q,{"aria-label":`Expires on`,type:`date`,value:e.expiresDate,onChange:n=>t({...e,expiresDate:n.target.value,expiresBad:n.target.validity.badInput}),className:`text-foreground`}),(0,Y.jsx)(q,{"aria-label":`Expiry time (optional)`,type:`time`,value:e.expiresTime,onChange:n=>t({...e,expiresTime:n.target.value}),className:`w-32 shrink-0 text-foreground`})]}),(0,Y.jsx)(`p`,{className:`text-[11px]`,children:`In your time zone. Without a time it expires at the end of that day.`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Revision`,(0,Y.jsx)(q,{"aria-label":`Revision`,maxLength:500,autoComplete:`off`,placeholder:`Vendor revision or number`,value:e.revision,onChange:n=>t({...e,revision:n.target.value}),className:`text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Source URL`,(0,Y.jsx)(q,{"aria-label":`Source URL`,type:`url`,inputMode:`url`,maxLength:2048,autoComplete:`off`,spellCheck:!1,placeholder:`https://vendor.example/keys`,value:e.sourceUrl,onChange:n=>t({...e,sourceUrl:n.target.value}),className:`font-mono text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`flex min-h-9 items-center gap-2 text-xs text-muted-foreground`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,"aria-label":`Show last four characters`,checked:e.hintEnabled,onChange:n=>t({...e,hintEnabled:n.target.checked}),className:`h-4 w-4`}),`Show the last four characters as a hint`]}),(0,Y.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`Stored as plain text, readable by agents. Never put a credential here.`})]});return n?(0,Y.jsxs)(`details`,{className:`rounded-md border border-border/60 px-2.5 py-1.5`,children:[(0,Y.jsx)(`summary`,{className:`cursor-pointer text-xs font-medium text-muted-foreground`,children:`Optional metadata`}),(0,Y.jsx)(`div`,{className:`mt-2`,children:r})]}):r}var me=e=>e.title||e.slug||e.id;function he({projects:e,defaultProjectId:t=``,onClose:n}){let i=A(e=>e.fetchVault),[a,o]=(0,J.useState)(``),[s,c]=(0,J.useState)(t),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(``),[m,h]=(0,J.useState)(r),[g,_]=(0,J.useState)(!1),[v,b]=(0,J.useState)(``),[x,S]=(0,J.useState)(null),C=y.test(a),w=O(m),T=C&&d.length>0&&!w&&!g;async function D(){if(T){_(!0),b(``);try{let[t,n=`prod`]=a.split(`@`),r=await p({name:t,environment:n,value:d,projectId:s||void 0,description:l.trim()||void 0,metadata:k(m)}),o=e.find(e=>e.id===s);S({name:a,where:o?me(o):`global`,signature:E(r.fingerprint,r.hint)}),f(``),i()}catch(e){b(N(e))}finally{_(!1)}}}return x?(0,Y.jsxs)(`div`,{"data-testid":`secret-new-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:[(0,Y.jsxs)(`p`,{children:[`Saved `,(0,Y.jsx)(`code`,{className:`break-all`,children:x.name}),` (`,x.where,`). Agents use it as `,(0,Y.jsxs)(`code`,{className:`break-all`,children:[`secret:`,x.name]}),`. The value is not shown again.`]}),x.signature&&(0,Y.jsxs)(`p`,{"data-testid":`saved-signature`,className:`text-xs text-muted-foreground`,children:[`Fingerprint `,(0,Y.jsx)(`code`,{children:x.signature}),`. Compare it with the key where you copied it from.`]}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(`form`,{"data-testid":`secret-new-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),D()},children:[(0,Y.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:`New secret`}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(q,{"aria-label":`Secret name`,"aria-invalid":a!==``&&!C,placeholder:`NAME or NAME@environment`,autoComplete:`off`,spellCheck:!1,value:a,onChange:e=>o(e.target.value),className:`font-mono`}),a!==``&&!C&&(0,Y.jsx)(`p`,{className:`mt-1 text-[11px] text-tone-danger-fg`,children:`Start with a letter or underscore; then letters, digits, _ . - (up to 256). Optional @environment: 1–32 lowercase letters, digits or hyphens.`})]}),(0,Y.jsxs)(`select`,{"aria-label":`Scope`,value:s,onChange:e=>c(e.target.value),className:`h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,children:[(0,Y.jsx)(`option`,{value:``,children:`Global (all projects)`}),e.map(e=>(0,Y.jsxs)(`option`,{value:e.id,children:[`Project: `,me(e)]},e.id))]}),(0,Y.jsx)(q,{"aria-label":`Description`,placeholder:`Description (optional)`,maxLength:500,autoComplete:`off`,value:l,onChange:e=>u(e.target.value)}),(0,Y.jsx)(q,{"aria-label":`Value`,type:`password`,placeholder:`Value`,autoComplete:`new-password`,spellCheck:!1,value:d,onChange:e=>f(e.target.value),className:`font-mono`}),(0,Y.jsx)(X,{draft:m,onChange:h}),w&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:w}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`Stored encrypted. It is never shown again, only replaced with Rotate.`]}),v&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:v}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!T,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[g&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:n,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ge({secret:e,scopedRef:t,onClose:n}){let{name:r,projectId:i,environment:a}=e,o=A(e=>e.fetchVault),[s,c]=(0,J.useState)(``),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(()=>T(e.metadata,e.hintEnabled)),[p,m]=(0,J.useState)(!1),[h,g]=(0,J.useState)(``),[_,v]=(0,J.useState)(null),[y,b]=(0,J.useState)(!1),x=O(d,e),S=s.length>0&&!x&&!p;async function C(){if(S){m(!0),g(``);try{let n=await M(t,s,l.trim()||void 0,k(d,e));v({version:n.version,signature:E(n.fingerprint,n.hint)}),c(``),o()}catch(e){g(N(e))}finally{m(!1)}}}return y?(0,Y.jsx)(ue,{rotate:r,projectId:i,environment:a,sourceUrl:e.metadata.sourceUrl,onClose:n}):_?(0,Y.jsxs)(`div`,{"data-testid":`secret-rotate-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,children:[(0,Y.jsxs)(`p`,{children:[(0,Y.jsx)(`code`,{className:`break-all`,children:r}),` is now v`,_.version,`. The value is not shown again.`]}),_.signature&&(0,Y.jsxs)(`p`,{"data-testid":`saved-signature`,className:`text-xs text-muted-foreground`,children:[`Fingerprint `,(0,Y.jsx)(`code`,{children:_.signature}),`. Compare it with the key where you copied it from.`]}),(0,Y.jsx)(G,{size:`sm`,variant:`ghost`,onClick:n,children:`Close`})]}):(0,Y.jsxs)(`form`,{"data-testid":`secret-rotate-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),C()},children:[(0,Y.jsxs)(`div`,{className:`text-xs font-medium text-foreground`,children:[`Rotate `,r]}),e.metadata.sourceUrl&&(0,Y.jsx)(le,{url:e.metadata.sourceUrl}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`New value`,(0,Y.jsx)(q,{"aria-label":`New value`,type:`password`,autoComplete:`new-password`,spellCheck:!1,value:s,onChange:e=>c(e.target.value),className:`font-mono text-foreground`})]}),(0,Y.jsxs)(`label`,{className:`block space-y-1 text-xs text-muted-foreground`,children:[`Reason (optional)`,(0,Y.jsx)(q,{"aria-label":`Reason (optional)`,maxLength:500,autoComplete:`off`,value:l,onChange:e=>u(e.target.value),className:`text-foreground`})]}),(0,Y.jsx)(X,{draft:d,onChange:f}),x&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:x}),(0,Y.jsxs)(`p`,{className:`flex items-start gap-1.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(U,{className:`mt-0.5 h-3 w-3 shrink-0`}),`Stored encrypted as the next version. It is never shown again.`]}),h&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:h}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!S,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[p&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save new value`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:n,className:`h-9 sm:h-8`,children:`Cancel`})]}),(0,Y.jsx)(`button`,{type:`button`,onClick:()=>b(!0),className:`text-xs text-primary underline-offset-2 hover:underline`,children:`Ask someone else to provide it`})]})}function Z({actor:e,labels:t}){let n=A(t=>t.agentsById[e]),r=A(e=>e.openAgentDetail),i=c(e)??(n?e.replace(/^agent-/,``):null);if(!i)return(0,Y.jsx)(`span`,{className:`break-all`,children:e});let a=n?F(n):t?.[e],o=a?`${a} · ${i}`:`agent · ${i}`;return n?(0,Y.jsx)(`button`,{type:`button`,"data-testid":`vault-actor`,"data-agent":`live`,title:e,onClick:()=>r(n),className:`min-w-0 break-words text-left text-primary underline-offset-2 hover:underline`,children:o}):(0,Y.jsx)(`span`,{"data-testid":`vault-actor`,"data-agent":`gone`,title:e,className:`min-w-0 break-words`,children:o})}function _e({secret:e,onClose:t,onDeleted:n}){let r=A(e=>e.fetchVault),i=a(),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(!1),[u,d]=(0,J.useState)(``),f=o===e.name&&!c;async function p(){if(f){l(!0),d(``);try{await m(g(e)),n(),r()}catch(e){d(N(e)),l(!1)}}}return(0,Y.jsxs)(`form`,{"data-testid":`secret-delete-panel`,className:`space-y-2 rounded-lg border border-tone-danger/40 bg-tone-danger/10 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),p()},children:[(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs font-medium text-tone-danger-fg`,children:[(0,Y.jsx)(oe,{className:`mt-0.5 h-3.5 w-3.5 shrink-0`}),`Delete `,e.name,` and all `,e.version,` version`,e.version===1?``:`s`]}),(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`This cannot be undone. Agents that use `,(0,Y.jsxs)(`code`,{className:`break-all`,children:[`secret:`,e.name,e.environment===`prod`?``:`@${e.environment}`]}),` will fail with “not found”.`]}),e.lastResolved&&(0,Y.jsxs)(`p`,{"data-testid":`delete-in-use`,className:`text-xs text-tone-warning-fg`,children:[`In use: last used `,P(i,e.lastResolved.at),` by `,(0,Y.jsx)(Z,{actor:e.lastResolved.actor}),`.`]}),(0,Y.jsx)(q,{"aria-label":`Type ${e.name} to confirm`,placeholder:`Type ${e.name} to confirm`,autoComplete:`off`,spellCheck:!1,value:o,onChange:e=>s(e.target.value),className:`font-mono`}),u&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:u}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,variant:`destructive`,disabled:!f,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[c&&(0,Y.jsx)(H,{className:`animate-spin`}),`Delete secret`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:t,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ve({secret:e,onClose:t,onSaved:n}){let r=A(e=>e.fetchVault),[i,a]=(0,J.useState)(()=>T(e.metadata,e.hintEnabled)),[o,s]=(0,J.useState)(!1),[c,l]=(0,J.useState)(``),u=O(i,e),d=u?void 0:k(i,e);async function f(){if(!(!d||o)){s(!0),l(``);try{await h(g(e),d),r(),n()}catch(e){l(N(e)),s(!1)}}}return(0,Y.jsxs)(`form`,{"data-testid":`secret-metadata-panel`,className:`space-y-2 rounded-lg border border-border bg-card/60 p-3 text-sm`,onSubmit:e=>{e.preventDefault(),f()},children:[(0,Y.jsxs)(`div`,{className:`text-xs font-medium text-foreground`,children:[`Edit metadata of `,e.name]}),(0,Y.jsx)(X,{draft:i,onChange:a,collapsible:!1}),u&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg`,children:u}),c&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-tone-danger-fg break-words`,children:c}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(G,{type:`submit`,size:`sm`,disabled:!d||o,className:`h-9 flex-1 sm:h-8 sm:flex-none`,children:[o&&(0,Y.jsx)(H,{className:`animate-spin`}),`Save metadata`]}),(0,Y.jsx)(G,{type:`button`,size:`sm`,variant:`ghost`,onClick:t,className:`h-9 sm:h-8`,children:`Cancel`})]})]})}function ye({history:e}){return e.error?(0,Y.jsx)(`p`,{role:`alert`,className:`mt-2 text-xs text-tone-danger-fg break-words`,children:e.error}):e.rows?e.rows.length?(0,Y.jsx)(`ul`,{"data-testid":`audit-list`,className:`mt-2 divide-y divide-border/60 rounded-md border border-border/60 text-xs`,"aria-label":`History of ${e.name}`,children:e.rows.map(t=>(0,Y.jsxs)(`li`,{"data-testid":`audit-row`,className:`flex flex-wrap items-baseline gap-x-2 gap-y-0.5 px-2.5 py-1.5`,children:[(0,Y.jsx)(`span`,{className:`shrink-0 whitespace-nowrap text-muted-foreground`,children:I(t.createdAt)}),(0,Y.jsx)(K,{variant:t.outcome===`ok`?`secondary`:`destructive`,className:`h-4 px-1 text-[10px]`,children:v(t.action)}),t.version!==void 0&&(0,Y.jsxs)(`span`,{className:`text-muted-foreground`,children:[`v`,t.version]}),t.version!==void 0&&(t.action===`set`||t.action===`rotated`)&&e.versions?.[t.version]&&(0,Y.jsx)(`code`,{"data-testid":`audit-signature`,className:`text-[11px] text-muted-foreground`,children:e.versions[t.version]}),(0,Y.jsx)(Z,{actor:t.actor,labels:e.labels}),t.outcome!==`ok`&&(0,Y.jsx)(`span`,{className:`text-tone-danger-fg`,children:t.outcome}),(0,Y.jsx)(be,{row:t,labels:e.labels})]},t.id))}):(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`No audit rows yet.`}):(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`Loading history…`})}function be({row:e,labels:t}){let{decisionId:n,requestedBy:r}=s(e),i=A(e=>n!==void 0&&e.openDecisions.some(e=>e.id===n));if(r)return(0,Y.jsxs)(`span`,{className:`min-w-0 break-words text-muted-foreground`,children:[`requested by `,(0,Y.jsx)(Z,{actor:r,labels:t})]});if(n!==void 0)return i?(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>document.querySelector(`[data-testid="decision-card-${n}"]`)?.scrollIntoView({block:`center`}),className:`text-primary underline-offset-2 hover:underline`,children:[`decision #`,n]}):(0,Y.jsxs)(`span`,{className:`text-muted-foreground`,children:[`decision #`,n]});let a=b(e);return a?(0,Y.jsx)(`span`,{className:`min-w-0 break-all text-muted-foreground`,children:a}):null}var xe=`humwick-vault-filter`;function Se(){try{let e=JSON.parse(localStorage.getItem(xe)??`null`);return{tab:e?.tab===`project`?`project`:`global`,projectId:typeof e?.projectId==`string`?e.projectId:``}}catch{return{tab:`global`,projectId:``}}}function Ce(e){try{localStorage.setItem(xe,JSON.stringify(e))}catch{}}var Q=e=>e.title||e.slug||e.id;function we(e,t,n){let r=new Map(e.map(e=>[e.id,e]));for(let e of t)e.projectId&&!r.has(e.projectId)&&r.set(e.projectId,{id:e.projectId,title:e.projectName??``,slug:``});return n&&!r.has(n)&&r.set(n,{id:n,title:``,slug:``}),[...r.values()].sort((e,t)=>Q(e).localeCompare(Q(t)))}function Te(){let e=A(e=>e.vault),t=A(e=>e.vaultProjects),n=A(e=>e.vaultBackup),r=A(e=>e.fetchVault),p=A(e=>e.agentsById),m=A(e=>e.openDecisions),h=a(),[_,v]=(0,J.useState)(null),[y,b]=(0,J.useState)(null),[x,w]=(0,J.useState)(Se),T=e.status===`key-problem`,D=e.status===`ready`?e.secrets:[],O=D.some(e=>e.environment&&e.environment!==`prod`),k=we(t,D,x.projectId),j=x.tab===`project`&&!x.projectId&&k[0]?{tab:`project`,projectId:k[0].id}:x,M=D.filter(e=>S(e,j)),P=m.filter(u).filter(e=>S(C(e.title),j)),F=D.filter(e=>e.projectId).length,I=j.tab===`project`?j.projectId:void 0;function L(e){w(e),Ce(e),v(null),b(null)}function R(e){b(t=>t?.name===e&&t.rows?t:{name:e}),f(e).then(t=>b(n=>n?.name===e?{...n,versions:Object.fromEntries(t.map(e=>[e.version,E(e.fingerprint,e.hint)]))}:n)).catch(()=>{}),l(e).then(t=>{b(n=>n?.name===e?{...n,rows:t}:n);let n=[...new Set(t.flatMap(e=>[e.actor,s(e).requestedBy??``]))].filter(e=>c(e)&&!p[e]);n.length&&o(n).then(t=>b(n=>n?.name===e?{...n,labels:t}:n))},t=>b(n=>n?.name===e?{name:e,error:N(t)}:n))}function z(e){y?.name===e?b(null):R(e)}function B(e){v(t=>t&&t.kind===e.kind&&(!(`ref`in t)||`ref`in e&&t.ref===e.ref)?null:e)}function V(){r(),y&&R(y.name)}return(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(te,{className:`h-5 w-5 text-muted-foreground`}),(0,Y.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Secrets`}),e.status===`ready`&&(0,Y.jsx)(K,{variant:`secondary`,children:M.length})]}),(e.status===`ready`||T)&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,onClick:V,children:[(0,Y.jsx)(re,{className:`h-3.5 w-3.5`}),` Refresh`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,disabled:T,onClick:()=>B({kind:`request`}),children:[(0,Y.jsx)(W,{className:`h-3.5 w-3.5`}),` Request secret`]}),(0,Y.jsx)(G,{size:`sm`,variant:`outline`,disabled:T,onClick:()=>B({kind:`import`}),children:`Import`}),(0,Y.jsxs)(G,{size:`sm`,disabled:T,onClick:()=>B({kind:`new`}),children:[(0,Y.jsx)(W,{className:`h-3.5 w-3.5`}),` New secret`]})]})]}),e.status===`ready`&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsxs)(`div`,{role:`tablist`,"aria-label":`Secret scope`,className:`inline-flex rounded-md border border-border p-0.5`,children:[(0,Y.jsx)(Ee,{selected:x.tab===`global`,onClick:()=>L({...x,tab:`global`}),children:`Global`}),(0,Y.jsxs)(Ee,{selected:x.tab===`project`,onClick:()=>L({...x,tab:`project`}),children:[`Project`,F>0?` (${F})`:``]})]}),x.tab===`project`&&(0,Y.jsxs)(`select`,{"aria-label":`Project`,value:j.projectId,onChange:e=>L({tab:`project`,projectId:e.target.value}),className:`h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm sm:h-8 sm:max-w-xs`,children:[k.length===0&&(0,Y.jsx)(`option`,{value:``,children:`No projects`}),k.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:Q(e)},e.id))]})]}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Names and versions only. Values are never shown, here or anywhere else in Relay.`}),e.status===`unknown`&&(0,Y.jsx)($,{children:`Loading…`}),e.status===`off`&&(0,Y.jsxs)($,{testId:`vault-off`,title:`The secrets vault is off`,children:[`The vault is on by default. Remove `,(0,Y.jsx)(`code`,{children:`AGENT_RELAY_SECRETS_VAULT=0`}),` from the hub environment and restart Relay to turn it on. This page needs an operator token with the secrets scope.`]}),e.status===`error`&&(0,Y.jsx)($,{testId:`vault-error`,title:`Could not read the vault`,tone:`danger`,children:e.message}),e.status===`key-problem`&&(0,Y.jsxs)($,{testId:`vault-key-problem`,title:i[e.code].title,tone:`danger`,children:[i[e.code].body,` Setting and using secrets is paused until then.`]}),n&&(e.status===`ready`||T)&&(0,Y.jsx)(pe,{status:n,disabled:T}),_?.kind===`request`&&(0,Y.jsx)(ue,{disabled:T,projectId:I,onClose:()=>v(null)}),_?.kind===`import`&&!T&&(0,Y.jsx)(de,{projects:k,defaultProjectId:I,onClose:()=>v(null)}),_?.kind===`new`&&!T&&(0,Y.jsx)(he,{projects:k,defaultProjectId:I,onClose:()=>v(null)}),P.length>0&&(0,Y.jsxs)(`section`,{className:`space-y-2`,"aria-label":`Pending requests`,children:[(0,Y.jsxs)(`h3`,{className:`text-sm font-medium text-tone-warning-fg`,children:[`Waiting for a value (`,d(P,h),`)`]}),P.map(e=>(0,Y.jsx)(ce,{decision:e},`${e.id}:${e.updatedAt}`))]}),e.status===`ready`&&(M.length===0?(0,Y.jsx)($,{testId:`vault-empty`,children:j.tab===`project`?`No secrets in this project yet. Create one, request one, or let an agent ask for it.`:`No global secrets yet. Create one, request one, or let an agent ask for it.`}):(0,Y.jsx)(`ul`,{className:`space-y-2`,"aria-label":`Secrets`,children:M.map(e=>{let t=g(e);return(0,Y.jsx)(De,{secret:e,showEnvironment:O,open:y?.name===t?y:null,panel:_&&`ref`in _&&_.ref===t?_.kind:null,onRotate:()=>B({kind:`rotate`,ref:t}),onEditMetadata:()=>B({kind:`metadata`,ref:t}),onMetadataSaved:()=>{v(null),y?.name===t&&R(t)},onDelete:()=>B({kind:`delete`,ref:t}),onHistory:()=>z(t),onClosePanel:()=>v(null),onDeleted:()=>{v(null),y?.name===t&&b(null)}},t)})}))]})}function Ee({selected:e,onClick:t,children:n}){return(0,Y.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":e,onClick:t,className:`h-8 rounded px-3 text-sm font-medium sm:h-7 ${e?`bg-secondary text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:n})}function $({title:e,tone:t,testId:n,children:r}){return(0,Y.jsxs)(`div`,{"data-testid":n,role:t===`danger`?`alert`:void 0,className:t===`danger`?`rounded-md border border-tone-danger/40 bg-tone-danger/10 px-3 py-3 text-sm text-tone-danger-fg`:`rounded-md border border-border px-3 py-6 text-center text-sm text-muted-foreground`,children:[e&&(0,Y.jsxs)(`div`,{className:`mb-1 flex items-center gap-1.5 font-medium`,children:[(0,Y.jsx)(ee,{className:`h-4 w-4 shrink-0`}),e]}),(0,Y.jsx)(`div`,{className:`break-words`,children:r})]})}function De({secret:e,showEnvironment:t,open:n,panel:r,onRotate:i,onEditMetadata:o,onMetadataSaved:s,onDelete:c,onHistory:l,onClosePanel:u,onDeleted:d}){let f=a();return(0,Y.jsxs)(`li`,{"data-testid":`secret-row`,"data-secret":e.name,"data-environment":e.environment??`prod`,"data-scope":e.projectId?`project`:`global`,className:`rounded-lg border border-border bg-card px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,Y.jsx)(`code`,{className:`break-all text-sm font-medium`,children:e.name}),(0,Y.jsx)(K,{variant:`outline`,className:`h-4 px-1 text-[10px]`,children:e.projectId?`project: ${e.projectName??e.projectId}`:`global`}),(0,Y.jsxs)(K,{variant:`secondary`,className:`h-4 px-1 text-[10px]`,children:[`v`,e.version]}),e.metadata?.expiresAt&&Date.parse(e.metadata.expiresAt)<=f&&(0,Y.jsx)(K,{variant:`destructive`,className:`h-4 px-1 text-[10px]`,children:`Expired`}),t&&(0,Y.jsx)(K,{"data-testid":`secret-environment`,variant:`outline`,className:`h-4 px-1 text-[10px]`,children:e.environment??`prod`})]}),(0,Y.jsxs)(`div`,{className:`mt-0.5 text-[11px] text-muted-foreground`,children:[(0,Y.jsxs)(`span`,{title:I(e.updatedAt),children:[e.version>1?`Rotated`:`Set`,` `,P(f,e.updatedAt)]}),(0,Y.jsx)(`span`,{children:` · `}),e.lastResolved?(0,Y.jsxs)(`span`,{title:I(e.lastResolved.at),children:[`Last used `,P(f,e.lastResolved.at),` by `,(0,Y.jsx)(Z,{actor:e.lastResolved.actor})]}):(0,Y.jsx)(`span`,{children:`Not used yet`})]}),(0,Y.jsx)(Oe,{secret:e,now:f})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap gap-1.5`,children:[(0,Y.jsxs)(G,{size:`sm`,variant:`outline`,"aria-expanded":r===`rotate`,onClick:i,className:`h-8`,children:[(0,Y.jsx)(ie,{className:`h-3.5 w-3.5`}),`Rotate`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":r===`metadata`,onClick:o,className:`h-8`,children:[(0,Y.jsx)(ne,{className:`h-3.5 w-3.5`}),`Edit metadata`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":!!n,onClick:l,className:`h-8`,children:[(0,Y.jsx)(V,{className:`h-3.5 w-3.5`}),`History`]}),(0,Y.jsxs)(G,{size:`sm`,variant:`ghost`,"aria-expanded":r===`delete`,onClick:c,className:`h-8 text-tone-danger-fg`,children:[(0,Y.jsx)(ae,{className:`h-3.5 w-3.5`}),`Delete`]})]})]}),r===`rotate`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(ge,{secret:e,scopedRef:g(e),onClose:u})}),r===`metadata`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(ve,{secret:e,onClose:u,onSaved:s})}),r===`delete`&&(0,Y.jsx)(`div`,{className:`mt-2`,children:(0,Y.jsx)(_e,{secret:e,onClose:u,onDeleted:d})}),n&&(0,Y.jsx)(ye,{history:n})]})}function Oe({secret:e,now:t}){let{expiresAt:n,revision:r,sourceUrl:i}=e.metadata,a=w(n,t),o=E(e.fingerprint,e.hint);return!o&&!a&&!r&&!i?null:(0,Y.jsxs)(`div`,{className:`mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-muted-foreground`,children:[o&&(0,Y.jsx)(`code`,{"data-testid":`secret-signature`,title:`Fingerprint (first 6 of SHA-256) and last 4 characters`,children:o}),a&&(a.expired?(0,Y.jsxs)(K,{"data-testid":`secret-expiry`,"data-expired":`true`,variant:`destructive`,title:I(new Date(n).getTime()),className:`h-4 px-1 text-[10px]`,children:[`Expired · `,a.label.replace(/^expired /,``),` (`,j(n),`)`]}):(0,Y.jsxs)(`span`,{"data-testid":`secret-expiry`,"data-expired":`false`,title:I(new Date(n).getTime()),children:[a.label,` (`,j(n),`)`]})),r&&(0,Y.jsxs)(`span`,{"data-testid":`secret-revision`,className:`break-all`,children:[`rev `,r]}),i&&(0,Y.jsxs)(`a`,{"data-testid":`source-link`,href:i,target:`_blank`,rel:`noreferrer noopener`,className:`inline-flex min-h-6 items-center gap-0.5 text-primary underline-offset-2 hover:underline`,children:[(0,Y.jsx)(B,{className:`h-3 w-3 shrink-0`}),`Source`]})]})}export{Te as SecretsView};
|
|
2
|
+
//# sourceMappingURL=secrets-CVXvfvbU.js.map
|
package/public/assets/{service-access-settings-Crq-6a-B.js → service-access-settings-D3Xxqb9w.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,o as n,p as r,u as i}from"./dist-DeW2Y1R5.js";import{et as a,h as o,v as s}from"./display-CDeH4I8T.js";import{t as c}from"./api-CIIVBtAV.js";import{t as l}from"./button-Do6Z3vvn.js";import{t as u}from"./textarea-hs6Mpyfl.js";var d=t(`camera`,[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`,key:`18u6gg`}],[`circle`,{cx:`12`,cy:`13`,r:`3`,key:`1vg3eu`}]]),f=t(`earth`,[[`path`,{d:`M21.54 15H17a2 2 0 0 0-2 2v4.54`,key:`1djwo0`}],[`path`,{d:`M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17`,key:`1tzkfa`}],[`path`,{d:`M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05`,key:`14pb5j`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),p=t(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),m=t(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),h=t(`monitor-cog`,[[`path`,{d:`M12 17v4`,key:`1riwvh`}],[`path`,{d:`m14.305 7.53.923-.382`,key:`1mlnsw`}],[`path`,{d:`m15.228 4.852-.923-.383`,key:`82mpwg`}],[`path`,{d:`m16.852 3.228-.383-.924`,key:`ln4sir`}],[`path`,{d:`m16.852 8.772-.383.923`,key:`1dejw0`}],[`path`,{d:`m19.148 3.228.383-.924`,key:`192kgf`}],[`path`,{d:`m19.53 9.696-.382-.924`,key:`fiavlr`}],[`path`,{d:`m20.772 4.852.924-.383`,key:`1j8mgp`}],[`path`,{d:`m20.772 7.148.924.383`,key:`zix9be`}],[`path`,{d:`M22 13v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7`,key:`1tnzv8`}],[`path`,{d:`M8 21h8`,key:`1ev6f3`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}]]),g=t(`power-off`,[[`path`,{d:`M18.36 6.64A9 9 0 0 1 20.77 15`,key:`dxknvb`}],[`path`,{d:`M6.16 6.16a9 9 0 1 0 12.68 12.68`,key:`1x7qb5`}],[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),_=t(`server-cog`,[[`path`,{d:`m10.852 14.772-.383.923`,key:`11vil6`}],[`path`,{d:`M13.148 14.772a3 3 0 1 0-2.296-5.544l-.383-.923`,key:`1v3clb`}],[`path`,{d:`m13.148 9.228.383-.923`,key:`t2zzyc`}],[`path`,{d:`m13.53 15.696-.382-.924a3 3 0 1 1-2.296-5.544`,key:`1bxfiv`}],[`path`,{d:`m14.772 10.852.923-.383`,key:`k9m8cz`}],[`path`,{d:`m14.772 13.148.923.383`,key:`1xvhww`}],[`path`,{d:`M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5`,key:`tn8das`}],[`path`,{d:`M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5`,key:`1g2pve`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M6 6h.01`,key:`1utrut`}],[`path`,{d:`m9.228 10.852-.923-.383`,key:`1wtb30`}],[`path`,{d:`m9.228 13.148-.923.383`,key:`1a830x`}]]),v=t(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),y=e(r(),1),b=i(),x={healthy:`bg-tone-success/10 text-tone-success-fg`,degraded:`bg-tone-warning/10 text-tone-warning-fg`,unknown:`bg-tone-neutral/10 text-tone-neutral-fg`,down:`bg-tone-danger/10 text-tone-danger-fg`},S={healthy:`Healthy`,degraded:`Degraded`,unknown:`Unknown`,down:`Down`},C=[`healthy`,`degraded`,`unknown`,`down`],w=e=>e.reduce((e,t)=>C.indexOf(t)>C.indexOf(e)?t:e,`healthy`),T={not_configured:`No service catalog is configured`,host_unconfigured:`No broker host is set in the catalog (broker.orchestratorId)`,host_unobserved:`Broker host has not reported yet`,host_stale:`Broker host report is out of date`,host_probe_failed:`Broker host health could not be read`,native_down:`Agent Vault service is not running`,watchdog_down:`Freshness watchdog is not running`,ingress_closed:`Proxy ingress is closed`,refresh_missing:`No upstream credential refresh state on the host`,refresh_invalid:`Upstream credential refresh state is unreadable`,refresh_failed:`Upstream credential refresh failed`,refresh_in_progress:`Upstream credential refresh in progress`,credential_expired:`Upstream credential has expired`,vault_unobserved:`Vault has not been checked yet`,vault_stale:`Vault check is out of date`,vault_unreachable:`Vault control API is unreachable`,sync_unknown:`Vault reports no sync state`,sync_failed:`Last credential sync failed`,sync_stale:`No credential sync in the last 15 minutes`,logs_failed:`Request log collection failed`,logs_lagging:`Request log collection is behind`,logs_backlog:`More request logs are waiting to be collected`};function E({state:e}){return(0,b.jsx)(`span`,{className:n(`rounded px-1.5 py-0.5 text-xs font-medium`,x[e]),children:S[e]})}function D({reasons:e}){return e.length?(0,b.jsx)(`ul`,{className:`list-disc pl-5 text-xs`,children:e.map(e=>(0,b.jsx)(`li`,{children:T[e]??e},e))}):null}function O({now:e,at:t,empty:n=`Never`}){return t?(0,b.jsx)(`time`,{dateTime:new Date(t).toISOString(),title:s(t),children:t>e?`in ${o(t,e)}`:a(e,t)}):(0,b.jsx)(b.Fragment,{children:n})}async function k(e){try{return{value:await e}}catch(e){return{error:e.message}}}async function A(e){let t=new URLSearchParams({limit:`50`,...e?{profile:e}:{}}),[n,r]=await Promise.all([k(c(`GET`,`/service-access/health`)),k(c(`GET`,`/service-access/logs?${t}`))]);return{health:n,logs:r}}function j({profile:e}){let[t,n]=(0,y.useState)(null),[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``),[u,d]=(0,y.useState)(!1);function f(e){n(e.health),`value`in e.logs?(i(e.logs.value),o(``)):(i(null),o(e.logs.error))}(0,y.useEffect)(()=>{let t=!0;return A(e).then(e=>{t&&f(e)}),()=>{t=!1}},[e]);async function p(){d(!0);try{f(await A(e))}finally{d(!1)}}async function m(){if(r?.next){d(!0);try{let t=await c(`GET`,`/service-access/logs?${new URLSearchParams({limit:`50`,before:r.next,...e?{profile:e}:{}})}`);i({logs:[...r.logs,...t.logs],...t.next?{next:t.next}:{}}),o(``)}catch(e){o(e.message)}finally{d(!1)}}}let h=t&&`value`in t?t.value:null,g=t&&`error`in t?t.error:``,_=h?.evaluatedAt??0,v=h?.vaults.filter(t=>!e||t.profile===e)??[],x=h?.host,S=g?`unknown`:e&&h?w([v[0]?.state??`unknown`,x?.state??`unknown`]):h?.state;return(0,b.jsxs)(`section`,{"aria-label":`Service access health`,className:`space-y-3`,children:[(0,b.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,b.jsx)(`h3`,{className:`font-semibold`,children:e?`Vault health`:`Health`}),S&&(0,b.jsx)(E,{state:S}),h&&(0,b.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Checked `,s(_)]}),(0,b.jsx)(l,{size:`sm`,variant:`outline`,disabled:u,onClick:p,children:`Refresh`})]}),g&&(0,b.jsxs)(`p`,{role:`alert`,className:`text-sm`,children:[`Health unavailable: `,g]}),h&&!e&&(0,b.jsx)(D,{reasons:h.reasons}),x&&(0,b.jsxs)(`div`,{"aria-label":`Broker host`,className:`rounded border p-2 text-sm space-y-1`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(`strong`,{children:[`Broker host `,x.orchestratorId]}),(0,b.jsx)(E,{state:x.state})]}),x.units?(0,b.jsxs)(`dl`,{className:`grid grid-cols-[max-content_1fr] gap-x-3 text-xs`,children:[(0,b.jsx)(`dt`,{children:`Proxy ingress`}),(0,b.jsx)(`dd`,{children:x.units.ingress===`active`?`Open`:`Closed (${x.units.ingress})`}),(0,b.jsx)(`dt`,{children:`Agent Vault`}),(0,b.jsx)(`dd`,{children:x.units.native}),(0,b.jsx)(`dt`,{children:`Watchdog`}),(0,b.jsx)(`dd`,{children:x.units.watchdog}),(0,b.jsx)(`dt`,{children:`Credential refresh`}),(0,b.jsxs)(`dd`,{children:[x.refresh?.status??`unknown`,x.refresh?.phase?` (${x.refresh.phase})`:``,x.refresh?.lastSuccessAt?(0,b.jsxs)(b.Fragment,{children:[`, last success `,(0,b.jsx)(O,{now:_,at:x.refresh.lastSuccessAt})]}):null]}),(0,b.jsx)(`dt`,{children:`Upstream credential expiry`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:x.refresh?.credentialExpiresAt,empty:`Unknown`})}),(0,b.jsx)(`dt`,{children:`Host checked`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:x.checkedAt||void 0})})]}):(0,b.jsxs)(`p`,{className:`text-xs`,children:[`Host checked `,(0,b.jsx)(O,{now:_,at:x.checkedAt||void 0}),x.error?` · ${x.error}`:``]}),e&&(0,b.jsx)(D,{reasons:x.reasons})]}),v.map(e=>(0,b.jsxs)(`div`,{"aria-label":`Vault ${e.profile}`,className:`rounded border p-2 text-sm space-y-1`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(`strong`,{children:e.profile}),(0,b.jsx)(E,{state:e.state}),(0,b.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.vault})]}),(0,b.jsxs)(`dl`,{className:`grid grid-cols-[max-content_1fr] gap-x-3 text-xs`,children:[(0,b.jsx)(`dt`,{children:`Credential sync`}),(0,b.jsx)(`dd`,{children:e.error?`Unreachable (${e.error})`:e.sync?(0,b.jsxs)(b.Fragment,{children:[e.sync.failed?`failed`:e.sync.status,`, `,(0,b.jsx)(O,{now:_,at:e.sync.syncedAt})]}):`Unknown`}),(0,b.jsx)(`dt`,{children:`Request logs`}),(0,b.jsxs)(`dd`,{children:[e.logs.stored,` stored, collected `,(0,b.jsx)(O,{now:_,at:e.logs.collectedAt}),e.logs.backlog?`, backlog pending`:``,e.logs.evicted?`, ${e.logs.evicted} removed by the storage cap`:``,e.logs.error?` · ${e.logs.error}`:``]}),(0,b.jsx)(`dt`,{children:`Vault checked`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:e.checkedAt})})]}),(0,b.jsx)(D,{reasons:e.reasons})]},e.vault)),h&&e&&!v.length&&(0,b.jsx)(`p`,{className:`text-sm`,children:`No vault for this profile yet. Save the profile and reconcile.`}),(r||a)&&(0,b.jsxs)(`section`,{"aria-label":`Unattributed request logs`,className:`space-y-1`,children:[(0,b.jsx)(`h4`,{className:`text-sm font-semibold`,children:`Request logs (unattributed)`}),a&&(0,b.jsxs)(`p`,{role:`alert`,className:`text-xs`,children:[`Request logs unavailable: `,a]}),(0,b.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Logged per vault and profile. A request is not linked to the agent that made it. Paths omit query strings and credential-like parts.`}),r?.logs.length?(0,b.jsx)(`div`,{className:`overflow-x-auto`,children:(0,b.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,b.jsx)(`thead`,{children:(0,b.jsxs)(`tr`,{className:`text-left`,children:[(0,b.jsx)(`th`,{className:`pr-2`,children:`Time`}),!e&&(0,b.jsx)(`th`,{className:`pr-2`,children:`Profile`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Request`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Service`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Status`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Latency`}),(0,b.jsx)(`th`,{children:`Attribution`})]})}),(0,b.jsx)(`tbody`,{children:r.logs.map(t=>(0,b.jsxs)(`tr`,{className:`border-t align-top`,children:[(0,b.jsx)(`td`,{className:`pr-2 whitespace-nowrap`,children:(0,b.jsx)(`time`,{dateTime:new Date(t.at).toISOString(),children:s(t.at)})}),!e&&(0,b.jsx)(`td`,{className:`pr-2`,children:t.profile}),(0,b.jsxs)(`td`,{className:`pr-2 break-all`,children:[t.method,` `,t.host,t.path]}),(0,b.jsx)(`td`,{className:`pr-2`,children:t.service??`Unmatched`}),(0,b.jsxs)(`td`,{className:`pr-2`,children:[t.status||`—`,t.errorCode?` ${t.errorCode}`:``]}),(0,b.jsxs)(`td`,{className:`pr-2`,children:[t.latencyMs,` ms`]}),(0,b.jsx)(`td`,{children:`Unattributed`})]},`${t.vault}:${t.id}`))})]})}):r&&(0,b.jsx)(`p`,{className:`text-xs`,children:`No requests logged.`}),r?.next&&(0,b.jsx)(l,{size:`sm`,variant:`outline`,disabled:u,onClick:m,children:`Load older`})]})]})}var M={catalog:{broker:{controlUrl:``,proxyUrl:``,caFingerprint:``,projectId:``},services:[]},profiles:{}};function N({states:e,profile:t}){return(0,b.jsx)(`div`,{className:`space-y-2`,children:e.filter(e=>!t||e.profile===t).map(e=>(0,b.jsxs)(`div`,{className:`rounded border p-2 text-sm`,children:[(0,b.jsx)(`strong`,{children:e.profile}),`: `,e.services.join(`, `)||`No services`,` — `,e.status,(0,b.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Vault: `,e.vault]}),(0,b.jsxs)(`div`,{className:`break-all text-xs`,children:[`Desired: `,e.desiredRevision]}),(0,b.jsxs)(`div`,{className:`break-all text-xs`,children:[`Applied: `,e.appliedRevision??`None`]}),e.error&&(0,b.jsxs)(`div`,{role:`alert`,children:[e.error.code,`: `,e.error.message]})]},e.profile))})}function P(){let[e,t]=(0,y.useState)(null),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(`{"service":"fixture","profile":"sec-ops","ungrantedProfile":"worker","negativePath":"/missing-rule"}`),[o,s]=(0,y.useState)(``),[d,f]=(0,y.useState)(``),[p,m]=(0,y.useState)(!1);async function h(){let e=await c(`GET`,`/service-access`);t(e),r(JSON.stringify(e.catalog?{catalog:e.catalog,profiles:Object.fromEntries(e.profiles.map(e=>[e.profile,{services:e.services,...e.vaultOverride?{vault:e.vaultOverride}:{}}]))}:M,null,2))}(0,y.useEffect)(()=>{h().catch(e=>s(e.message))},[]);async function g(e){m(!0),s(``),f(``);try{await c(`POST`,`/service-access/${e}`,e===`apply`?JSON.parse(n):e===`test`?JSON.parse(i):{}),f(e===`test`?`Probe passed: positive, missing rule and ungranted profile`:`Service access applied`),await h()}catch(e){s(e.message);try{t(await c(`GET`,`/service-access`))}catch{}}finally{m(!1)}}return(0,b.jsxs)(`section`,{className:`space-y-3`,children:[(0,b.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Service access`}),(0,b.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Profile services use Agent Vault. Enter Infisical key references and dummy variables only. Broker environment and secretPath select the existing store; profile vault adopts an existing native vault. Set broker orchestratorId to apply the same binding to its refresh job and watchdog and to show their health.`}),(0,b.jsxs)(`label`,{className:`block text-sm`,children:[`Catalog and profile mappings (JSON)`,(0,b.jsx)(u,{"aria-label":`Catalog and profile mappings (JSON)`,rows:16,value:n,onChange:e=>r(e.target.value)})]}),(0,b.jsxs)(`div`,{className:`flex gap-2`,children:[(0,b.jsx)(l,{disabled:p||!e,onClick:()=>g(`apply`),children:`Save and apply`}),(0,b.jsx)(l,{variant:`outline`,disabled:p||!e?.catalog,onClick:()=>g(`reconcile`),children:`Reconcile`}),(0,b.jsx)(l,{variant:`outline`,disabled:p,onClick:()=>{s(``),h().catch(e=>s(e.message))},children:`Reload`})]}),o&&(0,b.jsx)(`p`,{role:`alert`,children:o}),d&&(0,b.jsx)(`p`,{role:`status`,children:d}),e&&(0,b.jsx)(N,{states:e.profiles}),e?.catalog&&(0,b.jsx)(j,{}),!!e?.cleanup?.length&&(0,b.jsxs)(`section`,{"aria-label":`Removed profile cleanup`,className:`space-y-2`,children:[(0,b.jsx)(`h3`,{className:`font-semibold`,children:`Removed profile cleanup`}),(0,b.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`These profiles were removed. Their vault cleanup stays visible here and is excluded from editable mappings.`}),(0,b.jsx)(N,{states:e.cleanup})]}),(0,b.jsxs)(`label`,{className:`block text-sm`,children:[`Fixture probe (JSON)`,(0,b.jsx)(u,{"aria-label":`Fixture probe (JSON)`,value:i,onChange:e=>a(e.target.value)})]}),(0,b.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Uses safe GETs against your fixture/test service: granted path, missing rule, ungranted profile. The service must reject dummy auth with 401 or 403.`}),(0,b.jsx)(l,{variant:`outline`,disabled:p||!e?.catalog,onClick:()=>g(`test`),children:`Test fixture`})]})}function F({profile:e,onChange:t,readOnly:n}){let[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``);(0,y.useEffect)(()=>{let e=!0;return c(`GET`,`/service-access`).then(t=>{e&&i(t)}).catch(t=>{e&&o(t.message)}),()=>{e=!1}},[]);let s=e.serviceAccess?.services??[];return(0,b.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,b.jsx)(`p`,{children:`Standing access through this profile. Save the profile, then reconcile in Settings → Service access.`}),(0,b.jsxs)(`label`,{className:`block`,children:[`Native vault (optional)`,(0,b.jsx)(`input`,{"aria-label":`Native vault (optional)`,className:`ml-2 rounded border bg-background p-1`,disabled:n,value:e.serviceAccess?.vault??``,placeholder:`Derived from profile name`,onChange:e=>t({services:s,...e.target.value?{vault:e.target.value}:{}})})]}),r?.catalog?.services.map(r=>(0,b.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(`input`,{type:`checkbox`,disabled:n,checked:s.includes(r.name),onChange:n=>t({...e.serviceAccess,services:n.target.checked?[...s,r.name]:s.filter(e=>e!==r.name)})}),r.name,` (`,r.host,r.path,`)`]},r.name)),!r?.catalog&&(0,b.jsx)(`p`,{children:`No catalog configured. Open Settings → Service access.`}),s.filter(e=>!r?.catalog?.services.some(t=>t.name===e)).map(e=>(0,b.jsxs)(`p`,{children:[`Unknown service: `,e]},e)),a&&(0,b.jsx)(`p`,{role:`alert`,children:a}),r&&(0,b.jsx)(N,{states:r.profiles,profile:e.name}),r?.catalog&&r.profiles.some(t=>t.profile===e.name)&&(0,b.jsx)(j,{profile:e.name})]})}export{g as a,p as c,_ as i,f as l,P as n,h as o,v as r,m as s,F as t,d as u};
|
|
2
|
-
//# sourceMappingURL=service-access-settings-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,o as n,p as r,u as i}from"./dist-DeW2Y1R5.js";import{et as a,h as o,v as s}from"./display-BemJG1f_.js";import{t as c}from"./api-CIIVBtAV.js";import{t as l}from"./button-Do6Z3vvn.js";import{t as u}from"./textarea-hs6Mpyfl.js";var d=t(`camera`,[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`,key:`18u6gg`}],[`circle`,{cx:`12`,cy:`13`,r:`3`,key:`1vg3eu`}]]),f=t(`earth`,[[`path`,{d:`M21.54 15H17a2 2 0 0 0-2 2v4.54`,key:`1djwo0`}],[`path`,{d:`M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17`,key:`1tzkfa`}],[`path`,{d:`M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05`,key:`14pb5j`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),p=t(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),m=t(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),h=t(`monitor-cog`,[[`path`,{d:`M12 17v4`,key:`1riwvh`}],[`path`,{d:`m14.305 7.53.923-.382`,key:`1mlnsw`}],[`path`,{d:`m15.228 4.852-.923-.383`,key:`82mpwg`}],[`path`,{d:`m16.852 3.228-.383-.924`,key:`ln4sir`}],[`path`,{d:`m16.852 8.772-.383.923`,key:`1dejw0`}],[`path`,{d:`m19.148 3.228.383-.924`,key:`192kgf`}],[`path`,{d:`m19.53 9.696-.382-.924`,key:`fiavlr`}],[`path`,{d:`m20.772 4.852.924-.383`,key:`1j8mgp`}],[`path`,{d:`m20.772 7.148.924.383`,key:`zix9be`}],[`path`,{d:`M22 13v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7`,key:`1tnzv8`}],[`path`,{d:`M8 21h8`,key:`1ev6f3`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}]]),g=t(`power-off`,[[`path`,{d:`M18.36 6.64A9 9 0 0 1 20.77 15`,key:`dxknvb`}],[`path`,{d:`M6.16 6.16a9 9 0 1 0 12.68 12.68`,key:`1x7qb5`}],[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),_=t(`server-cog`,[[`path`,{d:`m10.852 14.772-.383.923`,key:`11vil6`}],[`path`,{d:`M13.148 14.772a3 3 0 1 0-2.296-5.544l-.383-.923`,key:`1v3clb`}],[`path`,{d:`m13.148 9.228.383-.923`,key:`t2zzyc`}],[`path`,{d:`m13.53 15.696-.382-.924a3 3 0 1 1-2.296-5.544`,key:`1bxfiv`}],[`path`,{d:`m14.772 10.852.923-.383`,key:`k9m8cz`}],[`path`,{d:`m14.772 13.148.923.383`,key:`1xvhww`}],[`path`,{d:`M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5`,key:`tn8das`}],[`path`,{d:`M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5`,key:`1g2pve`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M6 6h.01`,key:`1utrut`}],[`path`,{d:`m9.228 10.852-.923-.383`,key:`1wtb30`}],[`path`,{d:`m9.228 13.148-.923.383`,key:`1a830x`}]]),v=t(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),y=e(r(),1),b=i(),x={healthy:`bg-tone-success/10 text-tone-success-fg`,degraded:`bg-tone-warning/10 text-tone-warning-fg`,unknown:`bg-tone-neutral/10 text-tone-neutral-fg`,down:`bg-tone-danger/10 text-tone-danger-fg`},S={healthy:`Healthy`,degraded:`Degraded`,unknown:`Unknown`,down:`Down`},C=[`healthy`,`degraded`,`unknown`,`down`],w=e=>e.reduce((e,t)=>C.indexOf(t)>C.indexOf(e)?t:e,`healthy`),T={not_configured:`No service catalog is configured`,host_unconfigured:`No broker host is set in the catalog (broker.orchestratorId)`,host_unobserved:`Broker host has not reported yet`,host_stale:`Broker host report is out of date`,host_probe_failed:`Broker host health could not be read`,native_down:`Agent Vault service is not running`,watchdog_down:`Freshness watchdog is not running`,ingress_closed:`Proxy ingress is closed`,refresh_missing:`No upstream credential refresh state on the host`,refresh_invalid:`Upstream credential refresh state is unreadable`,refresh_failed:`Upstream credential refresh failed`,refresh_in_progress:`Upstream credential refresh in progress`,credential_expired:`Upstream credential has expired`,vault_unobserved:`Vault has not been checked yet`,vault_stale:`Vault check is out of date`,vault_unreachable:`Vault control API is unreachable`,sync_unknown:`Vault reports no sync state`,sync_failed:`Last credential sync failed`,sync_stale:`No credential sync in the last 15 minutes`,logs_failed:`Request log collection failed`,logs_lagging:`Request log collection is behind`,logs_backlog:`More request logs are waiting to be collected`};function E({state:e}){return(0,b.jsx)(`span`,{className:n(`rounded px-1.5 py-0.5 text-xs font-medium`,x[e]),children:S[e]})}function D({reasons:e}){return e.length?(0,b.jsx)(`ul`,{className:`list-disc pl-5 text-xs`,children:e.map(e=>(0,b.jsx)(`li`,{children:T[e]??e},e))}):null}function O({now:e,at:t,empty:n=`Never`}){return t?(0,b.jsx)(`time`,{dateTime:new Date(t).toISOString(),title:s(t),children:t>e?`in ${o(t,e)}`:a(e,t)}):(0,b.jsx)(b.Fragment,{children:n})}async function k(e){try{return{value:await e}}catch(e){return{error:e.message}}}async function A(e){let t=new URLSearchParams({limit:`50`,...e?{profile:e}:{}}),[n,r]=await Promise.all([k(c(`GET`,`/service-access/health`)),k(c(`GET`,`/service-access/logs?${t}`))]);return{health:n,logs:r}}function j({profile:e}){let[t,n]=(0,y.useState)(null),[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``),[u,d]=(0,y.useState)(!1);function f(e){n(e.health),`value`in e.logs?(i(e.logs.value),o(``)):(i(null),o(e.logs.error))}(0,y.useEffect)(()=>{let t=!0;return A(e).then(e=>{t&&f(e)}),()=>{t=!1}},[e]);async function p(){d(!0);try{f(await A(e))}finally{d(!1)}}async function m(){if(r?.next){d(!0);try{let t=await c(`GET`,`/service-access/logs?${new URLSearchParams({limit:`50`,before:r.next,...e?{profile:e}:{}})}`);i({logs:[...r.logs,...t.logs],...t.next?{next:t.next}:{}}),o(``)}catch(e){o(e.message)}finally{d(!1)}}}let h=t&&`value`in t?t.value:null,g=t&&`error`in t?t.error:``,_=h?.evaluatedAt??0,v=h?.vaults.filter(t=>!e||t.profile===e)??[],x=h?.host,S=g?`unknown`:e&&h?w([v[0]?.state??`unknown`,x?.state??`unknown`]):h?.state;return(0,b.jsxs)(`section`,{"aria-label":`Service access health`,className:`space-y-3`,children:[(0,b.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,b.jsx)(`h3`,{className:`font-semibold`,children:e?`Vault health`:`Health`}),S&&(0,b.jsx)(E,{state:S}),h&&(0,b.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Checked `,s(_)]}),(0,b.jsx)(l,{size:`sm`,variant:`outline`,disabled:u,onClick:p,children:`Refresh`})]}),g&&(0,b.jsxs)(`p`,{role:`alert`,className:`text-sm`,children:[`Health unavailable: `,g]}),h&&!e&&(0,b.jsx)(D,{reasons:h.reasons}),x&&(0,b.jsxs)(`div`,{"aria-label":`Broker host`,className:`rounded border p-2 text-sm space-y-1`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(`strong`,{children:[`Broker host `,x.orchestratorId]}),(0,b.jsx)(E,{state:x.state})]}),x.units?(0,b.jsxs)(`dl`,{className:`grid grid-cols-[max-content_1fr] gap-x-3 text-xs`,children:[(0,b.jsx)(`dt`,{children:`Proxy ingress`}),(0,b.jsx)(`dd`,{children:x.units.ingress===`active`?`Open`:`Closed (${x.units.ingress})`}),(0,b.jsx)(`dt`,{children:`Agent Vault`}),(0,b.jsx)(`dd`,{children:x.units.native}),(0,b.jsx)(`dt`,{children:`Watchdog`}),(0,b.jsx)(`dd`,{children:x.units.watchdog}),(0,b.jsx)(`dt`,{children:`Credential refresh`}),(0,b.jsxs)(`dd`,{children:[x.refresh?.status??`unknown`,x.refresh?.phase?` (${x.refresh.phase})`:``,x.refresh?.lastSuccessAt?(0,b.jsxs)(b.Fragment,{children:[`, last success `,(0,b.jsx)(O,{now:_,at:x.refresh.lastSuccessAt})]}):null]}),(0,b.jsx)(`dt`,{children:`Upstream credential expiry`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:x.refresh?.credentialExpiresAt,empty:`Unknown`})}),(0,b.jsx)(`dt`,{children:`Host checked`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:x.checkedAt||void 0})})]}):(0,b.jsxs)(`p`,{className:`text-xs`,children:[`Host checked `,(0,b.jsx)(O,{now:_,at:x.checkedAt||void 0}),x.error?` · ${x.error}`:``]}),e&&(0,b.jsx)(D,{reasons:x.reasons})]}),v.map(e=>(0,b.jsxs)(`div`,{"aria-label":`Vault ${e.profile}`,className:`rounded border p-2 text-sm space-y-1`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(`strong`,{children:e.profile}),(0,b.jsx)(E,{state:e.state}),(0,b.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.vault})]}),(0,b.jsxs)(`dl`,{className:`grid grid-cols-[max-content_1fr] gap-x-3 text-xs`,children:[(0,b.jsx)(`dt`,{children:`Credential sync`}),(0,b.jsx)(`dd`,{children:e.error?`Unreachable (${e.error})`:e.sync?(0,b.jsxs)(b.Fragment,{children:[e.sync.failed?`failed`:e.sync.status,`, `,(0,b.jsx)(O,{now:_,at:e.sync.syncedAt})]}):`Unknown`}),(0,b.jsx)(`dt`,{children:`Request logs`}),(0,b.jsxs)(`dd`,{children:[e.logs.stored,` stored, collected `,(0,b.jsx)(O,{now:_,at:e.logs.collectedAt}),e.logs.backlog?`, backlog pending`:``,e.logs.evicted?`, ${e.logs.evicted} removed by the storage cap`:``,e.logs.error?` · ${e.logs.error}`:``]}),(0,b.jsx)(`dt`,{children:`Vault checked`}),(0,b.jsx)(`dd`,{children:(0,b.jsx)(O,{now:_,at:e.checkedAt})})]}),(0,b.jsx)(D,{reasons:e.reasons})]},e.vault)),h&&e&&!v.length&&(0,b.jsx)(`p`,{className:`text-sm`,children:`No vault for this profile yet. Save the profile and reconcile.`}),(r||a)&&(0,b.jsxs)(`section`,{"aria-label":`Unattributed request logs`,className:`space-y-1`,children:[(0,b.jsx)(`h4`,{className:`text-sm font-semibold`,children:`Request logs (unattributed)`}),a&&(0,b.jsxs)(`p`,{role:`alert`,className:`text-xs`,children:[`Request logs unavailable: `,a]}),(0,b.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Logged per vault and profile. A request is not linked to the agent that made it. Paths omit query strings and credential-like parts.`}),r?.logs.length?(0,b.jsx)(`div`,{className:`overflow-x-auto`,children:(0,b.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,b.jsx)(`thead`,{children:(0,b.jsxs)(`tr`,{className:`text-left`,children:[(0,b.jsx)(`th`,{className:`pr-2`,children:`Time`}),!e&&(0,b.jsx)(`th`,{className:`pr-2`,children:`Profile`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Request`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Service`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Status`}),(0,b.jsx)(`th`,{className:`pr-2`,children:`Latency`}),(0,b.jsx)(`th`,{children:`Attribution`})]})}),(0,b.jsx)(`tbody`,{children:r.logs.map(t=>(0,b.jsxs)(`tr`,{className:`border-t align-top`,children:[(0,b.jsx)(`td`,{className:`pr-2 whitespace-nowrap`,children:(0,b.jsx)(`time`,{dateTime:new Date(t.at).toISOString(),children:s(t.at)})}),!e&&(0,b.jsx)(`td`,{className:`pr-2`,children:t.profile}),(0,b.jsxs)(`td`,{className:`pr-2 break-all`,children:[t.method,` `,t.host,t.path]}),(0,b.jsx)(`td`,{className:`pr-2`,children:t.service??`Unmatched`}),(0,b.jsxs)(`td`,{className:`pr-2`,children:[t.status||`—`,t.errorCode?` ${t.errorCode}`:``]}),(0,b.jsxs)(`td`,{className:`pr-2`,children:[t.latencyMs,` ms`]}),(0,b.jsx)(`td`,{children:`Unattributed`})]},`${t.vault}:${t.id}`))})]})}):r&&(0,b.jsx)(`p`,{className:`text-xs`,children:`No requests logged.`}),r?.next&&(0,b.jsx)(l,{size:`sm`,variant:`outline`,disabled:u,onClick:m,children:`Load older`})]})]})}var M={catalog:{broker:{controlUrl:``,proxyUrl:``,caFingerprint:``,projectId:``},services:[]},profiles:{}};function N({states:e,profile:t}){return(0,b.jsx)(`div`,{className:`space-y-2`,children:e.filter(e=>!t||e.profile===t).map(e=>(0,b.jsxs)(`div`,{className:`rounded border p-2 text-sm`,children:[(0,b.jsx)(`strong`,{children:e.profile}),`: `,e.services.join(`, `)||`No services`,` — `,e.status,(0,b.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Vault: `,e.vault]}),(0,b.jsxs)(`div`,{className:`break-all text-xs`,children:[`Desired: `,e.desiredRevision]}),(0,b.jsxs)(`div`,{className:`break-all text-xs`,children:[`Applied: `,e.appliedRevision??`None`]}),e.error&&(0,b.jsxs)(`div`,{role:`alert`,children:[e.error.code,`: `,e.error.message]})]},e.profile))})}function P(){let[e,t]=(0,y.useState)(null),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(`{"service":"fixture","profile":"sec-ops","ungrantedProfile":"worker","negativePath":"/missing-rule"}`),[o,s]=(0,y.useState)(``),[d,f]=(0,y.useState)(``),[p,m]=(0,y.useState)(!1);async function h(){let e=await c(`GET`,`/service-access`);t(e),r(JSON.stringify(e.catalog?{catalog:e.catalog,profiles:Object.fromEntries(e.profiles.map(e=>[e.profile,{services:e.services,...e.vaultOverride?{vault:e.vaultOverride}:{}}]))}:M,null,2))}(0,y.useEffect)(()=>{h().catch(e=>s(e.message))},[]);async function g(e){m(!0),s(``),f(``);try{await c(`POST`,`/service-access/${e}`,e===`apply`?JSON.parse(n):e===`test`?JSON.parse(i):{}),f(e===`test`?`Probe passed: positive, missing rule and ungranted profile`:`Service access applied`),await h()}catch(e){s(e.message);try{t(await c(`GET`,`/service-access`))}catch{}}finally{m(!1)}}return(0,b.jsxs)(`section`,{className:`space-y-3`,children:[(0,b.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Service access`}),(0,b.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Profile services use Agent Vault. Enter Infisical key references and dummy variables only. Broker environment and secretPath select the existing store; profile vault adopts an existing native vault. Set broker orchestratorId to apply the same binding to its refresh job and watchdog and to show their health.`}),(0,b.jsxs)(`label`,{className:`block text-sm`,children:[`Catalog and profile mappings (JSON)`,(0,b.jsx)(u,{"aria-label":`Catalog and profile mappings (JSON)`,rows:16,value:n,onChange:e=>r(e.target.value)})]}),(0,b.jsxs)(`div`,{className:`flex gap-2`,children:[(0,b.jsx)(l,{disabled:p||!e,onClick:()=>g(`apply`),children:`Save and apply`}),(0,b.jsx)(l,{variant:`outline`,disabled:p||!e?.catalog,onClick:()=>g(`reconcile`),children:`Reconcile`}),(0,b.jsx)(l,{variant:`outline`,disabled:p,onClick:()=>{s(``),h().catch(e=>s(e.message))},children:`Reload`})]}),o&&(0,b.jsx)(`p`,{role:`alert`,children:o}),d&&(0,b.jsx)(`p`,{role:`status`,children:d}),e&&(0,b.jsx)(N,{states:e.profiles}),e?.catalog&&(0,b.jsx)(j,{}),!!e?.cleanup?.length&&(0,b.jsxs)(`section`,{"aria-label":`Removed profile cleanup`,className:`space-y-2`,children:[(0,b.jsx)(`h3`,{className:`font-semibold`,children:`Removed profile cleanup`}),(0,b.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`These profiles were removed. Their vault cleanup stays visible here and is excluded from editable mappings.`}),(0,b.jsx)(N,{states:e.cleanup})]}),(0,b.jsxs)(`label`,{className:`block text-sm`,children:[`Fixture probe (JSON)`,(0,b.jsx)(u,{"aria-label":`Fixture probe (JSON)`,value:i,onChange:e=>a(e.target.value)})]}),(0,b.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Uses safe GETs against your fixture/test service: granted path, missing rule, ungranted profile. The service must reject dummy auth with 401 or 403.`}),(0,b.jsx)(l,{variant:`outline`,disabled:p||!e?.catalog,onClick:()=>g(`test`),children:`Test fixture`})]})}function F({profile:e,onChange:t,readOnly:n}){let[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``);(0,y.useEffect)(()=>{let e=!0;return c(`GET`,`/service-access`).then(t=>{e&&i(t)}).catch(t=>{e&&o(t.message)}),()=>{e=!1}},[]);let s=e.serviceAccess?.services??[];return(0,b.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,b.jsx)(`p`,{children:`Standing access through this profile. Save the profile, then reconcile in Settings → Service access.`}),(0,b.jsxs)(`label`,{className:`block`,children:[`Native vault (optional)`,(0,b.jsx)(`input`,{"aria-label":`Native vault (optional)`,className:`ml-2 rounded border bg-background p-1`,disabled:n,value:e.serviceAccess?.vault??``,placeholder:`Derived from profile name`,onChange:e=>t({services:s,...e.target.value?{vault:e.target.value}:{}})})]}),r?.catalog?.services.map(r=>(0,b.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(`input`,{type:`checkbox`,disabled:n,checked:s.includes(r.name),onChange:n=>t({...e.serviceAccess,services:n.target.checked?[...s,r.name]:s.filter(e=>e!==r.name)})}),r.name,` (`,r.host,r.path,`)`]},r.name)),!r?.catalog&&(0,b.jsx)(`p`,{children:`No catalog configured. Open Settings → Service access.`}),s.filter(e=>!r?.catalog?.services.some(t=>t.name===e)).map(e=>(0,b.jsxs)(`p`,{children:[`Unknown service: `,e]},e)),a&&(0,b.jsx)(`p`,{role:`alert`,children:a}),r&&(0,b.jsx)(N,{states:r.profiles,profile:e.name}),r?.catalog&&r.profiles.some(t=>t.profile===e.name)&&(0,b.jsx)(j,{profile:e.name})]})}export{g as a,p as c,_ as i,f as l,P as n,h as o,v as r,m as s,F as t,d as u};
|
|
2
|
+
//# sourceMappingURL=service-access-settings-D3Xxqb9w.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{o as t,p as n,u as r}from"./dist-DeW2Y1R5.js";import{Ct as i,Et as a,Ot as o,t as s}from"./store-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{o as t,p as n,u as r}from"./dist-DeW2Y1R5.js";import{Ct as i,Et as a,Ot as o,t as s}from"./store-BgDALGIX.js";import{N as c,a as l,r as u,s as d,t as f,u as p,v as m}from"./provider-display-bWwiuedV.js";import{a as h,n as g}from"./tasks-BIyeAaPC.js";import{o as _,s as v,t as y}from"./api-CIIVBtAV.js";import{t as b}from"./themes-G5j9m1Ji.js";import{a as x,i as S,n as C,o as w,r as T,s as E,t as ee}from"./dialog-uuJ9_geR.js";import{c as D,n as te,o as ne,r as re,s as ie,t as ae}from"./dropdown-menu-BXiNephE.js";import{t as O}from"./label-BPBzm9FJ.js";import{a as k,i as A,n as j,r as M,t as N}from"./select-DTQMP4Dk.js";import{t as P}from"./switch-DuCA7mrB.js";import{a as oe,c as se,i as ce,l as le,n as ue,o as de,r as fe,s as pe,u as me}from"./service-access-settings-D3Xxqb9w.js";import{t as he}from"./chevron-down-BoG3JCZn.js";import{t as ge}from"./chevron-right-iljytE0x.js";import{t as F}from"./circle-alert-CryagaZd.js";import{t as _e}from"./circle-check-CkUkN96J.js";import{t as ve}from"./eye-BAP6fHrX.js";import{t as ye}from"./gauge-BIODY-BQ.js";import{t as be}from"./key-round-CcSxl5qr.js";import{t as I}from"./loader-circle-BfPd4kOD.js";import{t as xe}from"./pencil-B1Hf2V_J.js";import{t as Se}from"./plus-D5Ek4e2S.js";import{t as Ce}from"./power-6tZOhYPg.js";import{t as we}from"./refresh-cw-CfpvQcUn.js";import{r as Te}from"./workflow-marker-CzOsB8BM.js";import{t as L}from"./save-B_PGqSm4.js";import{t as Ee}from"./trash-2-FbcSq927.js";import{t as De}from"./user-plus-D9749q73.js";import{t as Oe}from"./volume-2-XrcRKD9Z.js";import{t as R}from"./button-Do6Z3vvn.js";import{t as z}from"./badge-DqJRtj_p.js";import{t as ke}from"./copy-button-CjOj4HEf.js";import{t as B}from"./input-CsTB6jIx.js";import{t as V}from"./textarea-hs6Mpyfl.js";import{i as H,n as U,o as W,r as G,s as K,t as q}from"./card-C4QJ4hCW.js";import{t as Ae}from"./user-avatar-CkLhVBGu.js";var je={"admin:*":`system:admin`,"system:write":`system:admin`,"agents:read":`agent:read`,"agents:write":`agent:write`,"messages:read":`message:read`,"messages:write":`message:send`,"tasks:read":`task:read`,"tasks:write":`task:write`,"commands:read":`command:read`,"commands:write":`command:write`,"channels:read":`channel:read`,"channels:write":`channel:write`,"integrations:read":`integration:read`,"integrations:write":`integration:write`,"connectors:read":`integration:read`,"connectors:write":`integration:write`,"events:create":`integration:write`,"tasks:create":`task:write`};function Me(e){return je[e]??e}function Ne(e,t){let n=Me(t),r=Pe(n);if(!r)return!1;if(e?.includes(`*`))return!0;for(let t of e??[]){let e=Me(t),i=Pe(e);if(i&&(e===`system:admin`||e===n||e===`${r.category}:*`||r.category===`settings`&&r.action&&r.namespace&&i.category===`settings`&&i.action===r.action&&i.namespace===void 0))return!0}return!1}function Pe(e){if(e===`*`)return{category:`*`};let t=e.split(`:`);if(t.some(e=>!e))return null;if(t.length===2){let[e,n]=t;return{category:e,action:n}}if(t.length===3){let[e,n,r]=t;return e!==`settings`||n!==`read`&&n!==`write`||r===`*`?null:{category:e,action:n,namespace:r}}return null}var J=e(n(),1);function Fe(e){return`${e.namespace}/${e.key}`}function Ie(e){return`/settings/${encodeURIComponent(e.namespace)}/${encodeURIComponent(e.key)}`}function Le(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`settings`}function Re(e){let t=new Map;for(let n of e.filter(e=>e.readable)){let e=n.display?.group?.trim()||n.namespace;t.set(e,[...t.get(e)??[],n])}return[...t.entries()].map(([e,t])=>({group:e,slug:Le(e),settings:t.sort(ze)})).sort((e,t)=>Be(e.settings)-Be(t.settings)||e.group.localeCompare(t.group))}function ze(e,t){return(e.display?.order??2**53-1)-(t.display?.order??2**53-1)||e.display?.label?.localeCompare(t.display?.label??``)||Fe(e).localeCompare(Fe(t))}function Be(e){return Math.min(...e.map(e=>e.display?.order??2**53-1))}function Ve(e){return Array.isArray(e.type)?e.type.find(e=>e!==`null`):e.type}function He(e,t,n){if(!t.length)return n;let[r,...i]=t;if(r===void 0)return n;if(typeof r==`number`){let t=Array.isArray(e)?[...e]:[];return t[r]=He(t[r],i,n),t}let a=c(e)?{...e}:{},o=He(a[r],i,n);return o===void 0?delete a[r]:a[r]=o,a}function Ue(e){if(e.default!==void 0)return e.default;if(e.const!==void 0)return e.const;if(e.enum?.length)return e.enum[0];switch(Ve(e)){case`boolean`:return!1;case`integer`:case`number`:return 0;case`array`:return[];case`object`:return{};case`string`:return``;default:return}}function We(e){return e.split(/\r?\n|,/).map(e=>e.trim()).filter(Boolean)}function Ge(e){return Array.isArray(e)?e.map(e=>String(e)).join(`
|
|
2
2
|
`):``}function Ke(e){return c(e)?Object.entries(e).map(([e,t])=>`${e}=${String(t??``)}`).join(`
|
|
3
3
|
`):``}function qe(e){return Object.fromEntries(e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(e=>{let t=e.indexOf(`=`);return t>=0?[e.slice(0,t).trim(),e.slice(t+1)]:[e,``]}))}var Y=r(),Je=`__unset__`;function Ye(e){return e===`server-runtime`?`Server runtime`:e===`bootstrap`?`Bootstrap`:`Browser`}function Xe(e){return e===`server-runtime`?`Stored by Relay and mutable while the server is running.`:e===`bootstrap`?`Read from startup configuration; restart or host config changes are required.`:`Stored only in this browser profile.`}function Ze(e){return e===`browser`?(0,Y.jsx)(de,{className:`size-3.5`}):(0,Y.jsx)(ce,{className:`size-3.5`})}function X(e){return e.details??[]}function Qe({group:e,settings:t,onSaved:n}){let r=[...new Set(t.map(e=>e.tier))];return(0,Y.jsxs)(`section`,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:e}),(0,Y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:r.map(e=>(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,title:Xe(e),children:[Ze(e),Ye(e)]},e))})]}),t.length===0?(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsx)(G,{className:`text-sm text-muted-foreground`,children:`No settings in this group.`})}):(0,Y.jsx)(`div`,{className:`space-y-3`,children:t.map(e=>(0,Y.jsx)($e,{setting:e,onSaved:n},Fe(e)))})]})}function $e({setting:e,onSaved:t}){let[n,r]=(0,J.useState)(()=>e.value??e.defaults??Ue(e.schema)),[i,a]=(0,J.useState)(!1),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)([]),u=e.writable&&e.tier===`server-runtime`;function d(e,t){r(n=>He(n,e,t)),l([]),s(``)}async function f(){if(u){a(!0),l([]),s(``);try{let i=await y(`PUT`,Ie(e),{value:n,updatedBy:`dashboard`});r(i.value),t(i),s(`Saved`)}catch(e){let t=X(e);l(t.length?t:[e.message])}finally{a(!1)}}}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`flex flex-wrap items-center gap-2 text-sm`,children:[e.display.label,(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,title:Xe(e.tier),children:[Ze(e.tier),Ye(e.tier)]}),!e.writable&&(0,Y.jsx)(z,{variant:`secondary`,children:`Read only`})]}),e.display.description&&(0,Y.jsx)(H,{children:e.display.description}),(0,Y.jsx)(U,{children:(0,Y.jsxs)(R,{size:`sm`,onClick:f,disabled:!u||i,children:[(0,Y.jsx)(L,{className:`size-4`}),i?`Saving`:`Save`]})})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsx)(tt,{schema:e.schema,value:n,path:[],label:e.display.label,required:!0,disabled:!u||i,onChange:d}),(0,Y.jsxs)(`p`,{className:`flex flex-wrap items-center gap-x-2 text-[11px] text-muted-foreground`,children:[(0,Y.jsxs)(`code`,{className:`rounded bg-muted px-1.5 py-0.5 font-mono`,children:[e.namespace,`/`,e.key]}),(0,Y.jsxs)(`span`,{children:[`read `,(0,Y.jsx)(`span`,{className:`text-foreground/70`,children:e.scope.read})]}),(0,Y.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,Y.jsxs)(`span`,{children:[`write `,(0,Y.jsx)(`span`,{className:`text-foreground/70`,children:e.scope.write})]})]}),(0,Y.jsx)(et,{errors:c,status:o})]})]})}function et({errors:e,status:t}){return(0,Y.jsxs)(Y.Fragment,{children:[e.length>0&&(0,Y.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsxs)(`div`,{className:`mb-1 flex items-center gap-2 font-medium`,children:[(0,Y.jsx)(F,{className:`size-4`}),`Save failed`]}),(0,Y.jsx)(`ul`,{className:`list-disc space-y-1 pl-5`,children:e.map(e=>(0,Y.jsx)(`li`,{children:e},e))})]}),t&&(0,Y.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-tone-success-fg`,children:[(0,Y.jsx)(_e,{className:`size-4`}),t]})]})}function tt(e){let{schema:t,value:n,path:r,label:i,required:a,disabled:o,onChange:s}=e,l=Ve(t);if(t.enum?.length){let e=n==null||n===``?Je:String(n);return(0,Y.jsx)(Z,{label:i,description:t.description,children:(0,Y.jsxs)(N,{value:e,onValueChange:e=>s(r,e===`__unset__`?void 0:e),disabled:o,children:[(0,Y.jsx)(A,{"aria-label":i,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[!a&&(0,Y.jsx)(M,{value:`__unset__`,children:`Not set`}),t.enum.map(e=>(0,Y.jsx)(M,{value:String(e),children:String(e)},String(e)))]})]})})}if(l===`boolean`)return(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:i}),t.description&&(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:t.description})]}),(0,Y.jsx)(P,{"aria-label":i,checked:!!n,onCheckedChange:e=>s(r,e),disabled:o})]});if(l===`integer`||l===`number`)return(0,Y.jsx)(Z,{label:i,description:t.description,children:(0,Y.jsx)(B,{"aria-label":i,type:`number`,min:typeof t.minimum==`number`?t.minimum:void 0,max:typeof t.maximum==`number`?t.maximum:void 0,step:l===`integer`?1:`any`,value:typeof n==`number`?n:``,disabled:o,onChange:e=>s(r,e.target.value===``&&!a?void 0:Number(e.target.value))})});if(l===`array`)return(0,Y.jsx)(Z,{label:i,description:t.description??`One item per line.`,children:(0,Y.jsx)(V,{"aria-label":i,rows:Math.min(8,Math.max(3,Array.isArray(n)?n.length+1:3)),value:Ge(n),disabled:o,onChange:e=>s(r,We(e.target.value))})});if(l===`object`){let e=t.properties??{},a=new Set(t.required??[]);return Object.keys(e).length===0&&t.additionalProperties?(0,Y.jsx)(Z,{label:i,description:t.description??`KEY=value, one entry per line.`,children:(0,Y.jsx)(V,{"aria-label":i,rows:5,value:Ke(n),disabled:o,onChange:e=>s(r,qe(e.target.value))})}):(0,Y.jsxs)(`div`,{className:`space-y-3`,children:[r.length>0&&(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:i}),t.description&&(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:t.description})]}),(0,Y.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:Object.entries(e).map(([e,t])=>{let i=c(n)?n[e]:void 0;return(0,Y.jsx)(tt,{schema:t,value:i===void 0&&a.has(e)?Ue(t):i,path:[...r,e],label:t.title||nt(e),required:a.has(e),disabled:o,onChange:s},e)})})]})}return(0,Y.jsx)(Z,{label:i,description:t.description,children:(0,Y.jsx)(B,{"aria-label":i,value:typeof n==`string`?n:n==null?``:String(n),disabled:o,onChange:e=>s(r,e.target.value===``&&!a?void 0:e.target.value)})})}function Z({label:e,description:t,children:n}){return(0,Y.jsxs)(`label`,{className:`block space-y-1.5 text-sm`,children:[(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:e}),n,t&&(0,Y.jsx)(`span`,{className:`block text-xs text-muted-foreground`,children:t})]})}function nt(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1 $2`).replace(/[-_]+/g,` `).replace(/^\w/,e=>e.toUpperCase())}function rt(){let e=s(e=>e.theme),t=s(e=>e.set);return(0,Y.jsxs)(`section`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Browser preferences`}),(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`These are stored in local dashboard state, not in Relay server config.`})]}),(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Dashboard display`}),(0,Y.jsx)(H,{className:`text-xs`,children:`Browser tier · persisted in this browser profile.`}),(0,Y.jsx)(U,{children:(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,children:[(0,Y.jsx)(de,{className:`size-3.5`}),`Browser`]})})]}),(0,Y.jsx)(G,{className:`grid gap-3 md:grid-cols-2`,children:(0,Y.jsx)(Z,{label:`Theme`,children:(0,Y.jsxs)(N,{value:e,onValueChange:e=>t({theme:e}),children:[(0,Y.jsx)(A,{children:(0,Y.jsx)(k,{})}),(0,Y.jsx)(j,{children:b.map(e=>(0,Y.jsx)(M,{value:e.id,children:e.label},e.id))})]})})})]}),(0,Y.jsx)(it,{})]})}function it(){let e=s(e=>e.voiceTtsEnabled),t=s(e=>e.setVoiceTtsEnabled),n=s(e=>e.voiceTtsMode),r=s(e=>e.setVoiceTtsMode),i=s(e=>e.voiceTtsKokoroVoice),c=s(e=>e.setVoiceTtsKokoroVoice),l=s(e=>e.voiceTtsBrowserVoice),u=s(e=>e.setVoiceTtsBrowserVoice),d=s(e=>e.voiceInputMode),f=s(e=>e.setVoiceInputMode),[p,m]=(0,J.useState)(()=>o());(0,J.useEffect)(()=>{if(typeof window>`u`||!(`speechSynthesis`in window))return;let e=()=>m(o());return e(),window.speechSynthesis.addEventListener?.(`voiceschanged`,e),()=>window.speechSynthesis.removeEventListener?.(`voiceschanged`,e)},[]);let h=a.some(e=>e.id===i)?a:[...a,{id:i,label:i}];return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`flex items-center gap-2 text-sm`,children:[(0,Y.jsx)(Oe,{className:`size-4`}),`Voice`]}),(0,Y.jsx)(H,{className:`text-xs`,children:`Browser tier TTS and push-to-talk behavior.`}),(0,Y.jsx)(U,{children:(0,Y.jsx)(P,{checked:e,onCheckedChange:t})})]}),(0,Y.jsxs)(G,{className:`grid gap-3 md:grid-cols-2`,children:[(0,Y.jsx)(Z,{label:`Speech engine`,children:(0,Y.jsxs)(N,{value:n,onValueChange:e=>r(e),children:[(0,Y.jsx)(A,{children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:`kokoro`,children:`Kokoro (server, fallback to browser)`}),(0,Y.jsx)(M,{value:`browser`,children:`Browser Web Speech API`})]})]})}),(0,Y.jsx)(Z,{label:`Kokoro voice`,children:(0,Y.jsxs)(N,{value:i,onValueChange:c,children:[(0,Y.jsx)(A,{children:(0,Y.jsx)(k,{})}),(0,Y.jsx)(j,{children:h.map(e=>(0,Y.jsx)(M,{value:e.id,children:e.label},e.id))})]})}),(0,Y.jsx)(Z,{label:`Browser voice`,children:(0,Y.jsxs)(N,{value:l||`__unset__`,onValueChange:e=>u(e===`__unset__`?``:e),children:[(0,Y.jsx)(A,{children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:Je,children:`System default`}),p.map(e=>(0,Y.jsx)(M,{value:e.uri,children:e.label},e.uri))]})]})}),(0,Y.jsx)(Z,{label:`Push-to-talk input`,children:(0,Y.jsxs)(N,{value:d,onValueChange:e=>f(e),children:[(0,Y.jsx)(A,{children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:`compose`,children:`Fill message box`}),(0,Y.jsx)(M,{value:`autosend`,children:`Send immediately`})]})]})})]})]})}var at=[{value:``,label:`Until re-enabled`},{value:`1h`,label:`1 hour`,ms:60*6e4},{value:`1d`,label:`1 day`,ms:1440*6e4},{value:`7d`,label:`7 days`,ms:10080*6e4},{value:`30d`,label:`30 days`,ms:720*60*6e4}];function ot({entry:e,canWrite:t,onChanged:n,onError:r}){let[i,a]=(0,J.useState)(``),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(!1),u=e.disabled,d=u?.source===`operator`;async function f(c){if(t){l(!0);try{let t=at.find(e=>e.value===o)?.ms;await y(`PUT`,`/providers/${encodeURIComponent(e.provider)}/enablement`,{enabled:c,...!c&&t?{disabledUntil:Date.now()+t}:{},...!c&&i.trim()?{reason:i.trim()}:{},updatedBy:`dashboard`}),a(``),s(``),await n(`${e.provider} ${c?`enabled`:`disabled`}`)}catch(e){r(e)}finally{l(!1)}}}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`text-sm`,children:[`Provider `,e.label||e.provider]}),(0,Y.jsx)(U,{children:u?(0,Y.jsxs)(z,{variant:`destructive`,className:`gap-1`,children:[(0,Y.jsx)(oe,{className:`size-3.5`}),`Disabled`]}):(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,children:[(0,Y.jsx)(Ce,{className:`size-3.5`}),`Enabled`]})})]}),(0,Y.jsxs)(G,{className:`space-y-3 text-sm`,children:[u?.source===`all-models-disabled`&&(0,Y.jsx)(`p`,{className:`text-muted-foreground`,children:`All models are disabled, so the provider is disabled too. Enable a model below to bring it back.`}),d&&(0,Y.jsxs)(`p`,{className:`text-muted-foreground`,children:[`Disabled by the operator`,u.disabledUntil?` until ${new Date(u.disabledUntil).toLocaleString()}`:``,u.reason?` — ${u.reason}`:``,`.`,` `,`No new spawns, routing, quota polling or quota alerts. Running agents keep running.`]}),d?(0,Y.jsx)(R,{size:`sm`,disabled:!t||c,onClick:()=>void f(!0),children:`Enable provider`}):(0,Y.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[1fr_auto_auto] md:items-end`,children:[(0,Y.jsx)(Z,{label:`Reason (optional)`,children:(0,Y.jsx)(B,{value:i,disabled:!t||c,placeholder:`e.g. subscription ended`,onChange:e=>a(e.target.value)})}),(0,Y.jsx)(Z,{label:`Disable for`,children:(0,Y.jsx)(`select`,{className:`h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,value:o,disabled:!t||c,onChange:e=>s(e.target.value),children:at.map(e=>(0,Y.jsx)(`option`,{value:e.value,children:e.label},e.value))})}),(0,Y.jsx)(R,{size:`sm`,variant:`destructive`,disabled:!t||c,onClick:()=>void f(!1),children:`Disable provider`})]})]})]})}function st({catalog:e,error:t,canWrite:n,onCatalog:r}){let i=e[0]?.provider??``,[a,o]=(0,J.useState)(i),[s,c]=(0,J.useState)(()=>ct(i)),[l,u]=(0,J.useState)(``),[d,f]=(0,J.useState)([]),p=e.some(e=>e.provider===a)?a:i,m=e.find(e=>e.provider===p)??e[0],h=e.map(e=>e.provider);function g(e){c(t=>({...t,...e})),f([]),u(``)}function _(e){o(e),c(ct(e)),f([]),u(``)}async function v(){r((await y(`GET`,`/providers`)).catalog)}async function b(){if(n){f([]),u(``);try{await y(`PUT`,`/providers/${encodeURIComponent(s.provider)}/models/${encodeURIComponent(s.alias)}`,{label:s.label,providerModel:s.providerModel,efforts:We(s.efforts),defaultEffort:s.defaultEffort.trim()||void 0,limits:ut(s),capabilities:s.capabilities,contextThreshold:ft(s),disabled:s.disabled,updatedBy:`dashboard`}),await v(),u(`${s.alias} saved`),c(ct(s.provider))}catch(e){let t=X(e);f(t.length?t:[e.message])}}}async function x(e,t){if(n){f([]),u(``);try{await y(`PATCH`,`/providers/${encodeURIComponent(p)}/models/${encodeURIComponent(e.alias)}`,{disabled:t,updatedBy:`dashboard`}),await v(),u(`${e.alias} ${t?`disabled`:`enabled`}`)}catch(e){let t=X(e);f(t.length?t:[e.message])}}}async function S(e){if(n){f([]),u(``);try{await y(`PUT`,`/providers/${encodeURIComponent(p)}/default-model`,{alias:e.alias,updatedBy:`dashboard`}),await v(),u(`${e.alias} is now the default`)}catch(e){let t=X(e);f(t.length?t:[e.message])}}}async function C(e){if(n){f([]),u(``);try{await y(`DELETE`,`/providers/${encodeURIComponent(p)}/models/${encodeURIComponent(e.alias)}`),await v(),u(`${e.alias} removed`)}catch(e){let t=X(e);f(t.length?t:[e.message])}}}function w(e){c({provider:p,alias:e.alias,label:e.label,providerModel:e.providerModel,efforts:e.efforts.join(`, `),defaultEffort:e.defaultEffort??``,contextWindowTokens:e.limits?.contextWindowTokens?.value?.toString()??``,maxOutputTokens:e.limits?.maxOutputTokens?.value?.toString()??``,selfCompactUtilization:e.contextThreshold?.selfCompactUtilization?.toString()??``,warnUtilization:e.contextThreshold?.warnUtilization?.toString()??``,hardBackstopUtilization:e.contextThreshold?.hardBackstopUtilization?.toString()??``,disabled:!!e.disabled,capabilities:e.capabilities}),f([]),u(``)}return t?(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`text-sm text-muted-foreground`,children:[(0,Y.jsxs)(`div`,{className:`mb-1 flex items-center gap-2 font-medium text-foreground`,children:[(0,Y.jsx)(ie,{className:`size-4`}),`Model catalog`]}),t]})}):(0,Y.jsxs)(`section`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Model catalog`}),(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Switch a whole provider off or on, add override models, disable unavailable models, or remove custom entries from the provider catalog.`})]}),!n&&(0,Y.jsx)(z,{variant:`secondary`,children:`Read only: needs settings:write:provider`})]}),(0,Y.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:h.map(t=>(0,Y.jsxs)(R,{variant:t===p?`default`:`outline`,size:`sm`,onClick:()=>_(t),children:[t,e.find(e=>e.provider===t)?.disabled?` (off)`:``]},t))}),m&&(0,Y.jsx)(ot,{entry:m,canWrite:n,onChanged:async e=>{await v(),f([]),u(e)},onError:e=>{let t=X(e);f(t.length?t:[e.message])}}),(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Add or edit model`}),(0,Y.jsx)(U,{children:(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,children:[(0,Y.jsx)(ce,{className:`size-3.5`}),`Server runtime`]})})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:[(0,Y.jsx)(Z,{label:`Alias`,children:(0,Y.jsx)(B,{value:s.alias,disabled:!n,placeholder:`nightly`,onChange:e=>g({alias:e.target.value.trim()})})}),(0,Y.jsx)(Z,{label:`Label`,children:(0,Y.jsx)(B,{value:s.label,disabled:!n,placeholder:`Nightly Codex`,onChange:e=>g({label:e.target.value})})}),(0,Y.jsx)(Z,{label:`Provider model`,children:(0,Y.jsx)(B,{value:s.providerModel,disabled:!n,placeholder:`codex-nightly`,onChange:e=>g({providerModel:e.target.value})})}),(0,Y.jsx)(Z,{label:`Efforts`,children:(0,Y.jsx)(B,{value:s.efforts,disabled:!n,placeholder:`low, medium, high`,onChange:e=>g({efforts:e.target.value})})}),(0,Y.jsx)(Z,{label:`Default effort`,children:(0,Y.jsx)(B,{value:s.defaultEffort,disabled:!n,placeholder:`medium`,onChange:e=>g({defaultEffort:e.target.value})})}),(0,Y.jsx)(Z,{label:`Context window tokens`,children:(0,Y.jsx)(B,{value:s.contextWindowTokens,disabled:!n,placeholder:`e.g. 256000 (OpenRouter: context_length)`,inputMode:`numeric`,onChange:e=>g({contextWindowTokens:e.target.value})})}),(0,Y.jsx)(Z,{label:`Max output tokens`,children:(0,Y.jsx)(B,{value:s.maxOutputTokens,disabled:!n,placeholder:`e.g. 32000`,inputMode:`numeric`,onChange:e=>g({maxOutputTokens:e.target.value})})}),(0,Y.jsx)(Z,{label:`Self compact utilization`,children:(0,Y.jsx)(B,{value:s.selfCompactUtilization,disabled:!n,placeholder:`0.80`,inputMode:`decimal`,onChange:e=>g({selfCompactUtilization:e.target.value})})}),(0,Y.jsx)(Z,{label:`Warn utilization`,children:(0,Y.jsx)(B,{value:s.warnUtilization,disabled:!n,placeholder:`default: self - 0.10`,inputMode:`decimal`,onChange:e=>g({warnUtilization:e.target.value})})}),(0,Y.jsx)(Z,{label:`Hard backstop utilization`,children:(0,Y.jsx)(B,{value:s.hardBackstopUtilization,disabled:!n,placeholder:`0.90`,inputMode:`decimal`,onChange:e=>g({hardBackstopUtilization:e.target.value})})}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Disabled`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Keep visible but unavailable for new launches.`})]}),(0,Y.jsx)(P,{checked:s.disabled,disabled:!n,onCheckedChange:e=>g({disabled:e})})]})]}),lt(m,s.providerModel)&&(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Qualified runtime name: `,(0,Y.jsx)(`code`,{className:`rounded bg-muted px-1.5 py-0.5 font-mono`,children:lt(m,s.providerModel)})]}),(0,Y.jsxs)(R,{onClick:b,disabled:!n||!s.alias||!s.label||!s.providerModel,children:[(0,Y.jsx)(Se,{className:`size-4`}),`Save model`]})]})]}),(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[m&&m.models.length===0&&(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsx)(G,{className:`text-sm text-muted-foreground`,children:`No models in this provider catalog yet.`})}),m?.models.map(e=>(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsx)(`span`,{className:`font-medium`,children:e.label}),(0,Y.jsx)(`code`,{className:`rounded bg-muted px-1.5 py-0.5 font-mono text-xs`,children:e.alias}),e.disabled&&(0,Y.jsx)(z,{variant:`secondary`,children:`Disabled`}),e.alias===m.defaultModel&&(0,Y.jsx)(z,{variant:`secondary`,children:`Default`})]}),(0,Y.jsxs)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:[e.providerModel,e.efforts.length>0?` · efforts ${e.efforts.join(`, `)}`:` · no effort levels`,e.defaultEffort?` · default ${e.defaultEffort}`:``,` · context ${mt(e)}`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.alias!==m.defaultModel&&(0,Y.jsx)(R,{variant:`outline`,size:`sm`,disabled:!n||!!(e.disabled||e.unavailable),onClick:()=>void S(e),children:`Set default`}),(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>w(e),children:[(0,Y.jsx)(xe,{className:`size-4`}),`Edit`]}),(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,disabled:!n,onClick:()=>void x(e,!e.disabled),children:[e.disabled?(0,Y.jsx)(ve,{className:`size-4`}):(0,Y.jsx)(se,{className:`size-4`}),e.disabled?`Enable`:`Disable`]}),(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,disabled:!n,onClick:()=>void C(e),children:[(0,Y.jsx)(Ee,{className:`size-4`}),`Remove`]})]})]})},e.alias))]}),d.length>0&&(0,Y.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:(0,Y.jsx)(`ul`,{className:`list-disc space-y-1 pl-5`,children:d.map(e=>(0,Y.jsx)(`li`,{children:e},e))})}),l&&(0,Y.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-tone-success-fg`,children:[(0,Y.jsx)(_e,{className:`size-4`}),l]})]})}function ct(e){return{provider:e,alias:``,label:``,providerModel:``,efforts:``,defaultEffort:``,contextWindowTokens:``,maxOutputTokens:``,selfCompactUtilization:``,warnUtilization:``,hardBackstopUtilization:``,disabled:!1}}function lt(e,t){return p(e,t)}function ut(e){let t=dt(e.contextWindowTokens,`Context window tokens`),n=dt(e.maxOutputTokens,`Max output tokens`);if(!(!t&&!n))return{...t?{contextWindowTokens:t}:{},...n?{maxOutputTokens:n}:{}}}function dt(e,t){let n=e.trim();if(!n)return;let r=Number(n);if(!Number.isSafeInteger(r)||r<=0)throw Error(`${t} must be a positive integer`);return{value:r,source:`override`,confidence:`declared`}}function ft(e){let t=pt(e.selfCompactUtilization,`Self compact utilization`),n=pt(e.warnUtilization,`Warn utilization`),r=pt(e.hardBackstopUtilization,`Hard backstop utilization`);if(!(t===void 0&&n===void 0&&r===void 0)){if(t===void 0)throw Error(`Self compact utilization is required when setting context thresholds`);return{selfCompactUtilization:t,...n===void 0?{}:{warnUtilization:n},...r===void 0?{}:{hardBackstopUtilization:r}}}}function pt(e,t){let n=e.trim();if(!n)return;let r=Number(n);if(!Number.isFinite(r))throw Error(`${t} must be a number`);return r}function mt(e){if(e.contextThreshold)return`self ${ht(e.contextThreshold.selfCompactUtilization)}, warn ${ht(e.contextThreshold.warnUtilization??Math.max(0,e.contextThreshold.selfCompactUtilization-.1))}`;let t=d(e.limits?.contextWindowTokens?.value);return`derived self ${ht(t.selfCompactUtilization)}, warn ${ht(t.warnUtilization)}`}function ht(e){return`${Math.round(e*100)}%`}var gt=e=>e===void 0?`inherit`:e?`on`:`off`,_t=e=>e===`inherit`?void 0:e===`on`,vt=e=>({...e.defaults,...e.value,teams:{...e.value?.teams}});function yt({setting:e,teams:t,onSaved:n}){let[r,i]=(0,J.useState)(()=>vt(e)),[a,o]=(0,J.useState)(!1),[s,c]=(0,J.useState)(``),[l,u]=(0,J.useState)([]),d=e.writable&&e.tier===`server-runtime`,f=!d||a;function p(e){i(t=>({...t,...e})),u([]),c(``)}function m(e,t){let n={...r.teams[e],...t},{[e]:i,...a}=r.teams;p({teams:Object.values(n).some(e=>e!==void 0)?{...a,[e]:n}:a})}async function h(){if(d){o(!0),u([]),c(``);try{let e=await y(`PUT`,`/settings/idle-digest/default`,{value:r,updatedBy:`dashboard`});i(vt(e)),n(e),c(`Saved`)}catch(e){let t=X(e);u(t.length?t:[e.message])}finally{o(!1)}}}let g=new Map;for(let e of t)e.status===`active`&&g.set(e.id,e.title||e.id);for(let e of Object.keys(r.teams))g.has(e)||g.set(e,e);return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`flex flex-wrap items-center gap-2 text-sm`,children:[`Idle-agent digest`,(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,children:[(0,Y.jsx)(ce,{className:`size-3.5`}),`Server runtime`]}),!d&&(0,Y.jsx)(z,{variant:`secondary`,children:`Read only`})]}),(0,Y.jsx)(H,{children:`One digest per coordinator per window listing idle children; provably safe ones can be stopped automatically.`}),(0,Y.jsx)(U,{children:(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void h(),disabled:f,children:[(0,Y.jsx)(L,{className:`size-4`}),a?`Saving`:`Save`]})})]}),(0,Y.jsxs)(G,{className:`space-y-4`,children:[(0,Y.jsx)(xt,{label:`Send idle-agent digests to coordinators`,checked:r.enabled,disabled:f,onChange:e=>p({enabled:e})}),(0,Y.jsx)(Z,{label:`Digest window (hours)`,description:`Default for every team (0.25–168). The server validates the range.`,children:(0,Y.jsx)(B,{"aria-label":`Digest window (hours)`,type:`number`,step:`any`,min:.25,max:168,value:r.windowHours,disabled:f,onChange:e=>p({windowHours:Number(e.target.value)})})}),(0,Y.jsx)(xt,{label:`Stop provably safe idle children automatically`,checked:r.autoReapSafe,disabled:f,onChange:e=>p({autoReapSafe:e})}),(0,Y.jsxs)(`div`,{className:`space-y-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Per-team overrides`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Leave a window empty or a switch on “Inherit” to follow the defaults above. A team switched on here is digested even while the global switch is off.`})]}),g.size===0&&(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No active teams.`}),[...g].map(([e,t])=>{let n=r.teams[e];return(0,Y.jsxs)(`div`,{className:`grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_140px_160px_160px]`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`div`,{className:`truncate text-sm font-medium`,children:t}),t!==e&&(0,Y.jsx)(`code`,{className:`block truncate text-[11px] text-muted-foreground`,children:e})]}),(0,Y.jsx)(Z,{label:`Window (hours)`,children:(0,Y.jsx)(B,{"aria-label":`${t} digest window (hours)`,type:`number`,step:`any`,min:.25,max:168,placeholder:String(r.windowHours),value:n?.windowHours??``,disabled:f,onChange:t=>m(e,{windowHours:t.target.value===``?void 0:Number(t.target.value)})})}),(0,Y.jsx)(bt,{label:`Digest`,ariaLabel:`${t} digest`,value:n?.enabled,inherited:r.enabled,disabled:f,onChange:t=>m(e,{enabled:t})}),(0,Y.jsx)(bt,{label:`Auto-reap`,ariaLabel:`${t} auto-reap`,value:n?.autoReapSafe,inherited:r.autoReapSafe,disabled:f,onChange:t=>m(e,{autoReapSafe:t})})]},e)})]}),(0,Y.jsx)(et,{errors:l,status:s})]})]})}function bt({label:e,ariaLabel:t,value:n,inherited:r,disabled:i,onChange:a}){return(0,Y.jsx)(Z,{label:e,children:(0,Y.jsxs)(`select`,{"aria-label":t,className:`h-8 w-full rounded-lg border border-input bg-transparent px-2.5 text-sm`,value:gt(n),disabled:i,onChange:e=>a(_t(e.target.value)),children:[(0,Y.jsxs)(`option`,{value:`inherit`,children:[`Inherit (`,r?`on`:`off`,`)`]}),(0,Y.jsx)(`option`,{value:`on`,children:`On`}),(0,Y.jsx)(`option`,{value:`off`,children:`Off`})]})})}function xt({label:e,checked:t,disabled:n,onChange:r}){return(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:e}),(0,Y.jsx)(P,{"aria-label":e,checked:t,disabled:n,onCheckedChange:r})]})}var St=`unset`;function Ct(e){let t=e=>e?.trim()||void 0,n={communicationStyle:e.communicationStyle,responseStyle:e.responseStyle};e.communicationStyle===`custom`&&(n.communicationCustom=t(e.communicationCustom)),e.responseStyle===`custom`&&(n.responseCustom=t(e.responseCustom));for(let r of[`about`,`locale`,`timeZone`]){let i=t(e[r]);i&&(n[r]=i)}return e.dateFormat&&(n.dateFormat=e.dateFormat),Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function wt({title:e,hint:t,children:n}){return(0,Y.jsxs)(`section`,{className:`space-y-2 border-b border-border pb-4 last:border-b-0 last:pb-0`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h3`,{className:`text-sm font-medium`,children:e}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:t})]}),n]})}function Tt({setting:e,onSaved:t}){let[n,r]=(0,J.useState)(e.value),[i,a]=(0,J.useState)(!1),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(!1),u=e=>{r(t=>({...t,...e})),l(!1)},d=n.communicationStyle===`custom`&&!n.communicationCustom?.trim()||n.responseStyle===`custom`&&!n.responseCustom?.trim();async function f(){a(!0),s(``);try{let e=await y(`PUT`,`/settings/agent-prefs/default`,{value:Ct(n),updatedBy:`dashboard`});r(e.value),l(!0),t(e)}catch(e){s(e.message)}finally{a(!1)}}return(0,Y.jsx)(q,{size:`sm`,"data-testid":`agent-prefs`,children:(0,Y.jsxs)(G,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold`,children:`How agents talk to you`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Agents you own use these from their next start or context reset.`})]}),(0,Y.jsxs)(wt,{title:`Communication style`,hint:`The tone agents use with you.`,children:[(0,Y.jsxs)(N,{value:n.communicationStyle,onValueChange:e=>u({communicationStyle:e}),children:[(0,Y.jsx)(A,{className:`w-full sm:w-64`,"aria-label":`Communication style`,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:`neutral`,children:`Neutral`}),(0,Y.jsx)(M,{value:`warm`,children:`Warm and friendly`}),(0,Y.jsx)(M,{value:`custom`,children:`Custom`})]})]}),n.communicationStyle===`custom`&&(0,Y.jsx)(V,{"aria-label":`Custom communication style`,maxLength:300,rows:2,placeholder:`For example: direct, a little dry humor`,value:n.communicationCustom??``,onChange:e=>u({communicationCustom:e.target.value})})]}),(0,Y.jsxs)(wt,{title:`Response style`,hint:`How long and detailed replies are.`,children:[(0,Y.jsxs)(N,{value:n.responseStyle,onValueChange:e=>u({responseStyle:e}),children:[(0,Y.jsx)(A,{className:`w-full sm:w-64`,"aria-label":`Response style`,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:`normal`,children:`Normal`}),(0,Y.jsx)(M,{value:`brief`,children:`Brief`}),(0,Y.jsx)(M,{value:`custom`,children:`Custom`})]})]}),n.responseStyle===`custom`&&(0,Y.jsx)(V,{"aria-label":`Custom response style`,maxLength:300,rows:2,placeholder:`For example: bullet points, numbers first`,value:n.responseCustom??``,onChange:e=>u({responseCustom:e.target.value})})]}),(0,Y.jsx)(wt,{title:`About you`,hint:`What you want agents to know about you. Optional.`,children:(0,Y.jsx)(V,{"aria-label":`About you`,maxLength:600,rows:3,value:n.about??``,onChange:e=>u({about:e.target.value})})}),(0,Y.jsx)(wt,{title:`Language and time`,hint:`Optional. Leave empty to let agents decide.`,children:(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-3`,children:[(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{htmlFor:`agent-prefs-locale`,children:`Locale`}),(0,Y.jsx)(B,{id:`agent-prefs-locale`,placeholder:`en-GB`,maxLength:35,value:n.locale??``,onChange:e=>u({locale:e.target.value})})]}),(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{htmlFor:`agent-prefs-time-zone`,children:`Time zone`}),(0,Y.jsx)(B,{id:`agent-prefs-time-zone`,placeholder:`Europe/Stockholm`,maxLength:64,value:n.timeZone??``,onChange:e=>u({timeZone:e.target.value})})]}),(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{children:`Date format`}),(0,Y.jsxs)(N,{value:n.dateFormat??St,onValueChange:e=>u({dateFormat:e===St?void 0:e}),children:[(0,Y.jsx)(A,{className:`w-full`,"aria-label":`Date format`,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:St,children:`Not set`}),(0,Y.jsx)(M,{value:`iso`,children:`ISO (2026-11-07)`}),(0,Y.jsx)(M,{value:`locale`,children:`My locale`})]})]})]})]})}),o&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-3.5`}),(0,Y.jsx)(`span`,{children:o})]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void f(),disabled:i||d||!e.writable,children:[(0,Y.jsx)(L,{className:`size-4`}),i?`Saving…`:`Save preferences`]}),d&&(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Describe your custom style first.`}),c&&(0,Y.jsx)(`span`,{role:`status`,className:`text-xs text-muted-foreground`,children:`Saved`})]})]})})}var Et={decisions:{label:`Decisions`,important:`Important: only time-critical ones.`},actions:{label:`Actions`,important:`Important: only time-critical ones.`},escalations:{label:`Escalations`,important:`Important: stuck, blocked or failed agents, not passing heads-ups.`},finalReports:{label:`Final reports`,important:`Important: only replies that wait on your answer.`},failures:{label:`Failures`,important:`Important: errors and messages that gave up, not retries.`}};function Dt({setting:e,onSaved:t}){let[n,r]=(0,J.useState)(e.value),[i,a]=(0,J.useState)(!1),[o,s]=(0,J.useState)(``),[c,l]=(0,J.useState)(!1);async function u(){a(!0),s(``);try{let e=await y(`PUT`,`/settings/notification-prefs/default`,{value:n,updatedBy:`dashboard`});r(e.value),l(!0),t(e)}catch(e){s(e.message)}finally{a(!1)}}return(0,Y.jsx)(q,{size:`sm`,"data-testid":`notification-prefs`,children:(0,Y.jsxs)(G,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold`,children:`What notifies you`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Which events notify you in the dashboard. Other people keep their own settings.`})]}),(0,Y.jsx)(`div`,{className:`divide-y divide-border`,children:m.map(e=>(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 py-2 first:pt-0 last:pb-0`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:Et[e].label}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:Et[e].important})]}),(0,Y.jsxs)(N,{value:n[e],onValueChange:t=>{r(n=>({...n,[e]:t})),l(!1)},children:[(0,Y.jsx)(A,{className:`w-full sm:w-40`,"aria-label":Et[e].label,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[(0,Y.jsx)(M,{value:`all`,children:`All`}),(0,Y.jsx)(M,{value:`important`,children:`Important only`}),(0,Y.jsx)(M,{value:`none`,children:`None`})]})]})]},e))}),o&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-3.5`}),(0,Y.jsx)(`span`,{children:o})]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void u(),disabled:i||!e.writable,children:[(0,Y.jsx)(L,{className:`size-4`}),i?`Saving…`:`Save notifications`]}),c&&(0,Y.jsx)(`span`,{role:`status`,className:`text-xs text-muted-foreground`,children:`Saved`})]})]})})}function Ot(){let[e,t]=(0,J.useState)([]),[n,r]=(0,J.useState)(``),[i,a]=(0,J.useState)(!1);async function o(){try{t(await y(`GET`,`/users/authority-denials`)),r(``),a(!0)}catch(e){r(e.message)}}return(0,Y.jsxs)(`section`,{className:`space-y-2`,"aria-label":`Authority denials`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`h3`,{className:`text-sm font-semibold`,children:`Authority denials`}),(0,Y.jsx)(R,{size:`sm`,variant:`outline`,onClick:()=>void o(),children:i?`Refresh denials`:`Load denials`})]}),n&&(0,Y.jsx)(`p`,{role:`alert`,children:n}),i&&e.length===0&&(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No authority denials recorded.`}),(0,Y.jsx)(`ul`,{className:`max-h-80 space-y-2 overflow-auto text-xs`,children:e.map(e=>{let{actor:t,target:n,action:r,reason:i}=e.metadata;return(0,Y.jsxs)(`li`,{className:`rounded border border-border p-2 break-words`,children:[(0,Y.jsx)(`time`,{children:new Date(e.createdAt).toLocaleString()}),(0,Y.jsxs)(`div`,{children:[t.kind,`: `,t.id,` · `,r,` · `,n]}),(0,Y.jsx)(`p`,{children:i})]},e.id)})})]})}function kt(){let e=s(e=>e.sessionUser===null),t=s(e=>e.signIn),[n,r]=(0,J.useState)(null),[i,a]=(0,J.useState)(``),[o,c]=(0,J.useState)(``),[l,u]=(0,J.useState)(!1),[d,f]=(0,J.useState)(!1),[p,m]=(0,J.useState)(``);if((0,J.useEffect)(()=>{if(!e)return;let t=!0;return y(`GET`,`/users/me`).then(e=>{t&&r(e)}).catch(()=>void 0),()=>{t=!1}},[e]),!e||!n||n.hasPassword&&!l)return null;async function h(e){f(!0),m(``);try{await e()}catch(e){m(e.message)}finally{f(!1)}}function g(e){e.preventDefault(),h(async()=>{if(i!==o)throw Error(`The passwords do not match.`);await y(`PUT`,`/users/me/password`,{password:i}),u(!0)})}return(0,Y.jsx)(q,{size:`sm`,"data-testid":`set-password`,children:(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,Y.jsx)(be,{className:`mt-0.5 size-4 text-muted-foreground`}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold`,children:l?`Password set`:`Set your password`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:l?(0,Y.jsxs)(Y.Fragment,{children:[`You can now sign in as `,(0,Y.jsx)(`span`,{className:`font-mono`,children:n.handle}),` with your password. Signing in replaces the admin token in this browser.`]}):(0,Y.jsxs)(Y.Fragment,{children:[`You are using the admin token. Set a password to sign in as `,(0,Y.jsx)(`span`,{className:`font-mono`,children:n.handle}),` instead.`]})})]})]}),l?(0,Y.jsx)(R,{size:`sm`,disabled:d,onClick:()=>void h(()=>t(n.handle,i)),children:`Sign in with password`}):(0,Y.jsxs)(`form`,{className:`flex flex-wrap items-end gap-2`,onSubmit:g,children:[(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{htmlFor:`admin-password`,children:`New password`}),(0,Y.jsx)(B,{id:`admin-password`,type:`password`,autoComplete:`new-password`,className:`w-48`,value:i,onChange:e=>a(e.target.value),required:!0,minLength:10})]}),(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{htmlFor:`admin-password-confirm`,children:`Repeat password`}),(0,Y.jsx)(B,{id:`admin-password-confirm`,type:`password`,autoComplete:`new-password`,className:`w-48`,value:o,onChange:e=>c(e.target.value),required:!0})]}),(0,Y.jsx)(R,{type:`submit`,size:`sm`,disabled:d,children:`Set password`})]}),p&&(0,Y.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:p})]})})}var At={admin:`Admin`,operator:`Member`,viewer:`Viewer`},jt=Object.keys(At);function Mt({value:e,onChange:t,label:n,disabled:r}){return(0,Y.jsxs)(N,{value:e,onValueChange:e=>t(e),disabled:r,children:[(0,Y.jsx)(A,{className:`w-32`,"aria-label":n,children:(0,Y.jsx)(k,{})}),(0,Y.jsx)(j,{children:jt.map(e=>(0,Y.jsx)(M,{value:e,children:At[e]},e))})]})}function Nt({onError:e}){let[t,n]=(0,J.useState)(`operator`),[r,i]=(0,J.useState)(``),[a,o]=(0,J.useState)(!1),[s,c]=(0,J.useState)(null);async function l(){o(!0),e(``);try{let e=await y(`POST`,`/users/invites`,{role:t,...r.trim()?{displayName:r.trim()}:{}});c({link:new URL(e.path.replace(/^\//,``),v()).href,expiresAt:e.invite.expiresAt}),i(``)}catch(t){e(t.message)}finally{o(!1)}}return(0,Y.jsxs)(`div`,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2`,children:[(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{htmlFor:`invite-name`,children:`Name`}),(0,Y.jsx)(B,{id:`invite-name`,className:`w-48`,placeholder:`Optional`,value:r,onChange:e=>i(e.target.value)})]}),(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(O,{children:`Role`}),(0,Y.jsx)(Mt,{value:t,onChange:n,label:`Invite role`})]}),(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void l(),disabled:a,children:[(0,Y.jsx)(De,{className:`size-4`}),`Create invite link`]})]}),s&&(0,Y.jsxs)(`div`,{className:`rounded-md border border-border bg-muted/40 p-3 text-xs`,"data-testid":`invite-link`,children:[(0,Y.jsxs)(`p`,{className:`mb-2 text-muted-foreground`,children:[`Send this link yourself. It works once and expires on `,new Date(s.expiresAt).toLocaleDateString(),`.`]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsx)(`code`,{className:`min-w-0 flex-1 truncate font-mono`,children:s.link}),(0,Y.jsx)(ke,{value:s.link,label:`Copy invite link`,size:`xs`,variant:`outline`,showText:!0})]})]})]})}function Q(e){return e.displayName||e.handle}function Pt({from:e,users:t,onClose:n,onHandOver:r}){let[i,a]=(0,J.useState)(``),[o,s]=(0,J.useState)(!1),c=t.filter(t=>t.id!==e?.id&&t.status===`active`),l=c.find(e=>e.id===i);async function u(){if(!(!e||!l)){s(!0);try{await r(e,l)}finally{s(!1)}a(``)}}return(0,Y.jsx)(ee,{open:e!==null,onOpenChange:e=>{e||(a(``),n())},children:(0,Y.jsxs)(T,{className:`max-w-md`,children:[(0,Y.jsxs)(w,{children:[(0,Y.jsxs)(E,{className:`text-sm`,children:[`Hand over `,e?Q(e):``,`'s agents`]}),(0,Y.jsxs)(S,{children:[`Every agent `,e?Q(e):``,` owns moves to the person you pick. They become its principal and can restart or stop it.`]})]}),(0,Y.jsxs)(C,{children:[(0,Y.jsx)(O,{htmlFor:`handover-target`,className:`mb-1.5`,children:`New owner`}),(0,Y.jsxs)(N,{value:i,onValueChange:a,children:[(0,Y.jsx)(A,{id:`handover-target`,className:`w-full`,"aria-label":`New owner`,children:(0,Y.jsx)(k,{placeholder:`Pick a person`})}),(0,Y.jsx)(j,{children:c.map(e=>(0,Y.jsxs)(M,{value:e.id,children:[Q(e),` (`,e.handle,`)`]},e.id))})]})]}),(0,Y.jsx)(x,{children:(0,Y.jsx)(R,{size:`sm`,disabled:!l||o,onClick:()=>void u(),children:`Hand over`})})]})})}function Ft(){let e=s(e=>e.users),t=s(e=>e.agents),n=s(e=>e.fetchUsers),r=s(e=>e.fetchAgents),i=s(e=>e.sessionUser?.id??`default`),[a,o]=(0,J.useState)(``),[c,l]=(0,J.useState)(``),[u,d]=(0,J.useState)(``),[f,p]=(0,J.useState)(null),m=(0,J.useMemo)(()=>{let e=new Map;for(let n of t)n.principalUserId&&e.set(n.principalUserId,(e.get(n.principalUserId)??0)+1);return e},[t]);(0,J.useEffect)(()=>{n()},[n]);async function h(e,t){d(e.id),o(``),l(``);try{let e=await t();e&&l(e)}catch(e){o(e.message)}finally{d(``)}}let g=(e,t)=>h(e,async()=>{await y(`PATCH`,`/users/${encodeURIComponent(e.id)}`,t),await n()}),_=e=>h(e,async()=>{let{revoked:t}=await y(`DELETE`,`/users/${encodeURIComponent(e.id)}/sessions`);return`${Q(e)} is signed out everywhere (${t} ${t===1?`token`:`tokens`} revoked).`});return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(kt,{}),(0,Y.jsx)(q,{size:`sm`,"data-testid":`users-admin`,children:(0,Y.jsxs)(G,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold`,children:`People`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Invite people and manage their access. Changing a role or suspending someone signs them out.`})]}),(0,Y.jsx)(Nt,{onError:o}),a&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-3.5`}),(0,Y.jsx)(`span`,{children:a})]}),c&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs text-muted-foreground`,children:c}),(0,Y.jsx)(`ul`,{className:`divide-y divide-border rounded-md border border-border`,children:e.map(e=>{let t=e.id===i,n=e.status!==`active`,r=u===e.id,a=m.get(e.id)??0;return(0,Y.jsxs)(`li`,{className:`flex flex-wrap items-center gap-3 px-3 py-2`,"data-testid":`user-row-${e.handle}`,children:[(0,Y.jsx)(Ae,{user:e,distinct:!0,className:`size-7`}),(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsxs)(`div`,{className:`truncate text-sm font-medium`,children:[Q(e),t&&(0,Y.jsx)(`span`,{className:`ml-1 text-xs text-muted-foreground`,children:`(you)`})]}),(0,Y.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[(0,Y.jsx)(`span`,{className:`font-mono`,children:e.handle}),a>0&&(0,Y.jsxs)(`span`,{children:[` · `,a,` `,a===1?`agent`:`agents`]})]})]}),n&&(0,Y.jsx)(z,{variant:`outline`,className:`text-tone-warning-fg`,children:`Suspended`}),(0,Y.jsx)(Mt,{value:e.role,onChange:t=>void g(e,{role:t}),label:`Role for ${e.handle}`,disabled:t||r}),(0,Y.jsx)(R,{size:`sm`,variant:`outline`,disabled:t||r,onClick:()=>void g(e,{status:n?`active`:`suspended`}),children:n?`Reactivate`:`Suspend`}),(0,Y.jsxs)(ae,{children:[(0,Y.jsx)(ne,{asChild:!0,children:(0,Y.jsx)(R,{size:`sm`,variant:`ghost`,className:`px-2`,disabled:r,"aria-label":`More actions for ${e.handle}`,children:(0,Y.jsx)(D,{className:`size-4`})})}),(0,Y.jsxs)(te,{align:`end`,children:[(0,Y.jsx)(re,{disabled:t,onSelect:()=>void _(e),children:`Sign out everywhere`}),(0,Y.jsx)(re,{onSelect:()=>p(e),children:`Hand over agents…`})]})]})]},e.id)})}),(0,Y.jsx)(Ot,{})]})}),(0,Y.jsx)(Pt,{from:f,users:e,onClose:()=>p(null),onHandOver:(e,t)=>h(e,async()=>{let{agentIds:n}=await y(`POST`,`/users/${encodeURIComponent(e.id)}/handover`,{toUserId:t.id});return p(null),await r(),`${n.length} ${n.length===1?`agent`:`agents`} moved from ${Q(e)} to ${Q(t)}.`})})]})}var It=5,Lt=15;function Rt(e){return Math.round(e/6e4)}function zt(e){return`${Rt(e)} min`}function Bt({canWrite:e}){let[t,n]=(0,J.useState)(null),[r,i]=(0,J.useState)(``),[a,o]=(0,J.useState)(``),[c,d]=(0,J.useState)(null);(0,J.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await y(`GET`,`/providers/quota-config?stored=1`);e||n(t)}catch(t){e||i(t.message)}})(),()=>{e=!0}},[]);async function f(e,t){n(n=>({...n??{},[e]:t})),o(``),d(e);try{let r=await y(`PUT`,`/providers/${e}/quota-config`,t);n(t=>({...t??{},[e]:r}))}catch(t){o(`${u(e)}: ${t.message}`)}finally{d(null)}}let p=t?Object.keys(t).sort():[],m=s(e=>e.providerCatalog);return(0,Y.jsxs)(`section`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Quota`}),(0,Y.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Per-provider quota collection and display. `,(0,Y.jsx)(`strong`,{children:`Enabled`}),` governs collection (disabled stops polling — no API calls);`,(0,Y.jsx)(`strong`,{children:` Show in widget`}),` governs display only.`]})]}),r&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4`}),(0,Y.jsx)(`span`,{children:r})]}),a&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4`}),(0,Y.jsx)(`span`,{children:a})]}),!t&&!r&&(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,Y.jsx)(I,{className:`size-4 animate-spin`}),`Loading quota config…`]})}),p.map(r=>{let i=t[r],a=!e||c===r;return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`flex items-center gap-2 text-sm`,children:[(0,Y.jsx)(ye,{className:`size-4`}),u(r),c===r&&(0,Y.jsx)(I,{className:`size-3 animate-spin text-muted-foreground`})]}),(0,Y.jsxs)(H,{className:`text-xs`,children:[i.enabled?`Polled every ${zt(i.pollIntervalMs)}`:`Collection disabled`,i.enabled&&!i.showInWidget?` · hidden from widget`:``,m.find(e=>e.provider===r)?.disabled?` · provider disabled: not polled or shown`:``]})]}),(0,Y.jsxs)(G,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Enabled`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Collect quota for this provider. Off stops all polling (no API calls, no token spend).`})]}),(0,Y.jsx)(P,{checked:i.enabled,disabled:a,onCheckedChange:e=>void f(r,{...i,enabled:e})})]}),(0,Y.jsxs)(`div`,{className:`rounded-md border bg-muted/20 p-3 space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Polling interval`}),(0,Y.jsx)(z,{variant:`outline`,className:`tabular-nums`,children:zt(i.pollIntervalMs)})]}),(0,Y.jsx)(`input`,{type:`range`,min:It,max:Lt,step:1,value:Rt(i.pollIntervalMs),disabled:a||!i.enabled,onChange:e=>{let t=Number(e.target.value)*6e4;n(e=>({...e??{},[r]:{...i,pollIntervalMs:t}}))},onPointerUp:e=>void f(r,{...i,pollIntervalMs:Number(e.target.value)*6e4}),onKeyUp:e=>void f(r,{...i,pollIntervalMs:Number(e.target.value)*6e4}),className:`w-full accent-primary disabled:opacity-50`}),(0,Y.jsxs)(`div`,{className:`flex justify-between text-[10px] text-muted-foreground`,children:[(0,Y.jsxs)(`span`,{children:[It,` min`]}),(0,Y.jsxs)(`span`,{children:[Lt,` min`]})]})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Show in quota widget`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Display only. Off hides this provider from the dashboard widget; collection continues if enabled.`})]}),(0,Y.jsx)(P,{checked:i.showInWidget,disabled:a,onCheckedChange:e=>void f(r,{...i,showInWidget:e})})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Burn-rate sparkline`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Show a mini utilization chart per window in the expanded widget.`})]}),(0,Y.jsx)(P,{checked:i.sparklineEnabled??!0,disabled:a,onCheckedChange:e=>void f(r,{...i,sparklineEnabled:e})})]}),(0,Y.jsxs)(`div`,{className:`rounded-md border bg-muted/20 p-3 space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Sparkline range`}),(0,Y.jsxs)(z,{variant:`outline`,className:`tabular-nums`,children:[i.sparklineRangeHours??8,`h`]})]}),(0,Y.jsx)(`input`,{type:`range`,min:1,max:8,step:1,value:i.sparklineRangeHours??8,disabled:a||!(i.sparklineEnabled??!0),onChange:e=>{let t=Number(e.target.value);n(e=>({...e??{},[r]:{...i,sparklineRangeHours:t}}))},onPointerUp:e=>void f(r,{...i,sparklineRangeHours:Number(e.target.value)}),onKeyUp:e=>void f(r,{...i,sparklineRangeHours:Number(e.target.value)}),className:`w-full accent-primary disabled:opacity-50`}),(0,Y.jsxs)(`div`,{className:`flex justify-between text-[10px] text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`1h`}),(0,Y.jsx)(`span`,{children:`8h`})]})]}),l(r)&&(0,Y.jsxs)(`div`,{className:`rounded-md border bg-muted/20 p-3 space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Auto-fire banked reset`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Automatically consume a scarce banked reset when 7d usage nears exhaustion. Off by default.`})]}),(0,Y.jsx)(P,{checked:i.autoFireResetEnabled??!1,disabled:a,onCheckedChange:e=>void f(r,{...i,autoFireResetEnabled:e})})]}),(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium`,children:`Trigger threshold`}),(0,Y.jsxs)(z,{variant:`outline`,className:`tabular-nums`,children:[Math.round((i.autoFireResetThreshold??.99)*100),`%`]})]}),(0,Y.jsx)(`input`,{type:`range`,min:90,max:100,step:1,value:Math.round((i.autoFireResetThreshold??.99)*100),disabled:a||!(i.autoFireResetEnabled??!1),onChange:e=>{let t=Number(e.target.value)/100;n(e=>({...e??{},[r]:{...i,autoFireResetThreshold:t}}))},onPointerUp:e=>void f(r,{...i,autoFireResetThreshold:Number(e.target.value)/100}),onKeyUp:e=>void f(r,{...i,autoFireResetThreshold:Number(e.target.value)/100}),className:`w-full accent-primary disabled:opacity-50`}),(0,Y.jsxs)(`div`,{className:`flex justify-between text-[10px] text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`90%`}),(0,Y.jsx)(`span`,{children:`100%`})]})]})]})]})]},r)})]})}function Vt(e,t){return y(`PUT`,`/routing-policy`,e,{headers:{"If-Match":`"${t}"`}})}function Ht({message:e}){return(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4 shrink-0`}),(0,Y.jsx)(`span`,{children:e})]})}var Ut=f(),Wt={cautionAt:.15,avoidLargeAt:.5,hardAvoidAt:1},Gt=3,Kt=.99,qt=.5;function Jt(e,t){return((e??t)*100).toFixed(0)}function Yt(e){let t=e.trim();if(!t)return null;let n=Number(t);return!Number.isFinite(n)||n<0||n>100?null:n/100}function Xt(e){return String(Number(e.toFixed(2)))}function Zt(e,t){return String(e??t)}function Qt(e){let t=e.trim();if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function $t(e,t){return e.trim()?Yt(e):t}function en({policy:e,revision:t,canWrite:n,onPolicy:r}){let i=e.quotaBands,a=e.providerQuota??{},[o,s]=(0,J.useState)(Zt(i?.cautionAt,Wt.cautionAt)),[c,l]=(0,J.useState)(Zt(i?.avoidLargeAt,Wt.avoidLargeAt)),[d,f]=(0,J.useState)(Zt(i?.hardAvoidAt,Wt.hardAvoidAt)),[p,m]=(0,J.useState)(()=>{let e={};for(let t of Ut){let n=a[t]??{};e[t]={backstop:Jt(n.hardBackstopUtilization,Kt),floor:Jt(n.burnPenaltyUtilizationFloor,qt)}}return e}),[h,g]=(0,J.useState)(!1),[_,v]=(0,J.useState)(``),[y,b]=(0,J.useState)(!1),[x,S]=(0,J.useState)(``);async function C(){let n=Qt(o),i=Qt(c),a=Qt(d);if(n===null){S(`Caution cutoff must be a burn-penalty value of 0 or more.`);return}if(i===null){S(`Avoid-large cutoff must be a burn-penalty value of 0 or more.`);return}if(a===null){S(`Hard-avoid cutoff must be a burn-penalty value of 0 or more.`);return}if(n>=i){S(`Caution must be less than avoid-large.`);return}if(i>=a){S(`Avoid-large must be less than hard-avoid.`);return}let s={};for(let e of Ut){let t=p[e],n=$t(t.backstop,Kt),r=Yt(t.floor);if(n===null){S(`${u(e)}: hard-backstop must be 0–100%.`);return}if(r===null){S(`${u(e)}: burn-penalty floor must be 0–100%.`);return}s[e]={hardBackstopUtilization:n,burnPenaltyUtilizationFloor:r}}S(``),g(!0),v(``),b(!1);try{r(await Vt({...e,quotaBands:{cautionAt:n,avoidLargeAt:i,hardAvoidAt:a},providerQuota:s},t)),b(!0),setTimeout(()=>b(!1),2e3)}catch(e){v(e.message)}finally{g(!1)}}function w(e,t){m(n=>({...n,[e]:{...n[e],...t}})),S(``),b(!1)}function T(){S(``),b(!1)}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Quota thresholds`}),(0,Y.jsx)(H,{className:`text-xs`,children:`Band cutoffs act on the burn penalty (0–3): how early a provider would hit its limit at the current pace, times the window weight (3 for the 7-day window). They are not utilization percentages, so a band can fire well below the utilization shown. The hard backstop below is the real utilization gate.`})]}),(0,Y.jsxs)(G,{className:`space-y-4`,children:[(_||x)&&(0,Y.jsx)(Ht,{message:_||x}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[`Band cutoffs (burn penalty, 0–`,Gt,`)`]}),(0,Y.jsx)(rn,{caution:Number(o),avoidLarge:Number(c),hardAvoid:Number(d)}),(0,Y.jsxs)(`div`,{className:`mt-3 grid gap-3 sm:grid-cols-3`,children:[(0,Y.jsx)(an,{label:`Caution at`,hint:`Default: ${Wt.cautionAt}`,value:o,disabled:!n||h,onChange:e=>{s(e),T()}}),(0,Y.jsx)(an,{label:`Avoid-large at`,hint:`Default: ${Wt.avoidLargeAt}`,value:c,disabled:!n||h,onChange:e=>{l(e),T()}}),(0,Y.jsx)(an,{label:`Hard-avoid at`,hint:`Default: ${Wt.hardAvoidAt}`,value:d,disabled:!n||h,onChange:e=>{f(e),T()}})]})]}),Ut.map(e=>{let t=p[e];return(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[u(e),` overrides`]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsx)(on,{label:`Hard-backstop utilization`,hint:`0 = disable backstop (never block on this quota); blank uses the ${(Kt*100).toFixed(0)}% default.`,value:t.backstop,disabled:!n||h,onChange:t=>w(e,{backstop:t})}),(0,Y.jsx)(on,{label:`Burn-penalty floor`,hint:`Penalties suppressed below this. Default: ${(qt*100).toFixed(0)}%`,value:t.floor,disabled:!n||h,onChange:t=>w(e,{floor:t})})]})]},e)}),n&&(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void C(),disabled:h,children:[h?(0,Y.jsx)(I,{className:`size-4 animate-spin`}):(0,Y.jsx)(L,{className:`size-4`}),y?`Saved`:`Save thresholds`]})]})]})}var tn=.9;function nn({policy:e,revision:t,canWrite:n,onPolicy:r}){let[i,a]=(0,J.useState)(e.apiOverflow?.enabled??!1),[o,s]=(0,J.useState)(Jt(e.apiOverflow?.weeklyUtilizationAt,tn)),[c,l]=(0,J.useState)(!1),[u,d]=(0,J.useState)(``),[f,p]=(0,J.useState)(!1);async function m(){let n=$t(o,tn);if(n===null||n===0){d(`Weekly threshold must be 1–100%.`);return}l(!0),d(``),p(!1);try{r(await Vt({...e,apiOverflow:{enabled:i,weeklyUtilizationAt:n}},t)),p(!0),setTimeout(()=>p(!1),2e3)}catch(e){d(e.message)}finally{l(!1)}}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Claude API overflow`}),(0,Y.jsx)(H,{className:`text-xs`,children:`Spends API credits instead of waiting for the weekly reset. Applies only to unpinned Claude work when every Claude subscription is near its weekly limit, a ready host offers Claude API, and the monthly budget has room.`})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[u&&(0,Y.jsx)(Ht,{message:u}),(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,Y.jsx)(P,{checked:i,disabled:!n||c,size:`sm`,"aria-label":`Enable Claude API overflow`,onCheckedChange:e=>{a(e),d(``),p(!1)}}),`Route to Claude API when subscriptions run low`]}),(0,Y.jsx)(`div`,{className:`max-w-xs`,children:(0,Y.jsx)(on,{label:`Weekly near-limit threshold`,hint:`Default: ${(tn*100).toFixed(0)}%`,value:o,disabled:!n||c,onChange:e=>{s(e),d(``),p(!1)}})}),n&&(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void m(),disabled:c,children:[c?(0,Y.jsx)(I,{className:`size-4 animate-spin`}):(0,Y.jsx)(L,{className:`size-4`}),f?`Saved`:`Save overflow`]})]})]})}function rn({caution:e,avoidLarge:n,hardAvoid:r}){let i=e=>Math.max(0,Math.min(Gt,Number.isFinite(e)?e:0)),a=i(e),o=Math.max(a,i(n)),s=Math.max(o,i(r)),c=Xt,l=(e,t)=>`${(t-e)/Gt*100}%`,u=[{key:`normal`,label:`normal`,color:`bg-tone-success`,from:0,to:a,range:`0–${c(a)}`},{key:`caution`,label:`caution`,color:`bg-tone-warning`,from:a,to:o,range:`${c(a)}–${c(o)}`},{key:`avoid-large`,label:`avoid large`,color:`bg-tone-orange`,from:o,to:s,range:`${c(o)}–${c(s)}`},{key:`hard-avoid`,label:`hard avoid`,color:`bg-tone-danger`,from:s,to:Gt,range:`≥ ${c(s)}`}];return(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(`div`,{className:`flex h-2.5 overflow-hidden rounded-full bg-muted`,role:`img`,"aria-label":`Quota burn-penalty bands from 0 to ${Gt}`,children:u.map(e=>(0,Y.jsx)(`div`,{className:t(e.color,`transition-[width] duration-300`),style:{width:l(e.from,e.to)},title:`${e.label} · penalty ${e.range}`},e.key))}),(0,Y.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1 text-[10px] text-muted-foreground`,children:u.map(e=>(0,Y.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,Y.jsx)(`span`,{className:t(`size-2 shrink-0 rounded-full`,e.color)}),e.label,` `,(0,Y.jsx)(`span`,{className:`tabular-nums text-foreground/70`,children:e.range})]},e.key))})]})}function an({label:e,hint:t,value:n,disabled:r,onChange:i}){return(0,Y.jsxs)(`label`,{className:`space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:e}),(0,Y.jsx)(B,{value:n,onChange:e=>i(e.target.value),disabled:r,inputMode:`decimal`,className:`h-8 text-xs tabular-nums`}),(0,Y.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:t})]})}function on({label:e,hint:t,value:n,disabled:r,onChange:i}){return(0,Y.jsxs)(`label`,{className:`space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:e}),(0,Y.jsxs)(`div`,{className:`relative`,children:[(0,Y.jsx)(B,{value:n,onChange:e=>i(e.target.value),disabled:r,className:`h-8 pr-6 text-xs tabular-nums`}),(0,Y.jsx)(`span`,{className:`pointer-events-none absolute inset-y-0 right-2.5 flex items-center text-xs text-muted-foreground`,children:`%`})]}),(0,Y.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:t})]})}function sn(){let[e,n]=(0,J.useState)(null),[r,i]=(0,J.useState)(!1),[a,o]=(0,J.useState)(``),[s,c]=(0,J.useState)(!1),[l,u]=(0,J.useState)(!1);async function d(e=!1){if(!(l&&!e)){i(!0),o(``);try{let[e,t]=await Promise.all([y(`GET`,`/routing-policy`),y(`GET`,`/agent-profiles/coordinator`).catch(()=>null)]);n({policy:e.policy,profile:t}),u(!0)}catch(e){o(e.message)}finally{i(!1)}}}let f=()=>d(!0);function p(){let e=!s;c(e),e&&!l&&d()}return(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 text-left`,onClick:p,children:[(0,Y.jsx)(ve,{className:`size-4 text-muted-foreground`}),(0,Y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-semibold`,children:`What your coordinator knows`}),(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Active routing policy + coordinator profile instructions (read-only)`})]}),s?(0,Y.jsx)(he,{className:`size-4 shrink-0 text-muted-foreground`}):(0,Y.jsx)(ge,{className:`size-4 shrink-0 text-muted-foreground`})]}),s&&(0,Y.jsxs)(`div`,{className:`space-y-4 pt-1`,children:[(0,Y.jsx)(`div`,{className:`flex justify-end`,children:(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void f(),disabled:r,children:[(0,Y.jsx)(we,{className:t(`size-3.5`,r&&`animate-spin`)}),`Refresh`]})}),a&&(0,Y.jsx)(Ht,{message:a}),r&&!e&&(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground py-2`,children:[(0,Y.jsx)(I,{className:`size-3.5 animate-spin`}),`Loading…`]}),e&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(cn,{policy:e.policy}),e.profile?(0,Y.jsx)(un,{profile:e.profile}):(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`Coordinator profile not found.`})]})]})]})})}function cn({policy:e}){let n=e.quotaBands,r=e.providerQuota??{};return(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsx)(`div`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wide`,children:`Active routing policy`}),e.rules.length===0?(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`No routing preferences — dispatch policy and quota bands decide.`}):(0,Y.jsxs)(`div`,{className:`overflow-hidden rounded-md border border-border text-xs`,children:[(0,Y.jsxs)(`div`,{className:`grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:[(0,Y.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Match`}),(0,Y.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Preference`}),(0,Y.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Status`})]}),e.rules.map(e=>(0,Y.jsxs)(`div`,{className:t(`grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border`,e.enabled===!1&&`opacity-50`),children:[(0,Y.jsxs)(`div`,{className:`bg-card px-2 py-1.5`,children:[(0,Y.jsx)(`div`,{className:`font-medium`,children:e.label??e.id}),(0,Y.jsx)(`div`,{className:`font-mono`,children:Object.entries(e.match).map(([e,t])=>`${e}=${Array.isArray(t)?t.join(`|`):t}`).join(`, `)||`all work`})]}),(0,Y.jsxs)(`div`,{className:`bg-card px-2 py-1.5`,children:[e.prefer?.length?(0,Y.jsxs)(`div`,{children:[`prefer `,e.prefer.join(`, `)]}):null,e.avoid?.length?(0,Y.jsxs)(`div`,{className:`text-muted-foreground`,children:[`avoid `,e.avoid.join(`, `)]}):null]}),(0,Y.jsx)(`div`,{className:`bg-card px-2 py-1.5`,children:e.enabled===!1?(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:`disabled`}):(0,Y.jsx)(`span`,{className:`text-tone-success-fg`,children:`active`})})]},e.id))]}),(n||Object.keys(r).length>0)&&(0,Y.jsxs)(`div`,{className:`rounded-md border border-border bg-muted/10 px-3 py-2 text-xs space-y-1`,children:[n&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-0.5`,children:[(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:`burn penalty:`}),n.cautionAt!==void 0&&(0,Y.jsxs)(`span`,{children:[`caution ≥ `,Xt(n.cautionAt)]}),n.avoidLargeAt!==void 0&&(0,Y.jsxs)(`span`,{children:[`avoid-large ≥ `,Xt(n.avoidLargeAt)]}),n.hardAvoidAt!==void 0&&(0,Y.jsxs)(`span`,{children:[`hard-avoid ≥ `,Xt(n.hardAvoidAt)]})]}),Object.entries(r).map(([e,t])=>(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-0.5 text-muted-foreground`,children:[(0,Y.jsx)(`span`,{className:`font-medium text-foreground`,children:u(e)}),t?.hardBackstopUtilization!==void 0&&(0,Y.jsxs)(`span`,{children:[`backstop: `,(t.hardBackstopUtilization*100).toFixed(0),`%`]}),t?.burnPenaltyUtilizationFloor!==void 0&&(0,Y.jsxs)(`span`,{children:[`floor: `,(t.burnPenaltyUtilizationFloor*100).toFixed(0),`%`]})]},e))]})]})}function ln({text:e,index:t}){return(0,Y.jsxs)(`div`,{className:`relative max-h-72 overflow-y-auto rounded-md border border-border bg-muted/20`,children:[t!==void 0&&(0,Y.jsxs)(`span`,{className:`sticky top-0 float-right m-1.5 rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium tabular-nums text-muted-foreground`,children:[`#`,t]}),(0,Y.jsx)(`pre`,{className:`whitespace-pre-wrap break-words px-3 py-2.5 font-sans text-[11px] leading-relaxed text-foreground/90`,children:e})]})}function un({profile:e}){return(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wide`,children:[`Coordinator profile instructions`,(0,Y.jsx)(z,{variant:`secondary`,className:`ml-2 text-[10px]`,children:e.name}),e.builtIn&&(0,Y.jsx)(z,{variant:`outline`,className:`ml-1 text-[10px]`,children:`built-in`})]}),e.description&&(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.description}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2 text-[10px]`,children:[(0,Y.jsxs)(z,{variant:`outline`,children:[`base: `,e.base]}),(0,Y.jsxs)(z,{variant:`outline`,children:[`repo: `,e.instructions.repoInstructions]}),(0,Y.jsxs)(z,{variant:`outline`,children:[`global: `,e.instructions.globalInstructions]}),e.provider&&(0,Y.jsxs)(z,{variant:`outline`,children:[`provider: `,e.provider]})]}),e.instructions.system&&(0,Y.jsxs)(`div`,{className:`space-y-1`,children:[(0,Y.jsx)(`div`,{className:`text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:`System prompt`}),(0,Y.jsx)(ln,{text:e.instructions.system})]}),e.instructions.append.length>0&&(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:[`Appended instructions (`,e.instructions.append.length,`)`]}),e.instructions.append.map((e,t)=>(0,Y.jsx)(ln,{text:e,index:t+1},t))]}),e.instructions.append.length===0&&!e.instructions.system&&(0,Y.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`No instruction blocks defined.`})]})}function dn({policy:e,revision:t,canWrite:n,onPolicy:r}){let[i,a]=(0,J.useState)(e.apiExpiry?.enabled??!1),[o,s]=(0,J.useState)(e.subscriptionExpiry?.enabled??!1),[c,l]=(0,J.useState)(String((e.apiExpiry?.leadTimeMs??6048e5)/36e5)),[u,d]=(0,J.useState)(String((e.subscriptionExpiry?.leadTimeMs??1728e5)/36e5)),[f,p]=(0,J.useState)(!1),[m,h]=(0,J.useState)(``);async function g(){let n=Number(c),a=Number(u);if(!Number.isFinite(n)||n<=0||n>744||!Number.isFinite(a)||a<=0||a>168){h(`API lead must be 0–744 hours and subscription lead 0–168 hours, both greater than zero.`);return}p(!0),h(``);try{r(await Vt({...e,apiExpiry:{enabled:i,leadTimeMs:n*36e5},subscriptionExpiry:{enabled:o,leadTimeMs:a*36e5}},t)),h(`Saved`)}catch(e){h(e.message)}finally{p(!1)}}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Use expiring quota`}),(0,Y.jsx)(H,{className:`text-xs`,children:`Use subscription quota before its weekly reset. Pace unused API credits toward monthly expiry only when subscriptions cannot take the work. Pins and the hard dollar budget still win.`})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,Y.jsx)(P,{"aria-label":`Enable subscription expiry routing`,checked:o,disabled:!n||f,onCheckedChange:s}),`Prefer subscription quota approaching reset`]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Subscription lead (hours)`,(0,Y.jsx)(B,{"aria-label":`Subscription lead (hours)`,type:`number`,min:`0`,max:`168`,value:u,disabled:!n||f,onChange:e=>d(e.target.value)})]}),(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,Y.jsx)(P,{"aria-label":`Enable API credit expiry routing`,checked:i,disabled:!n||f,onCheckedChange:a}),`Spend unused monthly API credits gradually`]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`API credit lead (hours)`,(0,Y.jsx)(B,{"aria-label":`API credit lead (hours)`,type:`number`,min:`0`,max:`744`,value:c,disabled:!n||f,onChange:e=>l(e.target.value)})]}),m&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs`,children:m}),n&&(0,Y.jsx)(R,{size:`sm`,disabled:f,onClick:()=>void g(),children:f?`Saving…`:`Save expiry routing`})]})]})}var fn=1e6,pn=e=>String(e/fn),mn=e=>new Date(e).toISOString().slice(0,16),hn=e=>new Date(e).toISOString().slice(0,10);function gn({canWrite:e,budgetId:t=`claude-api`}){let n=t===`openai-api`,r=n?`/api-budgets/${t}`:`/claude-api-budget`,i=n?`platform.openai.com`:`platform.claude.com`,[a,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(!0),[l,u]=(0,J.useState)(n?`100`:`200`),[d,f]=(0,J.useState)(`0`),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(``),[_,v]=(0,J.useState)(!1),[b,x]=(0,J.useState)(``);function S(e){o(e),!(!e.baselineKnown||e.startsAt===void 0||e.endsAt===void 0)&&(c(e.enabled),u(pn(e.ceilingMicroUsd??200*fn)),f(pn(e.baselineMicroUsd??0)),m(n?mn(e.startsAt):hn(e.startsAt)),g(mn(e.endsAt)))}(0,J.useEffect)(()=>{let e=!0;return y(`GET`,`${r}/summary`).then(t=>{e&&S(t)}).catch(t=>{e&&x(t.message)}),()=>{e=!1}},[r]);async function C(){let e=Math.round(Number(l)*fn),t=Math.round(Number(d)*fn),i=Date.parse(n?`${p}:00Z`:`${p}T00:00:00Z`),o=Date.parse(`${h}:00Z`);if(!a||!Number.isFinite(e)||e<=0||!Number.isFinite(t)||t<0||!Number.isFinite(i)||!Number.isFinite(o)){x(`Enter an amount, spent so far, grant date and expiry.`);return}v(!0),x(``);try{S(await y(`POST`,r,{month:a.month,enabled:s,baselineMicroUsd:t,ceilingMicroUsd:e,grantedAt:i,endsAt:o,...a.marginMicroUsd===void 0?{}:{marginMicroUsd:a.marginMicroUsd},...a.allowanceMicroUsd===void 0?{}:{allowanceMicroUsd:a.allowanceMicroUsd}})),x(`Saved`)}catch(e){x(e.message)}finally{v(!1)}}let w=!e||_||!a;return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:n?`OpenAI API credit grant`:`Claude API credit grant`}),(0,Y.jsxs)(H,{className:`text-xs`,children:[`The budget window and expiry pacing follow this grant, not the calendar month. Changing the grant date starts a fresh ledger with Already spent as its baseline. Copy the verified amount and expiry from `,i,`. Without a grant the window is the UTC calendar month. After expiry new input waits for a configured window. Active work drains.`]})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,Y.jsx)(P,{"aria-label":`Enable ${t} budget`,checked:s,disabled:w,onCheckedChange:c}),`Allow `,t,` spend within this grant`]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Grant amount (USD)`,(0,Y.jsx)(B,{"aria-label":`Grant amount (USD)`,type:`number`,min:`0`,step:`0.01`,value:l,disabled:w,onChange:e=>u(e.target.value)})]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Already spent (USD)`,(0,Y.jsx)(B,{"aria-label":`Already spent (USD)`,type:`number`,min:`0`,step:`0.01`,value:d,disabled:w,onChange:e=>f(e.target.value)})]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[n?`Granted (UTC)`:`Granted (UTC date)`,(0,Y.jsx)(B,{"aria-label":n?`Granted (UTC)`:`Granted (UTC date)`,type:n?`datetime-local`:`date`,value:p,disabled:w,onChange:e=>m(e.target.value)})]}),(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Expires (UTC)`,(0,Y.jsx)(B,{"aria-label":`Expires (UTC)`,type:`datetime-local`,value:h,disabled:w,onChange:e=>g(e.target.value)})]}),b&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs`,children:b}),e&&(0,Y.jsx)(R,{size:`sm`,disabled:w,onClick:()=>void C(),children:_?`Saving…`:`Save credit grant`})]})]})}var _n=f(),$=`*`,vn=`keep`,yn=`Prefer this provider over quota bands until the expiry. Blocked, exhausted or unavailable providers are still excluded.`;function bn(){return{id:``,label:``,type:$,complexity:$,prefer:[],avoid:[],require:[],expires:``,enabled:!0}}function xn(e){return Array.isArray(e)?vn:e??$}var Sn=e=>String(e).padStart(2,`0`);function Cn(e){if(e===void 0)return``;let t=new Date(e);return`${t.getFullYear()}-${Sn(t.getMonth()+1)}-${Sn(t.getDate())}T${Sn(t.getHours())}:${Sn(t.getMinutes())}`}function wn(e){return{id:e.id,label:e.label??``,type:xn(e.match.type),complexity:xn(e.match.complexity),prefer:e.prefer??[],avoid:e.avoid??[],require:e.require??[],expires:Cn(e.expiresAt),enabled:e.enabled!==!1}}function Tn(e){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,60)||`rule`}-${Math.random().toString(36).slice(2,8)}`}function En(e,t){let n={...t?.match??{}};e.type!==vn&&(delete n.type,e.type!==$&&(n.type=e.type)),e.complexity!==vn&&(delete n.complexity,e.complexity!==$&&(n.complexity=e.complexity));let r=e.expires===Cn(t?.expiresAt)?t?.expiresAt:e.expires?new Date(e.expires).getTime():void 0;return{id:e.id||Tn(e.label),...e.label.trim()?{label:e.label.trim()}:{},match:n,...e.prefer.length?{prefer:e.prefer}:{},...e.avoid.length?{avoid:e.avoid}:{},...e.require.length?{require:e.require}:{},...r!==void 0&&Number.isFinite(r)?{expiresAt:r}:{},enabled:e.enabled}}var Dn={label:`Label`,type:`Work type`,complexity:`Complexity`,prefer:`Prefer`,avoid:`Avoid`,require:`Require`,expires:`Expiry`,enabled:`Enabled`},On=Object.keys(Dn),kn=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function An(e,t,n,r={}){let i=wn(e),a=wn(t),o={...a},s=[];for(let e of On){let t=!kn(n[e],i[e]),c=!kn(a[e],i[e]);!t||kn(n[e],a[e])||(!c||r[e]===`mine`?o[e]=n[e]:r[e]!==`theirs`&&s.push({key:e,mine:n[e],theirs:a[e]}))}return{form:o,conflicts:s}}function jn(e){return!e.prefer.length&&!e.avoid.length&&!e.require.length?`Prefer, avoid or require at least one provider.`:e.expires&&!Number.isFinite(new Date(e.expires).getTime())?`Enter a valid expiry date and time.`:null}function Mn({message:e}){return(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4 shrink-0`}),(0,Y.jsx)(`span`,{children:e})]})}function Nn({label:e,value:n,blocked:r=[],disabled:i,onChange:a}){return(0,Y.jsxs)(`div`,{className:`space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:e}),(0,Y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:_n.map(e=>{let o=n.includes(e);return(0,Y.jsxs)(`button`,{type:`button`,"aria-pressed":o,disabled:r.includes(e),onClick:()=>a(o?n.filter(t=>t!==e):[...n,e]),className:t(`rounded border px-2 py-0.5 text-[11px] disabled:opacity-30`,o?`border-primary bg-primary/10 text-foreground`:`border-border text-muted-foreground hover:bg-accent`),children:[u(e),i.has(e)?` (disabled)`:``]},e)})})]})}function Pn(e){return Array.isArray(e)?(0,Y.jsxs)(M,{value:vn,className:`text-xs`,children:[e.join(` or `),` (unchanged)`]}):null}function Fn({form:e,original:t,error:n,disabledProviders:r,onChange:i,onSave:a,onCancel:o,isNew:s}){function c(t){i({...e,...t})}return(0,Y.jsxs)(`div`,{className:`space-y-3 rounded-md border border-primary/30 bg-primary/5 p-3`,children:[(0,Y.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wide text-muted-foreground`,children:s?`New preference`:`Edit ${e.id}`}),(0,Y.jsxs)(`label`,{className:`block space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Label (optional)`}),(0,Y.jsx)(B,{value:e.label,onChange:e=>c({label:e.target.value}),placeholder:`e.g. Prefer Codex for builds`,className:`h-8 text-xs`})]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`label`,{className:`space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Work type`}),(0,Y.jsxs)(N,{value:e.type,onValueChange:e=>c({type:e}),children:[(0,Y.jsx)(A,{className:`h-8 text-xs`,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[Pn(t?.match.type),(0,Y.jsx)(M,{value:$,className:`text-xs`,children:`any`}),h.map(e=>(0,Y.jsx)(M,{value:e,className:`text-xs`,children:e},e))]})]})]}),(0,Y.jsxs)(`label`,{className:`space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Complexity`}),(0,Y.jsxs)(N,{value:e.complexity,onValueChange:e=>c({complexity:e}),children:[(0,Y.jsx)(A,{className:`h-8 text-xs`,children:(0,Y.jsx)(k,{})}),(0,Y.jsxs)(j,{children:[Pn(t?.match.complexity),(0,Y.jsx)(M,{value:$,className:`text-xs`,children:`any`}),g.map(e=>(0,Y.jsx)(M,{value:e,className:`text-xs`,children:e},e))]})]})]})]}),(0,Y.jsx)(Nn,{label:`Prefer`,value:e.prefer,blocked:e.avoid,disabled:r,onChange:e=>c({prefer:e})}),(0,Y.jsx)(Nn,{label:`Avoid (ranks lower, never excludes)`,value:e.avoid,blocked:e.prefer,disabled:r,onChange:e=>c({avoid:e})}),(0,Y.jsx)(Nn,{label:`Require (only these providers may run matching work)`,value:e.require,disabled:r,onChange:e=>c({require:e})}),(0,Y.jsxs)(`label`,{className:`block space-y-1`,children:[(0,Y.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Use spare quota until…`}),(0,Y.jsx)(B,{type:`datetime-local`,"aria-label":`Use spare quota until…`,value:e.expires,onChange:e=>c({expires:e.target.value}),className:`h-8 text-xs`}),(0,Y.jsx)(`span`,{className:`block text-[10px] text-muted-foreground`,children:e.expires?yn:`Optional. Without an expiry the preference only ranks providers within a quota band.`})]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsx)(P,{checked:e.enabled,onCheckedChange:e=>c({enabled:e})}),(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Enabled`})]}),n&&(0,Y.jsx)(Mn,{message:n}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsxs)(R,{size:`sm`,onClick:a,children:[(0,Y.jsx)(L,{className:`size-4`}),s?`Add`:`Save`]}),(0,Y.jsx)(R,{size:`sm`,variant:`outline`,onClick:o,children:`Cancel`})]})]})}function In(e){let t=Object.entries(e.match).map(([e,t])=>`${e}=${Array.isArray(t)?t.join(`|`):t}`);return t.length?t.join(`, `):`all work`}function Ln(e){return e.status===412}function Rn(e,n,r){return(n??[]).map(n=>(0,Y.jsxs)(z,{variant:`outline`,className:t(`text-[10px]`,e===`avoid`?`text-tone-yellow-fg`:`text-tone-success-fg`),children:[e,` `,n,r.has(n)?` (disabled${r.get(n)?`: ${r.get(n)}`:``})`:``]},`${e}-${n}`))}function zn({policy:e,revision:n,diagnostics:r,providerCatalog:i=[],now:a=Date.now(),canWrite:o,onPolicy:s,onReload:c}){let[l,u]=(0,J.useState)(!1),[d,f]=(0,J.useState)(``),[p,m]=(0,J.useState)(null),[h,g]=(0,J.useState)(null),[_,v]=(0,J.useState)(``),y=p===n,b=new Map(i.filter(e=>e.disabled).map(e=>[e.provider,e.disabled?.reason??e.disabled?.source??``])),x=new Set(b.keys());async function S(t){u(!0),f(``);try{s(await Vt({...e,rules:t},n)),g(null),m(null)}catch(e){Ln(e)&&m(n),f(e.message)}finally{u(!1)}}async function C(){f(``),await c?.()}function w(e){g({id:e?.id??null,...e?{original:e}:{},form:e?wn(e):bn(),choices:{}}),v(``)}let T=h?.id==null?void 0:e.rules.find(e=>e.id===h.id),E=h?.original&&T?An(h.original,T,h.form,h.choices):null;function ee(){if(!h)return;let t=jn(E?.form??h.form);if(t){v(t);return}if(E?.conflicts.length){v(`Choose which value to keep for the fields another editor also changed.`);return}let n=En(E?.form??h.form,T??h.original);S(e.rules.some(e=>e.id===n.id)?e.rules.map(e=>e.id===n.id?n:e):[...e.rules,n])}let D=(r??e.migration)?.notes??[],te=e=>Array.isArray(e)?e.join(`, `)||`none`:String(e===``?`none`:e),ne=(e,t)=>h&&(0,Y.jsxs)(Y.Fragment,{children:[E&&E.conflicts.length>0&&(0,Y.jsxs)(`div`,{className:`space-y-2 rounded-md border border-tone-yellow/30 bg-tone-yellow/10 p-3 text-xs`,"data-testid":`routing-merge-conflicts`,children:[(0,Y.jsxs)(`div`,{className:`font-medium`,children:[`Another editor also changed `,h.id]}),E.conflicts.map(({key:e,mine:t,theirs:n})=>(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsx)(`span`,{className:`w-24 text-muted-foreground`,children:Dn[e]}),(0,Y.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>g({...h,choices:{...h.choices,[e]:`mine`}}),children:[`Keep mine: `,te(t)]}),(0,Y.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>g({...h,choices:{...h.choices,[e]:`theirs`}}),children:[`Use theirs: `,te(n)]})]},e))]}),(0,Y.jsx)(Fn,{form:h.form,original:t,error:_,disabledProviders:x,isNew:e,onChange:e=>g({...h,form:e}),onSave:ee,onCancel:()=>{g(null),m(null)}},h.id??`new`)]});return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsxs)(K,{className:`flex items-center gap-2 text-sm`,children:[(0,Y.jsx)(Te,{className:`size-4`}),`Routing preferences`,(0,Y.jsxs)(z,{variant:`outline`,className:`ml-auto text-[10px]`,children:[e.rules.length,` rule`,e.rules.length===1?``:`s`]}),l&&(0,Y.jsx)(I,{className:`size-3 animate-spin text-muted-foreground`})]}),(0,Y.jsx)(H,{className:`text-xs`,children:`For matching work, prefer, avoid or require providers. Every matching enabled rule counts. The dispatcher still picks the provider, model and effort from the work shape and live quota: a preference ranks providers within a quota band, and disabled providers drop out on their own. Explicit spawn pins still win.`})]}),(0,Y.jsxs)(G,{className:`space-y-2`,children:[d&&!y&&(0,Y.jsx)(Mn,{message:d}),y&&(0,Y.jsxs)(`div`,{className:`space-y-2 rounded-md border border-tone-yellow/30 bg-tone-yellow/10 p-3 text-xs`,"data-testid":`routing-conflict-banner`,children:[(0,Y.jsx)(`div`,{className:`font-medium`,children:`The routing policy changed elsewhere.`}),(0,Y.jsx)(`p`,{className:`text-muted-foreground`,children:h?`Your draft is kept. Reload the latest policy, then save to apply your draft on top of it.`:`Reload the latest policy and repeat your change.`}),(0,Y.jsx)(R,{size:`sm`,variant:`outline`,onClick:()=>void C(),children:`Reload latest`})]}),D.length>0&&(0,Y.jsxs)(`div`,{className:`space-y-1 rounded-md border border-tone-yellow/30 bg-tone-yellow/10 p-3 text-xs`,"data-testid":`routing-migration-banner`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 font-medium`,children:[(0,Y.jsx)(pe,{className:`size-3.5`}),`Converted from v1 routing rules`]}),(0,Y.jsx)(`p`,{className:`text-muted-foreground`,children:`Converted rules start disabled. Model and effort now come from the work-shape dispatch policy.`}),(0,Y.jsx)(`ul`,{className:`list-disc space-y-0.5 pl-4 text-muted-foreground`,children:D.map(e=>(0,Y.jsx)(`li`,{children:e},e))})]}),e.rules.length===0&&!h&&(0,Y.jsx)(`div`,{className:`rounded-md border border-dashed border-border py-6 text-center text-xs text-muted-foreground`,children:`No preferences — the dispatch policy and quota bands decide alone.`}),e.rules.map(n=>{if(h?.id===n.id)return(0,Y.jsx)(J.Fragment,{children:ne(!1,n)},n.id);let r=n.expiresAt!==void 0&&n.expiresAt<=a,i=n.enabled!==!1&&!r&&!!n.prefer?.length&&n.prefer.every(e=>x.has(e));return(0,Y.jsxs)(`div`,{className:t(`group flex items-start gap-3 rounded-md border bg-muted/20 p-3`,(n.enabled===!1||r)&&`opacity-60`),children:[(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[n.label&&(0,Y.jsx)(`span`,{className:`text-xs font-medium`,children:n.label}),(0,Y.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground`,children:n.id}),Rn(`prefer`,n.prefer,b),Rn(`avoid`,n.avoid,b),Rn(`require`,n.require,b),n.expiresAt!==void 0&&(0,Y.jsxs)(z,{variant:`outline`,className:t(`text-[10px]`,r?`text-tone-yellow-fg`:`text-tone-success-fg`),children:[r?`expired`:`until`,` `,new Date(n.expiresAt).toLocaleString()]}),i&&(0,Y.jsx)(z,{variant:`outline`,className:`text-[10px] text-tone-yellow-fg`,children:`dormant: preferred providers are disabled`})]}),(0,Y.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[`match: `,(0,Y.jsx)(`span`,{className:`font-mono text-foreground`,children:In(n)})]})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,children:[(0,Y.jsx)(P,{checked:n.enabled!==!1,disabled:!o||l,onCheckedChange:t=>void S(e.rules.map(e=>e.id===n.id?{...e,enabled:t}:e)),title:n.enabled===!1?`Enable rule`:`Disable rule`}),o&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`button`,{type:`button`,title:`Edit`,onClick:()=>w(n),disabled:l,className:`rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none`,children:(0,Y.jsx)(xe,{className:`size-3.5`})}),(0,Y.jsx)(`button`,{type:`button`,title:`Remove`,onClick:()=>void S(e.rules.filter(e=>e.id!==n.id)),disabled:l,className:`rounded p-1 text-destructive hover:bg-destructive/10 disabled:pointer-events-none`,children:(0,Y.jsx)(Ee,{className:`size-3.5`})})]})]})]},n.id)}),h&&h.id!==null&&!e.rules.some(e=>e.id===h.id)&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[h.id,` was removed in the latest policy. Saving adds it back.`]}),ne(!1,h.original)]}),h?.id===null&&ne(!0),o&&!h&&(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,className:`w-full gap-1`,onClick:()=>w(),disabled:l,children:[(0,Y.jsx)(Se,{className:`size-4`}),`Add preference`]})]})]})}var Bn=[`provider`,`model`,`effort`,`orchestratorId`,`profile`],Vn=e=>e===`orchestratorId`?`Host`:e[0].toUpperCase()+e.slice(1),Hn=`h-8 w-full rounded-md border bg-background px-2 text-xs`;function Un({policy:e,revision:t,teams:n,canWrite:r,onPolicy:i}){let[a,o]=(0,J.useState)(e.stepDefaults??{}),[s,c]=(0,J.useState)(`global`),[l,d]=(0,J.useState)(``),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(!1),_=(s===`global`?a.global:a.teams?.[s])??{},v=[...new Set([`builder`,`reviewer`,...Object.keys(_),...Object.keys(a.global??{})])],y=[...new Set([...n.map(e=>e.id),...Object.keys(a.teams??{})])];function b(e){o(s===`global`?{...a,global:e}:{...a,teams:{...a.teams,[s]:e}}),m(``)}function x(e,t,n){let r={..._[e],[t]:n||void 0};t===`provider`&&n!==_[e]?.provider&&(r.model=void 0,r.effort=void 0),b({..._,[e]:r})}async function S(){g(!0),m(``);try{let n=await Vt({...e,stepDefaults:a},t);o(n.policy.stepDefaults??{}),i(n),m(`Saved`)}catch(e){m(e.message)}finally{g(!1)}}return(0,Y.jsxs)(q,{size:`sm`,children:[(0,Y.jsxs)(W,{children:[(0,Y.jsx)(K,{className:`text-sm`,children:`Workflow role defaults`}),(0,Y.jsx)(H,{className:`text-xs`,children:`Call pins override team defaults, then global defaults, workflow and role definitions, then automatic dispatch. Blank fields inherit. Changes apply to new runs.`})]}),(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`label`,{className:`block text-xs`,children:[`Scope`,(0,Y.jsxs)(`select`,{"aria-label":`Routing defaults scope`,className:Hn,value:s,onChange:e=>c(e.target.value),children:[(0,Y.jsx)(`option`,{value:`global`,children:`Global`}),y.map(e=>(0,Y.jsx)(`option`,{value:e,children:n.find(t=>t.id===e)?.title??e},e))]})]}),(0,Y.jsx)(`div`,{className:`overflow-x-auto`,children:(0,Y.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,Y.jsx)(`thead`,{children:(0,Y.jsxs)(`tr`,{children:[(0,Y.jsx)(`th`,{className:`text-left`,children:`Role`}),Bn.map(e=>(0,Y.jsx)(`th`,{className:`min-w-28 text-left`,children:Vn(e)},e))]})}),(0,Y.jsx)(`tbody`,{children:v.map(e=>(0,Y.jsxs)(`tr`,{children:[(0,Y.jsx)(`th`,{className:`pr-2 text-left font-medium`,children:e}),Bn.map(t=>(0,Y.jsx)(`td`,{className:`p-1`,children:t===`provider`?(0,Y.jsxs)(`select`,{"aria-label":`${e} Provider`,className:Hn,disabled:!r||h,value:_[e]?.provider??``,onChange:n=>x(e,t,n.target.value),children:[(0,Y.jsx)(`option`,{value:``,children:`Inherit`}),f().map(e=>(0,Y.jsx)(`option`,{value:e,children:u(e)},e))]}):(0,Y.jsx)(B,{"aria-label":`${e} ${Vn(t)}`,className:`h-8 text-xs`,value:_[e]?.[t]??``,placeholder:s===`global`?`Inherit`:a.global?.[e]?.[t]??`Inherit`,disabled:!r||h,onChange:n=>x(e,t,n.target.value)})},t))]},e))})]})}),r&&(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(B,{"aria-label":`New routing role`,placeholder:`Project role`,value:l,disabled:h,onChange:e=>d(e.target.value)}),(0,Y.jsx)(R,{size:`sm`,variant:`outline`,disabled:h||!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(l)||v.includes(l),onClick:()=>{b({..._,[l]:{}}),d(``)},children:`Add role`}),(0,Y.jsx)(R,{size:`sm`,disabled:h,onClick:()=>void S(),children:h?`Saving…`:`Save role defaults`})]}),p&&(0,Y.jsx)(`p`,{role:`status`,className:`text-xs`,children:p})]})]})}function Wn({message:e}){return(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4 shrink-0`}),(0,Y.jsx)(`span`,{children:e})]})}function Gn({canWrite:e,canWriteBudget:n=!1}){let[r,a]=(0,J.useState)(null),o=r?.policy,c=s(e=>e.providerCatalog),l=s(e=>e.teams),u=i(6e4),[d,f]=(0,J.useState)(!1),[p,m]=(0,J.useState)(``),[h,g]=(0,J.useState)(!1),[_,v]=(0,J.useState)(0);!h&&!d&&!p&&(f(!0),(async()=>{try{let e=await y(`GET`,`/routing-policy`);a(e),g(!0)}catch(e){m(e.message)}finally{f(!1)}})());async function b(){f(!0),m(``);try{let e=await y(`GET`,`/routing-policy`);a(e),v(e=>e+1),g(!0)}catch(e){m(e.message)}finally{f(!1)}}return(0,Y.jsxs)(`div`,{className:`space-y-6`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Routing`}),(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Routing preferences steer automatic spawns, Task dispatch and workflow steps; the dispatch policy picks model and effort. Explicit per-spawn pins always take precedence.`})]}),(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void b(),disabled:d,children:[(0,Y.jsx)(we,{className:t(`size-4`,d&&`animate-spin`)}),`Refresh`]})]}),p&&(0,Y.jsx)(Wn,{message:p}),d&&!o&&(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,Y.jsx)(I,{className:`size-4 animate-spin`}),`Loading routing policy…`]})}),o&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(Un,{policy:o,revision:r.revision,teams:l,canWrite:e,onPolicy:a},_),(0,Y.jsx)(zn,{policy:o,revision:r.revision,diagnostics:r.diagnostics,providerCatalog:c,now:u,canWrite:e,onPolicy:a,onReload:b}),(0,Y.jsx)(en,{policy:o,revision:r.revision,canWrite:e,onPolicy:a}),(0,Y.jsx)(nn,{policy:o,revision:r.revision,canWrite:e,onPolicy:a}),(0,Y.jsx)(dn,{policy:o,revision:r.revision,canWrite:e,onPolicy:a},JSON.stringify([o.apiExpiry,o.subscriptionExpiry])),(0,Y.jsx)(gn,{canWrite:n}),(0,Y.jsx)(gn,{canWrite:n,budgetId:`openai-api`})]}),(0,Y.jsx)(sn,{})]})}var Kn=`browser`,qn=`models`,Jn=`profile`,Yn=`routing`,Xn=[`branch.landed`,`landed-failure`,`agent.ready`,`agent.exited`,`agent.spawn_failed`,`agent.context_threshold`,`agent.quota_threshold`,`workspace.steward_task`,`workspace.conflict`,`workspace.review_request`];function Zn(){if(typeof window>`u`)return``;let e=window.location.hash.replace(/^#/,``);return e.startsWith(`settings/`)?decodeURIComponent(e.slice(9)):``}function Qn(e){if(typeof window>`u`)return;let t=new URL(window.location.href);t.hash=`settings/${encodeURIComponent(e)}`,window.history.pushState({},``,t)}function $n(){let[e,n]=(0,J.useState)([]),[r,i]=(0,J.useState)(null),[a,o]=(0,J.useState)([]),c=s(e=>e.set),l=s(e=>e.teams),u=s(e=>e.fetchTeams),[d,f]=(0,J.useState)(()=>Zn()),[p,m]=(0,J.useState)(!0),[h,g]=(0,J.useState)(``),[_,v]=(0,J.useState)(``);async function b(){m(!0),g(``),v(``);try{let[e,t,r]=await Promise.all([y(`GET`,`/settings`),y(`GET`,`/tokens/me`),y(`GET`,`/providers`).catch(e=>(v(e.message),{catalog:[]})),u()]);n(e.settings),i(t),o(r.catalog)}catch(e){g(e.message)}finally{m(!1)}}(0,J.useEffect)(()=>{b()},[]),(0,J.useEffect)(()=>{let e=()=>f(Zn());return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[]);let x=(0,J.useMemo)(()=>Re(e),[e]),S=(0,J.useMemo)(()=>[...x.map(e=>({slug:e.slug,label:e.group,description:`${e.settings.length} schema setting${e.settings.length===1?``:`s`}`,kind:`descriptors`,settings:e.settings})),{slug:`service-access`,label:`Service access`,description:`Profile services and Vault application`,kind:`service-access`,settings:[]},{slug:Yn,label:`Routing`,description:`Rules, quota thresholds, coordinator view`,kind:`routing`,settings:[]},{slug:Jn,label:`Profile`,description:`Display name and avatar`,kind:`profile`,settings:[]},{slug:Kn,label:`Browser`,description:`Local dashboard preferences`,kind:`browser`,settings:[]},{slug:qn,label:`Models`,description:`Provider model catalog`,kind:`models`,settings:[]}],[x]),C=S.find(e=>e.slug===d)??S[0];function w(e){f(e),Qn(e)}function T(e){n(t=>t.map(t=>Fe(t)===Fe(e)?e:t))}let E=C?.kind===`descriptors`?C.settings.find(e=>e.namespace===`idle-digest`&&e.key==="default"):void 0,ee=C?.kind===`descriptors`?C.settings.find(e=>e.namespace===`agent-prefs`&&e.key==="default"):void 0,D=C?.kind===`descriptors`?C.settings.find(e=>e.namespace===`notification-prefs`&&e.key==="default"):void 0,te=C?.kind===`descriptors`?C.settings.filter(e=>e!==E&&e!==ee&&e!==D):[];return(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold`,children:`Settings`}),(0,Y.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Schema-driven Relay settings, browser preferences, and model catalog controls.`})]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[r&&(0,Y.jsxs)(z,{variant:`outline`,className:`gap-1`,children:[(0,Y.jsx)(le,{className:`size-3`}),r.kind,`:`,r.actor]}),(0,Y.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void b(),disabled:p,children:[(0,Y.jsx)(we,{className:t(`size-4`,p&&`animate-spin`)}),`Refresh`]})]})]}),h&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4`}),(0,Y.jsx)(`span`,{children:h})]}),(0,Y.jsxs)(`div`,{className:`grid gap-4 lg:grid-cols-[230px_minmax(0,1fr)]`,children:[(0,Y.jsx)(`nav`,{className:`space-y-1 lg:sticky lg:top-4 lg:self-start`,children:S.map(e=>(0,Y.jsxs)(`button`,{type:`button`,className:t(`w-full rounded-md border px-3 py-2 text-left text-sm transition-colors`,C?.slug===e.slug?`border-primary/50 bg-primary/10 text-foreground`:`border-transparent hover:border-border hover:bg-accent`),onClick:()=>w(e.slug),children:[(0,Y.jsx)(`span`,{className:`block font-medium`,children:e.label}),(0,Y.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:e.description})]},e.slug))}),(0,Y.jsx)(`div`,{className:`min-w-0 space-y-4`,children:p&&!e.length?(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsx)(G,{className:`text-sm text-muted-foreground`,children:`Loading settings…`})}):C?.kind===`service-access`?(0,Y.jsx)(ue,{}):C?.kind===`routing`?(0,Y.jsx)(Gn,{canWrite:Ne(r?.scopes,`settings:write:routing`),canWriteBudget:Ne(r?.scopes,`system:admin`)}):C?.kind===`descriptors`?(0,Y.jsxs)(Y.Fragment,{children:[ee&&(0,Y.jsx)(Tt,{setting:ee,onSaved:T}),D&&(0,Y.jsx)(Dt,{setting:D,onSaved:T}),(0,Y.jsx)(Qe,{group:C.label,settings:te,onSaved:T}),C.label===`Users`&&Ne(r?.scopes,`system:admin`)&&(0,Y.jsx)(Ft,{}),E&&(0,Y.jsx)(yt,{setting:E,teams:l,onSaved:T},`${E.version}-${E.updatedAt}`),C.label===`Providers`&&(0,Y.jsx)(Bt,{canWrite:Ne(r?.scopes,`settings:write:provider`)}),C.label===`Notifications`&&(0,Y.jsx)(er,{})]}):C?.kind===`profile`?(0,Y.jsx)(tr,{}):C?.kind===`browser`?(0,Y.jsx)(rt,{}):(0,Y.jsx)(st,{catalog:a,error:_,canWrite:Ne(r?.scopes,`settings:write:provider`),onCatalog:e=>{o(e),c({providerCatalog:e})}})})]})]})}function er(){let[e,t]=(0,J.useState)(`branch.landed`),[n,r]=(0,J.useState)(`{
|
|
4
4
|
"repoRoot": "/repo"
|
|
5
5
|
}`),[i,a]=(0,J.useState)(null),[o,s]=(0,J.useState)(!1),[c,l]=(0,J.useState)(``);async function u(){s(!0),l(``);try{let t=JSON.parse(n);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Scope must be a JSON object`);let r=await y(`POST`,`/notifications/preview`,{type:e,scope:t});a(r.preview)}catch(e){a(null),l(e.message)}finally{s(!1)}}return(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`space-y-3`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold`,children:`Who gets what`}),(0,Y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Dry-run notification routing without sending.`})]}),(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void u(),disabled:o,children:[(0,Y.jsx)(Te,{className:`size-4`}),`Preview`]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[240px_minmax(0,1fr)]`,children:[(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`Type`}),(0,Y.jsxs)(N,{value:e,onValueChange:t,children:[(0,Y.jsx)(A,{className:`w-full`,children:(0,Y.jsx)(k,{})}),(0,Y.jsx)(j,{children:Xn.map(e=>(0,Y.jsx)(M,{value:e,children:e},e))})]})]}),(0,Y.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Y.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`Scope`}),(0,Y.jsx)(V,{value:n,onChange:e=>r(e.target.value),rows:4,className:`font-mono text-xs`})]})]}),c&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-3.5`}),(0,Y.jsx)(`span`,{children:c})]}),i&&(0,Y.jsx)(`div`,{className:`overflow-hidden rounded-md border border-border`,children:i.recipients.length===0?(0,Y.jsx)(`div`,{className:`px-3 py-4 text-center text-xs text-muted-foreground`,children:`No recipients`}):i.recipients.map(e=>(0,Y.jsxs)(`div`,{className:`grid gap-1 border-b border-border px-3 py-2 text-xs last:border-b-0 md:grid-cols-[minmax(0,180px)_minmax(0,160px)_minmax(0,1fr)]`,children:[(0,Y.jsx)(`span`,{className:`truncate font-medium`,children:e.recipient}),(0,Y.jsx)(`span`,{className:`truncate font-mono text-muted-foreground`,children:e.matchedRule}),(0,Y.jsx)(`span`,{className:`truncate text-muted-foreground`,children:e.reason})]},`${e.recipient}-${e.matchedRule}`))})]})})}function tr(){let e=s(e=>e.fetchUsers),t=(0,J.useRef)(null),[n,r]=(0,J.useState)(null),[i,a]=(0,J.useState)(``),[o,c]=(0,J.useState)(!0),[l,u]=(0,J.useState)(!1),[d,f]=(0,J.useState)(``);async function p(){c(!0),f(``);try{let e=await y(`GET`,`/users/me`);r(e),a(e.displayName||e.handle)}catch(e){f(e.message)}finally{c(!1)}}(0,J.useEffect)(()=>{p()},[]);async function m(){u(!0),f(``);try{let t=await y(`PATCH`,`/users/me`,{displayName:i});r(t),a(t.displayName||t.handle),await e()}catch(e){f(e.message)}finally{u(!1)}}async function h(n){if(n){u(!0),f(``);try{let t=await _(`/users/me/avatar`,n);r(t.user),a(t.user.displayName||t.user.handle),await e()}catch(e){f(e.message)}finally{u(!1),t.current&&(t.current.value=``)}}}async function g(){u(!0),f(``);try{let t=await y(`DELETE`,`/users/me/avatar`);r(t),await e()}catch(e){f(e.message)}finally{u(!1)}}return(0,Y.jsx)(q,{size:`sm`,children:(0,Y.jsxs)(G,{className:`space-y-4`,children:[d&&(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,Y.jsx)(F,{className:`mt-0.5 size-4`}),(0,Y.jsx)(`span`,{children:d})]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,Y.jsx)(Ae,{user:n??void 0,distinct:!0,className:`size-16 text-lg`}),(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-2`,children:[(0,Y.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground`,htmlFor:`profile-display-name`,children:`Display name`}),(0,Y.jsx)(`input`,{id:`profile-display-name`,className:`h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,value:i,onChange:e=>a(e.target.value),disabled:o||l,maxLength:120})]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsxs)(R,{size:`sm`,onClick:()=>void m(),disabled:o||l||!i.trim(),children:[(0,Y.jsx)(L,{className:`size-4`}),`Save`]}),(0,Y.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>t.current?.click(),disabled:o||l,children:[(0,Y.jsx)(fe,{className:`size-4`}),`Upload`]}),(0,Y.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>void g(),disabled:o||l||!n?.avatarArtifactId,children:[(0,Y.jsx)(Ee,{className:`size-4`}),`Remove`]}),l&&(0,Y.jsx)(me,{className:`size-4 animate-pulse text-muted-foreground`}),(0,Y.jsx)(`input`,{ref:t,type:`file`,accept:`image/png,image/jpeg,image/gif,image/webp`,className:`hidden`,onChange:e=>void h(e.target.files?.[0])})]})]})})}export{$n as SettingsView};
|
|
6
|
-
//# sourceMappingURL=settings-
|
|
6
|
+
//# sourceMappingURL=settings-CoUC7Jci.js.map
|