@suveren/gateway 0.23.0 → 0.23.2
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.
|
@@ -3538,10 +3538,31 @@ function createProposalStatusRouter(spUrl, vault2, dataDir, lockAsTlsMismatch2)
|
|
|
3538
3538
|
|
|
3539
3539
|
// src/routes/evidence.ts
|
|
3540
3540
|
import { Router as Router11 } from "express";
|
|
3541
|
-
import {
|
|
3541
|
+
import { createPublicKey as createPublicKey2, verify as verifyEd25519 } from "crypto";
|
|
3542
|
+
import { verifyTicketSignature, encodeDidKey, canonicalize as canonicalize2 } from "@hap/core";
|
|
3542
3543
|
function issuerFromPublicKeyHex(publicKeyHex) {
|
|
3543
3544
|
return encodeDidKey(Buffer.from(publicKeyHex, "hex"));
|
|
3544
3545
|
}
|
|
3546
|
+
var ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
|
|
3547
|
+
function isPreV07Ticket(receipt) {
|
|
3548
|
+
return receipt.issuer === void 0 || receipt.issuer === null;
|
|
3549
|
+
}
|
|
3550
|
+
function verifyPreV07TicketSignature(receipt, asPublicKeyHex) {
|
|
3551
|
+
const { signature, ...signed } = receipt;
|
|
3552
|
+
if (typeof signature !== "string" || !/^[0-9a-f]{64}$/i.test(asPublicKeyHex)) return false;
|
|
3553
|
+
try {
|
|
3554
|
+
const key = createPublicKey2({
|
|
3555
|
+
key: Buffer.concat([ED25519_SPKI_PREFIX, Buffer.from(asPublicKeyHex, "hex")]),
|
|
3556
|
+
format: "der",
|
|
3557
|
+
type: "spki"
|
|
3558
|
+
});
|
|
3559
|
+
const sig = Buffer.from(signature, "base64");
|
|
3560
|
+
if (sig.length !== 64) return false;
|
|
3561
|
+
return verifyEd25519(null, Buffer.from(canonicalize2(signed), "utf8"), key, sig);
|
|
3562
|
+
} catch {
|
|
3563
|
+
return false;
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3545
3566
|
async function verifyAll(receipts) {
|
|
3546
3567
|
const out = {};
|
|
3547
3568
|
for (const raw of receipts) {
|
|
@@ -3552,6 +3573,11 @@ async function verifyAll(receipts) {
|
|
|
3552
3573
|
out[id] = "unverifiable";
|
|
3553
3574
|
continue;
|
|
3554
3575
|
}
|
|
3576
|
+
const receipt = e.receipt;
|
|
3577
|
+
if (isPreV07Ticket(receipt)) {
|
|
3578
|
+
out[id] = verifyPreV07TicketSignature(receipt, e.asPublicKey) ? "valid-legacy" : "invalid";
|
|
3579
|
+
continue;
|
|
3580
|
+
}
|
|
3555
3581
|
try {
|
|
3556
3582
|
await verifyTicketSignature(e.receipt, { trustedIssuers: [issuerFromPublicKeyHex(e.asPublicKey)] });
|
|
3557
3583
|
out[id] = "valid";
|
|
@@ -80,7 +80,7 @@ Watch out — What should the agent avoid or be careful about?`;function dw(e,t,
|
|
|
80
80
|
`)||e.length>120)?"markdown":"text"}function sj(e,t){var o,c;const n=(t==null?void 0:t.approvalView)??{},r=((o=t==null?void 0:t.inputSchema)==null?void 0:o.properties)??{},a=[...new Set([...Object.keys(n),...Object.keys(r),...Object.keys(e)])],i=[];for(const l of a){if(!(l in e)||tj.has(l))continue;const u=e[l],f=n[l]??{},m=f.kind??rj(u),h={key:l,label:f.label??Os(l),kind:m,value:u,hint:(c=r[l])==null?void 0:c.description};m==="money"&&f.currencyArg&&typeof e[f.currencyArg]=="string"&&(h.currency=e[f.currencyArg]),m==="profile"&&typeof u=="string"&&(h.profileRef=u),(m==="profile-limits"||m==="profile-scope")&&f.profileArg&&typeof e[f.profileArg]=="string"&&(h.profileRef=e[f.profileArg]),i.push(h)}return i}function Zm(e,t){var r,a;const n=(a=(r=t==null?void 0:t.scopeSchema)==null?void 0:r.fields)==null?void 0:a[e];return n?{label:n.displayName??e,hint:n.description}:{label:e}}function aj(e,t,n){if(!e||typeof e!="object"||Array.isArray(e))return[];const r=n==="limits"?t==null?void 0:t.boundsSchema:t==null?void 0:t.scopeSchema,a=(r==null?void 0:r.fields)??{},i=[...new Set([...(r==null?void 0:r.keyOrder)??[],...Object.keys(e)])],o=[];for(const c of i){if(c==="profile"||!(c in e))continue;const l=e[c],u=a[c],f=Ac(u==null?void 0:u.unit),m=Array.isArray(l)?l.join(", "):String(l);o.push({key:c,label:(u==null?void 0:u.displayName)??Os(c),value:f?`${m} ${f}`:m,hint:u==null?void 0:u.description,unknown:t?!u:void 0})}return o}function ij(e){const t=e.indexOf("__");return t<0?{integrationId:"",toolName:e}:{integrationId:e.slice(0,t),toolName:e.slice(t+2)}}function oj(e,t){var l,u,f;const{integrationId:n,toolName:r}=ij(e.action),a=t.find(m=>m.id===n),i=(u=(l=a==null?void 0:a.toolGating)==null?void 0:l.overrides)==null?void 0:u[r];if(i!=null&&i.actionLabel)return i.actionLabel;const o=Le(e.profileId),c=(f=e.executionContext)==null?void 0:f.action_type;return typeof c=="string"&&c?`${o} · ${c}`:`${o} · ${r}`}function lj(e,t){var a;const n=(a=t==null?void 0:t.scopeSchema)==null?void 0:a.fields;if(!n)return"";const r=[];for(const[i,o]of Object.entries(e.executionContext??{})){if(!(i in n))continue;const c=String(o??"").trim();c&&r.push(c.split(",").map(l=>l.trim()).filter(Boolean).join(", "))}return r.join(" · ")}function cj(e,t){var a,i;if(!e)return"";const n=((a=t==null?void 0:t.scopeSchema)==null?void 0:a.fields)??{},r=[];for(const[o,c]of Object.entries(e)){if(o==="action_type")continue;const l=String(c??"").trim();if(!l)continue;const u=((i=n[o])==null?void 0:i.displayName)??o;r.push(`${u} ${l.split(",").map(f=>f.trim()).filter(Boolean).join(", ")}`)}return r.join(" · ")}function Sd(e){return e.appliesTo}function uj(e,t,n){var c,l,u,f;const r=[{window:"daily",label:"today"},{window:"monthly",label:"this month"}],a=e.actionType??(typeof((c=e.executionContext)==null?void 0:c.action_type)=="string"?e.executionContext.action_type:void 0),i=(l=n==null?void 0:n.boundsSchema)==null?void 0:l.fields,o=[];for(const{window:m,label:h}of r){const w=(u=e.cumulativeState)==null?void 0:u[m];if(!w)continue;let j;if(i&&t){const g=Object.entries(i).filter(([x,k])=>{if(!(x in t))return!1;const N=k.boundType;if(!N||N.kind!=="cumulative_sum"&&N.kind!=="cumulative_count"||N.window!==m)return!1;const C=Sd(k);return!C||!a||C.includes(a)}),y=(a?g.find(([,x])=>{var k;return(k=Sd(x))==null?void 0:k.includes(a)}):void 0)??(g.length===1?g[0]:void 0);y&&(j={key:y[0],isAmount:((f=y[1].boundType)==null?void 0:f.kind)==="cumulative_sum"})}const v=j?j.isAmount?w.amount:w.count:void 0,S=j?Number(t==null?void 0:t[j.key]):NaN;j&&Number.isFinite(S)?o.push(`${v} of ${S} ${h}`):o.push(`${w.count} ${w.count===1?"call":"calls"} ${h}`)}return o.join(" · ")}function dj(e,t,n){var i;const r=(i=n==null?void 0:n.boundsSchema)==null?void 0:i.fields;if(!e||!t||!r)return[];const a=[];for(const[o,c]of Object.entries(r)){const l=c.boundType;if(!l||l.kind!=="per_transaction")continue;const u=l.of;if(!(u in e)||!(o in t))continue;const f=Number(e[u]),m=Number(t[o]);if(!Number.isFinite(f)||!Number.isFinite(m))continue;const h=Ac(c.unit),w=c.displayName??Os(u),j=v=>h?`${v.toLocaleString()} ${h}`:v.toLocaleString();a.push({key:o,label:w,ok:f<=m,valueText:j(f),limitText:j(m)})}return a}function fj(e){return typeof e.proposalId=="string"&&e.proposalId.length>0}function hj(e){const t=Le(e),n=e.split("@")[1];return n?`${t}@${n}`:t}const kd=new Map;function mj(e){let t=kd.get(e);return t||(t=(async()=>{try{let n=e;if(!e.includes("@")){const r=await E.listProfiles(),a=o=>o.replace(/@.*$/,"").split("/").pop(),i=r.filter(o=>a(o.id)===e).sort((o,c)=>(c.id.split("@")[1]??"").localeCompare(o.id.split("@")[1]??"",void 0,{numeric:!0}));if(!i[0])return null;n=i[0].id}return await E.getProfile(n)}catch{return null}})(),kd.set(e,t)),t}function Ds(e){const[t,n]=d.useState(null);return d.useEffect(()=>{let r=!0;return e&&mj(e).then(a=>{r&&n(a)}),()=>{r=!1}},[e]),t}async function bd(e){const t=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function pj(e){return e.normalize("NFC").replace(/\r\n?/g,`
|
|
81
81
|
`).split(`
|
|
82
82
|
`).map(a=>a.replace(/[ \t]+$/,"")).join(`
|
|
83
|
-
`).replace(/\n+$/,"")}function ul(e){if(e===void 0)throw new Error("canonicalize: undefined is not serializable");if(typeof e=="number"&&!Number.isFinite(e))throw new Error(`canonicalize: ${e} is not a valid JSON number`);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return"["+e.map(a=>a===void 0?"null":ul(a)).join(",")+"]";const t=e,n=[];for(const r of Object.keys(t).sort()){const a=t[r];a!==void 0&&n.push(JSON.stringify(r)+":"+ul(a))}return"{"+n.join(",")+"}"}async function gj(e,t){if(e==="jcs"){if(typeof t=="string")throw new Error('content_binding kind="jcs" expects a record payload (object), got a string');return`sha256:${await bd(ul(t))}`}if(typeof t!="string")throw new Error('content_binding kind="text" expects a string, got an object');return`sha256:${await bd(pj(t))}`}function mr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ln(e,t=!1){return e==null?"—":typeof e=="string"?e:typeof e=="boolean"?String(e):typeof e=="number"?t||Number.isInteger(e)?String(e):String(Math.round(e*100)/100):"—"}function yj(e){return e==null?!1:typeof e=="string"||Array.isArray(e)?e.length>0:!0}function es(e,t,n){const r=t?Object.keys(t).filter(a=>a in e):Object.keys(e);return r.length===0?"—":r.map(a=>{var l,u;const i=e[a],o=((l=t==null?void 0:t[a])==null?void 0:l.title)??Os(a),c=mr(i)?es(i,(u=t==null?void 0:t[a])==null?void 0:u.properties,n):Ln(i,n);return`${o}: ${c}`}).join(" · ")}function vj(e,t){var a;if(Array.isArray(e)){if(e.length===0)return{value:"—"};if(e.every(u=>!mr(u)&&!Array.isArray(u))){const u=e.map(m=>Ln(m)).join(", "),f=e.map(m=>Ln(m,!0)).join(", ");return f===u?{value:u}:{value:u,valueTitle:f}}const i=(a=t==null?void 0:t.items)==null?void 0:a.properties,o=e.map(u=>mr(u)?es(u,i,!1):Ln(u)),c=e.map(u=>mr(u)?es(u,i,!0):Ln(u,!0)),l=o.map((u,f)=>u===c[f]?void 0:c[f]);return l.some(u=>u!==void 0)?{lines:o,lineTitles:l}:{lines:o}}if(mr(e)){const i=es(e,t==null?void 0:t.properties,!1),o=es(e,t==null?void 0:t.properties,!0);return o===i?{value:i}:{value:i,valueTitle:o}}const n=Ln(e),r=Ln(e,!0);return r===n?{value:n}:{value:n,valueTitle:r}}function xj(e){let t;try{t=JSON.parse(e)}catch{return null}return mr(t)?t:null}function ri(e){const t=e!=null&&e.structured&&Object.keys(e.structured).length>0?e.structured:void 0;if(t)return{obj:t,schema:e==null?void 0:e.outputSchema};const n=e!=null&&e.text?xj(e.text):null;return n?{obj:n}:null}function dl(e){const t=ri(e);if(!t)return[];const{obj:n,schema:r}=t,a=(r==null?void 0:r.properties)??{},i=[...new Set([...Object.keys(a),...Object.keys(n)])],o=[];for(const c of i){if(!(c in n))continue;const l=a[c],u=(l==null?void 0:l.title)??Os(c);o.push({key:c,label:u,...vj(n[c],l)})}return o}function fl(e,t){const n=ri(e);if(n){const a=dl(e),i=t==null?void 0:t.fields;let o;if(i&&i.length>0){const u=new Map(a.map(f=>[f.key,f]));o=i.map(f=>u.get(f)).filter(f=>f!==void 0)}else o=a.filter(u=>yj(n.obj[u.key]));const c=new Set(o.map(u=>u.key)),l=a.filter(u=>!c.has(u.key));return{kind:"structured",fields:o,moreFields:l,totalFields:a.length}}const r=e==null?void 0:e.text;return r&&r.trim().length>0?{kind:"text",fields:[],moreFields:[],totalFields:0,text:r}:{kind:"empty",fields:[],moreFields:[],totalFields:0}}function Nd(e){return e?e.lines?`lines:${JSON.stringify(e.lines)}`:`value:${e.value??""}`:""}function da(e){return{kind:e.length>0?"structured":"empty",fields:e,moreFields:[],totalFields:e.length}}function wj(e,t,n){const r=ri(e),a=ri(t);if(!r&&!a){const h=(e==null?void 0:e.text)??"",w=(t==null?void 0:t.text)??"";return h===w?{approved:da([]),current:da([]),unchanged:!0}:{approved:{kind:"text",fields:[],moreFields:[],totalFields:0,text:h},current:{kind:"text",fields:[],moreFields:[],totalFields:0,text:w},unchanged:!1}}const i=new Map(dl(e).map(h=>[h.key,h])),o=new Map(dl(t).map(h=>[h.key,h])),l=[...new Set([...i.keys(),...o.keys()])].filter(h=>h===(n==null?void 0:n.excludeKey)?!1:Nd(i.get(h))!==Nd(o.get(h))),u=n!=null&&n.fields&&n.fields.length>0?[...n.fields.filter(h=>l.includes(h)),...l.filter(h=>!n.fields.includes(h))]:l,f=u.map(h=>i.get(h)).filter(h=>h!==void 0),m=u.map(h=>o.get(h)).filter(h=>h!==void 0);return{approved:da(f),current:da(m),unchanged:l.length===0}}function jj(e){return e.offDevice?"off-device":e.boundContent===void 0?"none":e.hasHashToCheck?e.hashVerified===!0?"verified":"mismatch":"unchecked"}function Sj(e,t){return e===void 0?{kind:"empty",fields:[],moreFields:[],totalFields:0}:typeof e=="string"?fl({text:e}):fl({structured:e},{fields:t})}function kj(e,t){return e?Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,r])=>({key:n,label:Zm(n,t).label,value:String(r)})):[]}function Cd({rows:e}){return s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.3rem 0.75rem",fontSize:"0.85rem",margin:"0.4rem 0"},children:e.map(t=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-tertiary)",whiteSpace:"nowrap",alignSelf:"start"},children:t.label}),s.jsx("dd",{style:{margin:0,wordBreak:"break-word"},children:t.lines?s.jsx("div",{children:t.lines.map((n,r)=>{var a;return s.jsx("div",{title:(a=t.lineTitles)==null?void 0:a[r],children:n},r)})}):s.jsx("span",{title:t.valueTitle,children:t.value})})]},t.key))})}function Ta({rendered:e}){return e.kind==="empty"?s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.85rem",margin:"0.4rem 0"},children:"No fields returned."}):e.kind==="text"?s.jsx("div",{style:{whiteSpace:"pre-wrap",fontSize:"0.85rem",margin:"0.4rem 0"},children:e.text}):s.jsxs(s.Fragment,{children:[s.jsx(Cd,{rows:e.fields}),e.moreFields.length>0&&s.jsxs("details",{style:{fontSize:"0.8rem"},children:[s.jsxs("summary",{style:{cursor:"pointer",color:"var(--text-tertiary)"},children:["All fields (",e.totalFields,")"]}),s.jsx(Cd,{rows:e.moreFields})]})]})}function ep({receipt:e,profile:t}){var h;const[n,r]=d.useState(void 0),[a,i]=d.useState(null),o=!!(e.contentHash&&e.contentBinding);if(d.useEffect(()=>{let w=!0;return r(void 0),i(null),(async()=>{let j;try{j=await E.getArchivedReceipt(e.id)}catch{w&&r(null);return}let v=null;const S=j==null?void 0:j.entry.boundContent;if(S!==void 0&&o)try{v=await gj(e.contentBinding.kind,S)===e.contentHash}catch{v=!1}w&&(i(v),r(j))})(),()=>{w=!1}},[e.id,e.contentHash,e.contentBinding,o]),n===void 0)return s.jsx("div",{className:"ticket-done-box ticket-done-loading","data-testid":"ticket-what-was-done","data-bound":"loading","aria-busy":"true",children:"Loading…"});const c=n===null,l=n==null?void 0:n.entry.boundContent,u=jj({offDevice:c,boundContent:l,hasHashToCheck:o,hashVerified:a});if(u==="off-device")return s.jsx("div",{className:"ticket-done-box ticket-done-off-device","data-testid":"ticket-what-was-done","data-bound":"off-device",children:s.jsx("p",{className:"ticket-done-note",children:"Content not on this device — only the signed values are shown."})});if(u==="none"){const w=kj(e.executionContext,t);return s.jsxs("div",{className:"ticket-done-box","data-testid":"ticket-what-was-done","data-bound":"none",children:[s.jsx("h4",{children:"What was done"}),w.length>0?s.jsx("dl",{className:"ticket-done-fields",children:w.map(j=>s.jsxs("div",{className:"ticket-done-field-row",children:[s.jsx("dt",{children:j.label}),s.jsx("dd",{children:j.value})]},j.key))}):s.jsx("p",{className:"ticket-done-note",children:"No checked values recorded for this action."})]})}const f=Sj(l,(h=e.contentBinding)==null?void 0:h.fields),m=u==="verified"?"ticket-done-verified":u==="mismatch"?"ticket-done-mismatch":"ticket-done-unchecked";return s.jsxs("div",{className:`ticket-done-box ${m}`,"data-testid":"ticket-what-was-done","data-bound":u,children:[s.jsxs("h4",{children:["What was done",u!=="unchecked"&&s.jsxs(s.Fragment,{children:[" ",s.jsx("span",{className:"src-tag src-tag-sealed",children:"sealed"})]})]}),s.jsx(Ta,{rendered:f}),u==="verified"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-ok",children:"✓ This exact content is bound by hash — any change after the fact would break the ticket."}),u==="mismatch"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-bad",children:"⚠ This content does NOT match the ticket's signed hash — it may have been altered since archiving."}),u==="unchecked"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-neutral",children:"This content is kept on this device, but the ticket carries no content hash — it cannot be checked against the ticket."})]})}function Gr({label:e,children:t}){return s.jsxs(s.Fragment,{children:[s.jsx("dt",{className:"receipt-row-label",children:e}),s.jsx("dd",{className:"receipt-row-value",children:t})]})}function bj({receipt:e,manifests:t,localAuth:n,localUnavailable:r,signature:a,grantTitle:i,ownerLabel:o,spUrl:c,formatDate:l,onOpenComplete:u}){var p;const f=Ds(e.profileId),m=lj(e,f),h=cj(n==null?void 0:n.context,f),w=uj(e,(n==null?void 0:n.bounds)??e.limits,f),j=n==null?void 0:n.intent,v=qn(e.profileId).testSetup||bi(e.action),[S,g]=d.useState(!1);return s.jsxs("div",{className:"card id-card",style:{marginBottom:0},children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{className:"receipt-head",children:[s.jsx("span",{className:"receipt-what",children:oj(e,t)}),s.jsx("span",{className:"receipt-tag",children:fj(e)?"review":"automatic"}),e.contentHash&&s.jsx("span",{className:"receipt-tag receipt-tag-bound",title:(p=e.contentBinding)!=null&&p.fields?`The ticket binds: ${e.contentBinding.fields.join(", ")}`:"This exact content was authorized",children:"content bound"}),v&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),s.jsx("span",{className:"auth-card-time",children:l(e.timestamp)})]}),m&&s.jsx("div",{className:"receipt-scope",children:m}),s.jsx(ep,{receipt:e,profile:f}),s.jsxs("dl",{className:"receipt-rows",children:[s.jsxs(Gr,{label:"mandate",children:[s.jsx("strong",{children:i||hj(e.profileId)})," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}),o&&s.jsx(Gr,{label:"owner",children:o}),h&&s.jsxs(Gr,{label:"allowed",children:[h," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}),w&&s.jsxs(Gr,{label:"used",children:[s.jsx("span",{className:"receipt-num",children:w})," ",s.jsx("span",{className:"src-tag src-tag-sealed",children:"sealed"})]}),s.jsx(Gr,{label:"intent",children:j?s.jsxs(s.Fragment,{children:[s.jsx("span",{className:`intent-text${S?"":" intent-clamped"}`,children:j}),s.jsx("button",{type:"button",className:"btn btn-ghost btn-sm intent-toggle",onClick:()=>g(!S),children:S?"Show less":"Show full intent"})," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}):s.jsx("span",{className:"receipt-absent",children:r?"local store unreachable — sign in to the gateway to read it":"not on this device — the Authority Server stores only its hash"})})]}),s.jsxs("div",{className:"receipt-foot",children:[a==="valid"&&s.jsx("span",{className:"receipt-verified",title:"Ed25519 signature checked on this device against the issuer key archived when the ticket was issued — no Authority Server involved.",children:"✓ Verified on this device"}),a==="invalid"&&s.jsx("span",{className:"receipt-tamper",title:"The stored ticket does not match what was signed.",children:"⚠ Signature check FAILED"}),s.jsx("button",{type:"button",className:"receipt-evidence-link",onClick:u,children:"Complete ticket"}),c&&s.jsxs("span",{className:"receipt-public",children:["redacted, shareable:"," ",s.jsx("a",{className:"receipt-link",href:`${c}/r/${e.id}`,target:"_blank",rel:"noreferrer",children:"public link ↗"})]})]}),s.jsxs("details",{className:"receipt-more",children:[s.jsx("summary",{children:"Raw"}),s.jsxs("div",{className:"receipt-kv",children:[s.jsxs("div",{children:["ticket · ",e.id]}),s.jsxs("div",{children:["action · ",e.action]}),s.jsxs("div",{children:["profile · ",e.profileId]}),e.authorizationId&&s.jsxs("div",{children:["mandate · ",e.authorizationId]}),Object.keys(e.executionContext??{}).length>0&&s.jsxs("div",{children:["scope ·"," ",Object.entries(e.executionContext).map(([y,x])=>`${y}=${x}`).join(" · ")]}),(n==null?void 0:n.boundsHash)&&s.jsxs("div",{children:["bounds hash · ",n.boundsHash]}),(n==null?void 0:n.contextHash)&&s.jsxs("div",{children:["scope hash · ",n.contextHash]}),e.contentHash&&s.jsxs("div",{children:["content · ",e.contentHash]}),e.proposalId&&s.jsxs("div",{children:["proposal · ",e.proposalId]}),s.jsxs("div",{children:["signature · ",e.signature]})]})]})]})]})}function Nj({receipt:e,onClose:t}){const[n,r]=d.useState(null),[a,i]=d.useState(null),[o,c]=d.useState(null),[l,u]=d.useState(!0),[f,m]=d.useState(!1);d.useEffect(()=>{let S=!1;return u(!0),E.getArchivedReceipt(e.id).then(g=>{S||(r(g),i(g?"local":"authority-server"),c((g==null?void 0:g.signature)??null))}).catch(()=>{S||i("authority-server")}).finally(()=>{S||u(!1)}),()=>{S=!0}},[e.id]);const h=n?n.entry:{receipt:e},w=JSON.stringify(h,null,2);function j(){const S=URL.createObjectURL(new Blob([w],{type:"application/json"})),g=document.createElement("a");g.href=S,g.download=`suveren-ticket-${e.id.slice(0,8)}.json`,g.click(),URL.revokeObjectURL(S)}async function v(){try{await navigator.clipboard.writeText(w),m(!0),setTimeout(()=>m(!1),2e3)}catch{m(!1)}}return s.jsx("div",{className:"modal-backdrop",onClick:S=>S.target===S.currentTarget&&t(),children:s.jsxs("div",{className:"modal",style:{maxWidth:"44rem"},children:[s.jsxs("div",{className:"modal-header",children:[s.jsx("h3",{className:"modal-title",children:"Complete ticket"}),s.jsx("button",{className:"modal-close",onClick:t,"aria-label":"Close",children:"×"})]}),s.jsxs("div",{className:"modal-body",children:[o==="valid"&&s.jsx("p",{className:"receipt-verified",style:{margin:"0 0 0.5rem",fontSize:"0.8rem"},children:"✓ Ed25519 signature verified on this device, against the issuer key archived when this ticket was issued."}),o==="invalid"&&s.jsx("p",{className:"receipt-tamper",style:{margin:"0 0 0.5rem",fontSize:"0.8rem"},children:"⚠ Signature check FAILED — the stored ticket does not match what was signed."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-muted)",margin:"0 0 0.75rem"},children:l?"Loading…":a==="local"?"Held on this device — the signed ticket, the mandate it ran under, and the issuer key. Anyone with this file and that key can verify it offline, without Suveren.":"No local copy of this ticket (it predates local archiving, or ran on another device). Shown from the Authority Server — complete and signed, but it needs the server to retrieve."}),s.jsx("pre",{style:{fontFamily:"'SF Mono', Monaco, monospace",fontSize:"0.68rem",lineHeight:1.65,margin:0,background:"var(--accent-subtle)",border:"1px solid var(--border)",borderRadius:"6px",padding:"0.75rem 0.85rem",overflowX:"auto",maxHeight:"22rem",overflowY:"auto"},children:w})]}),s.jsxs("div",{className:"modal-footer",children:[s.jsx("button",{className:"btn btn-primary btn-sm",onClick:j,children:"Download"}),s.jsx("button",{className:"btn btn-secondary btn-sm",onClick:v,children:f?"Copied":"Copy"})]})]})})}function Cj(e){return new Date(e*1e3).toLocaleString()}function Ej(e,t){if(t==="all")return!0;const n=t==="1d"?1:t==="7d"?7:30,r=Math.floor(Date.now()/1e3)-n*86400;return e.timestamp>=r}function Tj(e,t){if(!t)return!0;const n=t.toLowerCase();return e.profileId.toLowerCase().includes(n)||Le(e.profileId).toLowerCase().includes(n)||e.path.toLowerCase().includes(n)||e.action.toLowerCase().includes(n)||e.attestationHash.toLowerCase().includes(n)||e.id.toLowerCase().includes(n)||JSON.stringify(e.executionContext).toLowerCase().includes(n)}function Ed(e,t){const n=new Map(e.map(r=>[r.id,r]));for(const r of t)n.set(r.id,r);return[...n.values()].sort((r,a)=>a.timestamp-r.timestamp)}function Ij(){const{activeTeam:e,groupId:t}=He(),n=(e==null?void 0:e.isAdmin)===!0,[r,a]=d.useState("mine"),[i,o]=d.useState([]),[c,l]=d.useState([]),[u,f]=d.useState(""),[m,h]=d.useState(!0),[w,j]=d.useState({}),[v,S]=d.useState(new Set),[g,p]=d.useState(""),[y,x]=d.useState(new Set),[k,N]=d.useState(new Set),[C,A]=d.useState("all"),[T,_]=d.useState(!1),[D,L]=d.useState(!1),[q,M]=d.useState(null),[X,re]=d.useState({}),[se,$]=d.useState(!1),[R,O]=d.useState({}),[P,z]=d.useState({}),[H,Q]=d.useState(null),[ee,oe]=d.useState(null),[de,fe]=d.useState(!1),[J,he]=d.useState(!1),te=d.useRef(""),ie=d.useCallback(b=>r==="team"&&n&&t?E.listTeamReceiptsPage(t,{before:b,limit:200}):E.getMyReceiptsPage({before:b,limit:200}),[r,n,t]),I=d.useCallback(()=>{const b=r==="team"?`team:${t}`:"mine",B=te.current!==b;te.current=b,h(!0),he(!1),ie().then(V=>{o(ne=>B?V.receipts:Ed(ne,V.receipts)),oe(ne=>B?V.nextBefore:ne??V.nextBefore)}).catch(()=>{B&&o([]),he(!0)}).finally(()=>h(!1))},[ie,r,t]),G=d.useCallback(()=>{!ee||de||(fe(!0),he(!1),ie(ee).then(b=>{o(B=>Ed(B,b.receipts)),oe(b.nextBefore)}).catch(()=>he(!0)).finally(()=>fe(!1)))},[ee,de,ie]);Tt(I,12e4),d.useEffect(()=>{E.getIntegrationManifests().then(({manifests:b})=>l(b)).catch(()=>{}),fetch("/health").then(b=>b.json()).then(b=>{typeof b.spUrl=="string"&&f(b.spUrl.replace(/\/$/,""))}).catch(()=>{})},[]),d.useEffect(()=>{E.getLocalAuthorizations().then(({authorizations:b,signatures:B})=>{re(b),O(B),$(!1)}).catch(()=>{re({}),O({}),$(!0)}),E.getMyAttestations().then(b=>{const B={};for(const V of b)V.authorization_id&&V.title&&(B[V.authorization_id]=V.title);z(B)}).catch(()=>{})},[]),d.useEffect(()=>{r!=="team"||Object.keys(w).length>0||E.listUsers().then(b=>{const B={};for(const V of b)B[V.id]={name:V.name,email:V.email};j(B)}).catch(()=>{})},[r,w]);const ae=d.useMemo(()=>{const b=new Set;for(const B of i)b.add(Le(B.profileId));return[...b].sort()},[i]),ye=d.useMemo(()=>{const b=new Set;for(const B of i)b.add(B.action);return[...b].sort()},[i]),me=d.useMemo(()=>{if(r!=="team")return[];const b=new Set;for(const B of i)B.userId&&b.add(B.userId);return[...b].map(B=>{var V;return{id:B,label:(V=w[B])!=null&&V.name?`${w[B].name} (${w[B].email})`:B}}).sort((B,V)=>B.label.localeCompare(V.label))},[r,i,w]),ze=d.useMemo(()=>i.filter(b=>!(!Tj(b,g)||y.size>0&&!y.has(Le(b.profileId))||k.size>0&&!k.has(b.action)||v.size>0&&b.userId&&!v.has(b.userId)||!Ej(b,C))),[i,g,y,k,v,C]),kt=y.size>0||k.size>0||v.size>0||C!=="all";function Ve(b){x(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function et(b){N(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function mt(b){S(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function at(){x(new Set),N(new Set),S(new Set),A("all"),p("")}async function le(){L(!0),M(null);try{const{bundle:b,filename:B}=await E.fetchEvidenceBundle(),V=URL.createObjectURL(new Blob([JSON.stringify(b,null,2)],{type:"application/json"})),ne=document.createElement("a");ne.href=V,ne.download=B,ne.click(),URL.revokeObjectURL(V);const W=b.sources??{};W.authorityServer?W.local||M(`Downloaded Authority Server history only — ${W.localError??"local archive unavailable."}`):M(`Downloaded local evidence only — ${W.asError??"Authority Server export unavailable."}`)}catch(b){M(`Export failed: ${b instanceof Error?b.message:String(b)}`)}finally{L(!1)}}return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("h1",{className:"page-title",children:"Tickets"}),s.jsx("p",{className:"page-subtitle",children:"Execution history for agent actions."})]}),s.jsx("button",{className:"btn btn-secondary",onClick:le,disabled:D,children:D?"Preparing…":"Download evidence"})]}),q&&s.jsx("div",{style:{marginBottom:"1rem",color:"var(--text-tertiary)",fontSize:"0.875rem"},children:q}),n&&s.jsx("div",{style:{display:"flex",gap:"0.5rem",marginBottom:"1rem",borderBottom:"1px solid var(--border)"},children:["mine","team"].map(b=>s.jsx("button",{onClick:()=>a(b),className:"btn btn-ghost",style:{borderRadius:0,padding:"0.5rem 0.875rem",borderBottom:r===b?"2px solid var(--accent)":"2px solid transparent",color:r===b?"var(--text-primary)":"var(--text-tertiary)",fontWeight:r===b?600:500},children:b==="mine"?"Mine":"Team"},b))}),s.jsxs("div",{className:"search-filter-bar",children:[s.jsxs("div",{className:"search-input-wrap",children:[s.jsx("span",{className:"search-icon",children:"⌕"}),s.jsx("input",{type:"text",className:"form-input search-input",placeholder:"Search by profile, action, path, or hash\\u2026",value:g,onChange:b=>p(b.target.value)}),g&&s.jsx("button",{className:"search-clear",onClick:()=>p(""),children:"×"})]}),s.jsxs("button",{className:`btn btn-sm btn-secondary${T?" active":""}`,onClick:()=>_(!T),children:["Filters",kt?` (${y.size+k.size+(C!=="all"?1:0)})`:""]})]}),T&&s.jsxs("div",{className:"filter-panel",children:[ae.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Profile"}),s.jsx("div",{className:"filter-chips",children:ae.map(b=>s.jsx("button",{className:`filter-chip${y.has(b)?" selected":""}`,onClick:()=>Ve(b),children:b},b))})]}),ye.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Action"}),s.jsx("div",{className:"filter-chips",children:ye.map(b=>s.jsx("button",{className:`filter-chip${k.has(b)?" selected":""}`,onClick:()=>et(b),children:b},b))})]}),r==="team"&&me.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Owner"}),s.jsx("div",{className:"filter-chips",children:me.map(b=>s.jsx("button",{className:`filter-chip${v.has(b.id)?" selected":""}`,onClick:()=>mt(b.id),children:b.label},b.id))})]}),s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Time range"}),s.jsx("div",{className:"filter-chips",children:[["1d","Today"],["7d","7 days"],["30d","30 days"],["all","All time"]].map(([b,B])=>s.jsx("button",{className:`filter-chip${C===b?" selected":""}`,onClick:()=>A(b),children:B},b))})]})]}),kt&&s.jsxs("div",{className:"active-filters",children:[[...y].map(b=>s.jsxs("span",{className:"active-chip",onClick:()=>Ve(b),children:[b," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)),[...k].map(b=>s.jsxs("span",{className:"active-chip",onClick:()=>et(b),children:[b," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)),[...v].map(b=>{const B=w[b],V=B?B.name:b;return s.jsxs("span",{className:"active-chip",onClick:()=>mt(b),children:[V," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)}),C!=="all"&&s.jsxs("span",{className:"active-chip",onClick:()=>A("all"),children:[C==="1d"?"Today":C==="7d"?"7 days":"30 days"," ",s.jsx("span",{className:"chip-remove",children:"×"})]}),s.jsx("button",{className:"clear-filters",onClick:at,children:"Clear all"})]}),J&&s.jsx("div",{className:"card",style:{borderColor:"var(--danger, #c0392b)",marginBottom:"0.75rem"},children:s.jsx("span",{style:{color:"var(--danger, #c0392b)",fontSize:"0.85rem"},children:"Couldn’t load tickets — your session may have expired. Try signing out and back in."})}),m&&i.length===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):ze.length===0?s.jsx(Ir,{icon:"⌕",title:i.length===0?"No tickets in the last 30 days":"No matching tickets",text:i.length===0?"Tickets appear here after an agent uses an authorized tool. Older tickets can be loaded below.":"Try adjusting your search or filters."}):s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.75rem"},children:ze.length===i.length?`${i.length} ticket${i.length!==1?"s":""}`:`${ze.length} of ${i.length} tickets`}),s.jsx("div",{className:"timeline",children:ze.map(b=>{const B=b.userId?w[b.userId]:void 0;return s.jsx("div",{className:"timeline-event",children:s.jsx(bj,{receipt:b,manifests:c,localAuth:b.authorizationId?X[b.authorizationId]:void 0,localUnavailable:se,signature:R[b.id],grantTitle:b.authorizationId?P[b.authorizationId]:null,ownerLabel:r==="team"&&b.userId?B?`${B.name} (${B.email})`:b.userId:null,spUrl:u,formatDate:Cj,onOpenComplete:()=>Q(b)})},b.id)})})]}),H&&s.jsx(Nj,{receipt:H,onClose:()=>Q(null)}),ee&&s.jsx("div",{style:{textAlign:"center",marginTop:"1rem"},children:s.jsx("button",{className:"btn btn-secondary btn-sm",onClick:G,disabled:de,children:de?"Loading…":"Load older"})})]})}function Rj(){const[e,t]=d.useState(null),[n,r]=d.useState({}),[a,i]=d.useState(!1),o=d.useCallback(()=>{E.getDenials({limit:200}).then(({records:l})=>{t(l),i(!1)}).catch(()=>i(!0))},[]);if(d.useEffect(()=>{o()},[o]),Tt(o,6e4),d.useEffect(()=>{if(!e)return;const l=[...new Set(e.map(u=>u.profile).filter(u=>!!u))].filter(u=>!(u in n));l.length!==0&&Promise.all(l.map(u=>E.getProfile(u).catch(()=>null))).then(u=>{r(f=>{const m={...f};return l.forEach((h,w)=>{u[w]&&(m[h]=u[w])}),m})})},[e,n]),a)return s.jsx(Ir,{icon:"⛔",title:"Could not load blocked actions",text:"Try again shortly."});if(e===null)return null;const c=Im(e,Date.now());return s.jsxs("div",{className:"blocked-page",children:[s.jsxs("div",{className:"page-header blocked-header",children:[s.jsx("h1",{className:"page-title",children:"Blocked actions"}),s.jsxs("span",{className:"blocked-today",children:[c," today · nothing ran"]})]}),e.length===0?s.jsx(Ir,{icon:"✓",title:"Nothing blocked",text:"Every call your agent made stayed within its mandate."}):s.jsx("div",{className:"blocked-list",children:e.map((l,u)=>{const f=Qx(l,l.profile?n[l.profile]:void 0);return s.jsxs("div",{className:"blocked-row","data-kind":Is(l),children:[s.jsx("span",{className:`blocked-dot blocked-dot-${Is(l)}`,"aria-hidden":"true"}),s.jsxs("div",{className:"blocked-row-main",children:[s.jsx("div",{className:"blocked-title",children:f.title}),s.jsx("div",{className:"blocked-sentence",children:f.sentence}),s.jsx("div",{className:"blocked-source",children:f.sourceLine}),s.jsxs("details",{children:[s.jsx("summary",{children:"What you can do"}),s.jsx("div",{className:"blocked-advice",children:f.whatYouCanDo})]})]}),s.jsx("div",{className:"blocked-when",children:new Date(l.ts).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})})]},`${l.ts}-${u}`)})})]})}const Aj={darwin:"a macOS login item",win32:"a Windows scheduled task",linux:"a systemd user service"};function Pj(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{t(await E.getAutostart())}catch(u){i(u instanceof Error?u.message:"Could not read autostart state")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(!(e!=null&&e.supported)||n)){r(!0),i(null);try{await E.setAutostart(!e.installed)}catch(u){i(u instanceof Error?u.message:"Failed")}finally{try{t(await E.getAutostart()),i(null)}catch(u){i(u instanceof Error?u.message:"Could not re-read state")}r(!1)}}},[e,n,o]);if(!e)return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Keep Suveren running"}),s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read autostart state: ${a}`:"Checking…"})]});const l=Aj[e.platform]??"a login service";return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Keep Suveren running"}),s.jsx("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:e.supported?s.jsxs(s.Fragment,{children:["Starts automatically when you log in, and restarts if it crashes. Uses ",l," — no admin rights needed."]}):e.reason})]}),e.supported&&s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e.installed,className:e.installed?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Working…":e.installed?"Turn off":"Turn on"})]}),e.supported&&s.jsxs("p",{style:{margin:"1rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:["Status: ",s.jsx("strong",{children:e.installed?"On — starts from your next login":"Off"})]}),e.supported&&s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:["Turning this on doesn't interrupt the gateway you're using — it takes effect at your next login. After any restart Suveren comes back ",s.jsx("strong",{children:"locked"}),": you enter your API key once to unlock it, because nothing stored on this machine can unlock it for you."]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger, #c00)"},children:a})]})}function _j(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{const l=await E.getGatewaySettings();t(l.desktopNotifications),i(null)}catch(l){i(l instanceof Error?l.message:"Could not read notification setting")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(e===null||n)){r(!0),i(null);try{const l=await E.setGatewaySettings({desktopNotifications:!e});t(l.desktopNotifications)}catch(l){i(l instanceof Error?l.message:"Failed to save"),await o()}finally{r(!1)}}},[e,n,o]);return e===null?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Desktop notifications"}),s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read the setting: ${a}`:"Checking…"})]}):s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Desktop notifications"}),s.jsx("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:"Tells you something is waiting for review — never what it is, and never with an approve button. Open Suveren to see and decide. At most one notification a minute; the browser tab always shows the count."})]}),s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e,className:e?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Saving…":e?"Turn off":"Turn on"})]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger)"},children:a})]})}const Td={as_vouched:"verified by",eudi:"verified with an EU digital identity (EUDI)"};function $j(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{t(await E.getIdentityDisclosure()),i(null)}catch(f){i(f instanceof Error?f.message:"Could not read the setting")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(!e||n)){r(!0),i(null);try{t(await E.setIdentityDisclosure(!e.always))}catch(f){i(f instanceof Error?f.message:"Failed to save"),await o()}finally{r(!1)}}},[e,n,o]),l=s.jsx("h3",{className:"card-title",style:{margin:0},children:"Your name on mandates and tickets"});if(!e)return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},children:[l,s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read the setting: ${a}`:"Checking…"})]});const u=e.verified&&e.name?`${e.name} — ${e.method==="as_vouched"?`${Td.as_vouched} ${e.verifier}`:Td[e.method??""]??e.method}`:null;return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[l,s.jsxs("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:[e.always?"On: your verified name is attached to every mandate you give — including ones the setup AI proposes and you approve — and to the tickets under them.":"Off: each mandate asks whether to show your name. Mandates the setup AI proposes carry no name."," ","Mandates already given stay as they are."]}),s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:u?`Your identity: ${u}.`:"Your identity is not verified yet — no name can be shown until it is."})]}),s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e.always,className:e.always?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Saving…":e.always?"Turn off":"Always show my name"})]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger)"},children:a})]})}const Lj={npm:"Checking npm for new releases",docker:"Checking the container registry for new images",dev:"Git checkout — comparing against origin/main, not npm releases",managed:"Checking npm for new releases — managed by your IT",msi:"Checking for new releases — update with the Windows installer"};function zj(){const{version:e,latestVersion:t,updateAvailable:n,installMethod:r}=jc();return e?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Version"}),s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:["Running ",s.jsx("strong",{children:e}),n&&t?s.jsxs(s.Fragment,{children:[" — ",s.jsx("strong",{children:t})," is available"]}):null]}),s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:[Lj[r]??"Update checking is unavailable",r==="dev"&&s.jsx(s.Fragment,{children:" — a development checkout is not told about published releases."})]})]}):null}function hl({title:e}){return s.jsxs("span",{className:"it-locked-badge",title:e,children:[s.jsx("span",{className:"lock-icon","aria-hidden":"true",children:"🔒"})," Set by your IT"]})}function Id(e){return e===!0}function Fj(){const[e,t]=d.useState(null),[n,r]=d.useState(null);d.useEffect(()=>{let o=!1;return E.getAsPairing().then(c=>{o||t(c)}).catch(c=>{o||r(c instanceof Error?c.message:"Could not read Authority Server info")}),()=>{o=!0}},[]);const a=Id(e==null?void 0:e.asUrlLockedByPolicy),i=Id(e==null?void 0:e.pinTlsLockedByPolicy);return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Authority Server"}),a&&s.jsx(hl,{})]}),!e&&!n&&s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:"Checking…"}),n&&s.jsx("p",{role:"alert",style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--danger, #c00)"},children:n}),e&&s.jsxs(s.Fragment,{children:[s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"URL:"})," ",s.jsx("code",{children:e.asUrl})]}),e.paired&&e.fingerprint?s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"Key fingerprint:"})," ",s.jsx("code",{children:e.fingerprint}),s.jsx("br",{}),s.jsx("span",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Compare this with the fingerprint on the Authority Server's own admin page over a second channel (phone, video call) to confirm this gateway is talking to the right server."})]}):s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:"Not yet paired — sign in once to pin this server's key."}),(e.tlsPinFingerprint||e.pinTlsEnabled)&&s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"TLS certificate pin:"})," ",i&&s.jsx(hl,{title:"TLS pinning is set by your IT policy"})," ",e.tlsPinFingerprint?s.jsx("code",{children:e.tlsPinFingerprint}):s.jsxs("span",{style:{color:"var(--text-tertiary)"},children:["not yet captured — this URL has no recorded pairing over TLS",e.pinTlsEnabled?"; sign in to establish one (re-pairing required)":""]}),s.jsx("br",{}),s.jsxs("span",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:[e.pinTlsEnabled?s.jsxs(s.Fragment,{children:["TLS pinning is ON",i?s.jsx(s.Fragment,{children:", set by your organization's IT policy"}):s.jsxs(s.Fragment,{children:[" (",s.jsx("code",{children:"config set pin-tls on"}),")"]}),". Every connection to the Authority Server must present this certificate's public key, or the gateway refuses it and locks."]}):s.jsxs(s.Fragment,{children:["Captured at sign-in; not currently enforced",i?s.jsx(s.Fragment,{children:" — controlled by your organization's IT policy on this computer"}):s.jsxs(s.Fragment,{children:[" (",s.jsx("code",{children:"config set pin-tls on"})," to require it on every connection)"]}),"."]})," ","A certificate renewal with the SAME key keeps this pin; a NEW key needs re-pairing."]})]}),a?s.jsx("p",{style:{margin:"0.75rem 0 0",fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"This Authority Server URL is set by your organization's IT policy and cannot be changed from this computer. Contact your IT administrator if it needs to change."}):s.jsxs("p",{style:{margin:"0.75rem 0 0",fontSize:"0.8rem",color:"var(--text-tertiary)"},children:["To point this gateway at a different Authority Server:"," ",s.jsx("code",{children:"suveren-gateway config set as-url <url>"}),", then restart. Changing it ends the current sign-in and clears cached mandates — you sign in again against the new server."]})]})]})}function Mj(){const{simulation:e,locked:t}=Om();return t?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Simulation mode"}),s.jsxs("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:['Blocks every real connector without a manifest "simulation" marker.',e!==null&&s.jsxs(s.Fragment,{children:[" ","Currently ",s.jsx("strong",{children:e?"ON":"OFF"}),e?" — real systems are not reachable from this gateway.":"."]})]})]}),s.jsx(hl,{})]}),s.jsxs("p",{style:{margin:"1rem 0 0",fontSize:"0.78rem",color:"var(--text-tertiary)"},children:["Simulation mode is set by your organization's IT policy",e!==null?` (currently ${e?"on":"off"})`:""," and cannot be changed from this computer — not even from the command line."]})]}):null}const Oj={ollama:{provider:"ollama",endpoint:"http://localhost:11434",models:["gemma4:e4b","gemma4:e2b","gemma4:26b","gemma4:31b","llama3.2","llama3.1","mistral","qwen2.5"]},openrouter:{provider:"openai-compatible",endpoint:"https://openrouter.ai/api/v1",models:["google/gemma-4-31b-it","qwen/qwen3.6-plus:free","stepfun/step-3.5-flash:free","google/gemini-2.5-flash","openai/gpt-4o-mini","anthropic/claude-haiku-4"]},openai:{provider:"openai-compatible",endpoint:"https://api.openai.com/v1",models:["gpt-4o-mini","gpt-4o","o3-mini"]},groq:{provider:"openai-compatible",endpoint:"https://api.groq.com/openai/v1",models:["llama-3.1-8b-instant","llama-3.3-70b-versatile","gemma2-9b-it"]},together:{provider:"openai-compatible",endpoint:"https://api.together.xyz/v1",models:["meta-llama/Llama-3-8b-chat-hf","meta-llama/Llama-3-70b-chat-hf"]}},Kr=["AI Assistant","Authority Server","This computer","Security","Version"],Yr={fontSize:"1rem",fontWeight:700,marginBottom:"1rem"};function Dj(){const[e,t]=d.useState(""),[n,r]=d.useState("openrouter"),[a,i]=d.useState("openai-compatible"),[o,c]=d.useState("https://openrouter.ai/api/v1"),[l,u]=d.useState("google/gemma-4-31b-it"),[f,m]=d.useState(""),[h,w]=d.useState(!1),[j,v]=d.useState(!1),[S,g]=d.useState(!1),[p,y]=d.useState(null),[x,k]=d.useState([]),[N,C]=d.useState(!1),[A,T]=d.useState(null),[_,D]=d.useState(""),L=d.useCallback(R=>{t(R),setTimeout(()=>t(""),3e3)},[]),q=d.useCallback(async(R,O,P)=>{C(!0),T(null);try{const z=await E.aiModels({provider:R,endpoint:O,...P?{apiKey:P}:{}});z.ok&&z.models.length>0?(k(z.models),T(`${z.models.length} models available`)):(k([]),T(z.message||"No models returned — using defaults"))}catch(z){k([]),T(z instanceof Error?z.message:"Failed to load models")}finally{C(!1)}},[]),M=d.useCallback(async()=>{try{const R=await E.getCredential("ai-config");if(w(R.configured),R.configured&&R.fields){const O=R.fields.provider||"openai-compatible",P=R.fields.endpoint||"";R.fields.provider&&i(O),R.fields.endpoint&&c(P),R.fields.model&&u(R.fields.model),P.includes("openai.com")?r("openai"):P.includes("groq.com")?r("groq"):P.includes("together.xyz")?r("together"):P.includes("openrouter.ai")?r("openrouter"):r("ollama"),P&&q(O,P)}}catch{}},[q]);d.useEffect(()=>{M()},[M]);const X=R=>{r(R),k([]),T(null),D("");const O=Oj[R];O&&(i(O.provider),c(O.endpoint),u(""),q(O.provider,O.endpoint,f||void 0))},re=()=>q(a,o,f||void 0),se=async()=>{v(!0);try{await E.setCredential("ai-config",{provider:a,endpoint:o,model:l,...f?{apiKey:f}:{}}),w(!0),L("AI configuration saved!")}catch{L("Failed to save AI config")}finally{v(!1)}},$=async()=>{g(!0),y(null);try{const R=await E.aiTest({provider:a,endpoint:o,model:l,...f?{apiKey:f}:{}});y(R.ok?`OK: ${R.message}`:`Failed: ${R.message}`)}catch(R){y(`Error: ${R instanceof Error?R.message:"Unknown"}`)}finally{g(!1)}};return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",children:[s.jsx("h1",{className:"page-title",children:"Settings"}),s.jsx("p",{className:"page-subtitle",children:"Your AI assistant, the connection to your Authority Server, security and version."})]}),e&&s.jsx("div",{className:"alert alert-success",children:e}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[0]}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",marginBottom:"1rem"},children:"Advisory AI to help you think through intent when giving mandates."}),s.jsxs("div",{className:"card",children:[s.jsx("h3",{className:"card-title",children:"Configuration"}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",marginBottom:"1rem"},children:"Connect a trusted AI model that has access to your intent — problem, objective, and tradeoffs — to help you think through mandates. Keys are encrypted in your vault."}),h&&s.jsxs("div",{className:"status-banner status-banner-success",style:{marginBottom:"1rem",fontSize:"0.8rem"},children:[s.jsx("span",{className:"status-banner-icon",children:"✓"}),s.jsx("span",{className:"status-banner-text",children:"AI configured"})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsx("label",{className:"form-label",children:"Provider Preset"}),s.jsxs("select",{className:"form-input",value:n,onChange:R=>X(R.target.value),children:[s.jsx("option",{value:"openrouter",children:"OpenRouter (recommended)"}),s.jsx("option",{value:"ollama",children:"Ollama (local)"}),s.jsx("option",{value:"openai",children:"OpenAI"}),s.jsx("option",{value:"groq",children:"Groq"}),s.jsx("option",{value:"together",children:"Together"})]})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsxs("label",{className:"form-label",children:["API Key ",a==="ollama"?"(not needed for Ollama)":"(required to load models)"]}),s.jsx("input",{className:"form-input",type:"password",name:"ai-provider-api-key-credential-top",autoComplete:"new-password",value:f,onChange:R=>m(R.target.value),onBlur:()=>{f.trim()&&q(a,o,f.trim())},placeholder:h?"••••••••••••••••":"sk-... (not needed for Ollama)"}),s.jsx("p",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",margin:"0.375rem 0 0"},children:"Each provider uses its own key — paste it and the model list loads automatically."})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[s.jsx("label",{className:"form-label",children:"Model"}),s.jsx("button",{type:"button",className:"btn btn-ghost",style:{fontSize:"0.75rem",padding:"0.125rem 0.5rem"},onClick:re,disabled:N,title:"Re-fetch the model list from the provider",children:N?"Loading…":"↻ Refresh"})]}),x.length===0?s.jsx("div",{className:"form-input",style:{display:"flex",alignItems:"center",minHeight:"2.5rem",color:"var(--text-secondary)",fontSize:"0.85rem"},children:N?"Loading models…":a==="ollama"?"Start Ollama locally, then ↻ Refresh to load models.":"Enter a valid API key above to load available models."}):(()=>{const R=x,O=R.includes(l),P=R.length>12,z=_.trim().toLowerCase();let H=z?R.filter(Q=>Q.toLowerCase().includes(z)):R;return O&&!H.includes(l)&&(H=[l,...H]),s.jsxs(s.Fragment,{children:[P&&s.jsx("input",{className:"form-input",value:_,onChange:Q=>D(Q.target.value),placeholder:"Filter models… (e.g. kimi)",style:{marginBottom:"0.375rem"}}),s.jsxs("select",{className:"form-input",value:O?l:"__unset__",onChange:Q=>u(Q.target.value==="__unset__"?"":Q.target.value),children:[s.jsx("option",{value:"__unset__",disabled:!0,children:"Select a model…"}),H.map(Q=>s.jsx("option",{value:Q,children:Q},Q)),z&&H.length===0&&s.jsxs("option",{value:"__unset__",disabled:!0,children:["No models match “",_,"”"]})]})]})})(),A&&s.jsx("p",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",margin:"0.375rem 0 0"},children:A})]}),s.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[s.jsx("button",{className:"btn btn-primary",onClick:se,disabled:j||!l.trim(),title:l.trim()?void 0:"Select a model first",children:j?"Saving...":"Save & Encrypt"}),h&&s.jsx("button",{className:"btn btn-ghost",onClick:$,disabled:S,children:S?"Testing...":"Test Connection"})]}),p&&s.jsx("div",{className:`alert ${p.startsWith("OK")?"alert-success":"alert-error"}`,style:{marginTop:"0.75rem"},children:p})]}),s.jsx(Bj,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[1]}),s.jsx(Fj,{}),s.jsx($j,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[2]}),s.jsx(Pj,{}),s.jsx(_j,{}),s.jsx(Mj,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[3]}),s.jsx("div",{className:"card",style:{padding:"1.5rem"},children:s.jsxs("div",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",lineHeight:1.7},children:[s.jsxs("div",{style:{marginBottom:"1rem"},children:[s.jsx("div",{style:{fontWeight:600,color:"var(--text-primary)",marginBottom:"0.375rem"},children:"What the gateway protects"}),s.jsxs("ul",{style:{margin:0,paddingLeft:"1.25rem"},children:[s.jsx("li",{children:"Every tool call verified against your mandate bounds"}),s.jsx("li",{children:"Credentials never exposed to agents through MCP"}),s.jsx("li",{children:"Every action produces a signed ticket"})]})]}),s.jsxs("div",{children:[s.jsx("div",{style:{fontWeight:600,color:"var(--text-primary)",marginBottom:"0.375rem"},children:"Your responsibility"}),s.jsxs("ul",{style:{margin:0,paddingLeft:"1.25rem"},children:[s.jsx("li",{children:"If your AI agent has full access to your computer, it could bypass the gateway"}),s.jsx("li",{children:"For best security, run agents in sandboxed environments"}),s.jsx("li",{children:"The gateway secures what agents do through tools — not what they do on your machine"})]})]})]})})]}),s.jsxs("section",{children:[s.jsx("h2",{style:Yr,children:Kr[4]}),s.jsx(zj,{})]})]})}function Bj(){const[e,t]=d.useState(null),[n,r]=d.useState({intent:"",context:""}),[a,i]=d.useState(null),[o,c]=d.useState(null),[l,u]=d.useState(null),[f,m]=d.useState(!1),h=d.useCallback(async()=>{if(!f)try{const v=await E.getAIPrompts();t(v),r({intent:v.intent.current,context:v.context.current}),m(!0)}catch(v){c(v instanceof Error?v.message:"Failed to load prompts")}},[f]),w=async v=>{if(e){i(v),c(null);try{const S=n[v],g=S.trim()===e[v].default.trim()?"":S;await E.setAIPrompt(v,g);const p=await E.getAIPrompts();t(p),r({intent:p.intent.current,context:p.context.current}),u(v),setTimeout(()=>u(null),2e3)}catch(S){c(S instanceof Error?S.message:"Save failed")}finally{i(null)}}},j=async v=>{if(confirm(`Revert ${v} prompt to the built-in default?`)){i(v),c(null);try{await E.setAIPrompt(v,"");const S=await E.getAIPrompts();t(S),r({intent:S.intent.current,context:S.context.current})}catch(S){c(S instanceof Error?S.message:"Revert failed")}finally{i(null)}}};return s.jsxs("details",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},onToggle:v=>{v.currentTarget.open&&h()},children:[s.jsx("summary",{style:{fontSize:"1rem",fontWeight:700,cursor:"pointer",listStyle:"revert",userSelect:"none"},children:"Advanced — AI assistant prompts"}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",margin:"0.75rem 0 1rem 0",lineHeight:1.55},children:"These are the system prompts the AI assistant sees when helping you write Intent (per-mandate) or Context (your standing-orders brief). Edit with care — changes apply on the next chat turn."}),o&&s.jsx("div",{className:"alert alert-error",style:{marginBottom:"0.75rem"},children:o}),!f&&!o&&s.jsx("p",{style:{color:"var(--text-muted)",fontSize:"0.85rem"},children:"Loading prompts…"}),e&&s.jsxs(s.Fragment,{children:[s.jsx(Rd,{kind:"intent",label:"Intent — per-mandate",description:"Used on the Intent gate when creating a new mandate.",state:e.intent,draft:n.intent,onChange:v=>r(S=>({...S,intent:v})),onSave:()=>w("intent"),onRevert:()=>j("intent"),saving:a==="intent",justSaved:l==="intent"}),s.jsx(Rd,{kind:"context",label:"Context — standing-orders brief",description:"Used on the Brief page when refining your context.md.",state:e.context,draft:n.context,onChange:v=>r(S=>({...S,context:v})),onSave:()=>w("context"),onRevert:()=>j("context"),saving:a==="context",justSaved:l==="context"})]})]})}function Rd({kind:e,label:t,description:n,state:r,draft:a,onChange:i,onSave:o,onRevert:c,saving:l,justSaved:u}){const f=a!==r.current;return s.jsxs("section",{style:{marginBottom:"1.5rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:"0.25rem",gap:"1rem",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{style:{fontWeight:600,fontSize:"0.9rem"},children:t}),s.jsx("div",{style:{fontSize:"0.78rem",color:"var(--text-secondary)"},children:n})]}),r.overridden&&s.jsx("span",{style:{fontSize:"0.7rem",color:"var(--accent)",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Custom"})]}),s.jsx("textarea",{className:"form-textarea",value:a,onChange:m=>i(m.target.value),rows:12,spellCheck:!1,style:{width:"100%",fontFamily:"'SF Mono', Monaco, 'Cascadia Code', monospace",fontSize:"0.82rem",lineHeight:1.55,resize:"vertical",minHeight:"14rem",marginTop:"0.5rem"},"aria-label":`${t} system prompt`}),s.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center",marginTop:"0.5rem",flexWrap:"wrap"},children:[s.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:o,disabled:l||!f,children:l?"Saving…":"Save"}),r.overridden&&s.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:c,disabled:l,title:"Discard the override and use the built-in default",children:"Revert to default"}),u&&s.jsx("span",{style:{fontSize:"0.78rem",color:"var(--success)"},children:"Saved"}),f&&!l&&!u&&s.jsx("span",{style:{fontSize:"0.78rem",color:"var(--text-muted)"},children:"Unsaved changes"})]}),s.jsxs("details",{style:{marginTop:"0.5rem"},children:[s.jsx("summary",{style:{fontSize:"0.78rem",color:"var(--text-muted)",cursor:"pointer"},children:"Show built-in default"}),s.jsx("pre",{style:{marginTop:"0.5rem",padding:"0.75rem 1rem",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.5rem",fontSize:"0.78rem",lineHeight:1.55,whiteSpace:"pre-wrap",maxHeight:"20rem",overflowY:"auto"},children:r.default})]}),s.jsx("span",{style:{display:"none"},children:e})]})}function Uj(e){return e.proposalId?"review":"automatic"}function Ad(e,t,n={}){const r=n.status??"pending",a=n.includeAutonomous??!1,i=[];for(const o of e)r==="pending"&&o.status!=="pending"||n.profile&&o.profileId!==n.profile||i.push({kind:"proposal",id:o.id,sortTimestamp:o.createdAt,commitmentMode:"review",profileId:o.profileId,proposal:o});if(r==="all")for(const o of t){const c=Uj(o);!a&&c==="automatic"||n.profile&&o.profileId!==n.profile||i.push({kind:"receipt",id:o.id,sortTimestamp:o.timestamp,commitmentMode:c,profileId:o.profileId,receipt:o})}return i.sort((o,c)=>c.sortTimestamp-o.sortTimestamp),typeof n.limit=="number"&&n.limit>0?i.slice(0,n.limit):i}const Wj=["https://","http://"];function tp(e,t){return e!=null&&e.length?e.flatMap(n=>{const r=n.template.replace(/\{(\w+)\}/g,(a,i)=>{const o=t[i];return typeof o=="string"||typeof o=="number"?String(o):"\0"});return r.includes("\0")||/\{|\}/.test(r)?[]:Wj.some(a=>r.toLowerCase().startsWith(a))?[{label:n.label,href:r,description:n.description}]:[]}):[]}function np(e,t){const n=e-Math.floor(t/1e3);if(n<=0)return{label:"expired",urgent:!1,expired:!0};const r=Math.floor(n/86400),a=Math.floor(n%86400/3600),i=Math.floor(n%3600/60);let o;return r>0?o=`expires in ${r}d ${a}h`:a>0?o=`expires in ${a}h ${i}m`:o=`expires in ${Math.max(1,i)}m`,{label:o,urgent:n<2*3600,expired:!1}}const Hj=/^(image|img|photo|picture|thumbnail)(_?url)?$/i;function Vj(e,t){return typeof t!="string"?!1:/^data:image\//i.test(t)?!0:Hj.test(e)?/^https?:\/\//.test(t):/^https?:\/\/.+\.(jpe?g|png|gif|webp|svg|avif)(\?|$)/i.test(t)}function er(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);try{return JSON.stringify(e,null,2)}catch{return String(e)}}function Pd({row:e,which:t}){const n=Ds(e.profileRef),r=aj(e.value,n,t);return r.length===0?s.jsx("span",{style:{color:"var(--text-tertiary)"},children:"none"}):s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.15rem 0.75rem",margin:0},children:r.map(a=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-secondary)"},title:a.hint,children:a.label}),s.jsxs("dd",{style:{margin:0,fontWeight:600},children:[a.value,a.unknown&&s.jsx("span",{style:{color:"var(--danger)",fontWeight:400,marginLeft:"0.5rem"},children:"not defined by this profile"})]})]},a.key))})}function Gj({row:e}){const t=Ds(e.profileRef),n=(t==null?void 0:t.id)??e.profileRef??"";return s.jsxs(s.Fragment,{children:[(t==null?void 0:t.name)??Le(n),s.jsx("div",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:n})]})}function Kj({row:e,altText:t}){switch(e.kind){case"profile":return s.jsx(Gj,{row:e});case"profile-limits":return s.jsx(Pd,{row:e,which:"limits"});case"profile-scope":return s.jsx(Pd,{row:e,which:"scope"});case"markdown":return s.jsx("div",{style:{whiteSpace:"pre-wrap",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.375rem",padding:"0.5rem 0.625rem"},children:er(e.value)});case"list":return Array.isArray(e.value)?s.jsx("ul",{style:{margin:0,paddingLeft:"1.1rem"},children:e.value.map((n,r)=>s.jsx("li",{children:er(n)},r))}):s.jsx(s.Fragment,{children:er(e.value)});case"money":return s.jsxs(s.Fragment,{children:[er(e.value),e.currency?` ${e.currency}`:""]});case"object":return s.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",fontSize:"0.8rem"},children:er(e.value)});default:return Vj(e.key,e.value)?s.jsx("img",{src:e.value,alt:t??e.key,style:{display:"block",maxWidth:"100%",maxHeight:"240px",borderRadius:"0.375rem",border:"1px solid var(--border)"}}):s.jsx(s.Fragment,{children:er(e.value)})}}function rp({args:e,display:t,heading:n="Details"}){const r=sj(e,t);if(r.length===0)return null;const a=typeof e.altText=="string"?e.altText:void 0;return s.jsxs("div",{style:{marginBottom:"0.75rem"},children:[n&&s.jsx("div",{style:{fontSize:"0.7rem",fontWeight:600,color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em",marginBottom:"0.35rem"},children:n}),s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.35rem 0.75rem",fontSize:"0.85rem",margin:0},children:r.map(i=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-tertiary)",whiteSpace:"nowrap",alignSelf:"start"},title:i.hint,children:i.label}),s.jsx("dd",{style:{color:"var(--text-primary)",margin:0,wordBreak:"break-word",whiteSpace:"pre-wrap"},children:s.jsx(Kj,{row:i,altText:a})})]},i.key))})]})}const _d=500;function ml(e){return e.length>_d?`${e.slice(0,_d)}…`:e}function $d(e){return e.length?e[0].toUpperCase()+e.slice(1):e}function Yj(e,t){switch(e.status){case"none":return e.reason==="no_target"?{heading:"Nothing to read beforehand",note:`This action does not refer to an existing record — nothing to read beforehand. Showing exactly what will be sent to ${t}.`}:{heading:"No preview declared",note:`No preview declared for this tool — showing exactly what will be sent to ${t}.`};case"unavailable":return e.reason==="no_connector"?{heading:"Preview not available",note:"Preview not available on this gateway."}:{heading:"Preview not available",note:e.message?`Preview not available — ${ml(e.message)}`:"Preview not available."};case"not_found":return{heading:"Not found in your system",note:e.message?`Not found in your system — ${ml(e.message)}`:"Not found in your system."};case"ok":{const n=fl(e.body,{fields:e.fields}),r={heading:`From ${t}, before it runs`,note:`Read by the gateway with ${e.tool} when you opened this card — the AI is not involved.`,rendered:n},a=e.version;if(a&&(r.versionNote=`You approve ${a.field} ${a.approved}; if it changes, ${t} refuses it.`,a.stale)){const i=wj(e.body,a.currentBody,{fields:e.fields,excludeKey:a.field});r.stale={heading:`A newer ${a.field} exists (${a.current})`,approvedLabel:`${$d(a.field)} ${a.approved}`,currentLabel:`${$d(a.field)} ${a.current}`,...i.unchanged?{unchangedNote:"No visible change in the fields."}:{approvedRendered:i.approved,currentRendered:i.current}}}return r}}}function Jj(e,t){if(e.state!=="failed")return null;const n=e.detail?ml(e.detail):void 0;return e.outcome==="changed"?{heading:"Changed since your approval",note:`The record changed in ${t} since you approved it — nothing was done. Ask the AI to request it again.`}:{heading:`Refused by ${t}`,note:`${t} refused it${n?`: ${n}`:""} — nothing was done. Ask the AI to request it again.`}}function Qj({proposalId:e,systemName:t}){const[n,r]=d.useState(null);if(d.useEffect(()=>{let i=!0;return r(null),E.getProposalOutcome(e).then(o=>{i&&r(o)}).catch(()=>{}),()=>{i=!1}},[e]),!n)return null;const a=Jj(n,t);return a?s.jsxs("div",{className:"outcome-box",children:[s.jsx("h4",{children:a.heading}),s.jsx("p",{className:"outcome-note",children:a.note})]}):null}function qj({proposalId:e,systemName:t}){const[n,r]=d.useState(null),[a,i]=d.useState(!1);if(d.useEffect(()=>{let l=!0;return r(null),i(!1),E.getProposalPreview(e).then(u=>{l&&r(u)}).catch(()=>{l&&i(!0)}),()=>{l=!1}},[e]),a)return s.jsxs("div",{className:"preview-box preview-box-unavailable","data-testid":"approval-preview","data-preview-status":"unavailable",children:[s.jsx("h4",{children:"Preview not available"}),s.jsx("p",{className:"preview-note",children:"Preview not available on this gateway."})]});if(!n)return s.jsxs("div",{className:"preview-box preview-box-loading","data-testid":"approval-preview","data-preview-status":"loading","aria-busy":"true",children:["Reading from ",t,"…"]});const o=Yj(n,t),c=n.status==="ok"?o.stale?"stale":"ok":n.status;return s.jsxs("div",{className:`preview-box preview-box-${c}`,"data-testid":"approval-preview","data-preview-status":c,children:[s.jsx("h4",{children:o.heading}),o.rendered&&s.jsx(Ta,{rendered:o.rendered}),s.jsx("p",{className:"preview-note",children:o.note}),o.versionNote&&!o.stale&&s.jsx("p",{className:"preview-note",children:o.versionNote}),o.stale&&s.jsxs("div",{className:"preview-stale",children:[s.jsx("h5",{children:o.stale.heading}),o.stale.unchangedNote?s.jsx("p",{className:"preview-note",children:o.stale.unchangedNote}):s.jsxs("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.3rem 0.75rem",fontSize:"0.85rem",margin:"0.5rem 0 0"},children:[s.jsx("dt",{children:o.stale.approvedLabel}),s.jsx("dd",{children:s.jsx(Ta,{rendered:o.stale.approvedRendered})}),s.jsx("dt",{children:o.stale.currentLabel}),s.jsx("dd",{children:s.jsx(Ta,{rendered:o.stale.currentRendered})})]})]})]})}let oo=null;function Xj(){return oo||(oo=E.getEnrichedAuthorizations().then(e=>new Map(e.map(t=>[t.authorizationId,t.bounds]))).catch(()=>new Map)),oo}function Zj(e){const[t,n]=d.useState(void 0);return d.useEffect(()=>{let r=!0;if(e)return Xj().then(a=>{r&&n(a.get(e))}),()=>{r=!1}},[e]),t}function eS(e,t){const[n,r]=d.useState(null),[a,i]=d.useState(!1),[o,c]=d.useState(null);return d.useEffect(()=>{let l=!0;return r(null),c(null),i(!0),(async()=>{try{const u=await E.getAttestationIntent(e);if(!u){l&&c("Intent not available or you are not an authorized approver.");return}const f=await E.decryptIntent({intentCiphertext:u.intentCiphertext,encryptedKey:u.encryptedKey,approverId:t});l&&r(f)}catch(u){l&&c(u instanceof Error?u.message:"Failed to decrypt intent")}finally{l&&i(!1)}})(),()=>{l=!1}},[e,t]),{intent:n,loading:a,error:o}}function sp(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e))return e.map(t=>sp(t)).join(", ");try{return JSON.stringify(e,null,2)}catch{return String(e)}}function ap({proposal:e,currentUserId:t,proposalLinks:n,toolDisplay:r,manifests:a}){const[i,o]=d.useState(!1),c=Object.entries(e.executionContext),l=Ds(e.profileId),u=Zj(e.authorizationId),f=dj(e.executionContext,u,l),m=tp(n,e.toolArgs),h=nj(e.tool),{integrationId:w}=_c(e.tool),j=Xm(w,a),{intent:v,loading:S,error:g}=eS(e.authorizationId,t);return s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"approval-headline",children:h}),s.jsx(qj,{proposalId:e.id,systemName:j}),f.length>0&&s.jsxs("div",{className:"limit-checks",children:[s.jsx("h4",{children:"Within your limits"}),s.jsx("ul",{className:"limit-check-list",children:f.map(p=>s.jsxs("li",{className:p.ok?"ok":"bad",children:[s.jsx("span",{className:"limit-check-icon",children:p.ok?"✓":"✗"}),s.jsxs("span",{children:[p.label," ",p.valueText," — your limit ",p.limitText]})]},p.key))})]}),s.jsxs("div",{className:"mandate-intent",children:[s.jsxs("dl",{children:[s.jsx("dt",{children:"Mandate"}),s.jsxs("dd",{children:[s.jsx("strong",{children:(l==null?void 0:l.name)??Le(e.profileId)}),s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]})]}),s.jsxs("dl",{children:[s.jsx("dt",{children:"Intent"}),s.jsx("dd",{children:g?s.jsx("p",{style:{color:"var(--danger)",fontSize:"0.8rem",margin:0},children:g}):v!==null?s.jsxs(s.Fragment,{children:[s.jsx("p",{className:`intent-text${i?"":" intent-clamped"}`,children:v}),s.jsx("button",{className:"btn btn-ghost btn-sm intent-toggle",onClick:()=>o(!i),children:i?"Show less":"Show full intent"})]}):S?s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.8rem",margin:0},children:"Loading intent…"}):s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.8rem",margin:0},children:"No intent available for this mandate."})})]})]}),m.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:m.map(p=>s.jsxs("a",{href:p.href,target:"_blank",rel:"noopener noreferrer",className:"btn btn-secondary btn-sm",style:{textDecoration:"none"},title:p.description??p.href,children:[p.label," ↗"]},p.label))}),s.jsxs("details",{className:"proposal-args-fold",style:{marginBottom:"0.75rem"},children:[s.jsx("summary",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",cursor:"pointer"},children:"Details (exactly what is bound)"}),s.jsxs("div",{style:{marginTop:"0.5rem"},children:[s.jsx(rp,{args:e.toolArgs,display:r,heading:""}),c.length>0&&s.jsx("div",{style:{fontSize:"0.85rem",color:"var(--text-secondary)"},children:c.map(([p,y],x)=>{const{label:k,hint:N}=Zm(p,l);return s.jsxs("span",{children:[x>0&&" · ",s.jsxs("span",{title:N,children:[k,"=",sp(y)]})]},p)})})]})]})]})}const tS={pending:"Pending",committed:"Approved",executed:"Executed",rejected:"Rejected",expired:"Expired"},nS={pending:"status-pending",committed:"status-active",executed:"status-active",rejected:"status-revoked",expired:"status-expired"};function rS(e){const t=Date.now()-e*1e3,n=t/36e5;return n<48?n<1?`${Math.max(1,Math.round(t/6e4))}m ago`:`${Math.round(n)}h ago`:new Date(e*1e3).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function sS(e){return e.split("__").pop()??e}function aS(e){const t=e.toLowerCase();return t.includes("delete")||t.includes("refund")||t.includes("cancel")||t.includes("revoke")}function ip(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e))return e.map(t=>ip(t)).join(", ");try{return JSON.stringify(e,null,2)}catch{return String(e)}}function Ld({item:e,onApprove:t,onReject:n,resolving:r,proposalLinks:a,toolDisplay:i,manifests:o,currentUserId:c}){const l=e.kind==="proposal",u=l?e.proposal.status:"executed",f=l?e.proposal.tool:e.receipt.action,m=sS(f),h=aS(f),{integrationId:w}=_c(f),j=Xm(w,o),v=Ds(e.profileId),S=l?e.proposal.toolArgs:null,g=l?e.proposal.executionContext:e.receipt.executionContext,p=l?null:e.receipt.cumulativeState,y=l?tp(a,e.proposal.toolArgs):[],x=Object.entries(g??{}),k=qn(e.profileId).testSetup||bi(f);return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem",flexWrap:"wrap"},children:[s.jsx("code",{style:{fontSize:"0.85rem"},children:m}),k&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),e.commitmentMode==="automatic"&&s.jsx("span",{style:{fontSize:"0.7rem",color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em"},children:"autonomous"}),s.jsxs("span",{style:{marginLeft:"auto",display:"flex",alignItems:"center",gap:"0.5rem"},children:[l&&u==="pending"&&(()=>{const N=np(e.proposal.expiresAt,Date.now());return s.jsx("span",{style:{fontSize:"0.72rem",color:N.urgent?"var(--warning)":"var(--text-tertiary)",fontWeight:N.urgent?600:400,whiteSpace:"nowrap"},children:N.label})})(),s.jsx("span",{className:`status-badge ${nS[u]}`,children:tS[u]}),s.jsx("span",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:rS(e.sortTimestamp)})]})]}),l&&e.proposal.status==="executed"&&s.jsx(Qj,{proposalId:e.proposal.id,systemName:j}),h&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem",fontSize:"0.8rem",color:"var(--warning)",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.375rem",padding:"0.4rem 0.6rem",marginBottom:"0.75rem"},children:[s.jsx("span",{children:"⚠"}),s.jsx("span",{children:"Irreversible action"})]}),l&&typeof(S==null?void 0:S._imagePreview)=="string"&&s.jsxs("div",{style:{marginBottom:"0.75rem"},children:[s.jsx("div",{style:{fontSize:"0.7rem",fontWeight:600,color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em",marginBottom:"0.35rem"},children:"Preview"}),s.jsx("img",{src:S._imagePreview,alt:typeof(S==null?void 0:S.altText)=="string"?S.altText:"local image preview",style:{display:"block",maxWidth:"100%",maxHeight:"240px",borderRadius:"0.375rem",border:"1px solid var(--border)"}})]}),l&&u==="pending"?s.jsx(ap,{proposal:e.proposal,currentUserId:c??"",proposalLinks:a,toolDisplay:i,manifests:o}):s.jsxs(s.Fragment,{children:[y.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:y.map(N=>s.jsxs("a",{href:N.href,target:"_blank",rel:"noopener noreferrer",className:"btn btn-secondary btn-sm",style:{textDecoration:"none"},title:N.description??N.href,children:[N.label," ↗"]},N.label))}),l?s.jsxs(s.Fragment,{children:[S&&s.jsx(rp,{args:S,display:i}),x.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",fontSize:"0.8rem",color:"var(--text-secondary)"},children:x.map(([N,C])=>`${N}=${ip(C)}`).join(" · ")})]}):s.jsx(ep,{receipt:e.receipt,profile:v})]}),p&&s.jsxs("div",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:["After this action · today: ",p.daily.count," action",p.daily.count===1?"":"s",p.daily.amount>0?`, ${p.daily.amount}`:""," · ","this month: ",p.monthly.count,p.monthly.amount>0?`, ${p.monthly.amount}`:""]}),l&&u==="pending"&&s.jsxs("div",{style:{display:"flex",gap:"0.5rem"},children:[s.jsx("button",{className:"btn btn-primary",onClick:()=>t==null?void 0:t(e.id),disabled:r,children:r?"Approving…":"Approve"}),s.jsx("button",{className:"btn btn-ghost",style:{color:"var(--danger)"},onClick:()=>n==null?void 0:n(e.id),disabled:r,children:"Reject"})]}),s.jsxs("div",{style:{marginTop:"0.5rem",fontSize:"0.7rem",color:"var(--text-tertiary)"},children:[l?"Proposal":"Ticket",": ",e.id]})]})]})}function iS(e){const t=Date.now()-e*1e3,n=Math.floor(t/6e4);if(n<60)return`${Math.max(1,n)}m ago`;const r=Math.floor(t/36e5);return r<48?`${r}h ago`:`${Math.floor(r/24)}d ago`}function oS({proposal:e,currentUserId:t,onAction:n,onMessage:r,proposalLinks:a,toolDisplay:i,manifests:o}){const[c,l]=d.useState(!1),[u,f]=d.useState(!1),m=qn(e.profileId).testSetup||bi(e.tool),h=e.pendingApprovers??[],w=e.approvedBy??{},j=Object.keys(w).length,v=h.filter(x=>!(x in w)).length,S=t in w,g=async()=>{if(Tc()){r(Ic);return}l(!0),r("");try{await E.approveProposal(e.id);try{const x=await E.getAttestationIntent(e.authorizationId);if(x){const k=await E.decryptIntent({intentCiphertext:x.intentCiphertext,encryptedKey:x.encryptedKey,approverId:t});await E.storeApprovedIntent(e.authorizationId,k)}}catch{}r(`Approved. ${v-1>0?`${v-1} more approver(s) still needed.`:"All approvers signed off — action is ready to execute."}`),n()}catch(x){r(x instanceof Error?x.message:"Approval failed")}finally{l(!1)}},p=async()=>{const x=prompt("Rejection reason (optional):");if(x!==null){f(!0),r("");try{await E.rejectProposal(e.id,x||void 0),r("Action rejected."),n()}catch(k){r(k instanceof Error?k.message:"Rejection failed")}finally{f(!1)}}},y=c||u;return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[s.jsx("span",{style:{fontSize:"0.65rem",padding:"0.15rem 0.4rem",borderRadius:"0.25rem",background:"var(--accent-subtle)",color:"var(--accent)",fontWeight:600},children:"Above cap"}),m&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),s.jsxs("span",{style:{marginLeft:"auto",display:"flex",alignItems:"center",gap:"0.5rem"},children:[(()=>{const x=np(e.expiresAt,Date.now());return s.jsx("span",{style:{fontSize:"0.72rem",color:x.urgent?"var(--warning)":"var(--text-tertiary)",fontWeight:x.urgent?600:400,whiteSpace:"nowrap"},children:x.label})})(),s.jsx("span",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:iS(e.createdAt)})]})]}),s.jsxs("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:[j," of ",h.length," approver",h.length===1?"":"s"," signed off",h.map(x=>{const k=x in w;return s.jsxs("span",{style:{marginLeft:"0.5rem",color:k?"var(--success, green)":"var(--text-tertiary)"},children:[k?"✓":"○"," ",x===t?"You":x]},x)})]}),s.jsx(ap,{proposal:e,currentUserId:t,proposalLinks:a,toolDisplay:i,manifests:o}),!S&&s.jsxs("div",{style:{display:"flex",gap:"0.5rem",marginTop:"0.25rem"},children:[s.jsx("button",{className:"btn btn-primary",onClick:g,disabled:y,children:c?"Approving...":"Approve"}),s.jsx("button",{className:"btn btn-ghost",style:{color:"var(--danger)"},onClick:p,disabled:y,children:u?"Rejecting...":"Reject"})]}),S&&s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginTop:"0.25rem"},children:"You approved this action. Waiting on other approvers."}),s.jsxs("div",{style:{marginTop:"0.5rem",fontSize:"0.7rem",color:"var(--text-tertiary)"},children:["Proposal: ",e.id]})]})]})}function lS(){const{domain:e,user:t}=He(),n=(t==null?void 0:t.id)??"",[r,a]=d.useState("awaiting-me"),[i,o]=d.useState([]),[c,l]=d.useState([]),[u,f]=d.useState({}),[m,h]=d.useState(!0),[w,j]=d.useState(""),v=d.useCallback(async()=>{try{const I=await E.getProposalsForApprover();o(I)}catch{}finally{h(!1)}},[]);ve("proposal-added",v),ve("proposal-approved",v),ve("proposal-rejected",v),ve("proposal-resolved",v),Tt(v,3e4);const[S,g]=d.useState([]),p=d.useCallback(async()=>{try{const I=await E.getMyProposals(e);g(I)}catch{}},[e]);ve("proposal-added",p),ve("proposal-approved",p),ve("proposal-rejected",p),ve("proposal-resolved",p),Tt(p,3e4,e);const y=d.useMemo(()=>S.filter(I=>{var G;return I.status==="pending"&&(((G=I.pendingApprovers)==null?void 0:G.length)??0)===0}),[S]),x=d.useMemo(()=>Ad(y,[],{status:"pending"}),[y]),[k,N]=d.useState([]),C=d.useCallback(async()=>{if(n)try{const G=(await E.getMyProposals(e)).filter(ae=>ae.status==="pending"&&ae.pendingApprovers&&ae.pendingApprovers.includes(n)&&ae.approvedBy&&n in ae.approvedBy);N(G)}catch{}},[n,e]);ve("proposal-approved",C),ve("proposal-rejected",C),Tt(C,3e4,`${n}:${e}`),d.useEffect(()=>{E.getIntegrationManifests().then(I=>l(I.manifests??[])).catch(()=>{}),E.getToolDisplay().then(f).catch(()=>{})},[]);const A=I=>{var G;return(G=c.find(ae=>ae.id===I.split("__")[0]))==null?void 0:G.proposalLinks};d.useEffect(()=>{v(),p(),C()},[]);const[T,_]=d.useState([]),[D,L]=d.useState([]),[q,M]=d.useState(!0),[X,re]=d.useState(null),[se,$]=d.useState(""),[R,O]=d.useState("pending"),[P,z]=d.useState(null),[H,Q]=d.useState(!1),ee=d.useCallback(async()=>{try{const{proposals:I,receipts:G}=await E.getThread({domain:e,status:R,sinceDays:7});_(I),L(G)}catch{}finally{M(!1)}},[e,R]);Tt(ee,3e4,`${e}:${R}`);const oe=async(I,G)=>{if(G==="commit"&&Tc()){$(Ic);return}re(I),$("");try{const ae=T.find(ze=>ze.id===I)??S.find(ze=>ze.id===I),ye=Sx(ae,e),me=await E.resolveProposal(I,G,ye);$(G==="commit"?`Action approved. Status: ${me.status}`:"Action rejected."),await Promise.all([ee(),p()])}catch(ae){$(ae instanceof Error?ae.message:"Failed")}finally{re(null)}},de=d.useMemo(()=>{const I=new Set;for(const G of T)I.add(G.profileId);for(const G of D)I.add(G.profileId);return Array.from(I).sort()},[T,D]),fe=d.useMemo(()=>Ad(T,D,{status:R,profile:P??void 0,includeAutonomous:H}),[T,D,R,P,H]),J=d.useCallback(()=>{v(),C()},[v,C]),he=d.useMemo(()=>{const I=new Set,G=[];for(const ae of k)I.has(ae.id)||(I.add(ae.id),G.push(ae));return G.sort((ae,ye)=>ye.createdAt-ae.createdAt)},[k]),te=i.length+x.length,ie=he.length;return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",children:[s.jsx("h1",{className:"page-title",children:"Pending Approvals"}),s.jsx("p",{className:"page-subtitle",children:"Actions awaiting approval, plus recent activity from the last 7 days."}),s.jsx(Fm,{what:"approve"})]}),s.jsxs("div",{className:"nav-tabs",style:{marginBottom:"1rem"},children:[s.jsxs("button",{className:`nav-tab${r==="awaiting-me"?" active":""}`,onClick:()=>a("awaiting-me"),children:["Awaiting me ",te>0&&s.jsx("span",{style:{marginLeft:"0.4rem",background:"var(--warning)",color:"var(--bg-elevated)",borderRadius:"0.625rem",padding:"0 0.375rem",fontSize:"0.7rem",fontWeight:600},children:te})]}),s.jsxs("button",{className:`nav-tab${r==="awaiting-others"?" active":""}`,onClick:()=>a("awaiting-others"),children:["Awaiting others ",ie>0&&s.jsx("span",{style:{marginLeft:"0.4rem",background:"var(--border)",color:"var(--text-secondary)",borderRadius:"0.625rem",padding:"0 0.375rem",fontSize:"0.7rem",fontWeight:600},children:ie})]}),s.jsx("button",{className:`nav-tab${r==="all"?" active":""}`,onClick:()=>{a("all"),ee()},children:"All"})]}),r==="awaiting-me"&&s.jsx(s.Fragment,{children:m&&te===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):te===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:"No actions awaiting your approval."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Review-mode actions and above-cap actions you must approve will appear here."})]}):s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[(w||se)&&s.jsx("div",{className:"alert alert-success",children:w||se}),x.map(I=>s.jsx(Ld,{proposalLinks:I.kind==="proposal"?A(I.proposal.tool):void 0,toolDisplay:I.kind==="proposal"?u[I.proposal.tool]:void 0,manifests:c,currentUserId:n,item:I,onApprove:G=>oe(G,"commit"),onReject:G=>oe(G,"reject"),resolving:X===I.id},I.id)),i.map(I=>s.jsx(oS,{proposal:I,currentUserId:n,onAction:J,onMessage:j,proposalLinks:A(I.tool),toolDisplay:u[I.tool],manifests:c},I.id))]})}),r==="awaiting-others"&&s.jsx(s.Fragment,{children:he.length===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:"No actions waiting on others."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Actions you proposed or approved that are pending other approvers will appear here."})]}):s.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:he.map(I=>s.jsx(uS,{proposal:I,currentUserId:n,onCancel:async()=>{try{await E.rejectProposal(I.id,"cancelled by creator"),C(),p()}catch(G){alert(G instanceof Error?G.message:"Cancel failed")}}},I.id))})}),r==="all"&&s.jsxs(s.Fragment,{children:[se&&s.jsx("div",{className:"alert alert-success",style:{marginBottom:"1rem"},children:se}),s.jsxs("div",{className:"filter-chips",style:{marginBottom:"1rem"},children:[s.jsx("button",{className:`filter-chip ${R==="pending"?"selected":""}`,onClick:()=>O("pending"),children:"Pending"}),s.jsx("button",{className:`filter-chip ${R==="all"?"selected":""}`,onClick:()=>O("all"),children:"All"}),de.length>0&&s.jsx("span",{style:{width:1,background:"var(--border)",alignSelf:"stretch",margin:"0 0.25rem"}}),de.map(I=>s.jsx("button",{className:`filter-chip ${P===I?"selected":""}`,onClick:()=>z(P===I?null:I),children:Le(I)},I)),R==="all"&&s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{width:1,background:"var(--border)",alignSelf:"stretch",margin:"0 0.25rem"}}),s.jsxs("button",{className:`filter-chip ${H?"selected":""}`,onClick:()=>Q(!H),title:"Include actions executed without human review (automatic commitment mode)",children:[H?"✓ ":"","Autonomous actions"]})]})]}),q&&fe.length===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):fe.length===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:R==="pending"?"No actions awaiting your approval.":"Nothing here yet."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:R==="pending"?"Your agents are operating within their mandates. Switch to All to see recent activity.":"When an agent calls a gated tool, activity will appear here."})]}):s.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:fe.map(I=>s.jsx(Ld,{proposalLinks:I.kind==="proposal"?A(I.proposal.tool):void 0,toolDisplay:I.kind==="proposal"?u[I.proposal.tool]:void 0,manifests:c,currentUserId:n,item:I,onApprove:G=>oe(G,"commit"),onReject:G=>oe(G,"reject"),resolving:X===I.id},I.id))})]})]})}function cS(e){const t=Date.now()-e*1e3,n=Math.floor(t/6e4);if(n<60)return`${Math.max(1,n)}m ago`;const r=Math.floor(t/36e5);return r<48?`${r}h ago`:`${Math.floor(r/24)}d ago`}function uS({proposal:e,currentUserId:t,onCancel:n}){var f;const[r,a]=d.useState(!1),i=Object.keys(e.approvedBy??{}),o=(e.pendingApprovers??[]).filter(m=>!(m in(e.approvedBy??{}))),c=(((f=e.pendingApprovers)==null?void 0:f.length)??0)>0,l=async()=>{if(confirm("Cancel this action? All approvers will be notified.")){a(!0);try{await n()}finally{a(!1)}}},u=qn(e.profileId).testSetup||bi(e.tool);return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[s.jsx("code",{style:{fontSize:"0.85rem"},children:e.tool.split("__").pop()??e.tool}),u&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),c&&s.jsx("span",{style:{fontSize:"0.65rem",padding:"0.15rem 0.4rem",borderRadius:"0.25rem",background:"var(--accent-subtle)",color:"var(--accent)",fontWeight:600},children:"Above cap"}),s.jsx("span",{style:{marginLeft:"auto",fontSize:"0.75rem",color:"var(--text-tertiary)"},children:cS(e.createdAt)})]}),c&&s.jsxs("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:[i.map(m=>s.jsx("span",{style:{marginRight:"0.75rem",color:"var(--success, green)"},children:m===t?"You approved":`${m} approved`},m)),o.map(m=>s.jsxs("span",{style:{marginRight:"0.75rem",color:"var(--text-tertiary)"},children:["Waiting on ",m===t?"you":m]},m))]}),s.jsx("div",{style:{display:"flex",justifyContent:"flex-end",gap:"0.5rem",marginTop:"0.5rem"},children:s.jsx("button",{className:"btn btn-ghost btn-sm",style:{color:"var(--danger)"},onClick:l,disabled:r,children:r?"Cancelling...":"Cancel"})})]})]})}const dS=`# Agent Brief
|
|
83
|
+
`).replace(/\n+$/,"")}function ul(e){if(e===void 0)throw new Error("canonicalize: undefined is not serializable");if(typeof e=="number"&&!Number.isFinite(e))throw new Error(`canonicalize: ${e} is not a valid JSON number`);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return"["+e.map(a=>a===void 0?"null":ul(a)).join(",")+"]";const t=e,n=[];for(const r of Object.keys(t).sort()){const a=t[r];a!==void 0&&n.push(JSON.stringify(r)+":"+ul(a))}return"{"+n.join(",")+"}"}async function gj(e,t){if(e==="jcs"){if(typeof t=="string")throw new Error('content_binding kind="jcs" expects a record payload (object), got a string');return`sha256:${await bd(ul(t))}`}if(typeof t!="string")throw new Error('content_binding kind="text" expects a string, got an object');return`sha256:${await bd(pj(t))}`}function mr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ln(e,t=!1){return e==null?"—":typeof e=="string"?e:typeof e=="boolean"?String(e):typeof e=="number"?t||Number.isInteger(e)?String(e):String(Math.round(e*100)/100):"—"}function yj(e){return e==null?!1:typeof e=="string"||Array.isArray(e)?e.length>0:!0}function es(e,t,n){const r=t?Object.keys(t).filter(a=>a in e):Object.keys(e);return r.length===0?"—":r.map(a=>{var l,u;const i=e[a],o=((l=t==null?void 0:t[a])==null?void 0:l.title)??Os(a),c=mr(i)?es(i,(u=t==null?void 0:t[a])==null?void 0:u.properties,n):Ln(i,n);return`${o}: ${c}`}).join(" · ")}function vj(e,t){var a;if(Array.isArray(e)){if(e.length===0)return{value:"—"};if(e.every(u=>!mr(u)&&!Array.isArray(u))){const u=e.map(m=>Ln(m)).join(", "),f=e.map(m=>Ln(m,!0)).join(", ");return f===u?{value:u}:{value:u,valueTitle:f}}const i=(a=t==null?void 0:t.items)==null?void 0:a.properties,o=e.map(u=>mr(u)?es(u,i,!1):Ln(u)),c=e.map(u=>mr(u)?es(u,i,!0):Ln(u,!0)),l=o.map((u,f)=>u===c[f]?void 0:c[f]);return l.some(u=>u!==void 0)?{lines:o,lineTitles:l}:{lines:o}}if(mr(e)){const i=es(e,t==null?void 0:t.properties,!1),o=es(e,t==null?void 0:t.properties,!0);return o===i?{value:i}:{value:i,valueTitle:o}}const n=Ln(e),r=Ln(e,!0);return r===n?{value:n}:{value:n,valueTitle:r}}function xj(e){let t;try{t=JSON.parse(e)}catch{return null}return mr(t)?t:null}function ri(e){const t=e!=null&&e.structured&&Object.keys(e.structured).length>0?e.structured:void 0;if(t)return{obj:t,schema:e==null?void 0:e.outputSchema};const n=e!=null&&e.text?xj(e.text):null;return n?{obj:n}:null}function dl(e){const t=ri(e);if(!t)return[];const{obj:n,schema:r}=t,a=(r==null?void 0:r.properties)??{},i=[...new Set([...Object.keys(a),...Object.keys(n)])],o=[];for(const c of i){if(!(c in n))continue;const l=a[c],u=(l==null?void 0:l.title)??Os(c);o.push({key:c,label:u,...vj(n[c],l)})}return o}function fl(e,t){const n=ri(e);if(n){const a=dl(e),i=t==null?void 0:t.fields;let o;if(i&&i.length>0){const u=new Map(a.map(f=>[f.key,f]));o=i.map(f=>u.get(f)).filter(f=>f!==void 0)}else o=a.filter(u=>yj(n.obj[u.key]));const c=new Set(o.map(u=>u.key)),l=a.filter(u=>!c.has(u.key));return{kind:"structured",fields:o,moreFields:l,totalFields:a.length}}const r=e==null?void 0:e.text;return r&&r.trim().length>0?{kind:"text",fields:[],moreFields:[],totalFields:0,text:r}:{kind:"empty",fields:[],moreFields:[],totalFields:0}}function Nd(e){return e?e.lines?`lines:${JSON.stringify(e.lines)}`:`value:${e.value??""}`:""}function da(e){return{kind:e.length>0?"structured":"empty",fields:e,moreFields:[],totalFields:e.length}}function wj(e,t,n){const r=ri(e),a=ri(t);if(!r&&!a){const h=(e==null?void 0:e.text)??"",w=(t==null?void 0:t.text)??"";return h===w?{approved:da([]),current:da([]),unchanged:!0}:{approved:{kind:"text",fields:[],moreFields:[],totalFields:0,text:h},current:{kind:"text",fields:[],moreFields:[],totalFields:0,text:w},unchanged:!1}}const i=new Map(dl(e).map(h=>[h.key,h])),o=new Map(dl(t).map(h=>[h.key,h])),l=[...new Set([...i.keys(),...o.keys()])].filter(h=>h===(n==null?void 0:n.excludeKey)?!1:Nd(i.get(h))!==Nd(o.get(h))),u=n!=null&&n.fields&&n.fields.length>0?[...n.fields.filter(h=>l.includes(h)),...l.filter(h=>!n.fields.includes(h))]:l,f=u.map(h=>i.get(h)).filter(h=>h!==void 0),m=u.map(h=>o.get(h)).filter(h=>h!==void 0);return{approved:da(f),current:da(m),unchanged:l.length===0}}function jj(e){return e.offDevice?"off-device":e.boundContent===void 0?"none":e.hasHashToCheck?e.hashVerified===!0?"verified":"mismatch":"unchecked"}function Sj(e,t){return e===void 0?{kind:"empty",fields:[],moreFields:[],totalFields:0}:typeof e=="string"?fl({text:e}):fl({structured:e},{fields:t})}function kj(e,t){return e?Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,r])=>({key:n,label:Zm(n,t).label,value:String(r)})):[]}function Cd({rows:e}){return s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.3rem 0.75rem",fontSize:"0.85rem",margin:"0.4rem 0"},children:e.map(t=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-tertiary)",whiteSpace:"nowrap",alignSelf:"start"},children:t.label}),s.jsx("dd",{style:{margin:0,wordBreak:"break-word"},children:t.lines?s.jsx("div",{children:t.lines.map((n,r)=>{var a;return s.jsx("div",{title:(a=t.lineTitles)==null?void 0:a[r],children:n},r)})}):s.jsx("span",{title:t.valueTitle,children:t.value})})]},t.key))})}function Ta({rendered:e}){return e.kind==="empty"?s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.85rem",margin:"0.4rem 0"},children:"No fields returned."}):e.kind==="text"?s.jsx("div",{style:{whiteSpace:"pre-wrap",fontSize:"0.85rem",margin:"0.4rem 0"},children:e.text}):s.jsxs(s.Fragment,{children:[s.jsx(Cd,{rows:e.fields}),e.moreFields.length>0&&s.jsxs("details",{style:{fontSize:"0.8rem"},children:[s.jsxs("summary",{style:{cursor:"pointer",color:"var(--text-tertiary)"},children:["All fields (",e.totalFields,")"]}),s.jsx(Cd,{rows:e.moreFields})]})]})}function ep({receipt:e,profile:t}){var h;const[n,r]=d.useState(void 0),[a,i]=d.useState(null),o=!!(e.contentHash&&e.contentBinding);if(d.useEffect(()=>{let w=!0;return r(void 0),i(null),(async()=>{let j;try{j=await E.getArchivedReceipt(e.id)}catch{w&&r(null);return}let v=null;const S=j==null?void 0:j.entry.boundContent;if(S!==void 0&&o)try{v=await gj(e.contentBinding.kind,S)===e.contentHash}catch{v=!1}w&&(i(v),r(j))})(),()=>{w=!1}},[e.id,e.contentHash,e.contentBinding,o]),n===void 0)return s.jsx("div",{className:"ticket-done-box ticket-done-loading","data-testid":"ticket-what-was-done","data-bound":"loading","aria-busy":"true",children:"Loading…"});const c=n===null,l=n==null?void 0:n.entry.boundContent,u=jj({offDevice:c,boundContent:l,hasHashToCheck:o,hashVerified:a});if(u==="off-device")return s.jsx("div",{className:"ticket-done-box ticket-done-off-device","data-testid":"ticket-what-was-done","data-bound":"off-device",children:s.jsx("p",{className:"ticket-done-note",children:"Content not on this device — only the signed values are shown."})});if(u==="none"){const w=kj(e.executionContext,t);return s.jsxs("div",{className:"ticket-done-box","data-testid":"ticket-what-was-done","data-bound":"none",children:[s.jsx("h4",{children:"What was done"}),w.length>0?s.jsx("dl",{className:"ticket-done-fields",children:w.map(j=>s.jsxs("div",{className:"ticket-done-field-row",children:[s.jsx("dt",{children:j.label}),s.jsx("dd",{children:j.value})]},j.key))}):s.jsx("p",{className:"ticket-done-note",children:"No checked values recorded for this action."})]})}const f=Sj(l,(h=e.contentBinding)==null?void 0:h.fields),m=u==="verified"?"ticket-done-verified":u==="mismatch"?"ticket-done-mismatch":"ticket-done-unchecked";return s.jsxs("div",{className:`ticket-done-box ${m}`,"data-testid":"ticket-what-was-done","data-bound":u,children:[s.jsxs("h4",{children:["What was done",u!=="unchecked"&&s.jsxs(s.Fragment,{children:[" ",s.jsx("span",{className:"src-tag src-tag-sealed",children:"sealed"})]})]}),s.jsx(Ta,{rendered:f}),u==="verified"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-ok",children:"✓ This exact content is bound by hash — any change after the fact would break the ticket."}),u==="mismatch"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-bad",children:"⚠ This content does NOT match the ticket's signed hash — it may have been altered since archiving."}),u==="unchecked"&&s.jsx("p",{className:"ticket-done-note ticket-done-note-neutral",children:"This content is kept on this device, but the ticket carries no content hash — it cannot be checked against the ticket."})]})}function Gr({label:e,children:t}){return s.jsxs(s.Fragment,{children:[s.jsx("dt",{className:"receipt-row-label",children:e}),s.jsx("dd",{className:"receipt-row-value",children:t})]})}function bj({receipt:e,manifests:t,localAuth:n,localUnavailable:r,signature:a,grantTitle:i,ownerLabel:o,spUrl:c,formatDate:l,onOpenComplete:u}){var p;const f=Ds(e.profileId),m=lj(e,f),h=cj(n==null?void 0:n.context,f),w=uj(e,(n==null?void 0:n.bounds)??e.limits,f),j=n==null?void 0:n.intent,v=qn(e.profileId).testSetup||bi(e.action),[S,g]=d.useState(!1);return s.jsxs("div",{className:"card id-card",style:{marginBottom:0},children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{className:"receipt-head",children:[s.jsx("span",{className:"receipt-what",children:oj(e,t)}),s.jsx("span",{className:"receipt-tag",children:fj(e)?"review":"automatic"}),e.contentHash&&s.jsx("span",{className:"receipt-tag receipt-tag-bound",title:(p=e.contentBinding)!=null&&p.fields?`The ticket binds: ${e.contentBinding.fields.join(", ")}`:"This exact content was authorized",children:"content bound"}),v&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),s.jsx("span",{className:"auth-card-time",children:l(e.timestamp)})]}),m&&s.jsx("div",{className:"receipt-scope",children:m}),s.jsx(ep,{receipt:e,profile:f}),s.jsxs("dl",{className:"receipt-rows",children:[s.jsxs(Gr,{label:"mandate",children:[s.jsx("strong",{children:i||hj(e.profileId)})," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}),o&&s.jsx(Gr,{label:"owner",children:o}),h&&s.jsxs(Gr,{label:"allowed",children:[h," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}),w&&s.jsxs(Gr,{label:"used",children:[s.jsx("span",{className:"receipt-num",children:w})," ",s.jsx("span",{className:"src-tag src-tag-sealed",children:"sealed"})]}),s.jsx(Gr,{label:"intent",children:j?s.jsxs(s.Fragment,{children:[s.jsx("span",{className:`intent-text${S?"":" intent-clamped"}`,children:j}),s.jsx("button",{type:"button",className:"btn btn-ghost btn-sm intent-toggle",onClick:()=>g(!S),children:S?"Show less":"Show full intent"})," ",s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]}):s.jsx("span",{className:"receipt-absent",children:r?"local store unreachable — sign in to the gateway to read it":"not on this device — the Authority Server stores only its hash"})})]}),s.jsxs("div",{className:"receipt-foot",children:[a==="valid"&&s.jsx("span",{className:"receipt-verified",title:"Ed25519 signature checked on this device against the issuer key archived when the ticket was issued — no Authority Server involved.",children:"✓ Verified on this device"}),a==="valid-legacy"&&s.jsx("span",{className:"receipt-verified",title:"Ed25519 signature checked on this device against the issuer key archived when the ticket was issued. This ticket was issued before protocol 0.7 and is checked with that version's format.",children:"✓ Verified on this device · issued before protocol 0.7"}),a==="invalid"&&s.jsx("span",{className:"receipt-tamper",title:"The stored ticket does not match what was signed.",children:"⚠ Signature check FAILED"}),s.jsx("button",{type:"button",className:"receipt-evidence-link",onClick:u,children:"Complete ticket"}),c&&s.jsxs("span",{className:"receipt-public",children:["redacted, shareable:"," ",s.jsx("a",{className:"receipt-link",href:`${c}/r/${e.id}`,target:"_blank",rel:"noreferrer",children:"public link ↗"})]})]}),s.jsxs("details",{className:"receipt-more",children:[s.jsx("summary",{children:"Raw"}),s.jsxs("div",{className:"receipt-kv",children:[s.jsxs("div",{children:["ticket · ",e.id]}),s.jsxs("div",{children:["action · ",e.action]}),s.jsxs("div",{children:["profile · ",e.profileId]}),e.authorizationId&&s.jsxs("div",{children:["mandate · ",e.authorizationId]}),Object.keys(e.executionContext??{}).length>0&&s.jsxs("div",{children:["scope ·"," ",Object.entries(e.executionContext).map(([y,x])=>`${y}=${x}`).join(" · ")]}),(n==null?void 0:n.boundsHash)&&s.jsxs("div",{children:["bounds hash · ",n.boundsHash]}),(n==null?void 0:n.contextHash)&&s.jsxs("div",{children:["scope hash · ",n.contextHash]}),e.contentHash&&s.jsxs("div",{children:["content · ",e.contentHash]}),e.proposalId&&s.jsxs("div",{children:["proposal · ",e.proposalId]}),s.jsxs("div",{children:["signature · ",e.signature]})]})]})]})]})}function Nj({receipt:e,onClose:t}){const[n,r]=d.useState(null),[a,i]=d.useState(null),[o,c]=d.useState(null),[l,u]=d.useState(!0),[f,m]=d.useState(!1);d.useEffect(()=>{let S=!1;return u(!0),E.getArchivedReceipt(e.id).then(g=>{S||(r(g),i(g?"local":"authority-server"),c((g==null?void 0:g.signature)??null))}).catch(()=>{S||i("authority-server")}).finally(()=>{S||u(!1)}),()=>{S=!0}},[e.id]);const h=n?n.entry:{receipt:e},w=JSON.stringify(h,null,2);function j(){const S=URL.createObjectURL(new Blob([w],{type:"application/json"})),g=document.createElement("a");g.href=S,g.download=`suveren-ticket-${e.id.slice(0,8)}.json`,g.click(),URL.revokeObjectURL(S)}async function v(){try{await navigator.clipboard.writeText(w),m(!0),setTimeout(()=>m(!1),2e3)}catch{m(!1)}}return s.jsx("div",{className:"modal-backdrop",onClick:S=>S.target===S.currentTarget&&t(),children:s.jsxs("div",{className:"modal",style:{maxWidth:"44rem"},children:[s.jsxs("div",{className:"modal-header",children:[s.jsx("h3",{className:"modal-title",children:"Complete ticket"}),s.jsx("button",{className:"modal-close",onClick:t,"aria-label":"Close",children:"×"})]}),s.jsxs("div",{className:"modal-body",children:[o==="valid"&&s.jsx("p",{className:"receipt-verified",style:{margin:"0 0 0.5rem",fontSize:"0.8rem"},children:"✓ Ed25519 signature verified on this device, against the issuer key archived when this ticket was issued."}),o==="valid-legacy"&&s.jsx("p",{className:"receipt-verified",style:{margin:"0 0 0.5rem",fontSize:"0.8rem"},children:"✓ Ed25519 signature verified on this device, against the issuer key archived when this ticket was issued. Issued before protocol 0.7 — checked with that version's format."}),o==="invalid"&&s.jsx("p",{className:"receipt-tamper",style:{margin:"0 0 0.5rem",fontSize:"0.8rem"},children:"⚠ Signature check FAILED — the stored ticket does not match what was signed."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-muted)",margin:"0 0 0.75rem"},children:l?"Loading…":a==="local"?"Held on this device — the signed ticket, the mandate it ran under, and the issuer key. Anyone with this file and that key can verify it offline, without Suveren.":"No local copy of this ticket (it predates local archiving, or ran on another device). Shown from the Authority Server — complete and signed, but it needs the server to retrieve."}),s.jsx("pre",{style:{fontFamily:"'SF Mono', Monaco, monospace",fontSize:"0.68rem",lineHeight:1.65,margin:0,background:"var(--accent-subtle)",border:"1px solid var(--border)",borderRadius:"6px",padding:"0.75rem 0.85rem",overflowX:"auto",maxHeight:"22rem",overflowY:"auto"},children:w})]}),s.jsxs("div",{className:"modal-footer",children:[s.jsx("button",{className:"btn btn-primary btn-sm",onClick:j,children:"Download"}),s.jsx("button",{className:"btn btn-secondary btn-sm",onClick:v,children:f?"Copied":"Copy"})]})]})})}function Cj(e){return new Date(e*1e3).toLocaleString()}function Ej(e,t){if(t==="all")return!0;const n=t==="1d"?1:t==="7d"?7:30,r=Math.floor(Date.now()/1e3)-n*86400;return e.timestamp>=r}function Tj(e,t){if(!t)return!0;const n=t.toLowerCase();return e.profileId.toLowerCase().includes(n)||Le(e.profileId).toLowerCase().includes(n)||e.path.toLowerCase().includes(n)||e.action.toLowerCase().includes(n)||e.attestationHash.toLowerCase().includes(n)||e.id.toLowerCase().includes(n)||JSON.stringify(e.executionContext).toLowerCase().includes(n)}function Ed(e,t){const n=new Map(e.map(r=>[r.id,r]));for(const r of t)n.set(r.id,r);return[...n.values()].sort((r,a)=>a.timestamp-r.timestamp)}function Ij(){const{activeTeam:e,groupId:t}=He(),n=(e==null?void 0:e.isAdmin)===!0,[r,a]=d.useState("mine"),[i,o]=d.useState([]),[c,l]=d.useState([]),[u,f]=d.useState(""),[m,h]=d.useState(!0),[w,j]=d.useState({}),[v,S]=d.useState(new Set),[g,p]=d.useState(""),[y,x]=d.useState(new Set),[k,N]=d.useState(new Set),[C,A]=d.useState("all"),[T,_]=d.useState(!1),[D,L]=d.useState(!1),[q,M]=d.useState(null),[X,re]=d.useState({}),[se,$]=d.useState(!1),[R,O]=d.useState({}),[P,z]=d.useState({}),[H,Q]=d.useState(null),[ee,oe]=d.useState(null),[de,fe]=d.useState(!1),[J,he]=d.useState(!1),te=d.useRef(""),ie=d.useCallback(b=>r==="team"&&n&&t?E.listTeamReceiptsPage(t,{before:b,limit:200}):E.getMyReceiptsPage({before:b,limit:200}),[r,n,t]),I=d.useCallback(()=>{const b=r==="team"?`team:${t}`:"mine",B=te.current!==b;te.current=b,h(!0),he(!1),ie().then(V=>{o(ne=>B?V.receipts:Ed(ne,V.receipts)),oe(ne=>B?V.nextBefore:ne??V.nextBefore)}).catch(()=>{B&&o([]),he(!0)}).finally(()=>h(!1))},[ie,r,t]),G=d.useCallback(()=>{!ee||de||(fe(!0),he(!1),ie(ee).then(b=>{o(B=>Ed(B,b.receipts)),oe(b.nextBefore)}).catch(()=>he(!0)).finally(()=>fe(!1)))},[ee,de,ie]);Tt(I,12e4),d.useEffect(()=>{E.getIntegrationManifests().then(({manifests:b})=>l(b)).catch(()=>{}),fetch("/health").then(b=>b.json()).then(b=>{typeof b.spUrl=="string"&&f(b.spUrl.replace(/\/$/,""))}).catch(()=>{})},[]),d.useEffect(()=>{E.getLocalAuthorizations().then(({authorizations:b,signatures:B})=>{re(b),O(B),$(!1)}).catch(()=>{re({}),O({}),$(!0)}),E.getMyAttestations().then(b=>{const B={};for(const V of b)V.authorization_id&&V.title&&(B[V.authorization_id]=V.title);z(B)}).catch(()=>{})},[]),d.useEffect(()=>{r!=="team"||Object.keys(w).length>0||E.listUsers().then(b=>{const B={};for(const V of b)B[V.id]={name:V.name,email:V.email};j(B)}).catch(()=>{})},[r,w]);const ae=d.useMemo(()=>{const b=new Set;for(const B of i)b.add(Le(B.profileId));return[...b].sort()},[i]),ye=d.useMemo(()=>{const b=new Set;for(const B of i)b.add(B.action);return[...b].sort()},[i]),me=d.useMemo(()=>{if(r!=="team")return[];const b=new Set;for(const B of i)B.userId&&b.add(B.userId);return[...b].map(B=>{var V;return{id:B,label:(V=w[B])!=null&&V.name?`${w[B].name} (${w[B].email})`:B}}).sort((B,V)=>B.label.localeCompare(V.label))},[r,i,w]),ze=d.useMemo(()=>i.filter(b=>!(!Tj(b,g)||y.size>0&&!y.has(Le(b.profileId))||k.size>0&&!k.has(b.action)||v.size>0&&b.userId&&!v.has(b.userId)||!Ej(b,C))),[i,g,y,k,v,C]),kt=y.size>0||k.size>0||v.size>0||C!=="all";function Ve(b){x(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function et(b){N(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function mt(b){S(B=>{const V=new Set(B);return V.has(b)?V.delete(b):V.add(b),V})}function at(){x(new Set),N(new Set),S(new Set),A("all"),p("")}async function le(){L(!0),M(null);try{const{bundle:b,filename:B}=await E.fetchEvidenceBundle(),V=URL.createObjectURL(new Blob([JSON.stringify(b,null,2)],{type:"application/json"})),ne=document.createElement("a");ne.href=V,ne.download=B,ne.click(),URL.revokeObjectURL(V);const W=b.sources??{};W.authorityServer?W.local||M(`Downloaded Authority Server history only — ${W.localError??"local archive unavailable."}`):M(`Downloaded local evidence only — ${W.asError??"Authority Server export unavailable."}`)}catch(b){M(`Export failed: ${b instanceof Error?b.message:String(b)}`)}finally{L(!1)}}return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("h1",{className:"page-title",children:"Tickets"}),s.jsx("p",{className:"page-subtitle",children:"Execution history for agent actions."})]}),s.jsx("button",{className:"btn btn-secondary",onClick:le,disabled:D,children:D?"Preparing…":"Download evidence"})]}),q&&s.jsx("div",{style:{marginBottom:"1rem",color:"var(--text-tertiary)",fontSize:"0.875rem"},children:q}),n&&s.jsx("div",{style:{display:"flex",gap:"0.5rem",marginBottom:"1rem",borderBottom:"1px solid var(--border)"},children:["mine","team"].map(b=>s.jsx("button",{onClick:()=>a(b),className:"btn btn-ghost",style:{borderRadius:0,padding:"0.5rem 0.875rem",borderBottom:r===b?"2px solid var(--accent)":"2px solid transparent",color:r===b?"var(--text-primary)":"var(--text-tertiary)",fontWeight:r===b?600:500},children:b==="mine"?"Mine":"Team"},b))}),s.jsxs("div",{className:"search-filter-bar",children:[s.jsxs("div",{className:"search-input-wrap",children:[s.jsx("span",{className:"search-icon",children:"⌕"}),s.jsx("input",{type:"text",className:"form-input search-input",placeholder:"Search by profile, action, path, or hash\\u2026",value:g,onChange:b=>p(b.target.value)}),g&&s.jsx("button",{className:"search-clear",onClick:()=>p(""),children:"×"})]}),s.jsxs("button",{className:`btn btn-sm btn-secondary${T?" active":""}`,onClick:()=>_(!T),children:["Filters",kt?` (${y.size+k.size+(C!=="all"?1:0)})`:""]})]}),T&&s.jsxs("div",{className:"filter-panel",children:[ae.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Profile"}),s.jsx("div",{className:"filter-chips",children:ae.map(b=>s.jsx("button",{className:`filter-chip${y.has(b)?" selected":""}`,onClick:()=>Ve(b),children:b},b))})]}),ye.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Action"}),s.jsx("div",{className:"filter-chips",children:ye.map(b=>s.jsx("button",{className:`filter-chip${k.has(b)?" selected":""}`,onClick:()=>et(b),children:b},b))})]}),r==="team"&&me.length>1&&s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Owner"}),s.jsx("div",{className:"filter-chips",children:me.map(b=>s.jsx("button",{className:`filter-chip${v.has(b.id)?" selected":""}`,onClick:()=>mt(b.id),children:b.label},b.id))})]}),s.jsxs("div",{className:"filter-section",children:[s.jsx("div",{className:"filter-label",children:"Time range"}),s.jsx("div",{className:"filter-chips",children:[["1d","Today"],["7d","7 days"],["30d","30 days"],["all","All time"]].map(([b,B])=>s.jsx("button",{className:`filter-chip${C===b?" selected":""}`,onClick:()=>A(b),children:B},b))})]})]}),kt&&s.jsxs("div",{className:"active-filters",children:[[...y].map(b=>s.jsxs("span",{className:"active-chip",onClick:()=>Ve(b),children:[b," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)),[...k].map(b=>s.jsxs("span",{className:"active-chip",onClick:()=>et(b),children:[b," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)),[...v].map(b=>{const B=w[b],V=B?B.name:b;return s.jsxs("span",{className:"active-chip",onClick:()=>mt(b),children:[V," ",s.jsx("span",{className:"chip-remove",children:"×"})]},b)}),C!=="all"&&s.jsxs("span",{className:"active-chip",onClick:()=>A("all"),children:[C==="1d"?"Today":C==="7d"?"7 days":"30 days"," ",s.jsx("span",{className:"chip-remove",children:"×"})]}),s.jsx("button",{className:"clear-filters",onClick:at,children:"Clear all"})]}),J&&s.jsx("div",{className:"card",style:{borderColor:"var(--danger, #c0392b)",marginBottom:"0.75rem"},children:s.jsx("span",{style:{color:"var(--danger, #c0392b)",fontSize:"0.85rem"},children:"Couldn’t load tickets — your session may have expired. Try signing out and back in."})}),m&&i.length===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):ze.length===0?s.jsx(Ir,{icon:"⌕",title:i.length===0?"No tickets in the last 30 days":"No matching tickets",text:i.length===0?"Tickets appear here after an agent uses an authorized tool. Older tickets can be loaded below.":"Try adjusting your search or filters."}):s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.75rem"},children:ze.length===i.length?`${i.length} ticket${i.length!==1?"s":""}`:`${ze.length} of ${i.length} tickets`}),s.jsx("div",{className:"timeline",children:ze.map(b=>{const B=b.userId?w[b.userId]:void 0;return s.jsx("div",{className:"timeline-event",children:s.jsx(bj,{receipt:b,manifests:c,localAuth:b.authorizationId?X[b.authorizationId]:void 0,localUnavailable:se,signature:R[b.id],grantTitle:b.authorizationId?P[b.authorizationId]:null,ownerLabel:r==="team"&&b.userId?B?`${B.name} (${B.email})`:b.userId:null,spUrl:u,formatDate:Cj,onOpenComplete:()=>Q(b)})},b.id)})})]}),H&&s.jsx(Nj,{receipt:H,onClose:()=>Q(null)}),ee&&s.jsx("div",{style:{textAlign:"center",marginTop:"1rem"},children:s.jsx("button",{className:"btn btn-secondary btn-sm",onClick:G,disabled:de,children:de?"Loading…":"Load older"})})]})}function Rj(){const[e,t]=d.useState(null),[n,r]=d.useState({}),[a,i]=d.useState(!1),o=d.useCallback(()=>{E.getDenials({limit:200}).then(({records:l})=>{t(l),i(!1)}).catch(()=>i(!0))},[]);if(d.useEffect(()=>{o()},[o]),Tt(o,6e4),d.useEffect(()=>{if(!e)return;const l=[...new Set(e.map(u=>u.profile).filter(u=>!!u))].filter(u=>!(u in n));l.length!==0&&Promise.all(l.map(u=>E.getProfile(u).catch(()=>null))).then(u=>{r(f=>{const m={...f};return l.forEach((h,w)=>{u[w]&&(m[h]=u[w])}),m})})},[e,n]),a)return s.jsx(Ir,{icon:"⛔",title:"Could not load blocked actions",text:"Try again shortly."});if(e===null)return null;const c=Im(e,Date.now());return s.jsxs("div",{className:"blocked-page",children:[s.jsxs("div",{className:"page-header blocked-header",children:[s.jsx("h1",{className:"page-title",children:"Blocked actions"}),s.jsxs("span",{className:"blocked-today",children:[c," today · nothing ran"]})]}),e.length===0?s.jsx(Ir,{icon:"✓",title:"Nothing blocked",text:"Every call your agent made stayed within its mandate."}):s.jsx("div",{className:"blocked-list",children:e.map((l,u)=>{const f=Qx(l,l.profile?n[l.profile]:void 0);return s.jsxs("div",{className:"blocked-row","data-kind":Is(l),children:[s.jsx("span",{className:`blocked-dot blocked-dot-${Is(l)}`,"aria-hidden":"true"}),s.jsxs("div",{className:"blocked-row-main",children:[s.jsx("div",{className:"blocked-title",children:f.title}),s.jsx("div",{className:"blocked-sentence",children:f.sentence}),s.jsx("div",{className:"blocked-source",children:f.sourceLine}),s.jsxs("details",{children:[s.jsx("summary",{children:"What you can do"}),s.jsx("div",{className:"blocked-advice",children:f.whatYouCanDo})]})]}),s.jsx("div",{className:"blocked-when",children:new Date(l.ts).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})})]},`${l.ts}-${u}`)})})]})}const Aj={darwin:"a macOS login item",win32:"a Windows scheduled task",linux:"a systemd user service"};function Pj(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{t(await E.getAutostart())}catch(u){i(u instanceof Error?u.message:"Could not read autostart state")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(!(e!=null&&e.supported)||n)){r(!0),i(null);try{await E.setAutostart(!e.installed)}catch(u){i(u instanceof Error?u.message:"Failed")}finally{try{t(await E.getAutostart()),i(null)}catch(u){i(u instanceof Error?u.message:"Could not re-read state")}r(!1)}}},[e,n,o]);if(!e)return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Keep Suveren running"}),s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read autostart state: ${a}`:"Checking…"})]});const l=Aj[e.platform]??"a login service";return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Keep Suveren running"}),s.jsx("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:e.supported?s.jsxs(s.Fragment,{children:["Starts automatically when you log in, and restarts if it crashes. Uses ",l," — no admin rights needed."]}):e.reason})]}),e.supported&&s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e.installed,className:e.installed?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Working…":e.installed?"Turn off":"Turn on"})]}),e.supported&&s.jsxs("p",{style:{margin:"1rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:["Status: ",s.jsx("strong",{children:e.installed?"On — starts from your next login":"Off"})]}),e.supported&&s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:["Turning this on doesn't interrupt the gateway you're using — it takes effect at your next login. After any restart Suveren comes back ",s.jsx("strong",{children:"locked"}),": you enter your API key once to unlock it, because nothing stored on this machine can unlock it for you."]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger, #c00)"},children:a})]})}function _j(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{const l=await E.getGatewaySettings();t(l.desktopNotifications),i(null)}catch(l){i(l instanceof Error?l.message:"Could not read notification setting")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(e===null||n)){r(!0),i(null);try{const l=await E.setGatewaySettings({desktopNotifications:!e});t(l.desktopNotifications)}catch(l){i(l instanceof Error?l.message:"Failed to save"),await o()}finally{r(!1)}}},[e,n,o]);return e===null?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Desktop notifications"}),s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read the setting: ${a}`:"Checking…"})]}):s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Desktop notifications"}),s.jsx("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:"Tells you something is waiting for review — never what it is, and never with an approve button. Open Suveren to see and decide. At most one notification a minute; the browser tab always shows the count."})]}),s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e,className:e?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Saving…":e?"Turn off":"Turn on"})]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger)"},children:a})]})}const Td={as_vouched:"verified by",eudi:"verified with an EU digital identity (EUDI)"};function $j(){const[e,t]=d.useState(null),[n,r]=d.useState(!1),[a,i]=d.useState(null),o=d.useCallback(async()=>{try{t(await E.getIdentityDisclosure()),i(null)}catch(f){i(f instanceof Error?f.message:"Could not read the setting")}},[]);d.useEffect(()=>{o()},[o]);const c=d.useCallback(async()=>{if(!(!e||n)){r(!0),i(null);try{t(await E.setIdentityDisclosure(!e.always))}catch(f){i(f instanceof Error?f.message:"Failed to save"),await o()}finally{r(!1)}}},[e,n,o]),l=s.jsx("h3",{className:"card-title",style:{margin:0},children:"Your name on mandates and tickets"});if(!e)return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},children:[l,s.jsx("p",{role:a?"alert":void 0,style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:a?`Could not read the setting: ${a}`:"Checking…"})]});const u=e.verified&&e.name?`${e.name} — ${e.method==="as_vouched"?`${Td.as_vouched} ${e.verifier}`:Td[e.method??""]??e.method}`:null;return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[l,s.jsxs("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:[e.always?"On: your verified name is attached to every mandate you give — including ones the setup AI proposes and you approve — and to the tickets under them.":"Off: each mandate asks whether to show your name. Mandates the setup AI proposes carry no name."," ","Mandates already given stay as they are."]}),s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:u?`Your identity: ${u}.`:"Your identity is not verified yet — no name can be shown until it is."})]}),s.jsx("button",{type:"button",onClick:()=>void c(),disabled:n,"aria-pressed":e.always,className:e.always?"btn btn-secondary":"btn btn-primary",style:{whiteSpace:"nowrap"},children:n?"Saving…":e.always?"Turn off":"Always show my name"})]}),a&&s.jsx("p",{role:"alert",style:{margin:"0.75rem 0 0",fontSize:"0.85rem",color:"var(--danger)"},children:a})]})}const Lj={npm:"Checking npm for new releases",docker:"Checking the container registry for new images",dev:"Git checkout — comparing against origin/main, not npm releases",managed:"Checking npm for new releases — managed by your IT",msi:"Checking for new releases — update with the Windows installer"};function zj(){const{version:e,latestVersion:t,updateAvailable:n,installMethod:r}=jc();return e?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Version"}),s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:["Running ",s.jsx("strong",{children:e}),n&&t?s.jsxs(s.Fragment,{children:[" — ",s.jsx("strong",{children:t})," is available"]}):null]}),s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:[Lj[r]??"Update checking is unavailable",r==="dev"&&s.jsx(s.Fragment,{children:" — a development checkout is not told about published releases."})]})]}):null}function hl({title:e}){return s.jsxs("span",{className:"it-locked-badge",title:e,children:[s.jsx("span",{className:"lock-icon","aria-hidden":"true",children:"🔒"})," Set by your IT"]})}function Id(e){return e===!0}function Fj(){const[e,t]=d.useState(null),[n,r]=d.useState(null);d.useEffect(()=>{let o=!1;return E.getAsPairing().then(c=>{o||t(c)}).catch(c=>{o||r(c instanceof Error?c.message:"Could not read Authority Server info")}),()=>{o=!0}},[]);const a=Id(e==null?void 0:e.asUrlLockedByPolicy),i=Id(e==null?void 0:e.pinTlsLockedByPolicy);return s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Authority Server"}),a&&s.jsx(hl,{})]}),!e&&!n&&s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:"Checking…"}),n&&s.jsx("p",{role:"alert",style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--danger, #c00)"},children:n}),e&&s.jsxs(s.Fragment,{children:[s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"URL:"})," ",s.jsx("code",{children:e.asUrl})]}),e.paired&&e.fingerprint?s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"Key fingerprint:"})," ",s.jsx("code",{children:e.fingerprint}),s.jsx("br",{}),s.jsx("span",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Compare this with the fingerprint on the Authority Server's own admin page over a second channel (phone, video call) to confirm this gateway is talking to the right server."})]}):s.jsx("p",{style:{margin:"0.5rem 0 0",fontSize:"0.85rem",color:"var(--text-tertiary)"},children:"Not yet paired — sign in once to pin this server's key."}),(e.tlsPinFingerprint||e.pinTlsEnabled)&&s.jsxs("p",{style:{margin:"0.5rem 0 0",fontSize:"0.9rem",color:"var(--text-secondary)"},children:[s.jsx("strong",{children:"TLS certificate pin:"})," ",i&&s.jsx(hl,{title:"TLS pinning is set by your IT policy"})," ",e.tlsPinFingerprint?s.jsx("code",{children:e.tlsPinFingerprint}):s.jsxs("span",{style:{color:"var(--text-tertiary)"},children:["not yet captured — this URL has no recorded pairing over TLS",e.pinTlsEnabled?"; sign in to establish one (re-pairing required)":""]}),s.jsx("br",{}),s.jsxs("span",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:[e.pinTlsEnabled?s.jsxs(s.Fragment,{children:["TLS pinning is ON",i?s.jsx(s.Fragment,{children:", set by your organization's IT policy"}):s.jsxs(s.Fragment,{children:[" (",s.jsx("code",{children:"config set pin-tls on"}),")"]}),". Every connection to the Authority Server must present this certificate's public key, or the gateway refuses it and locks."]}):s.jsxs(s.Fragment,{children:["Captured at sign-in; not currently enforced",i?s.jsx(s.Fragment,{children:" — controlled by your organization's IT policy on this computer"}):s.jsxs(s.Fragment,{children:[" (",s.jsx("code",{children:"config set pin-tls on"})," to require it on every connection)"]}),"."]})," ","A certificate renewal with the SAME key keeps this pin; a NEW key needs re-pairing."]})]}),a?s.jsx("p",{style:{margin:"0.75rem 0 0",fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"This Authority Server URL is set by your organization's IT policy and cannot be changed from this computer. Contact your IT administrator if it needs to change."}):s.jsxs("p",{style:{margin:"0.75rem 0 0",fontSize:"0.8rem",color:"var(--text-tertiary)"},children:["To point this gateway at a different Authority Server:"," ",s.jsx("code",{children:"suveren-gateway config set as-url <url>"}),", then restart. Changing it ends the current sign-in and clears cached mandates — you sign in again against the new server."]})]})]})}function Mj(){const{simulation:e,locked:t}=Om();return t?s.jsxs("div",{className:"card",style:{padding:"1.5rem",marginTop:"2rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"1rem"},children:[s.jsxs("div",{children:[s.jsx("h2",{style:{fontSize:"1rem",fontWeight:700,margin:0},children:"Simulation mode"}),s.jsxs("p",{style:{color:"var(--text-secondary)",margin:"0.5rem 0 0",fontSize:"0.9rem"},children:['Blocks every real connector without a manifest "simulation" marker.',e!==null&&s.jsxs(s.Fragment,{children:[" ","Currently ",s.jsx("strong",{children:e?"ON":"OFF"}),e?" — real systems are not reachable from this gateway.":"."]})]})]}),s.jsx(hl,{})]}),s.jsxs("p",{style:{margin:"1rem 0 0",fontSize:"0.78rem",color:"var(--text-tertiary)"},children:["Simulation mode is set by your organization's IT policy",e!==null?` (currently ${e?"on":"off"})`:""," and cannot be changed from this computer — not even from the command line."]})]}):null}const Oj={ollama:{provider:"ollama",endpoint:"http://localhost:11434",models:["gemma4:e4b","gemma4:e2b","gemma4:26b","gemma4:31b","llama3.2","llama3.1","mistral","qwen2.5"]},openrouter:{provider:"openai-compatible",endpoint:"https://openrouter.ai/api/v1",models:["google/gemma-4-31b-it","qwen/qwen3.6-plus:free","stepfun/step-3.5-flash:free","google/gemini-2.5-flash","openai/gpt-4o-mini","anthropic/claude-haiku-4"]},openai:{provider:"openai-compatible",endpoint:"https://api.openai.com/v1",models:["gpt-4o-mini","gpt-4o","o3-mini"]},groq:{provider:"openai-compatible",endpoint:"https://api.groq.com/openai/v1",models:["llama-3.1-8b-instant","llama-3.3-70b-versatile","gemma2-9b-it"]},together:{provider:"openai-compatible",endpoint:"https://api.together.xyz/v1",models:["meta-llama/Llama-3-8b-chat-hf","meta-llama/Llama-3-70b-chat-hf"]}},Kr=["AI Assistant","Authority Server","This computer","Security","Version"],Yr={fontSize:"1rem",fontWeight:700,marginBottom:"1rem"};function Dj(){const[e,t]=d.useState(""),[n,r]=d.useState("openrouter"),[a,i]=d.useState("openai-compatible"),[o,c]=d.useState("https://openrouter.ai/api/v1"),[l,u]=d.useState("google/gemma-4-31b-it"),[f,m]=d.useState(""),[h,w]=d.useState(!1),[j,v]=d.useState(!1),[S,g]=d.useState(!1),[p,y]=d.useState(null),[x,k]=d.useState([]),[N,C]=d.useState(!1),[A,T]=d.useState(null),[_,D]=d.useState(""),L=d.useCallback(R=>{t(R),setTimeout(()=>t(""),3e3)},[]),q=d.useCallback(async(R,O,P)=>{C(!0),T(null);try{const z=await E.aiModels({provider:R,endpoint:O,...P?{apiKey:P}:{}});z.ok&&z.models.length>0?(k(z.models),T(`${z.models.length} models available`)):(k([]),T(z.message||"No models returned — using defaults"))}catch(z){k([]),T(z instanceof Error?z.message:"Failed to load models")}finally{C(!1)}},[]),M=d.useCallback(async()=>{try{const R=await E.getCredential("ai-config");if(w(R.configured),R.configured&&R.fields){const O=R.fields.provider||"openai-compatible",P=R.fields.endpoint||"";R.fields.provider&&i(O),R.fields.endpoint&&c(P),R.fields.model&&u(R.fields.model),P.includes("openai.com")?r("openai"):P.includes("groq.com")?r("groq"):P.includes("together.xyz")?r("together"):P.includes("openrouter.ai")?r("openrouter"):r("ollama"),P&&q(O,P)}}catch{}},[q]);d.useEffect(()=>{M()},[M]);const X=R=>{r(R),k([]),T(null),D("");const O=Oj[R];O&&(i(O.provider),c(O.endpoint),u(""),q(O.provider,O.endpoint,f||void 0))},re=()=>q(a,o,f||void 0),se=async()=>{v(!0);try{await E.setCredential("ai-config",{provider:a,endpoint:o,model:l,...f?{apiKey:f}:{}}),w(!0),L("AI configuration saved!")}catch{L("Failed to save AI config")}finally{v(!1)}},$=async()=>{g(!0),y(null);try{const R=await E.aiTest({provider:a,endpoint:o,model:l,...f?{apiKey:f}:{}});y(R.ok?`OK: ${R.message}`:`Failed: ${R.message}`)}catch(R){y(`Error: ${R instanceof Error?R.message:"Unknown"}`)}finally{g(!1)}};return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",children:[s.jsx("h1",{className:"page-title",children:"Settings"}),s.jsx("p",{className:"page-subtitle",children:"Your AI assistant, the connection to your Authority Server, security and version."})]}),e&&s.jsx("div",{className:"alert alert-success",children:e}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[0]}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",marginBottom:"1rem"},children:"Advisory AI to help you think through intent when giving mandates."}),s.jsxs("div",{className:"card",children:[s.jsx("h3",{className:"card-title",children:"Configuration"}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",marginBottom:"1rem"},children:"Connect a trusted AI model that has access to your intent — problem, objective, and tradeoffs — to help you think through mandates. Keys are encrypted in your vault."}),h&&s.jsxs("div",{className:"status-banner status-banner-success",style:{marginBottom:"1rem",fontSize:"0.8rem"},children:[s.jsx("span",{className:"status-banner-icon",children:"✓"}),s.jsx("span",{className:"status-banner-text",children:"AI configured"})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsx("label",{className:"form-label",children:"Provider Preset"}),s.jsxs("select",{className:"form-input",value:n,onChange:R=>X(R.target.value),children:[s.jsx("option",{value:"openrouter",children:"OpenRouter (recommended)"}),s.jsx("option",{value:"ollama",children:"Ollama (local)"}),s.jsx("option",{value:"openai",children:"OpenAI"}),s.jsx("option",{value:"groq",children:"Groq"}),s.jsx("option",{value:"together",children:"Together"})]})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsxs("label",{className:"form-label",children:["API Key ",a==="ollama"?"(not needed for Ollama)":"(required to load models)"]}),s.jsx("input",{className:"form-input",type:"password",name:"ai-provider-api-key-credential-top",autoComplete:"new-password",value:f,onChange:R=>m(R.target.value),onBlur:()=>{f.trim()&&q(a,o,f.trim())},placeholder:h?"••••••••••••••••":"sk-... (not needed for Ollama)"}),s.jsx("p",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",margin:"0.375rem 0 0"},children:"Each provider uses its own key — paste it and the model list loads automatically."})]}),s.jsxs("div",{className:"form-group",style:{marginBottom:"0.75rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[s.jsx("label",{className:"form-label",children:"Model"}),s.jsx("button",{type:"button",className:"btn btn-ghost",style:{fontSize:"0.75rem",padding:"0.125rem 0.5rem"},onClick:re,disabled:N,title:"Re-fetch the model list from the provider",children:N?"Loading…":"↻ Refresh"})]}),x.length===0?s.jsx("div",{className:"form-input",style:{display:"flex",alignItems:"center",minHeight:"2.5rem",color:"var(--text-secondary)",fontSize:"0.85rem"},children:N?"Loading models…":a==="ollama"?"Start Ollama locally, then ↻ Refresh to load models.":"Enter a valid API key above to load available models."}):(()=>{const R=x,O=R.includes(l),P=R.length>12,z=_.trim().toLowerCase();let H=z?R.filter(Q=>Q.toLowerCase().includes(z)):R;return O&&!H.includes(l)&&(H=[l,...H]),s.jsxs(s.Fragment,{children:[P&&s.jsx("input",{className:"form-input",value:_,onChange:Q=>D(Q.target.value),placeholder:"Filter models… (e.g. kimi)",style:{marginBottom:"0.375rem"}}),s.jsxs("select",{className:"form-input",value:O?l:"__unset__",onChange:Q=>u(Q.target.value==="__unset__"?"":Q.target.value),children:[s.jsx("option",{value:"__unset__",disabled:!0,children:"Select a model…"}),H.map(Q=>s.jsx("option",{value:Q,children:Q},Q)),z&&H.length===0&&s.jsxs("option",{value:"__unset__",disabled:!0,children:["No models match “",_,"”"]})]})]})})(),A&&s.jsx("p",{style:{fontSize:"0.75rem",color:"var(--text-secondary)",margin:"0.375rem 0 0"},children:A})]}),s.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[s.jsx("button",{className:"btn btn-primary",onClick:se,disabled:j||!l.trim(),title:l.trim()?void 0:"Select a model first",children:j?"Saving...":"Save & Encrypt"}),h&&s.jsx("button",{className:"btn btn-ghost",onClick:$,disabled:S,children:S?"Testing...":"Test Connection"})]}),p&&s.jsx("div",{className:`alert ${p.startsWith("OK")?"alert-success":"alert-error"}`,style:{marginTop:"0.75rem"},children:p})]}),s.jsx(Bj,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[1]}),s.jsx(Fj,{}),s.jsx($j,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[2]}),s.jsx(Pj,{}),s.jsx(_j,{}),s.jsx(Mj,{})]}),s.jsxs("section",{style:{marginBottom:"2rem"},children:[s.jsx("h2",{style:Yr,children:Kr[3]}),s.jsx("div",{className:"card",style:{padding:"1.5rem"},children:s.jsxs("div",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",lineHeight:1.7},children:[s.jsxs("div",{style:{marginBottom:"1rem"},children:[s.jsx("div",{style:{fontWeight:600,color:"var(--text-primary)",marginBottom:"0.375rem"},children:"What the gateway protects"}),s.jsxs("ul",{style:{margin:0,paddingLeft:"1.25rem"},children:[s.jsx("li",{children:"Every tool call verified against your mandate bounds"}),s.jsx("li",{children:"Credentials never exposed to agents through MCP"}),s.jsx("li",{children:"Every action produces a signed ticket"})]})]}),s.jsxs("div",{children:[s.jsx("div",{style:{fontWeight:600,color:"var(--text-primary)",marginBottom:"0.375rem"},children:"Your responsibility"}),s.jsxs("ul",{style:{margin:0,paddingLeft:"1.25rem"},children:[s.jsx("li",{children:"If your AI agent has full access to your computer, it could bypass the gateway"}),s.jsx("li",{children:"For best security, run agents in sandboxed environments"}),s.jsx("li",{children:"The gateway secures what agents do through tools — not what they do on your machine"})]})]})]})})]}),s.jsxs("section",{children:[s.jsx("h2",{style:Yr,children:Kr[4]}),s.jsx(zj,{})]})]})}function Bj(){const[e,t]=d.useState(null),[n,r]=d.useState({intent:"",context:""}),[a,i]=d.useState(null),[o,c]=d.useState(null),[l,u]=d.useState(null),[f,m]=d.useState(!1),h=d.useCallback(async()=>{if(!f)try{const v=await E.getAIPrompts();t(v),r({intent:v.intent.current,context:v.context.current}),m(!0)}catch(v){c(v instanceof Error?v.message:"Failed to load prompts")}},[f]),w=async v=>{if(e){i(v),c(null);try{const S=n[v],g=S.trim()===e[v].default.trim()?"":S;await E.setAIPrompt(v,g);const p=await E.getAIPrompts();t(p),r({intent:p.intent.current,context:p.context.current}),u(v),setTimeout(()=>u(null),2e3)}catch(S){c(S instanceof Error?S.message:"Save failed")}finally{i(null)}}},j=async v=>{if(confirm(`Revert ${v} prompt to the built-in default?`)){i(v),c(null);try{await E.setAIPrompt(v,"");const S=await E.getAIPrompts();t(S),r({intent:S.intent.current,context:S.context.current})}catch(S){c(S instanceof Error?S.message:"Revert failed")}finally{i(null)}}};return s.jsxs("details",{className:"card",style:{padding:"1.5rem",marginTop:"1rem"},onToggle:v=>{v.currentTarget.open&&h()},children:[s.jsx("summary",{style:{fontSize:"1rem",fontWeight:700,cursor:"pointer",listStyle:"revert",userSelect:"none"},children:"Advanced — AI assistant prompts"}),s.jsx("p",{style:{fontSize:"0.85rem",color:"var(--text-secondary)",margin:"0.75rem 0 1rem 0",lineHeight:1.55},children:"These are the system prompts the AI assistant sees when helping you write Intent (per-mandate) or Context (your standing-orders brief). Edit with care — changes apply on the next chat turn."}),o&&s.jsx("div",{className:"alert alert-error",style:{marginBottom:"0.75rem"},children:o}),!f&&!o&&s.jsx("p",{style:{color:"var(--text-muted)",fontSize:"0.85rem"},children:"Loading prompts…"}),e&&s.jsxs(s.Fragment,{children:[s.jsx(Rd,{kind:"intent",label:"Intent — per-mandate",description:"Used on the Intent gate when creating a new mandate.",state:e.intent,draft:n.intent,onChange:v=>r(S=>({...S,intent:v})),onSave:()=>w("intent"),onRevert:()=>j("intent"),saving:a==="intent",justSaved:l==="intent"}),s.jsx(Rd,{kind:"context",label:"Context — standing-orders brief",description:"Used on the Brief page when refining your context.md.",state:e.context,draft:n.context,onChange:v=>r(S=>({...S,context:v})),onSave:()=>w("context"),onRevert:()=>j("context"),saving:a==="context",justSaved:l==="context"})]})]})}function Rd({kind:e,label:t,description:n,state:r,draft:a,onChange:i,onSave:o,onRevert:c,saving:l,justSaved:u}){const f=a!==r.current;return s.jsxs("section",{style:{marginBottom:"1.5rem"},children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:"0.25rem",gap:"1rem",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{style:{fontWeight:600,fontSize:"0.9rem"},children:t}),s.jsx("div",{style:{fontSize:"0.78rem",color:"var(--text-secondary)"},children:n})]}),r.overridden&&s.jsx("span",{style:{fontSize:"0.7rem",color:"var(--accent)",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Custom"})]}),s.jsx("textarea",{className:"form-textarea",value:a,onChange:m=>i(m.target.value),rows:12,spellCheck:!1,style:{width:"100%",fontFamily:"'SF Mono', Monaco, 'Cascadia Code', monospace",fontSize:"0.82rem",lineHeight:1.55,resize:"vertical",minHeight:"14rem",marginTop:"0.5rem"},"aria-label":`${t} system prompt`}),s.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center",marginTop:"0.5rem",flexWrap:"wrap"},children:[s.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:o,disabled:l||!f,children:l?"Saving…":"Save"}),r.overridden&&s.jsx("button",{type:"button",className:"btn btn-ghost btn-sm",onClick:c,disabled:l,title:"Discard the override and use the built-in default",children:"Revert to default"}),u&&s.jsx("span",{style:{fontSize:"0.78rem",color:"var(--success)"},children:"Saved"}),f&&!l&&!u&&s.jsx("span",{style:{fontSize:"0.78rem",color:"var(--text-muted)"},children:"Unsaved changes"})]}),s.jsxs("details",{style:{marginTop:"0.5rem"},children:[s.jsx("summary",{style:{fontSize:"0.78rem",color:"var(--text-muted)",cursor:"pointer"},children:"Show built-in default"}),s.jsx("pre",{style:{marginTop:"0.5rem",padding:"0.75rem 1rem",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.5rem",fontSize:"0.78rem",lineHeight:1.55,whiteSpace:"pre-wrap",maxHeight:"20rem",overflowY:"auto"},children:r.default})]}),s.jsx("span",{style:{display:"none"},children:e})]})}function Uj(e){return e.proposalId?"review":"automatic"}function Ad(e,t,n={}){const r=n.status??"pending",a=n.includeAutonomous??!1,i=[];for(const o of e)r==="pending"&&o.status!=="pending"||n.profile&&o.profileId!==n.profile||i.push({kind:"proposal",id:o.id,sortTimestamp:o.createdAt,commitmentMode:"review",profileId:o.profileId,proposal:o});if(r==="all")for(const o of t){const c=Uj(o);!a&&c==="automatic"||n.profile&&o.profileId!==n.profile||i.push({kind:"receipt",id:o.id,sortTimestamp:o.timestamp,commitmentMode:c,profileId:o.profileId,receipt:o})}return i.sort((o,c)=>c.sortTimestamp-o.sortTimestamp),typeof n.limit=="number"&&n.limit>0?i.slice(0,n.limit):i}const Wj=["https://","http://"];function tp(e,t){return e!=null&&e.length?e.flatMap(n=>{const r=n.template.replace(/\{(\w+)\}/g,(a,i)=>{const o=t[i];return typeof o=="string"||typeof o=="number"?String(o):"\0"});return r.includes("\0")||/\{|\}/.test(r)?[]:Wj.some(a=>r.toLowerCase().startsWith(a))?[{label:n.label,href:r,description:n.description}]:[]}):[]}function np(e,t){const n=e-Math.floor(t/1e3);if(n<=0)return{label:"expired",urgent:!1,expired:!0};const r=Math.floor(n/86400),a=Math.floor(n%86400/3600),i=Math.floor(n%3600/60);let o;return r>0?o=`expires in ${r}d ${a}h`:a>0?o=`expires in ${a}h ${i}m`:o=`expires in ${Math.max(1,i)}m`,{label:o,urgent:n<2*3600,expired:!1}}const Hj=/^(image|img|photo|picture|thumbnail)(_?url)?$/i;function Vj(e,t){return typeof t!="string"?!1:/^data:image\//i.test(t)?!0:Hj.test(e)?/^https?:\/\//.test(t):/^https?:\/\/.+\.(jpe?g|png|gif|webp|svg|avif)(\?|$)/i.test(t)}function er(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);try{return JSON.stringify(e,null,2)}catch{return String(e)}}function Pd({row:e,which:t}){const n=Ds(e.profileRef),r=aj(e.value,n,t);return r.length===0?s.jsx("span",{style:{color:"var(--text-tertiary)"},children:"none"}):s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.15rem 0.75rem",margin:0},children:r.map(a=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-secondary)"},title:a.hint,children:a.label}),s.jsxs("dd",{style:{margin:0,fontWeight:600},children:[a.value,a.unknown&&s.jsx("span",{style:{color:"var(--danger)",fontWeight:400,marginLeft:"0.5rem"},children:"not defined by this profile"})]})]},a.key))})}function Gj({row:e}){const t=Ds(e.profileRef),n=(t==null?void 0:t.id)??e.profileRef??"";return s.jsxs(s.Fragment,{children:[(t==null?void 0:t.name)??Le(n),s.jsx("div",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:n})]})}function Kj({row:e,altText:t}){switch(e.kind){case"profile":return s.jsx(Gj,{row:e});case"profile-limits":return s.jsx(Pd,{row:e,which:"limits"});case"profile-scope":return s.jsx(Pd,{row:e,which:"scope"});case"markdown":return s.jsx("div",{style:{whiteSpace:"pre-wrap",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.375rem",padding:"0.5rem 0.625rem"},children:er(e.value)});case"list":return Array.isArray(e.value)?s.jsx("ul",{style:{margin:0,paddingLeft:"1.1rem"},children:e.value.map((n,r)=>s.jsx("li",{children:er(n)},r))}):s.jsx(s.Fragment,{children:er(e.value)});case"money":return s.jsxs(s.Fragment,{children:[er(e.value),e.currency?` ${e.currency}`:""]});case"object":return s.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",fontSize:"0.8rem"},children:er(e.value)});default:return Vj(e.key,e.value)?s.jsx("img",{src:e.value,alt:t??e.key,style:{display:"block",maxWidth:"100%",maxHeight:"240px",borderRadius:"0.375rem",border:"1px solid var(--border)"}}):s.jsx(s.Fragment,{children:er(e.value)})}}function rp({args:e,display:t,heading:n="Details"}){const r=sj(e,t);if(r.length===0)return null;const a=typeof e.altText=="string"?e.altText:void 0;return s.jsxs("div",{style:{marginBottom:"0.75rem"},children:[n&&s.jsx("div",{style:{fontSize:"0.7rem",fontWeight:600,color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em",marginBottom:"0.35rem"},children:n}),s.jsx("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.35rem 0.75rem",fontSize:"0.85rem",margin:0},children:r.map(i=>s.jsxs(d.Fragment,{children:[s.jsx("dt",{style:{color:"var(--text-tertiary)",whiteSpace:"nowrap",alignSelf:"start"},title:i.hint,children:i.label}),s.jsx("dd",{style:{color:"var(--text-primary)",margin:0,wordBreak:"break-word",whiteSpace:"pre-wrap"},children:s.jsx(Kj,{row:i,altText:a})})]},i.key))})]})}const _d=500;function ml(e){return e.length>_d?`${e.slice(0,_d)}…`:e}function $d(e){return e.length?e[0].toUpperCase()+e.slice(1):e}function Yj(e,t){switch(e.status){case"none":return e.reason==="no_target"?{heading:"Nothing to read beforehand",note:`This action does not refer to an existing record — nothing to read beforehand. Showing exactly what will be sent to ${t}.`}:{heading:"No preview declared",note:`No preview declared for this tool — showing exactly what will be sent to ${t}.`};case"unavailable":return e.reason==="no_connector"?{heading:"Preview not available",note:"Preview not available on this gateway."}:{heading:"Preview not available",note:e.message?`Preview not available — ${ml(e.message)}`:"Preview not available."};case"not_found":return{heading:"Not found in your system",note:e.message?`Not found in your system — ${ml(e.message)}`:"Not found in your system."};case"ok":{const n=fl(e.body,{fields:e.fields}),r={heading:`From ${t}, before it runs`,note:`Read by the gateway with ${e.tool} when you opened this card — the AI is not involved.`,rendered:n},a=e.version;if(a&&(r.versionNote=`You approve ${a.field} ${a.approved}; if it changes, ${t} refuses it.`,a.stale)){const i=wj(e.body,a.currentBody,{fields:e.fields,excludeKey:a.field});r.stale={heading:`A newer ${a.field} exists (${a.current})`,approvedLabel:`${$d(a.field)} ${a.approved}`,currentLabel:`${$d(a.field)} ${a.current}`,...i.unchanged?{unchangedNote:"No visible change in the fields."}:{approvedRendered:i.approved,currentRendered:i.current}}}return r}}}function Jj(e,t){if(e.state!=="failed")return null;const n=e.detail?ml(e.detail):void 0;return e.outcome==="changed"?{heading:"Changed since your approval",note:`The record changed in ${t} since you approved it — nothing was done. Ask the AI to request it again.`}:{heading:`Refused by ${t}`,note:`${t} refused it${n?`: ${n}`:""} — nothing was done. Ask the AI to request it again.`}}function Qj({proposalId:e,systemName:t}){const[n,r]=d.useState(null);if(d.useEffect(()=>{let i=!0;return r(null),E.getProposalOutcome(e).then(o=>{i&&r(o)}).catch(()=>{}),()=>{i=!1}},[e]),!n)return null;const a=Jj(n,t);return a?s.jsxs("div",{className:"outcome-box",children:[s.jsx("h4",{children:a.heading}),s.jsx("p",{className:"outcome-note",children:a.note})]}):null}function qj({proposalId:e,systemName:t}){const[n,r]=d.useState(null),[a,i]=d.useState(!1);if(d.useEffect(()=>{let l=!0;return r(null),i(!1),E.getProposalPreview(e).then(u=>{l&&r(u)}).catch(()=>{l&&i(!0)}),()=>{l=!1}},[e]),a)return s.jsxs("div",{className:"preview-box preview-box-unavailable","data-testid":"approval-preview","data-preview-status":"unavailable",children:[s.jsx("h4",{children:"Preview not available"}),s.jsx("p",{className:"preview-note",children:"Preview not available on this gateway."})]});if(!n)return s.jsxs("div",{className:"preview-box preview-box-loading","data-testid":"approval-preview","data-preview-status":"loading","aria-busy":"true",children:["Reading from ",t,"…"]});const o=Yj(n,t),c=n.status==="ok"?o.stale?"stale":"ok":n.status;return s.jsxs("div",{className:`preview-box preview-box-${c}`,"data-testid":"approval-preview","data-preview-status":c,children:[s.jsx("h4",{children:o.heading}),o.rendered&&s.jsx(Ta,{rendered:o.rendered}),s.jsx("p",{className:"preview-note",children:o.note}),o.versionNote&&!o.stale&&s.jsx("p",{className:"preview-note",children:o.versionNote}),o.stale&&s.jsxs("div",{className:"preview-stale",children:[s.jsx("h5",{children:o.stale.heading}),o.stale.unchangedNote?s.jsx("p",{className:"preview-note",children:o.stale.unchangedNote}):s.jsxs("dl",{style:{display:"grid",gridTemplateColumns:"max-content 1fr",gap:"0.3rem 0.75rem",fontSize:"0.85rem",margin:"0.5rem 0 0"},children:[s.jsx("dt",{children:o.stale.approvedLabel}),s.jsx("dd",{children:s.jsx(Ta,{rendered:o.stale.approvedRendered})}),s.jsx("dt",{children:o.stale.currentLabel}),s.jsx("dd",{children:s.jsx(Ta,{rendered:o.stale.currentRendered})})]})]})]})}let oo=null;function Xj(){return oo||(oo=E.getEnrichedAuthorizations().then(e=>new Map(e.map(t=>[t.authorizationId,t.bounds]))).catch(()=>new Map)),oo}function Zj(e){const[t,n]=d.useState(void 0);return d.useEffect(()=>{let r=!0;if(e)return Xj().then(a=>{r&&n(a.get(e))}),()=>{r=!1}},[e]),t}function eS(e,t){const[n,r]=d.useState(null),[a,i]=d.useState(!1),[o,c]=d.useState(null);return d.useEffect(()=>{let l=!0;return r(null),c(null),i(!0),(async()=>{try{const u=await E.getAttestationIntent(e);if(!u){l&&c("Intent not available or you are not an authorized approver.");return}const f=await E.decryptIntent({intentCiphertext:u.intentCiphertext,encryptedKey:u.encryptedKey,approverId:t});l&&r(f)}catch(u){l&&c(u instanceof Error?u.message:"Failed to decrypt intent")}finally{l&&i(!1)}})(),()=>{l=!1}},[e,t]),{intent:n,loading:a,error:o}}function sp(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e))return e.map(t=>sp(t)).join(", ");try{return JSON.stringify(e,null,2)}catch{return String(e)}}function ap({proposal:e,currentUserId:t,proposalLinks:n,toolDisplay:r,manifests:a}){const[i,o]=d.useState(!1),c=Object.entries(e.executionContext),l=Ds(e.profileId),u=Zj(e.authorizationId),f=dj(e.executionContext,u,l),m=tp(n,e.toolArgs),h=nj(e.tool),{integrationId:w}=_c(e.tool),j=Xm(w,a),{intent:v,loading:S,error:g}=eS(e.authorizationId,t);return s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"approval-headline",children:h}),s.jsx(qj,{proposalId:e.id,systemName:j}),f.length>0&&s.jsxs("div",{className:"limit-checks",children:[s.jsx("h4",{children:"Within your limits"}),s.jsx("ul",{className:"limit-check-list",children:f.map(p=>s.jsxs("li",{className:p.ok?"ok":"bad",children:[s.jsx("span",{className:"limit-check-icon",children:p.ok?"✓":"✗"}),s.jsxs("span",{children:[p.label," ",p.valueText," — your limit ",p.limitText]})]},p.key))})]}),s.jsxs("div",{className:"mandate-intent",children:[s.jsxs("dl",{children:[s.jsx("dt",{children:"Mandate"}),s.jsxs("dd",{children:[s.jsx("strong",{children:(l==null?void 0:l.name)??Le(e.profileId)}),s.jsx("span",{className:"src-tag src-tag-local",children:"local"})]})]}),s.jsxs("dl",{children:[s.jsx("dt",{children:"Intent"}),s.jsx("dd",{children:g?s.jsx("p",{style:{color:"var(--danger)",fontSize:"0.8rem",margin:0},children:g}):v!==null?s.jsxs(s.Fragment,{children:[s.jsx("p",{className:`intent-text${i?"":" intent-clamped"}`,children:v}),s.jsx("button",{className:"btn btn-ghost btn-sm intent-toggle",onClick:()=>o(!i),children:i?"Show less":"Show full intent"})]}):S?s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.8rem",margin:0},children:"Loading intent…"}):s.jsx("p",{style:{color:"var(--text-tertiary)",fontSize:"0.8rem",margin:0},children:"No intent available for this mandate."})})]})]}),m.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:m.map(p=>s.jsxs("a",{href:p.href,target:"_blank",rel:"noopener noreferrer",className:"btn btn-secondary btn-sm",style:{textDecoration:"none"},title:p.description??p.href,children:[p.label," ↗"]},p.label))}),s.jsxs("details",{className:"proposal-args-fold",style:{marginBottom:"0.75rem"},children:[s.jsx("summary",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",cursor:"pointer"},children:"Details (exactly what is bound)"}),s.jsxs("div",{style:{marginTop:"0.5rem"},children:[s.jsx(rp,{args:e.toolArgs,display:r,heading:""}),c.length>0&&s.jsx("div",{style:{fontSize:"0.85rem",color:"var(--text-secondary)"},children:c.map(([p,y],x)=>{const{label:k,hint:N}=Zm(p,l);return s.jsxs("span",{children:[x>0&&" · ",s.jsxs("span",{title:N,children:[k,"=",sp(y)]})]},p)})})]})]})]})}const tS={pending:"Pending",committed:"Approved",executed:"Executed",rejected:"Rejected",expired:"Expired"},nS={pending:"status-pending",committed:"status-active",executed:"status-active",rejected:"status-revoked",expired:"status-expired"};function rS(e){const t=Date.now()-e*1e3,n=t/36e5;return n<48?n<1?`${Math.max(1,Math.round(t/6e4))}m ago`:`${Math.round(n)}h ago`:new Date(e*1e3).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function sS(e){return e.split("__").pop()??e}function aS(e){const t=e.toLowerCase();return t.includes("delete")||t.includes("refund")||t.includes("cancel")||t.includes("revoke")}function ip(e){if(e==null)return"—";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e))return e.map(t=>ip(t)).join(", ");try{return JSON.stringify(e,null,2)}catch{return String(e)}}function Ld({item:e,onApprove:t,onReject:n,resolving:r,proposalLinks:a,toolDisplay:i,manifests:o,currentUserId:c}){const l=e.kind==="proposal",u=l?e.proposal.status:"executed",f=l?e.proposal.tool:e.receipt.action,m=sS(f),h=aS(f),{integrationId:w}=_c(f),j=Xm(w,o),v=Ds(e.profileId),S=l?e.proposal.toolArgs:null,g=l?e.proposal.executionContext:e.receipt.executionContext,p=l?null:e.receipt.cumulativeState,y=l?tp(a,e.proposal.toolArgs):[],x=Object.entries(g??{}),k=qn(e.profileId).testSetup||bi(f);return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem",flexWrap:"wrap"},children:[s.jsx("code",{style:{fontSize:"0.85rem"},children:m}),k&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),e.commitmentMode==="automatic"&&s.jsx("span",{style:{fontSize:"0.7rem",color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em"},children:"autonomous"}),s.jsxs("span",{style:{marginLeft:"auto",display:"flex",alignItems:"center",gap:"0.5rem"},children:[l&&u==="pending"&&(()=>{const N=np(e.proposal.expiresAt,Date.now());return s.jsx("span",{style:{fontSize:"0.72rem",color:N.urgent?"var(--warning)":"var(--text-tertiary)",fontWeight:N.urgent?600:400,whiteSpace:"nowrap"},children:N.label})})(),s.jsx("span",{className:`status-badge ${nS[u]}`,children:tS[u]}),s.jsx("span",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:rS(e.sortTimestamp)})]})]}),l&&e.proposal.status==="executed"&&s.jsx(Qj,{proposalId:e.proposal.id,systemName:j}),h&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem",fontSize:"0.8rem",color:"var(--warning)",background:"var(--bg-main)",border:"1px solid var(--border)",borderRadius:"0.375rem",padding:"0.4rem 0.6rem",marginBottom:"0.75rem"},children:[s.jsx("span",{children:"⚠"}),s.jsx("span",{children:"Irreversible action"})]}),l&&typeof(S==null?void 0:S._imagePreview)=="string"&&s.jsxs("div",{style:{marginBottom:"0.75rem"},children:[s.jsx("div",{style:{fontSize:"0.7rem",fontWeight:600,color:"var(--text-tertiary)",textTransform:"uppercase",letterSpacing:"0.04em",marginBottom:"0.35rem"},children:"Preview"}),s.jsx("img",{src:S._imagePreview,alt:typeof(S==null?void 0:S.altText)=="string"?S.altText:"local image preview",style:{display:"block",maxWidth:"100%",maxHeight:"240px",borderRadius:"0.375rem",border:"1px solid var(--border)"}})]}),l&&u==="pending"?s.jsx(ap,{proposal:e.proposal,currentUserId:c??"",proposalLinks:a,toolDisplay:i,manifests:o}):s.jsxs(s.Fragment,{children:[y.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:y.map(N=>s.jsxs("a",{href:N.href,target:"_blank",rel:"noopener noreferrer",className:"btn btn-secondary btn-sm",style:{textDecoration:"none"},title:N.description??N.href,children:[N.label," ↗"]},N.label))}),l?s.jsxs(s.Fragment,{children:[S&&s.jsx(rp,{args:S,display:i}),x.length>0&&s.jsx("div",{style:{marginBottom:"0.75rem",fontSize:"0.8rem",color:"var(--text-secondary)"},children:x.map(([N,C])=>`${N}=${ip(C)}`).join(" · ")})]}):s.jsx(ep,{receipt:e.receipt,profile:v})]}),p&&s.jsxs("div",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:["After this action · today: ",p.daily.count," action",p.daily.count===1?"":"s",p.daily.amount>0?`, ${p.daily.amount}`:""," · ","this month: ",p.monthly.count,p.monthly.amount>0?`, ${p.monthly.amount}`:""]}),l&&u==="pending"&&s.jsxs("div",{style:{display:"flex",gap:"0.5rem"},children:[s.jsx("button",{className:"btn btn-primary",onClick:()=>t==null?void 0:t(e.id),disabled:r,children:r?"Approving…":"Approve"}),s.jsx("button",{className:"btn btn-ghost",style:{color:"var(--danger)"},onClick:()=>n==null?void 0:n(e.id),disabled:r,children:"Reject"})]}),s.jsxs("div",{style:{marginTop:"0.5rem",fontSize:"0.7rem",color:"var(--text-tertiary)"},children:[l?"Proposal":"Ticket",": ",e.id]})]})]})}function iS(e){const t=Date.now()-e*1e3,n=Math.floor(t/6e4);if(n<60)return`${Math.max(1,n)}m ago`;const r=Math.floor(t/36e5);return r<48?`${r}h ago`:`${Math.floor(r/24)}d ago`}function oS({proposal:e,currentUserId:t,onAction:n,onMessage:r,proposalLinks:a,toolDisplay:i,manifests:o}){const[c,l]=d.useState(!1),[u,f]=d.useState(!1),m=qn(e.profileId).testSetup||bi(e.tool),h=e.pendingApprovers??[],w=e.approvedBy??{},j=Object.keys(w).length,v=h.filter(x=>!(x in w)).length,S=t in w,g=async()=>{if(Tc()){r(Ic);return}l(!0),r("");try{await E.approveProposal(e.id);try{const x=await E.getAttestationIntent(e.authorizationId);if(x){const k=await E.decryptIntent({intentCiphertext:x.intentCiphertext,encryptedKey:x.encryptedKey,approverId:t});await E.storeApprovedIntent(e.authorizationId,k)}}catch{}r(`Approved. ${v-1>0?`${v-1} more approver(s) still needed.`:"All approvers signed off — action is ready to execute."}`),n()}catch(x){r(x instanceof Error?x.message:"Approval failed")}finally{l(!1)}},p=async()=>{const x=prompt("Rejection reason (optional):");if(x!==null){f(!0),r("");try{await E.rejectProposal(e.id,x||void 0),r("Action rejected."),n()}catch(k){r(k instanceof Error?k.message:"Rejection failed")}finally{f(!1)}}},y=c||u;return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[s.jsx("span",{style:{fontSize:"0.65rem",padding:"0.15rem 0.4rem",borderRadius:"0.25rem",background:"var(--accent-subtle)",color:"var(--accent)",fontWeight:600},children:"Above cap"}),m&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),s.jsxs("span",{style:{marginLeft:"auto",display:"flex",alignItems:"center",gap:"0.5rem"},children:[(()=>{const x=np(e.expiresAt,Date.now());return s.jsx("span",{style:{fontSize:"0.72rem",color:x.urgent?"var(--warning)":"var(--text-tertiary)",fontWeight:x.urgent?600:400,whiteSpace:"nowrap"},children:x.label})})(),s.jsx("span",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)"},children:iS(e.createdAt)})]})]}),s.jsxs("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:[j," of ",h.length," approver",h.length===1?"":"s"," signed off",h.map(x=>{const k=x in w;return s.jsxs("span",{style:{marginLeft:"0.5rem",color:k?"var(--success, green)":"var(--text-tertiary)"},children:[k?"✓":"○"," ",x===t?"You":x]},x)})]}),s.jsx(ap,{proposal:e,currentUserId:t,proposalLinks:a,toolDisplay:i,manifests:o}),!S&&s.jsxs("div",{style:{display:"flex",gap:"0.5rem",marginTop:"0.25rem"},children:[s.jsx("button",{className:"btn btn-primary",onClick:g,disabled:y,children:c?"Approving...":"Approve"}),s.jsx("button",{className:"btn btn-ghost",style:{color:"var(--danger)"},onClick:p,disabled:y,children:u?"Rejecting...":"Reject"})]}),S&&s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginTop:"0.25rem"},children:"You approved this action. Waiting on other approvers."}),s.jsxs("div",{style:{marginTop:"0.5rem",fontSize:"0.7rem",color:"var(--text-tertiary)"},children:["Proposal: ",e.id]})]})]})}function lS(){const{domain:e,user:t}=He(),n=(t==null?void 0:t.id)??"",[r,a]=d.useState("awaiting-me"),[i,o]=d.useState([]),[c,l]=d.useState([]),[u,f]=d.useState({}),[m,h]=d.useState(!0),[w,j]=d.useState(""),v=d.useCallback(async()=>{try{const I=await E.getProposalsForApprover();o(I)}catch{}finally{h(!1)}},[]);ve("proposal-added",v),ve("proposal-approved",v),ve("proposal-rejected",v),ve("proposal-resolved",v),Tt(v,3e4);const[S,g]=d.useState([]),p=d.useCallback(async()=>{try{const I=await E.getMyProposals(e);g(I)}catch{}},[e]);ve("proposal-added",p),ve("proposal-approved",p),ve("proposal-rejected",p),ve("proposal-resolved",p),Tt(p,3e4,e);const y=d.useMemo(()=>S.filter(I=>{var G;return I.status==="pending"&&(((G=I.pendingApprovers)==null?void 0:G.length)??0)===0}),[S]),x=d.useMemo(()=>Ad(y,[],{status:"pending"}),[y]),[k,N]=d.useState([]),C=d.useCallback(async()=>{if(n)try{const G=(await E.getMyProposals(e)).filter(ae=>ae.status==="pending"&&ae.pendingApprovers&&ae.pendingApprovers.includes(n)&&ae.approvedBy&&n in ae.approvedBy);N(G)}catch{}},[n,e]);ve("proposal-approved",C),ve("proposal-rejected",C),Tt(C,3e4,`${n}:${e}`),d.useEffect(()=>{E.getIntegrationManifests().then(I=>l(I.manifests??[])).catch(()=>{}),E.getToolDisplay().then(f).catch(()=>{})},[]);const A=I=>{var G;return(G=c.find(ae=>ae.id===I.split("__")[0]))==null?void 0:G.proposalLinks};d.useEffect(()=>{v(),p(),C()},[]);const[T,_]=d.useState([]),[D,L]=d.useState([]),[q,M]=d.useState(!0),[X,re]=d.useState(null),[se,$]=d.useState(""),[R,O]=d.useState("pending"),[P,z]=d.useState(null),[H,Q]=d.useState(!1),ee=d.useCallback(async()=>{try{const{proposals:I,receipts:G}=await E.getThread({domain:e,status:R,sinceDays:7});_(I),L(G)}catch{}finally{M(!1)}},[e,R]);Tt(ee,3e4,`${e}:${R}`);const oe=async(I,G)=>{if(G==="commit"&&Tc()){$(Ic);return}re(I),$("");try{const ae=T.find(ze=>ze.id===I)??S.find(ze=>ze.id===I),ye=Sx(ae,e),me=await E.resolveProposal(I,G,ye);$(G==="commit"?`Action approved. Status: ${me.status}`:"Action rejected."),await Promise.all([ee(),p()])}catch(ae){$(ae instanceof Error?ae.message:"Failed")}finally{re(null)}},de=d.useMemo(()=>{const I=new Set;for(const G of T)I.add(G.profileId);for(const G of D)I.add(G.profileId);return Array.from(I).sort()},[T,D]),fe=d.useMemo(()=>Ad(T,D,{status:R,profile:P??void 0,includeAutonomous:H}),[T,D,R,P,H]),J=d.useCallback(()=>{v(),C()},[v,C]),he=d.useMemo(()=>{const I=new Set,G=[];for(const ae of k)I.has(ae.id)||(I.add(ae.id),G.push(ae));return G.sort((ae,ye)=>ye.createdAt-ae.createdAt)},[k]),te=i.length+x.length,ie=he.length;return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"page-header",children:[s.jsx("h1",{className:"page-title",children:"Pending Approvals"}),s.jsx("p",{className:"page-subtitle",children:"Actions awaiting approval, plus recent activity from the last 7 days."}),s.jsx(Fm,{what:"approve"})]}),s.jsxs("div",{className:"nav-tabs",style:{marginBottom:"1rem"},children:[s.jsxs("button",{className:`nav-tab${r==="awaiting-me"?" active":""}`,onClick:()=>a("awaiting-me"),children:["Awaiting me ",te>0&&s.jsx("span",{style:{marginLeft:"0.4rem",background:"var(--warning)",color:"var(--bg-elevated)",borderRadius:"0.625rem",padding:"0 0.375rem",fontSize:"0.7rem",fontWeight:600},children:te})]}),s.jsxs("button",{className:`nav-tab${r==="awaiting-others"?" active":""}`,onClick:()=>a("awaiting-others"),children:["Awaiting others ",ie>0&&s.jsx("span",{style:{marginLeft:"0.4rem",background:"var(--border)",color:"var(--text-secondary)",borderRadius:"0.625rem",padding:"0 0.375rem",fontSize:"0.7rem",fontWeight:600},children:ie})]}),s.jsx("button",{className:`nav-tab${r==="all"?" active":""}`,onClick:()=>{a("all"),ee()},children:"All"})]}),r==="awaiting-me"&&s.jsx(s.Fragment,{children:m&&te===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):te===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:"No actions awaiting your approval."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Review-mode actions and above-cap actions you must approve will appear here."})]}):s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[(w||se)&&s.jsx("div",{className:"alert alert-success",children:w||se}),x.map(I=>s.jsx(Ld,{proposalLinks:I.kind==="proposal"?A(I.proposal.tool):void 0,toolDisplay:I.kind==="proposal"?u[I.proposal.tool]:void 0,manifests:c,currentUserId:n,item:I,onApprove:G=>oe(G,"commit"),onReject:G=>oe(G,"reject"),resolving:X===I.id},I.id)),i.map(I=>s.jsx(oS,{proposal:I,currentUserId:n,onAction:J,onMessage:j,proposalLinks:A(I.tool),toolDisplay:u[I.tool],manifests:c},I.id))]})}),r==="awaiting-others"&&s.jsx(s.Fragment,{children:he.length===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:"No actions waiting on others."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:"Actions you proposed or approved that are pending other approvers will appear here."})]}):s.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:he.map(I=>s.jsx(uS,{proposal:I,currentUserId:n,onCancel:async()=>{try{await E.rejectProposal(I.id,"cancelled by creator"),C(),p()}catch(G){alert(G instanceof Error?G.message:"Cancel failed")}}},I.id))})}),r==="all"&&s.jsxs(s.Fragment,{children:[se&&s.jsx("div",{className:"alert alert-success",style:{marginBottom:"1rem"},children:se}),s.jsxs("div",{className:"filter-chips",style:{marginBottom:"1rem"},children:[s.jsx("button",{className:`filter-chip ${R==="pending"?"selected":""}`,onClick:()=>O("pending"),children:"Pending"}),s.jsx("button",{className:`filter-chip ${R==="all"?"selected":""}`,onClick:()=>O("all"),children:"All"}),de.length>0&&s.jsx("span",{style:{width:1,background:"var(--border)",alignSelf:"stretch",margin:"0 0.25rem"}}),de.map(I=>s.jsx("button",{className:`filter-chip ${P===I?"selected":""}`,onClick:()=>z(P===I?null:I),children:Le(I)},I)),R==="all"&&s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{width:1,background:"var(--border)",alignSelf:"stretch",margin:"0 0.25rem"}}),s.jsxs("button",{className:`filter-chip ${H?"selected":""}`,onClick:()=>Q(!H),title:"Include actions executed without human review (automatic commitment mode)",children:[H?"✓ ":"","Autonomous actions"]})]})]}),q&&fe.length===0?s.jsx("p",{style:{color:"var(--text-tertiary)"},children:"Loading..."}):fe.length===0?s.jsxs("div",{className:"card",style:{textAlign:"center",padding:"2rem"},children:[s.jsx("p",{style:{color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:R==="pending"?"No actions awaiting your approval.":"Nothing here yet."}),s.jsx("p",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)"},children:R==="pending"?"Your agents are operating within their mandates. Switch to All to see recent activity.":"When an agent calls a gated tool, activity will appear here."})]}):s.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:fe.map(I=>s.jsx(Ld,{proposalLinks:I.kind==="proposal"?A(I.proposal.tool):void 0,toolDisplay:I.kind==="proposal"?u[I.proposal.tool]:void 0,manifests:c,currentUserId:n,item:I,onApprove:G=>oe(G,"commit"),onReject:G=>oe(G,"reject"),resolving:X===I.id},I.id))})]})]})}function cS(e){const t=Date.now()-e*1e3,n=Math.floor(t/6e4);if(n<60)return`${Math.max(1,n)}m ago`;const r=Math.floor(t/36e5);return r<48?`${r}h ago`:`${Math.floor(r/24)}d ago`}function uS({proposal:e,currentUserId:t,onCancel:n}){var f;const[r,a]=d.useState(!1),i=Object.keys(e.approvedBy??{}),o=(e.pendingApprovers??[]).filter(m=>!(m in(e.approvedBy??{}))),c=(((f=e.pendingApprovers)==null?void 0:f.length)??0)>0,l=async()=>{if(confirm("Cancel this action? All approvers will be notified.")){a(!0);try{await n()}finally{a(!1)}}},u=qn(e.profileId).testSetup||bi(e.tool);return s.jsxs("div",{className:"card id-card",children:[s.jsx(Ms,{profileId:e.profileId}),s.jsxs("div",{className:"id-body",children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.5rem",flexWrap:"wrap"},children:[s.jsx("code",{style:{fontSize:"0.85rem"},children:e.tool.split("__").pop()??e.tool}),u&&s.jsx("span",{className:"sim-mark",children:"Test setup"}),c&&s.jsx("span",{style:{fontSize:"0.65rem",padding:"0.15rem 0.4rem",borderRadius:"0.25rem",background:"var(--accent-subtle)",color:"var(--accent)",fontWeight:600},children:"Above cap"}),s.jsx("span",{style:{marginLeft:"auto",fontSize:"0.75rem",color:"var(--text-tertiary)"},children:cS(e.createdAt)})]}),c&&s.jsxs("div",{style:{fontSize:"0.8rem",color:"var(--text-tertiary)",marginBottom:"0.5rem"},children:[i.map(m=>s.jsx("span",{style:{marginRight:"0.75rem",color:"var(--success, green)"},children:m===t?"You approved":`${m} approved`},m)),o.map(m=>s.jsxs("span",{style:{marginRight:"0.75rem",color:"var(--text-tertiary)"},children:["Waiting on ",m===t?"you":m]},m))]}),s.jsx("div",{style:{display:"flex",justifyContent:"flex-end",gap:"0.5rem",marginTop:"0.5rem"},children:s.jsx("button",{className:"btn btn-ghost btn-sm",style:{color:"var(--danger)"},onClick:l,disabled:r,children:r?"Cancelling...":"Cancel"})})]})]})}const dS=`# Agent Brief
|
|
84
84
|
|
|
85
85
|
You act on my behalf through Suveren — the gateway that gates every
|
|
86
86
|
privileged tool call you make. Suveren implements the bounded-authority
|
package/dist/ui/index.html
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<meta name="apple-mobile-web-app-title" content="Suveren" />
|
|
15
15
|
<meta name="theme-color" content="#111111" />
|
|
16
16
|
<title>Suveren</title>
|
|
17
|
-
<script type="module" crossorigin src="/assets/index-
|
|
17
|
+
<script type="module" crossorigin src="/assets/index-BbNwMAOD.js"></script>
|
|
18
18
|
<link rel="stylesheet" crossorigin href="/assets/index-C604QQYJ.css">
|
|
19
19
|
</head>
|
|
20
20
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suveren/gateway",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.2",
|
|
4
4
|
"description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|