@prooflane/inspector-beta 0.1.0-beta.14 → 0.1.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs
CHANGED
|
@@ -18889,7 +18889,7 @@ var POLICY_CACHE_VERSION = "prooflane-policy-cache-v1";
|
|
|
18889
18889
|
var HASH2 = /^sha256:[a-f0-9]{64}$/;
|
|
18890
18890
|
var CACHE_SEGMENT = /^[a-f0-9]{64}$/;
|
|
18891
18891
|
var ID5 = /^[A-Za-z0-9][A-Za-z0-9_.:/-]{1,159}$/;
|
|
18892
|
-
var ORGANIZATION = /^[A-Za-z0-9][A-Za-z0-9_
|
|
18892
|
+
var ORGANIZATION = /^[A-Za-z0-9][A-Za-z0-9_.:@|/-]{1,159}$/;
|
|
18893
18893
|
var PROJECT3 = /^[A-Za-z0-9][A-Za-z0-9_.:-]{1,127}$/;
|
|
18894
18894
|
var SLUG2 = /^[a-z0-9][a-z0-9_-]{1,63}$/;
|
|
18895
18895
|
var MAX_CACHE_FILES = 2e4;
|
|
@@ -19812,7 +19812,7 @@ var MAX_CI_TOKEN_LIFETIME_SECONDS = 90 * 24 * 60 * 60;
|
|
|
19812
19812
|
var MAX_CLOCK_SKEW_SECONDS = 300;
|
|
19813
19813
|
var MAX_TOKEN_LENGTH = 16384;
|
|
19814
19814
|
var MAX_CONTEXT_LENGTH = 32768;
|
|
19815
|
-
var principalPattern2 = /^[A-Za-z0-9][A-Za-z0-9_
|
|
19815
|
+
var principalPattern2 = /^[A-Za-z0-9][A-Za-z0-9_.:@|/-]{1,159}$/;
|
|
19816
19816
|
var projectPattern4 = /^[A-Za-z0-9][A-Za-z0-9_.:-]{1,127}$/;
|
|
19817
19817
|
var hashPattern5 = /^sha256:[a-f0-9]{64}$/;
|
|
19818
19818
|
var base64urlPattern = /^[A-Za-z0-9_-]+$/;
|
|
@@ -20129,7 +20129,7 @@ import { createHash as createHash24, randomUUID as randomUUID11 } from "node:cry
|
|
|
20129
20129
|
import { closeSync as closeSync5, constants as constants4, existsSync as existsSync5, fstatSync as fstatSync5, linkSync as linkSync4, lstatSync as lstatSync4, mkdirSync as mkdirSync6, openSync as openSync5, readFileSync as readFileSync7, readdirSync as readdirSync3, rmdirSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
20130
20130
|
import { dirname as dirname7, join as join8, resolve as resolve9 } from "node:path";
|
|
20131
20131
|
var QUEUE_VERSION = "prooflane-offline-run-sync-v1";
|
|
20132
|
-
var PRINCIPAL = /^[A-Za-z0-9][A-Za-z0-9_
|
|
20132
|
+
var PRINCIPAL = /^[A-Za-z0-9][A-Za-z0-9_.:@|/-]{1,159}$/;
|
|
20133
20133
|
var PROJECT4 = /^[A-Za-z0-9][A-Za-z0-9_.:-]{1,127}$/;
|
|
20134
20134
|
var RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_.:/-]{1,159}$/;
|
|
20135
20135
|
var QUEUE_KEY = /^(?:offline|github):[a-f0-9]{64}$/;
|
|
@@ -69,8 +69,10 @@ ${B.join(`
|
|
|
69
69
|
PROOFLANE_TOKEN=<the token shown above>
|
|
70
70
|
PROOFLANE_PROJECT=${o??"<project-id>"}
|
|
71
71
|
|
|
72
|
-
npx --yes @prooflane/
|
|
72
|
+
npx --yes @prooflane/inspector-beta@beta gate "$PROOFLANE_CONNECTIONS" \\
|
|
73
|
+
--target <connection-id> \\
|
|
73
74
|
--gate ${t} \\
|
|
75
|
+
--project ${o??"<project-id>"} \\
|
|
74
76
|
--github`;return s.jsx("div",{className:"modal-backdrop",onClick:e,children:s.jsxs("div",{className:"modal",onClick:w=>w.stopPropagation(),style:{maxWidth:640},children:[s.jsx("div",{className:"screen-title",style:{marginBottom:4},children:"Scoped GitHub CI token"}),s.jsx("div",{className:"screen-sub",style:{marginBottom:14},children:"This project-bound service credential resolves the approved signed Gate, its exact Suite and Policy pins, and creates compact Run records. It cannot write governance state or administer Prooflane."}),s.jsxs("div",{className:"card mono",style:{padding:10,fontSize:11,marginBottom:14},children:["GitHub selector: --gate ",t,s.jsx("br",{}),s.jsx("span",{className:"muted",children:"The immutable slug is used in CI; changing the Gate display name does not change this command."})]}),n?s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"card mono",style:{padding:12,fontSize:12,wordBreak:"break-all",background:"var(--panel-2, rgba(128,128,128,0.06))"},children:n}),s.jsxs("div",{className:"row spread",style:{marginTop:8,alignItems:"center"},children:[s.jsxs("span",{className:"muted",style:{fontSize:11.5},children:["Expires ",r?new Date(r*1e3).toLocaleDateString():"in 90 days"," · shown once — copy it now."]}),s.jsx("button",{className:"btn sm ghost",onClick:j,children:b?"Copied ✓":"Copy token"})]}),s.jsxs("div",{className:"mono muted",style:{fontSize:10.5,marginTop:8},children:["Project ",o," · scopes ",c.join(", ")]}),s.jsx("div",{className:"section-label",style:{marginTop:16},children:"GitHub Actions command"}),s.jsx("pre",{className:"card mono",style:{padding:12,fontSize:11.5,whiteSpace:"pre-wrap",lineHeight:1.5,margin:0,overflowX:"auto"},children:S}),s.jsx("div",{className:"row",style:{justifyContent:"flex-end",marginTop:16},children:s.jsx("button",{className:"btn primary",onClick:e,children:"Done"})})]}):s.jsxs(s.Fragment,{children:[g&&s.jsx("div",{className:"drift dirty",style:{marginBottom:12},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:`tag ${f?"warn":"fail"}`,children:f?"upgrade":"error"}),s.jsx("span",{style:{fontSize:12.5},children:g})]})}),s.jsxs("div",{className:"row",style:{justifyContent:"flex-end",gap:8},children:[s.jsx("button",{className:"btn ghost",onClick:e,children:"Cancel"}),s.jsx("button",{className:"btn primary",onClick:x,disabled:d,children:d?"Generating…":"Generate CI token"})]})]})]})})}const m5={tool:"Tool",security:"Security",rag:"RAG",prompt:"Prompt",contract:"Contract",performance:"Performance"},f5=["mcp-protocol","tool-abuse","resource"];function aC(e){var t,n,a;if(e.determinism)return e.determinism;if(e.pillar==="tool"||e.pillar==="contract")return"deterministic";if(e.pillar==="security"){const r=e.security,i=!!((t=r==null?void 0:r.packs)!=null&&t.length||(n=r==null?void 0:r.categories)!=null&&n.length||(a=r==null?void 0:r.attackIds)!=null&&a.length),o=(r==null?void 0:r.layers)??[];return!i&&o.length&&o.every(l=>f5.includes(l))?"deterministic":"non-deterministic"}return"non-deterministic"}function Fv(e){return`tag-${e}`.replace(/[^A-Za-z0-9_.:/-]+/g,"-").slice(0,128)}function g5(e){var t,n;return e.pillar==="tool"||e.pillar==="contract"?aC(e)==="deterministic":e.pillar!=="rag"||e.determinism==="non-deterministic"||!((t=e.rag)!=null&&t.tool)||(n=e.rag.expectedAnswer)!=null&&n.length?!1:e.rag.judgeStrategy===void 0||e.rag.judgeStrategy==="deterministic"}function rC(e,t,n){const a=t.filter(l=>l.tags.includes(e)),r=[...new Set(a.map(l=>l.pillar))],i=r.length===1&&["prompt","rag","contract","security","performance","tool","model"].includes(r[0])?r[0]:"tool",o=Fv(e);if(a.length>0&&a.every(g5)){const l=n[e];return{id:o,label:`Reviewed test group #${e}`,pillar:i,executionType:"LOCAL_DETERMINISTIC",executor:"TAG_REFERENCE",operation:"tag.execute",localRef:{kind:"TAG",name:e},...l?{parameters:{tagSnapshot:l}}:{}}}return{id:o,label:`Reviewed test group #${e}`,pillar:i,executionType:"LEASED_INTELLIGENCE",intelligenceRef:{controlId:o,leaseRequired:!0}}}function iC(e){return e.some(t=>t.executionType==="LEASED_INTELLIGENCE")?"HYBRID":"LOCAL_ONLY"}function v5({tags:e,tests:t,tagSnapshots:n,policies:a,targetFingerprint:r,requiredCapabilities:i,onSave:o,onClose:l}){var _;const[c,u]=p.useState(""),[d,h]=p.useState(""),[g,v]=p.useState([]),f=a.filter(N=>{var $;return($=N.approvedVersion)==null?void 0:$.manifestHash}),[y,b]=p.useState(((_=f[0])==null?void 0:_.policy.id)??""),[m,x]=p.useState(!1),[j,S]=p.useState(null),w=c.toLowerCase().trim().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64),C=async()=>{var E;const N=f.find(k=>k.policy.id===y);if(w.length<2||!g.length||!((E=N==null?void 0:N.approvedVersion)!=null&&E.manifestHash)){S("Give the Suite a name, select a reviewed test group, and choose an APPROVED signed Policy.");return}const $=g.map(k=>rC(k,t,n));x(!0),S(null);try{await o({slug:w,displayName:c.trim(),...d.trim()?{description:d.trim()}:{},manifest:{schemaVersion:"prooflane-suite-manifest-v1",executionClass:iC($),controls:$,...r?{targetFingerprint:r}:{},...i!=null&&i.length?{requiredCapabilities:i}:{},policyRef:{policyId:N.policy.id,version:N.approvedVersion.version,manifestHash:N.approvedVersion.manifestHash},privacy:{rawEvidence:"LOCAL_ONLY",synchronization:"COMPACT_ONLY"}}}),l()}catch(k){S(k instanceof Error?k.message:"Could not create the Cloud Suite.")}finally{x(!1)}};return s.jsx("div",{className:"modal-backdrop",onClick:l,children:s.jsxs("div",{className:"modal",onClick:N=>N.stopPropagation(),style:{maxWidth:680},children:[s.jsx("div",{className:"screen-title",children:"Review & import local tests"}),s.jsx("div",{className:"screen-sub",style:{marginBottom:16},children:"Select captured tag snapshots and create a new Cloud Suite DRAFT. This does not approve a Suite, move a Policy pin, or sign a Gate; those remain explicit transitions on the Gate workflow."}),s.jsxs("label",{className:"field",children:[s.jsx("span",{children:"Cloud Suite name"}),s.jsx("input",{value:c,onChange:N=>u(N.target.value),placeholder:"RAG nightly"})]}),s.jsxs("div",{className:"mono muted",style:{fontSize:11.5,marginTop:5},children:["Suite identity: ",w||"rag-nightly"]}),s.jsxs("label",{className:"field",style:{marginTop:14},children:[s.jsx("span",{children:"Description"}),s.jsx("textarea",{value:d,maxLength:600,onChange:N=>h(N.target.value),placeholder:"Nightly governed RAG regression Suite"})]}),s.jsxs("label",{className:"field",style:{marginTop:14},children:[s.jsx("span",{children:"Approved Policy"}),s.jsxs("select",{value:y,onChange:N=>b(N.target.value),children:[s.jsx("option",{value:"",children:"Choose a signed Policy"}),f.map(N=>s.jsxs("option",{value:N.policy.id,children:[N.policy.displayName," · v",N.approvedVersion.version]},N.policy.id))]})]}),!f.length&&s.jsx("div",{className:"muted",style:{fontSize:12,marginTop:7},children:"Create, review, and approve a Policy before this Suite can become executable."}),s.jsx("div",{className:"section-label",style:{marginTop:16},children:"Reviewed test groups"}),s.jsx("div",{className:"row",style:{gap:8,flexWrap:"wrap"},children:e.map(N=>s.jsxs("button",{className:`btn sm ${g.includes(N)?"primary":"ghost"}`,onClick:()=>v($=>$.includes(N)?$.filter(E=>E!==N):[...$,N]),children:["#",N]},N))}),g.map(N=>{var $,E;return s.jsxs("div",{className:"card",style:{padding:"9px 11px",marginTop:8},children:[s.jsxs("div",{className:"row spread",children:[s.jsxs("strong",{children:["#",N]}),s.jsxs("span",{className:"tag informational",children:[(($=n[N])==null?void 0:$.testCount)??0," TESTS"]})]}),s.jsx("div",{className:"mono muted",style:{fontSize:10.5,marginTop:5},children:((E=n[N])==null?void 0:E.fingerprint)??"Snapshot unavailable — refresh required"}),s.jsx("div",{className:"muted",style:{fontSize:11,marginTop:5},children:t.filter(k=>k.tags.includes(N)).map(k=>k.name).join(" · ")})]},`preview:${N}`)}),!e.length&&s.jsx("div",{className:"muted",style:{fontSize:12},children:"Capture and tag a test before creating a Suite."}),j&&s.jsx("div",{className:"drift dirty",style:{marginTop:12},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{children:j})]})}),s.jsxs("div",{className:"row",style:{justifyContent:"flex-end",gap:8,marginTop:18},children:[s.jsx("button",{className:"btn ghost",onClick:l,children:"Cancel"}),s.jsx("button",{className:"btn primary",disabled:m||!e.length,onClick:C,children:m?"Creating DRAFT…":"Create Cloud Suite DRAFT"})]})]})})}function y5({entry:e,tags:t,tests:n,tagSnapshots:a,policies:r,currentTargetFingerprint:i,currentRequiredCapabilities:o,onSave:l,onClose:c}){var w,C;const u=t.filter(_=>e.latestVersion.manifest.controls.some(N=>N.id===Fv(_))),[d,h]=p.useState(u),g=r.filter(_=>{var N;return(N=_.approvedVersion)==null?void 0:N.manifestHash}),[v,f]=p.useState(((w=e.latestVersion.manifest.policyRef)==null?void 0:w.policyId)??((C=g[0])==null?void 0:C.policy.id)??""),[y,b]=p.useState(!1),[m,x]=p.useState(null),j=e.latestVersion.state!=="DRAFT",S=async()=>{var k;const _=new Set(t.map(Fv)),N=e.latestVersion.manifest.controls.filter(T=>!_.has(T.id)),$=d.map(T=>rC(T,n,a)),E=g.find(T=>T.policy.id===v);if(!N.length&&!$.length){x("Select at least one reviewed test group.");return}if(!((k=E==null?void 0:E.approvedVersion)!=null&&k.manifestHash)){x("Choose an APPROVED signed Policy.");return}b(!0),x(null);try{const T=[...N,...$];await l({...e.latestVersion.manifest,executionClass:iC(T),controls:T,...i?{targetFingerprint:i}:{},...o!=null&&o.length?{requiredCapabilities:o}:{},policyRef:{policyId:E.policy.id,version:E.approvedVersion.version,manifestHash:E.approvedVersion.manifestHash}}),c()}catch(T){x(T instanceof Error?T.message:"Could not save the Suite version.")}finally{b(!1)}};return s.jsx("div",{className:"modal-backdrop",onClick:c,children:s.jsxs("div",{className:"modal",onClick:_=>_.stopPropagation(),style:{maxWidth:680},children:[s.jsx("div",{className:"screen-title",children:j?`Create v${e.latestVersion.version+1} DRAFT`:`Edit ${e.suite.slug}@${e.latestVersion.version}`}),s.jsx("div",{className:"screen-sub",style:{marginBottom:16},children:j?`Version ${e.latestVersion.version} is immutable. Saving creates a new DRAFT that supersedes it; the approved alias does not move.`:"Only a DRAFT can be changed. Review freezes its manifest before signing."}),s.jsx("div",{className:"section-label",children:"Reviewed test groups"}),s.jsx("div",{className:"row",style:{gap:8,flexWrap:"wrap"},children:t.map(_=>s.jsxs("button",{className:`btn sm ${d.includes(_)?"primary":"ghost"}`,onClick:()=>h(N=>N.includes(_)?N.filter($=>$!==_):[...N,_]),children:["#",_]},_))}),s.jsxs("label",{className:"field",style:{marginTop:14},children:[s.jsx("span",{children:"Exact approved Policy pin"}),s.jsxs("select",{value:v,onChange:_=>f(_.target.value),children:[s.jsx("option",{value:"",children:"Choose a signed Policy"}),g.map(_=>s.jsxs("option",{value:_.policy.id,children:[_.policy.displayName," · v",_.approvedVersion.version]},_.policy.id))]})]}),m&&s.jsx("div",{className:"drift dirty",style:{marginTop:12},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{children:m})]})}),s.jsxs("div",{className:"row",style:{justifyContent:"flex-end",gap:8,marginTop:18},children:[s.jsx("button",{className:"btn ghost",onClick:c,children:"Cancel"}),s.jsx("button",{className:"btn primary",disabled:y,onClick:S,children:y?"Saving…":j?"Create new DRAFT":"Save DRAFT"})]})]})})}function x5({onSynchronized:e}){const[t,n]=p.useState(null),[a,r]=p.useState(!1),[i,o]=p.useState([]),[l,c]=p.useState(!1),[u,d]=p.useState(null),h=async()=>{try{const f=await M.localSuiteMigrationStatus();n(f),o(f.suites.filter(y=>y.action==="CREATE_SUITE_DRAFT"||y.action==="CREATE_VERSION_DRAFT").map(y=>y.slug)),d(null)}catch(f){d(f instanceof Error?f.message:"Could not inspect local Suite migration status.")}};if(p.useEffect(()=>{h()},[]),!t&&!u||t&&!t.suites.length&&!t.issues.length)return null;const g=(t==null?void 0:t.suites.filter(f=>f.action==="CREATE_SUITE_DRAFT"||f.action==="CREATE_VERSION_DRAFT"))??[],v=async()=>{const f=g.filter(y=>i.includes(y.slug)).map(y=>({slug:y.slug,localFingerprint:y.localFingerprint}));if(!f.length){d("Select at least one reviewed local Suite migration.");return}c(!0),d(null);try{await M.localSuiteMigrationSync(f),await h(),await e()}catch(y){d(y instanceof Error?y.message:"Local Suite migration failed safely.")}finally{c(!1)}};return s.jsxs("div",{className:"card",style:{padding:"14px 16px",borderStyle:"dashed"},children:[s.jsxs("div",{className:"row spread",style:{gap:12,flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"EXISTING LOCAL SUITES"}),s.jsxs("div",{style:{fontWeight:700},children:[(t==null?void 0:t.pending)??0," local Suite",(t==null?void 0:t.pending)===1?"":"s"," not synchronized"]}),s.jsx("div",{className:"muted",style:{fontSize:12,marginTop:5},children:"Migration creates Cloud DRAFT versions only. Local files are never changed or deleted, and approval remains a separate explicit action."})]}),s.jsx("button",{className:"btn sm ghost",onClick:()=>r(f=>!f),children:a?"Close review":"Review & Sync"})]}),u&&s.jsx("div",{className:"drift dirty",style:{marginTop:10},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"migration"}),s.jsx("span",{children:u})]})}),a&&t&&s.jsxs("div",{className:"stack",style:{gap:8,marginTop:13},children:[t.suites.map(f=>{const y=f.action==="CREATE_SUITE_DRAFT"||f.action==="CREATE_VERSION_DRAFT";return s.jsxs("label",{className:"card",style:{padding:"10px 12px",display:"flex",gap:10,alignItems:"flex-start"},children:[y?s.jsx("input",{type:"checkbox",checked:i.includes(f.slug),onChange:()=>o(b=>b.includes(f.slug)?b.filter(m=>m!==f.slug):[...b,f.slug])}):s.jsx("span",{className:`tag ${f.state==="IN_SYNC"?"pass":"warn"}`,children:f.state}),s.jsxs("span",{style:{flex:1},children:[s.jsxs("span",{className:"row",style:{gap:7,flexWrap:"wrap"},children:[s.jsx("strong",{children:f.slug}),s.jsxs("span",{className:"tag informational",children:["local v",f.localVersion," ",f.localStatus]}),y&&s.jsx("span",{className:"tag warn",children:f.action.replaceAll("_"," ")})]}),s.jsxs("span",{className:"mono muted",style:{display:"block",fontSize:10.5,marginTop:4},children:[f.localFingerprint," · ",f.testCount," tests"]}),s.jsxs("span",{className:"muted",style:{display:"block",fontSize:11.5,marginTop:4},children:[f.reason,f.genericCompatibility.unsupported?` ${f.genericCompatibility.unsupported} test(s) require a compatible local/private runner before execution.`:""]})]})]},`${f.slug}:${f.localFingerprint}`)}),t.issues.map(f=>s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"invalid"}),s.jsxs("span",{children:[f.fileName,": ",f.error]})]})},f.fileName)),s.jsx("div",{className:"row",style:{justifyContent:"flex-end",gap:8},children:s.jsx("button",{className:"btn sm primary",disabled:l||!g.some(f=>i.includes(f.slug)),onClick:()=>void v(),children:l?"Creating DRAFTs…":"Create selected Cloud DRAFTs"})})]})]})}function j5({tags:e,initial:t,onSave:n,onClose:a}){const[r,i]=p.useState((t==null?void 0:t.name)??""),[o,l]=p.useState((t==null?void 0:t.tags)??[]),[c,u]=p.useState((t==null?void 0:t.minScore)??80),[d,h]=p.useState((t==null?void 0:t.repeat)??1),[g,v]=p.useState((t==null?void 0:t.deterministicOnly)??!1),[f,y]=p.useState(!1),[b,m]=p.useState(null),x=((t==null?void 0:t.id)??r.toLowerCase().trim().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")).slice(0,64),j=async()=>{if(x.length<2||o.length===0){m("Give the legacy group a name and select at least one test group.");return}y(!0),m(null);const S=new Date().toISOString();try{await n({id:x,name:r.trim(),tags:o,minScore:c,repeat:d,deterministicOnly:g,createdAt:(t==null?void 0:t.createdAt)??S,updatedAt:S}),a()}catch(w){m(w instanceof Error?w.message:"Could not save the legacy local regression group.")}finally{y(!1)}};return s.jsx("div",{className:"modal-backdrop",onClick:a,children:s.jsxs("div",{className:"modal",onClick:S=>S.stopPropagation(),style:{maxWidth:680},children:[s.jsx("div",{className:"screen-title",children:t?"Edit legacy local group":"Create a legacy local regression group"}),s.jsx("div",{className:"screen-sub",style:{marginBottom:16},children:"P8 compatibility artifact only. This local tag group is not a governed Cloud Gate and cannot be resolved by the public Runner with --gate."}),s.jsxs("label",{className:"field",children:[s.jsx("span",{children:"Legacy group name"}),s.jsx("input",{value:r,disabled:!!t,onChange:S=>i(S.target.value),placeholder:"Smoke test"})]}),s.jsx("div",{className:"section-label",style:{marginTop:16},children:"Scans and test groups"}),s.jsx("div",{className:"row",style:{gap:8,flexWrap:"wrap"},children:e.map(S=>s.jsxs("button",{className:`btn sm ${o.includes(S)?"primary":"ghost"}`,onClick:()=>l(w=>w.includes(S)?w.filter(C=>C!==S):[...w,S]),children:["#",S]},S))}),!e.length&&s.jsx("div",{className:"muted",style:{fontSize:12},children:"Capture and tag a test from Security, RAG, Prompts, Contracts, or MCP Inspector first."}),s.jsxs("div",{className:"row",style:{gap:12,marginTop:16,flexWrap:"wrap"},children:[s.jsxs("label",{className:"field",style:{minWidth:150},children:[s.jsx("span",{children:"Minimum score"}),s.jsx("input",{type:"number",min:0,max:100,value:c,onChange:S=>u(Math.max(0,Math.min(100,Number(S.target.value))))})]}),s.jsxs("label",{className:"field",style:{minWidth:150},children:[s.jsx("span",{children:"Variable-test repetitions"}),s.jsx("input",{type:"number",min:1,max:10,value:d,onChange:S=>h(Math.max(1,Math.min(10,Number(S.target.value))))})]})]}),s.jsxs("label",{className:"row",style:{gap:8,marginTop:12,fontSize:12.5},children:[s.jsx("input",{type:"checkbox",checked:g,onChange:S=>v(S.target.checked)})," Run deterministic tests only"]}),b&&s.jsx("div",{className:"drift dirty",style:{marginTop:12},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{children:b})]})}),s.jsxs("div",{className:"row",style:{justifyContent:"flex-end",gap:8,marginTop:18},children:[s.jsx("button",{className:"btn ghost",onClick:a,children:"Cancel"}),s.jsx("button",{className:"btn primary",disabled:f||!e.length,onClick:j,children:f?"Saving…":"Save legacy group"})]})]})})}function b5({gate:e,open:t,onClose:n}){var E;const[a,r]=p.useState(null),[i,o]=p.useState([]),[l,c]=p.useState(),[u,d]=p.useState(!1),[h,g]=p.useState(!1),[v,f]=p.useState(null),[y,b]=p.useState(null),m=a?["READY","REVIEW","BLOCK","FAILED","CANCELLED"].includes(a.lifecycleState):!1,x=async k=>{const T=await M.assuranceRun(k);r(T.run),c(T.evidence),T.error&&b(T.error)},j=async()=>{d(!0),b(null),o([]),c(void 0);try{const k=await M.assuranceGateRun(e.gateId);r(k.run);const T=M.assuranceRunEvents(k.run.id,P=>{o(W=>W.some(R=>R.sequence===P.sequence)?W:[...W,P].sort((R,q)=>R.sequence-q.sequence)),P.type==="GATE_DECIDED"&&r(W=>W&&{...W,lifecycleState:P.decision??"REVIEW",decision:P.decision}),["RUN_COMPLETED","RUN_CANCELLED","RUN_FAILED"].includes(P.type)&&(T(),x(k.run.id))},()=>{x(k.run.id).catch(()=>b("Live stream disconnected. Reconnect will resume from the last event."))})}catch(k){b(k instanceof Error?k.message:"Could not start the legacy assurance binding run.")}finally{d(!1)}};p.useEffect(()=>{j()},[e.gateId]);const S=i.filter(k=>k.type==="TEST_COMPLETED"),w=["prompt","rag","contract","security","performance"],C=i.filter(k=>k.type==="FINDING_CREATED"),_=async()=>{if(a)try{await M.assuranceRunCancel(a.id),r({...a,lifecycleState:"CANCELLED"})}catch(k){b(k instanceof Error?k.message:"Could not cancel run.")}},N=k=>{if(!a)return;const T=URL.createObjectURL(new Blob([k],{type:"text/html;charset=utf-8"})),P=document.createElement("a"),W=e.gateId.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-|-$/g,"")||"gate";P.href=T,P.download=`prooflane-${W}-${a.id}.html`,P.click(),window.setTimeout(()=>URL.revokeObjectURL(T),6e4)},$=async k=>{if(!(!a||!l)){g(!0),b(null);try{const T=await M.assuranceRunReport(a.id);k?N(T):f(T)}catch(T){b(T instanceof Error?T.message:"Could not create the Gate report.")}finally{g(!1)}}};return t?s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"modal-backdrop gate-run-backdrop",onClick:n,children:s.jsxs("div",{className:"modal gate-run-console",onClick:k=>k.stopPropagation(),children:[s.jsxs("div",{className:"gate-run-head",children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"LEGACY LOCAL ASSURANCE BINDING · LIVE RUN"}),s.jsx("h2",{children:e.name??e.gateId}),s.jsxs("div",{className:"mono muted",children:["Compatibility binding, not a governed Cloud Gate · ",e.target?`${e.target} · `:"","Suite ",e.suiteId," v",e.suiteVersion," · ",e.testCount??"—"," runnable tests · Policy ",e.policyVersion,a?` · ${a.id}`:""]})]}),s.jsx("div",{className:`gate-decision ${((E=a==null?void 0:a.decision)==null?void 0:E.toLowerCase())??(a==null?void 0:a.lifecycleState.toLowerCase())??"queued"}`,children:(a==null?void 0:a.decision)??(a==null?void 0:a.lifecycleState)??"QUEUED"})]}),s.jsxs("div",{className:"gate-run-body",children:[s.jsxs("div",{className:"gate-progress-grid",children:[s.jsxs("div",{className:"gate-progress-total",children:[s.jsxs("strong",{children:[S.length," / ",e.testCount??S.length]}),s.jsx("span",{children:"suite tests completed"})]}),w.map(k=>{var P;const T=t5(k,(P=e.coverage)==null?void 0:P[k],i);return s.jsxs("div",{className:"gate-progress-row",children:[s.jsx("span",{children:k}),s.jsx("div",{children:s.jsx("i",{style:{width:`${T.progressPercent}%`}})}),s.jsx("b",{className:T.tone,children:T.label}),s.jsx("small",{children:T.countLabel})]},k)})]}),(l==null?void 0:l.policyEvaluation)&&s.jsxs("div",{className:"gate-policy-evaluation",children:[s.jsxs("div",{className:"gate-policy-evaluation-head",children:[s.jsxs("div",{children:[s.jsxs("strong",{children:["Policy decision · ",l.policyEvaluation.policyName]}),s.jsx("span",{children:l.policyEvaluation.summary}),s.jsx("code",{children:l.policyEvaluation.aggregateRuleId})]}),s.jsx("span",{className:`tag ${l.policyEvaluation.gateDecision==="READY"?"pass":l.policyEvaluation.gateDecision==="BLOCK"?"fail":"warn"}`,children:l.policyEvaluation.gateDecision==="REVIEW"&&l.policyEvaluation.reviewRequired?"HUMAN REVIEW REQUIRED":l.policyEvaluation.gateDecision})]}),s.jsx("div",{className:"gate-policy-pillars",children:l.policyEvaluation.pillars.map(k=>s.jsxs("div",{className:"gate-policy-pillar",children:[s.jsxs("span",{children:[k.pillar,s.jsx("b",{className:k.disposition.toLowerCase(),children:k.disposition})]}),s.jsx("code",{title:k.ruleIds.join(" · "),children:k.ruleIds.join(" · ")})]},k.pillar))})]}),s.jsxs("div",{className:"gate-console-grid",children:[s.jsxs("div",{className:"gate-terminal",children:[s.jsxs("div",{className:"gate-terminal-title",children:[s.jsx("span",{children:"Execution stream"}),s.jsx("span",{className:"live-dot",children:"LIVE"})]}),s.jsx("div",{className:"gate-terminal-lines",children:i.length?i.map(k=>{var T;return s.jsxs("div",{children:[s.jsx("time",{children:new Date(k.timestamp).toLocaleTimeString()}),s.jsx("span",{className:`event-mark ${((T=k.status)==null?void 0:T.toLowerCase())??""}`,children:k.type==="TEST_COMPLETED"?k.status==="PASS"?"✓":k.status==="FAIL"?"×":"!":"›"}),s.jsx("code",{children:k.type.replaceAll("_"," ").toLowerCase()}),s.jsx("p",{children:k.message??[k.pillar,k.testId].filter(Boolean).join(" · ")})]},k.sequence)}):s.jsx("div",{className:"gate-terminal-empty",children:"Dispatching the pinned suite to the shared runner…"})})]}),s.jsxs("div",{className:"gate-findings",children:[s.jsxs("div",{className:"gate-terminal-title",children:[s.jsx("span",{children:"Findings"}),s.jsx("span",{children:C.length})]}),C.length?C.map(k=>{var T;return s.jsxs("div",{className:`gate-finding ${(T=k.status)==null?void 0:T.toLowerCase()}`,children:[s.jsx("strong",{children:k.status}),s.jsxs("span",{children:[k.pillar," · ",k.testId]}),s.jsx("p",{children:k.message})]},k.sequence)}):s.jsx("div",{className:"gate-terminal-empty",children:"Findings appear here as evidence is produced."})]})]}),l&&s.jsxs("div",{className:"gate-evidence",children:[s.jsxs("div",{children:[s.jsx("span",{children:"EVIDENCE FINGERPRINT"}),s.jsx("code",{children:l.fingerprint})]}),s.jsxs("div",{children:[s.jsx("span",{children:"VERIFIED"}),s.jsx("strong",{children:l.counts.PASS??0})]}),s.jsxs("div",{children:[s.jsx("span",{children:"REVIEW"}),s.jsx("strong",{children:(l.counts.REVIEW??0)+(l.counts.INCONCLUSIVE??0)})]}),s.jsxs("div",{children:[s.jsx("span",{children:"FAILED"}),s.jsx("strong",{children:(l.counts.FAIL??0)+(l.counts.ERROR??0)})]})]}),y&&s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{children:y})]})})]}),s.jsxs("div",{className:"gate-run-actions",children:[s.jsx("button",{className:"btn ghost",onClick:n,children:"Close"}),s.jsxs("div",{className:"row",style:{gap:8,flexWrap:"wrap",justifyContent:"flex-end"},children:[a&&!m&&s.jsx("button",{className:"btn ghost",onClick:_,children:"Cancel run"}),m&&s.jsx("button",{className:"btn ghost",onClick:()=>void j(),disabled:u,children:"Rerun Gate"}),m&&s.jsx("button",{className:"btn ghost",disabled:!l||h,onClick:()=>void $(!0),children:"Download HTML"}),s.jsx("button",{className:"btn ghost",disabled:!l,onClick:()=>l&&navigator.clipboard.writeText(JSON.stringify({run:a,evidence:l},null,2)),children:"Copy evidence"}),m&&s.jsx("button",{className:"btn primary",disabled:!l||h,onClick:()=>void $(!1),children:h?"Preparing…":"Open Spine report"})]})]})]})}),v&&s.jsx("div",{className:"modal-backdrop gate-report-preview-backdrop",onClick:()=>f(null),children:s.jsxs("div",{className:"modal gate-report-preview",onClick:k=>k.stopPropagation(),children:[s.jsxs("div",{className:"gate-report-preview-head",children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"POST-RUN ASSURANCE ARTIFACT"}),s.jsx("strong",{children:"Prooflane Spine report"}),s.jsxs("span",{children:[e.name??e.gateId," · ",a==null?void 0:a.id]})]}),s.jsxs("div",{className:"row",style:{gap:8},children:[s.jsx("button",{className:"btn ghost",onClick:()=>N(v),children:"Download HTML"}),s.jsx("button",{className:"btn primary",onClick:()=>f(null),children:"Close report"})]})]}),s.jsx("iframe",{title:`Prooflane Spine report for ${e.name??e.gateId}`,srcDoc:v,sandbox:""})]})})]}):null}function w5({hostedRunner:e=!1,focusedLegacyGateId:t=null,onFocusedLegacyGateConsumed:n,focusedSuiteSlug:a=null,onFocusedSuiteConsumed:r}){const[i,o]=p.useState([]),[l,c]=p.useState(!0),[u,d]=p.useState(null),[h,g]=p.useState([]),[v,f]=p.useState([]),[y,b]=p.useState([]),[m,x]=p.useState([]),[j,S]=p.useState(null),[w,C]=p.useState([]),[_,N]=p.useState(null),[$,E]=p.useState(!1),[k,T]=p.useState(null),[P,W]=p.useState(!1),[R,q]=p.useState(null),[Y,K]=p.useState(null),[ce,B]=p.useState(null),[ae,ue]=p.useState(),[re,V]=p.useState(),[ne,te]=p.useState(),[fe,me]=p.useState({}),[A,L]=p.useState(null),ve=()=>{M.suitesList().then(O=>{f(O.suites),S(null)}).catch(O=>S(O instanceof Error?O.message:"Cloud Suite registry is unavailable.")),M.policiesList().then(O=>b(O.policies)).catch(O=>S(O instanceof Error?O.message:"Cloud Policy registry is unavailable.")),M.governedRuns(20).then(O=>{x(O.runs),_u(O.runs)}).catch(()=>x([])),M.intelligenceSurface().then(O=>{V(O!=null&&O.connected&&typeof O.fingerprint=="string"?O.fingerprint:void 0),ue(O!=null&&O.connected&&typeof O.governedTargetFingerprint=="string"?O.governedTargetFingerprint:void 0),te(O!=null&&O.connected&&Array.isArray(O.governedCapabilities)?O.governedCapabilities:void 0)}).catch(()=>{V(void 0),ue(void 0),te(void 0)});const Q=e?Promise.resolve({version:"prooflane-assurance-gates-v1",gates:[]}):M.legacyAssuranceBindings().catch(()=>({version:"prooflane-assurance-gates-v1",gates:[]}));return Promise.all([M.tagsList(),M.legacyRegressionGroupsList().catch(()=>({version:"prooflane-regression-gates-v1",gates:[]})),Q]).then(([O,he,Pe])=>{o(O.config.tests),me(O.tagSnapshots??{}),L(O.refreshedAt??null),g(he.gates),C(Pe.gates),d(null);const qe=t?Pe.gates.find(ct=>ct.gateId===t):void 0;qe&&(n==null||n(),N(qe),E(!0))}).catch(O=>d(O instanceof Error?O.message:"Could not load tagged tests.")).finally(()=>c(!1))};p.useEffect(()=>{ve()},[e,t]),p.useEffect(()=>{const Q=()=>{c(!0),ve()};return window.addEventListener("prooflane:tags-updated",Q),()=>window.removeEventListener("prooflane:tags-updated",Q)},[e,t]),p.useEffect(()=>{if(!a)return;let Q=!1;return K(null),M.suitesList().then(O=>{if(Q)return;f(O.suites);const he=O.suites.find(Pe=>Pe.suite.slug===a);if(!he){S(`Prepared Suite ${a} is not available in the governed registry yet.`);return}S(null),K(he.suite.slug),r==null||r()}).catch(O=>{Q||S(O instanceof Error?O.message:"Cloud Suite registry is unavailable.")}),()=>{Q=!0}},[a,r]);const D=async Q=>{try{const O=await M.tagRemove(Q);o(O.config.tests),me(O.tagSnapshots??{}),L(O.refreshedAt??null)}catch(O){d(O instanceof Error?O.message:"Could not remove the test.")}},J=new Map;for(const Q of i)for(const O of Q.tags){const he=J.get(O)??[];he.push(Q),J.set(O,he)}const oe=[...J.keys()].sort((Q,O)=>Q.localeCompare(O)),de=async Q=>{const O=await M.legacyRegressionGroupSave(Q);g(O.gates)},Se=async Q=>{const O=await M.legacyRegressionGroupRemove(Q);g(O.gates)},Ce=async Q=>{const O=await M.suiteCreate(Q);f(he=>[O,...he.filter(Pe=>Pe.suite.slug!==O.suite.slug)])},_e=async Q=>{window.confirm(`Archive Suite ${Q.suite.slug}? Its Gate remains separately governed and must be deprecated before it can be archived.`)&&(await M.suiteArchive(Q.suite.slug),f(O=>O.filter(he=>he.suite.slug!==Q.suite.slug)))},ie=(Q,O)=>f(he=>he.map(Pe=>Pe.suite.slug===Q?{...Pe,latestVersion:O}:Pe)),De=async(Q,O)=>{const he=Q.latestVersion.state==="DRAFT"?await M.suiteUpdateDraft(Q.suite.slug,Q.latestVersion.version,O):await M.suiteCreateVersion(Q.suite.slug,{manifest:O,supersedesVersionId:Q.latestVersion.id});ie(Q.suite.slug,he.version)},Ge=async(Q,O)=>{S(null);try{const he=O==="review"?await M.suiteReview(Q.suite.slug,Q.latestVersion.version):O==="approve"?await M.suiteApprove(Q.suite.slug,Q.latestVersion.version):await M.suiteDeprecate(Q.suite.slug,Q.latestVersion.version);ie(Q.suite.slug,he.version)}catch(he){S(he instanceof Error?he.message:`Could not ${O} the Suite version.`)}},le=async Q=>{S(null);try{let O=Q.latestVersion;if(O.state==="DRAFT"&&(O=(await M.suiteReview(Q.suite.slug,O.version)).version,ie(Q.suite.slug,O)),O.state==="REVIEWED"&&(O=(await M.suiteApprove(Q.suite.slug,O.version)).version,ie(Q.suite.slug,O)),O.state!=="APPROVED"||!O.manifestHash||!O.signature)throw new Error(`Suite ${Q.suite.slug}@${O.version} did not reach an APPROVED signed state.`);return{...Q,latestVersion:O}}catch(O){const he=O instanceof Error?O.message:"Could not review and approve the Suite version.";throw S(he),O instanceof Error?O:new Error(he)}},Te=async Q=>{S(null);try{const O=await M.suiteAssessDrift(Q.suite.slug);O.draft?ie(Q.suite.slug,O.draft):await ve()}catch(O){S(O instanceof Error?O.message:"Could not govern target drift.")}},We=w.filter(Q=>Q.currentTargetMatch!==!1),Be=w.filter(Q=>Q.currentTargetMatch===!1);return s.jsxs("div",{className:"stack",style:{gap:20},children:[s.jsxs("div",{className:"row spread",style:{alignItems:"center",flexWrap:"wrap",gap:10},children:[s.jsx("span",{className:"muted",style:{fontSize:12.5,maxWidth:"60ch"},children:"Govern first-class Cloud Gates that pin one exact approved signed Suite and Policy. The same Gate slug resolves to the same signed release identity in the UI, CLI, and GitHub Actions."}),s.jsxs("div",{className:"row",style:{gap:8},children:[s.jsx("button",{className:"btn sm primary",onClick:()=>W(!0),children:"Review & import local tests"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>T("new"),children:"+ Legacy local group"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>{c(!0),ve()},title:"Reload captured tests",children:"↻ Refresh"})]})]}),s.jsxs("div",{className:"card",style:{padding:"11px 14px",borderStyle:"dashed"},children:[s.jsx("span",{className:"muted",style:{fontSize:12},children:"Capture runnable tests locally and group them with tags. Governed Suites synchronize only bounded control references and compact metadata; raw prompts, documents, answers, credentials, and evidence stay local."}),s.jsxs("span",{className:"mono muted",style:{display:"block",fontSize:10.5,marginTop:6},children:["Local tag state ",A?`refreshed ${new Date(A).toLocaleTimeString()}`:"not loaded — refresh required",". Capture events refresh this view automatically."]})]}),(re||ae)&&s.jsxs("div",{className:"card",style:{padding:"11px 14px",borderStyle:"dashed"},children:[s.jsxs("div",{className:"row",style:{gap:8,flexWrap:"wrap"},children:[re&&s.jsxs("span",{className:"tag informational",children:["DISCOVERY ",re]}),ae&&s.jsxs("span",{className:"tag ok",children:["GOVERNED ",ae]})]}),s.jsx("span",{className:"muted",style:{display:"block",fontSize:12,marginTop:7},children:"The discovery fingerprint identifies the normalized planning surface used by Assurance Intelligence. The governed fingerprint pins the canonical executable protocol, tool, resource, and prompt surface used by signed Suite and Gate versions. Different values and lengths are intentional; execution drift compares governed fingerprints only."})]}),P&&s.jsx(v5,{tags:oe,tests:i,tagSnapshots:fe,policies:y,targetFingerprint:ae,requiredCapabilities:ne,onSave:Ce,onClose:()=>W(!1)}),R&&s.jsx(y5,{entry:R,tags:oe,tests:i,tagSnapshots:fe,policies:y,currentTargetFingerprint:ae,currentRequiredCapabilities:ne,onSave:Q=>De(R,Q),onClose:()=>q(null)}),k&&s.jsx(j5,{tags:oe,initial:k==="new"?void 0:k,onSave:de,onClose:()=>T(null)}),_&&s.jsx(b5,{gate:_,open:$,onClose:()=>E(!1)},_.gateId),ce&&s.jsx(p5,{gateSlug:ce,onClose:()=>B(null)}),s.jsx(x5,{onSynchronized:ve}),j&&s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag warn",children:"Gate setup"}),s.jsx("span",{children:j})]})}),s.jsx(u5,{suites:v,policies:y,governedRuns:m,currentTargetFingerprint:ae,focusedSuiteSlug:Y,onApproveSuite:le,onEditSuite:q,onArchiveSuite:_e,onDeprecateSuite:Q=>Ge(Q,"deprecate"),onReviewSuiteDrift:Te,onOpenCi:B,onGovernedRunsChanged:Q=>{x(Q),_u(Q)},onRunCompleted:Q=>{_u([Q.run]),x(O=>[Q.run,...O.filter(he=>he.id!==Q.run.id)])}}),s.jsx(h5,{runs:m,onRunDisposition:(Q,O)=>{const he=m.find(Pe=>Pe.id===Q);he&&_u([{...he,finalDecision:O}]),x(Pe=>Pe.map(qe=>qe.id===Q?{...qe,finalDecision:O}:qe))}}),s.jsxs("div",{className:"stack",style:{gap:10},children:[s.jsx("div",{className:"section-label",children:"Governed CI Runs"}),m.length===0&&s.jsx("div",{className:"card",style:{padding:18},children:s.jsx("span",{className:"muted",style:{fontSize:12.5},children:"No GitHub CI Runs have been recorded for this project. Compact decisions appear here after the scoped Runner completes."})}),m.map(Q=>s.jsxs("div",{className:"card",style:{padding:"14px 18px"},children:[s.jsxs("div",{className:"row spread",style:{gap:12,flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsxs("div",{className:"eyebrow",children:[Q.gate?"GOVERNED GATE RUN":"SUITE COMPATIBILITY RUN"," · ",Q.status]}),s.jsx("div",{style:{fontWeight:700},children:Q.gate?`Gate ${Q.gate.slug}@${Q.gate.version} · ${Q.gate.manifestHash}`:"Suite compatibility run · no Gate pin"}),s.jsxs("div",{className:"mono muted",style:{fontSize:11,marginTop:5},children:["Suite ",Q.suite.slug,"@",Q.suite.version," · Policy v",Q.policy.version," · Run ",Q.id]}),s.jsxs("div",{className:"mono muted",style:{fontSize:10.5,marginTop:3},children:[Q.runner.type.replaceAll("_"," ")," · runner ",Q.runner.runnerId]})]}),s.jsx("span",{className:`tag ${Q.finalDecision==="READY"?"pass":Q.finalDecision==="BLOCK"||Q.status==="EXECUTION_ERROR"?"fail":"warn"}`,children:Q.finalDecision??Q.automatedDecision??Q.status})]}),s.jsxs("div",{className:"mono muted",style:{fontSize:10.5,marginTop:8},children:["Suite ",Q.suite.manifestHash," · Policy ",Q.policy.manifestHash," · evidence ",Q.evidenceFingerprint??"pending"]}),Q.counts&&s.jsxs("div",{className:"muted",style:{fontSize:12,marginTop:7},children:[Q.counts.passed,"/",Q.counts.total," passed · ",Q.counts.failed," failed · ",Q.counts.errors," errors · ",Q.durationMs===null?"duration pending":`${(Q.durationMs/1e3).toFixed(1)}s`]})]},Q.id))]}),We.length>0&&s.jsxs("div",{className:"stack",style:{gap:10},children:[s.jsx("div",{className:"section-label",children:"Legacy local assurance bindings"}),s.jsx("div",{className:"muted",style:{fontSize:12},children:"P8 compatibility bindings from the local assurance file. These can run the old local executor, but they are not first-class Cloud Gates and are not resolvable with --gate."}),We.map(Q=>{var he,Pe;const O=(_==null?void 0:_.gateId)===Q.gateId;return s.jsxs("div",{className:`card approved-gate-card ${(he=Q.staleness)!=null&&he.stale?"stale":""}`,children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"LEGACY LOCAL BINDING · PINNED RELEASE DECISION"}),s.jsx("h3",{children:Q.name??Q.gateId}),s.jsxs("div",{className:"mono muted",children:[Q.target?`${Q.target} · `:"",Q.suiteId," v",Q.suiteVersion," · ",Q.testCount??"—"," runnable tests · ",Q.policyVersion," · ",Q.runnerId??"auto runner"]}),((Pe=Q.staleness)==null?void 0:Pe.stale)&&s.jsxs("div",{className:"gate-stale-warning",children:[s.jsx("span",{children:"△ SURFACE DRIFT"}),s.jsx("p",{children:Q.staleness.warning}),s.jsxs("code",{children:[Q.staleness.suiteTargetFingerprint," → ",Q.staleness.currentTargetFingerprint]})]}),Q.staleness&&!Q.staleness.stale&&s.jsx("div",{className:"gate-surface-current",children:"✓ Suite matches the current target surface"})]}),s.jsxs("button",{className:"btn primary run-gate-button",onClick:()=>{N(Q),E(!0)},children:[s.jsx("span",{children:"▶"})," ",O?"Open latest readiness proof":"Run readiness proof"]})]},Q.gateId)})]}),Be.length>0&&s.jsxs("div",{className:"card gate-stale-warning",children:[s.jsx("span",{children:"LEGACY BINDINGS FOR OTHER TARGETS"}),s.jsxs("p",{children:[Be.length," local compatibility binding",Be.length===1?" belongs":"s belong"," to a different MCP target and will not run against ",Be[0].currentTarget??"the current connection","."]}),Be.map(Q=>s.jsxs("code",{children:[Q.target??Q.suiteId," · ",Q.testCount??"—"," tests · ",Q.name??Q.gateId]},Q.gateId))]}),h.length>0&&s.jsxs("div",{className:"stack",style:{gap:10},children:[s.jsx("div",{className:"section-label",children:"Legacy local regression groups"}),h.map(Q=>s.jsxs("div",{className:"card",style:{padding:"16px 18px"},children:[s.jsxs("div",{className:"row spread",style:{gap:12,flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{style:{fontWeight:700},children:Q.name}),s.jsx("div",{className:"mono muted",style:{fontSize:11.5,marginTop:5},children:"Project-local compatibility artifact · not resolvable by the public CI Runner"})]}),s.jsxs("div",{className:"row",style:{gap:7},children:[s.jsx("button",{className:"btn sm ghost",onClick:()=>T(Q),children:"Edit"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>void Se(Q.id),children:"Delete"})]})]}),s.jsxs("div",{className:"row",style:{gap:7,marginTop:11,flexWrap:"wrap"},children:[Q.tags.map(O=>s.jsxs("span",{className:"tag pass",children:["#",O]},O)),s.jsxs("span",{className:"tag informational",children:["score ≥ ",Q.minScore]}),Q.repeat>1&&s.jsxs("span",{className:"tag warn",children:["variable ×",Q.repeat]}),Q.deterministicOnly&&s.jsx("span",{className:"tag pass",children:"deterministic only"})]})]},Q.id))]}),l?s.jsx(Vc,{label:"Loading tagged tests…"}):u?s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{style:{fontSize:13},children:u})]})}):i.length===0?s.jsx("div",{className:"card",style:{padding:22},children:s.jsxs("span",{className:"muted",style:{fontSize:13},children:["No tagged tests yet. Run a test on any pillar (Security, RAG, Prompts, Contracts, Performance, or a tool test) and click"," ",s.jsx("b",{children:"Tag"})," to capture it for CI. It will appear here, grouped by the tags you gave it."]})}):s.jsx("div",{className:"stack",style:{gap:16},children:oe.map(Q=>{const O=J.get(Q);return s.jsxs("div",{className:"card",style:{padding:"14px 16px"},children:[s.jsxs("div",{className:"row spread",style:{alignItems:"baseline",flexWrap:"wrap",gap:8},children:[s.jsxs("div",{className:"row",style:{gap:10,alignItems:"baseline"},children:[s.jsx("span",{className:"tag pass",style:{fontSize:12},children:Q}),s.jsxs("span",{className:"muted",style:{fontSize:12},children:[O.length," test",O.length===1?"":"s"]})]}),s.jsx("span",{className:"mono muted",style:{fontSize:11},children:"local capture · import into a Cloud Suite DRAFT for CI"})]}),s.jsx("div",{className:"stack",style:{gap:6,marginTop:10},children:O.map(he=>s.jsxs("div",{className:"row spread",style:{padding:"7px 10px",border:"1px solid var(--border)",borderRadius:8,gap:8},children:[s.jsxs("span",{className:"row",style:{gap:8,alignItems:"baseline",flexWrap:"wrap"},children:[s.jsx("span",{className:"pill",style:{fontSize:11},children:m5[he.pillar]??he.pillar}),aC(he)==="deterministic"?s.jsx("span",{className:"tag pass",style:{fontSize:10},title:"Repeatable — the gate holds it to an exact pass.",children:"deterministic"}):s.jsx("span",{className:"tag warn",style:{fontSize:10},title:"Variable or LLM-driven — the gate scores it on a threshold and can repeat it (--repeat).",children:"non-deterministic"}),s.jsx("span",{style:{fontSize:13},children:he.name}),he.tags.filter(Pe=>Pe!==Q).map(Pe=>s.jsxs("span",{className:"mono muted",style:{fontSize:10.5},children:["#",Pe]},Pe))]}),s.jsx("button",{className:"btn sm ghost",onClick:()=>D(he.id),title:"Remove this captured test",children:"Delete"})]},he.id))})]},Q)})})]})}const S5=()=>`policy_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,7)}`,N5=["off","critical","high","medium","low"],Gv=["prompt","rag","contract","security","performance","tool"],Wv=["PASS","REVIEW","FAIL","INCONCLUSIVE","ERROR"],k5=["PASS","REVIEW","BLOCK"];function E5(){return s.jsxs("div",{className:"stack policy-control-center",children:[s.jsx(_5,{}),s.jsx(T5,{})]})}function _5(){const[e,t]=p.useState([]),[n,a]=p.useState(""),[r,i]=p.useState(null),[o,l]=p.useState(!1),[c,u]=p.useState(null),d=async()=>{try{const y=await M.policiesList();t(y.policies),a(b=>{var m;return b&&y.policies.some(x=>x.policy.id===b)?b:((m=y.policies[0])==null?void 0:m.policy.id)??""}),u(null)}catch(y){u(y instanceof Error?y.message:"Could not load governed Policies.")}};p.useEffect(()=>{d()},[]);const h=e.find(y=>y.policy.id===n)??e[0],g=()=>({schemaVersion:"prooflane-policy-manifest-v1",name:"Production assurance",description:"Verified failures block. Unresolved evidence requires review. Only passing evidence is ready.",scope:"production",pillarMappings:Object.fromEntries(Gv.map(y=>[y,{PASS:"PASS",REVIEW:"REVIEW",FAIL:"BLOCK",INCONCLUSIVE:"REVIEW",ERROR:"REVIEW"}])),aggregation:{blockWhenAnyPillarBlocks:!0,reviewWhenAnyPillarReviews:!0,emptySuiteDecision:"REVIEW"},humanReview:{requiredForReview:!0,allowBlockException:!1,exceptionRequiresReason:!0}}),v=async(y,b)=>{l(!0),u(null);try{if(b){const m=b.latestVersion.state==="DRAFT"?await M.policyUpdateDraft(b.policy.id,b.latestVersion.version,y):await M.policyCreateVersion(b.policy.id,{manifest:y,supersedesVersionId:b.latestVersion.id});t(x=>x.map(j=>j.policy.id===b.policy.id?{...j,latestVersion:m.version}:j))}else{const m=y.name.toLowerCase().trim().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64);if(m.length<2)throw new Error("Policy name must produce a valid 2-character slug.");const x=await M.policyCreate({slug:m,displayName:y.name,description:y.description,manifest:y});t(j=>[x,...j]),a(x.policy.id)}i(null)}catch(m){u(m instanceof Error?m.message:"Could not save the governed Policy version.")}finally{l(!1)}},f=async(y,b)=>{l(!0),u(null);try{const m=b==="review"?await M.policyReview(y.policy.id,y.latestVersion.version):b==="approve"?await M.policyApprove(y.policy.id,y.latestVersion.version):await M.policyDeprecate(y.policy.id,y.latestVersion.version);t(x=>x.map(j=>j.policy.id===y.policy.id?{...j,latestVersion:m.version,approvedVersion:m.version.state==="APPROVED"?m.version:m.version.state==="DEPRECATED"?null:j.approvedVersion}:j))}catch(m){u(m instanceof Error?m.message:`Could not ${b} the Policy version.`)}finally{l(!1)}};return s.jsxs("section",{className:"stack policy-section",style:{gap:14},children:[s.jsxs("div",{className:"policy-section-head",children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"ASSURANCE POLICY · CLOUD AUTHORITATIVE"}),s.jsx("h2",{children:"Evidence-to-decision control"}),s.jsx("p",{children:"Approved versions are canonicalized, hashed, and signed by the Control Plane. Suites pin one exact Policy version and hash."})]}),s.jsx("button",{className:"btn primary",onClick:()=>i({manifest:g()}),children:"+ New Policy"})]}),s.jsxs("div",{className:"policy-flow","aria-label":"Policy evaluation flow",children:[s.jsx("span",{children:"Immutable test facts"}),s.jsx("i",{children:"→"}),s.jsx("span",{children:"Pillar mapping"}),s.jsx("i",{children:"→"}),s.jsx("span",{children:"Gate aggregation"}),s.jsx("i",{children:"→"}),s.jsx("span",{children:"Human review"})]}),c&&s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"error"}),s.jsx("span",{children:c})]})}),s.jsxs("div",{className:"policy-version-layout",children:[s.jsx("div",{className:"policy-version-list",children:e.map(y=>s.jsxs("button",{className:`policy-version-card ${y.policy.id===(h==null?void 0:h.policy.id)?"selected":""}`,onClick:()=>a(y.policy.id),children:[s.jsxs("span",{children:[s.jsx("strong",{children:y.policy.displayName}),s.jsxs("code",{children:[y.policy.slug," · v",y.latestVersion.version]})]}),s.jsx("em",{children:y.latestVersion.state})]},y.policy.id))}),h&&s.jsxs("div",{className:"card policy-version-detail",children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start"},children:[s.jsxs("div",{children:[s.jsxs("div",{className:"eyebrow",children:["VERSION ",h.latestVersion.version," · ",h.latestVersion.state]}),s.jsx("h3",{children:h.latestVersion.manifest.name}),s.jsx("p",{children:h.latestVersion.manifest.description})]}),s.jsx("span",{className:`tag ${h.latestVersion.state==="APPROVED"?"pass":"warn"}`,children:h.latestVersion.signature?"signed":h.latestVersion.state.toLowerCase()})]}),s.jsxs("div",{className:"policy-meta",children:[s.jsxs("span",{children:[s.jsx("b",{children:"Policy ID"}),s.jsx("code",{children:h.policy.id})]}),s.jsxs("span",{children:[s.jsx("b",{children:"Scope"}),s.jsx("strong",{children:h.latestVersion.manifest.scope})]}),s.jsxs("span",{children:[s.jsx("b",{children:"Author"}),s.jsx("strong",{children:h.latestVersion.createdBy})]}),s.jsxs("span",{children:[s.jsx("b",{children:"Created"}),s.jsx("strong",{children:new Date(h.latestVersion.createdAt).toLocaleString()})]})]}),s.jsx("div",{className:"policy-mapping-preview",children:Gv.map(y=>s.jsxs("div",{children:[s.jsx("strong",{children:y}),Wv.map(b=>s.jsxs("span",{className:h.latestVersion.manifest.pillarMappings[y][b].toLowerCase(),children:[b," → ",h.latestVersion.manifest.pillarMappings[y][b]]},b))]},y))}),s.jsxs("div",{className:"policy-rule-summary",children:[s.jsxs("span",{children:[s.jsx("b",{children:"BLOCK"})," if any pillar maps to BLOCK"]}),s.jsxs("span",{children:[s.jsx("b",{children:"REVIEW"})," if none block and any pillar maps to REVIEW"]}),s.jsxs("span",{children:[s.jsx("b",{children:"READY"})," only when every evaluated fact maps to PASS"]})]}),s.jsxs("div",{className:"row",style:{gap:7,flexWrap:"wrap"},children:[s.jsxs("span",{className:`tag ${h.latestVersion.manifest.humanReview.requiredForReview?"warn":"pass"}`,children:["Review ",h.latestVersion.manifest.humanReview.requiredForReview?"requires human":"automatic"]}),h.latestVersion.manifestHash&&s.jsxs("code",{children:[h.latestVersion.manifestHash.slice(0,28),"…"]})]}),s.jsxs("div",{className:"row",style:{gap:8,marginTop:12,flexWrap:"wrap"},children:[h.latestVersion.state==="DRAFT"&&s.jsxs(s.Fragment,{children:[s.jsx("button",{className:"btn sm ghost",onClick:()=>i({manifest:structuredClone(h.latestVersion.manifest),policy:h}),children:"Edit DRAFT"}),s.jsx("button",{className:"btn sm primary",disabled:o,onClick:()=>void f(h,"review"),children:"Submit review"})]}),h.latestVersion.state==="REVIEWED"&&s.jsxs(s.Fragment,{children:[s.jsx("button",{className:"btn sm ghost",onClick:()=>i({manifest:structuredClone(h.latestVersion.manifest),policy:h}),children:"Create replacement DRAFT"}),s.jsx("button",{className:"btn sm primary",disabled:o,onClick:()=>void f(h,"approve"),children:"Approve + sign"})]}),h.latestVersion.state==="APPROVED"&&s.jsxs(s.Fragment,{children:[s.jsx("button",{className:"btn sm ghost",onClick:()=>i({manifest:structuredClone(h.latestVersion.manifest),policy:h}),children:"Create new version"}),s.jsx("button",{className:"btn sm ghost",disabled:o,onClick:()=>void f(h,"deprecate"),children:"Deprecate"})]}),h.latestVersion.state==="DEPRECATED"&&s.jsx("button",{className:"btn sm ghost",onClick:()=>i({manifest:structuredClone(h.latestVersion.manifest),policy:h}),children:"Create replacement DRAFT"})]})]})]}),s.jsx("div",{className:"card policy-bindings",children:s.jsxs("div",{children:[s.jsx("div",{className:"section-label",children:"Exact Suite pinning"}),s.jsx("p",{children:"Only APPROVED signed versions appear in Suite authoring. The Suite stores the Policy ID, version, and manifest hash; approval fails if any value differs."})]})}),r&&s.jsx(C5,{manifest:r.manifest,busy:o,onClose:()=>i(null),onSave:y=>void v(y,r.policy)})]})}function C5({manifest:e,busy:t,onClose:n,onSave:a}){const[r,i]=p.useState(e),o=(c,u,d)=>i(h=>({...h,pillarMappings:{...h.pillarMappings,[c]:{...h.pillarMappings[c],[u]:d}}})),l=!!(r.name.trim()&&r.description.trim()&&r.scope.trim());return s.jsx("div",{className:"modal-backdrop",onClick:n,children:s.jsxs("div",{className:"modal assurance-policy-editor",onClick:c=>c.stopPropagation(),children:[s.jsx("div",{className:"screen-title",children:"Create immutable Policy version"}),s.jsx("p",{className:"muted",children:"Save a DRAFT, submit it for review, then approve and sign it before a Suite can pin it."}),s.jsxs("div",{className:"grid-2",children:[s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Policy name"}),s.jsx("input",{className:"field",value:r.name,onChange:c=>i({...r,name:c.target.value})})]}),s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Scope"}),s.jsx("input",{className:"field",value:r.scope,onChange:c=>i({...r,scope:c.target.value})})]})]}),s.jsxs("div",{style:{marginTop:10},children:[s.jsx("label",{className:"label",children:"Description"}),s.jsx("input",{className:"field",value:r.description,onChange:c=>i({...r,description:c.target.value})})]}),s.jsxs("div",{className:"policy-mapping-table",children:[s.jsxs("div",{className:"policy-mapping-header",children:[s.jsx("b",{children:"Pillar"}),Wv.map(c=>s.jsx("b",{children:c},c))]}),Gv.map(c=>s.jsxs("div",{className:"policy-mapping-row",children:[s.jsx("strong",{children:c}),Wv.map(u=>s.jsx("select",{value:r.pillarMappings[c][u],onChange:d=>o(c,u,d.target.value),children:k5.map(d=>s.jsx("option",{children:d},d))},u))]},c))]}),s.jsxs("div",{className:"policy-human-rules",children:[s.jsxs("label",{children:[s.jsx("input",{type:"checkbox",checked:r.humanReview.requiredForReview,onChange:c=>i({...r,humanReview:{...r.humanReview,requiredForReview:c.target.checked}})})," Require human disposition for REVIEW"]}),s.jsxs("label",{children:[s.jsx("input",{type:"checkbox",checked:r.humanReview.allowBlockException,onChange:c=>i({...r,humanReview:{...r.humanReview,allowBlockException:c.target.checked}})})," Allow a reasoned human exception to BLOCK"]})]}),s.jsxs("div",{className:"row spread",style:{marginTop:16},children:[s.jsx("span",{className:"muted",style:{fontSize:11},children:l?"Approval makes the version immutable and signed.":"Complete the name, description, and scope."}),s.jsxs("div",{className:"row",style:{gap:8},children:[s.jsx("button",{className:"btn ghost",onClick:n,children:"Cancel"}),s.jsx("button",{className:"btn primary",disabled:!l||t,onClick:()=>a(r),children:t?"Saving…":"Save DRAFT"})]})]})]})})}function T5(){const[e,t]=p.useState(ip()),[n,a]=p.useState(jx()),[r,i]=p.useState(null),o=d=>{const g=e.some(v=>v.id===d.id)?e.map(v=>v.id===d.id?d:v):[...e,d];t(g),Rw(g),i(null)},l=d=>{a(d),RE(d)},c=()=>i({...structuredClone(jd[1]),id:S5(),name:"New release policy",description:""}),u=d=>{if(e.length<=1)return;const h=e.filter(g=>g.id!==d);t(h),Rw(h),n===d&&l(h[0].id)};return s.jsxs("section",{className:"stack policy-section release-policy-section",style:{gap:20},children:[s.jsx("div",{className:"policy-section-head",children:s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"DEPLOYMENT SCORE POLICY · LOCAL"}),s.jsx("h2",{children:"Weighted release scoring"}),s.jsx("p",{children:"These browser-local profiles score Deployment Assurance. They do not change the pinned, server-side Assurance Gate policy above."})]})}),s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"center",flexWrap:"wrap"},children:[s.jsxs("span",{className:"muted",style:{fontSize:12.5},children:["Policies turn assurance evidence into a weighted ",s.jsx("b",{children:"Pass / Review / Block"})," release decision. Hard gates always win over the score."]}),s.jsx("button",{className:"btn sm primary",onClick:c,children:"+ New score policy"})]}),s.jsx("div",{className:"stack",style:{gap:10},children:e.map(d=>{const h=d.id===n;return s.jsxs("div",{className:"card",style:{padding:"14px 16px",borderColor:h?"var(--accent)":void 0},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"baseline",flexWrap:"wrap"},children:[s.jsxs("div",{className:"stack",style:{gap:4},children:[s.jsxs("div",{className:"row",style:{gap:8,alignItems:"baseline",flexWrap:"wrap"},children:[s.jsx("span",{style:{fontSize:15,fontWeight:700},children:d.name}),h&&s.jsx("span",{className:"tag pass",children:"active"}),s.jsxs("span",{className:"muted mono",style:{fontSize:11},children:["PASS ≥",d.passAt," · REVIEW ≥",d.reviewAt]})]}),s.jsx("span",{className:"muted",style:{fontSize:12.5},children:d.description||"No description"})]}),s.jsxs("div",{className:"row",style:{gap:6},children:[!h&&s.jsx("button",{className:"btn sm",onClick:()=>l(d.id),children:"Use for releases"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>i(structuredClone(d)),children:"Edit"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>u(d.id),disabled:e.length<=1,children:"Delete"})]})]}),s.jsxs("div",{className:"row",style:{gap:6,marginTop:10,flexWrap:"wrap"},children:[ul.map(g=>s.jsxs("span",{className:"pill",children:[Nl[g]," ",Math.round(d.weights[g]*100),"%"]},g)),d.hardGates.contracts&&s.jsx("span",{className:"tag fail",children:"Contracts block"}),d.hardGates.securityMaxSeverity!=="off"&&s.jsxs("span",{className:"tag fail",children:["Security ≥",d.hardGates.securityMaxSeverity]}),d.hardGates.ragMinScore!=null&&s.jsxs("span",{className:"tag warn",children:["RAG ≥",d.hardGates.ragMinScore]}),d.hardGates.promptMinScore!=null&&s.jsxs("span",{className:"tag warn",children:["Prompts ≥",d.hardGates.promptMinScore]}),d.hardGates.perfMinScore!=null&&s.jsxs("span",{className:"tag warn",children:["Perf ≥",d.hardGates.perfMinScore]})]})]},d.id)})}),r&&s.jsx(R5,{policy:r,onClose:()=>i(null),onSave:o})]})}function R5({policy:e,onClose:t,onSave:n}){const[a,r]=p.useState(e),i=p.useMemo(()=>ul.reduce((u,d)=>u+a.weights[d],0),[a.weights]),o=(u,d)=>{const h=Math.max(0,Number(d)||0);r(g=>({...g,weights:{...g.weights,[u]:h/100}}))},l=(u,d)=>r(h=>({...h,hardGates:{...h.hardGates,[u]:d===""?void 0:d}})),c=a.name.trim()&&i>0&&a.reviewAt<=a.passAt;return s.jsx("div",{className:"modal-backdrop",onClick:t,children:s.jsxs("div",{className:"modal",style:{maxWidth:670,maxHeight:"86vh",overflowY:"auto"},onClick:u=>u.stopPropagation(),children:[s.jsx("div",{className:"screen-title",style:{marginBottom:12},children:e.name==="New release policy"?"New policy":"Edit policy"}),s.jsxs("div",{className:"stack",style:{gap:14},children:[s.jsxs("div",{className:"grid-2",children:[s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Policy name"}),s.jsx("input",{className:"field",value:a.name,onChange:u=>r({...a,name:u.target.value})})]}),s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Description"}),s.jsx("input",{className:"field",value:a.description,onChange:u=>r({...a,description:u.target.value}),placeholder:"When to use this release policy"})]})]}),s.jsxs("fieldset",{style:{border:"1px solid var(--border)",borderRadius:9,padding:"10px 12px",margin:0},children:[s.jsx("legend",{className:"muted",style:{fontSize:11,padding:"0 6px"},children:"Weighted decision"}),s.jsxs("div",{className:"grid-2",children:[s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Pass score"}),s.jsx("input",{className:"field mono",type:"number",min:"0",max:"100",value:a.passAt,onChange:u=>r({...a,passAt:Number(u.target.value)})})]}),s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Review score"}),s.jsx("input",{className:"field mono",type:"number",min:"0",max:"100",value:a.reviewAt,onChange:u=>r({...a,reviewAt:Number(u.target.value)})})]})]}),s.jsx("div",{className:"grid-2",style:{marginTop:10},children:ul.map(u=>s.jsxs("div",{children:[s.jsxs("label",{className:"label",children:[Nl[u]," weight (%)"]}),s.jsx("input",{className:"field mono",type:"number",min:"0",max:"100",value:Math.round(a.weights[u]*100),onChange:d=>o(u,d.target.value)})]},u))}),s.jsxs("span",{className:"muted",style:{display:"block",marginTop:8,fontSize:11.5},children:["Weights total ",Math.round(i*100),"%. Prooflane normalizes the entered weights when calculating the score."]})]}),s.jsxs("fieldset",{style:{border:"1px solid var(--border)",borderRadius:9,padding:"10px 12px",margin:0},children:[s.jsx("legend",{className:"muted",style:{fontSize:11,padding:"0 6px"},children:"Hard gates — always block a release"}),s.jsxs("div",{className:"grid-2",children:[s.jsxs("label",{className:"row",style:{gap:7,alignItems:"center",fontSize:12.5,cursor:"pointer"},children:[s.jsx("input",{type:"checkbox",checked:a.hardGates.contracts,onChange:u=>l("contracts",u.target.checked)})," Breaking contract failure"]}),s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Security breach severity"}),s.jsx("select",{className:"field",value:a.hardGates.securityMaxSeverity,onChange:u=>l("securityMaxSeverity",u.target.value),children:N5.map(u=>s.jsx("option",{value:u,children:u==="off"?"Do not hard-block":`${u} or above`},u))})]}),s.jsx(If,{label:"RAG minimum score",value:a.hardGates.ragMinScore,onChange:u=>l("ragMinScore",u)}),s.jsx(If,{label:"Prompt minimum score",value:a.hardGates.promptMinScore,onChange:u=>l("promptMinScore",u)}),s.jsx(If,{label:"Performance minimum score",value:a.hardGates.perfMinScore,onChange:u=>l("perfMinScore",u)})]})]})]}),s.jsxs("div",{className:"row spread",style:{marginTop:18,alignItems:"center"},children:[s.jsx("span",{className:"muted",style:{fontSize:11.5},children:c?"Hard gates override the weighted score.":"Use a name, positive weights, and a Review score no higher than Pass."}),s.jsxs("div",{className:"row",style:{gap:8},children:[s.jsx("button",{className:"btn ghost",onClick:t,children:"Cancel"}),s.jsx("button",{className:"btn primary",disabled:!c,onClick:()=>n(a),children:"Save policy"})]})]})]})})}function If({label:e,value:t,onChange:n}){return s.jsxs("div",{children:[s.jsx("label",{className:"label",children:e}),s.jsx("input",{className:"field mono",type:"number",min:"0",max:"100",value:t??"",placeholder:"Optional",onChange:a=>n(a.target.value)})]})}const I5="prooflane-github-oidc-trust-v1",oC={repository:"",repositoryId:"",repositoryOwnerId:"",workflowPath:".github/workflows/prooflane-assurance-gate.yml",refPatterns:`refs/heads/main
|
|
75
77
|
refs/pull/*/merge`,environment:"",jobWorkflowRef:"",eventNames:"pull_request, push, workflow_dispatch",runnerEnvironment:"any"};function XS(e){return[...new Set(e.split(/[\n,]+/).map(t=>t.trim()).filter(Boolean))]}function QS(e){return!e||e.revokedAt?oC:{repository:e.manifest.repository,repositoryId:e.manifest.repositoryId,repositoryOwnerId:e.manifest.repositoryOwnerId,workflowPath:e.manifest.workflowPath,refPatterns:e.manifest.refPatterns.join(`
|
|
76
78
|
`),environment:e.manifest.environment??"",jobWorkflowRef:e.manifest.jobWorkflowRef??"",eventNames:e.manifest.eventNames.join(", "),runnerEnvironment:e.manifest.runnerEnvironment??"any"}}function A5(e){return{schemaVersion:I5,repository:e.repository.trim(),repositoryId:e.repositoryId.trim(),repositoryOwnerId:e.repositoryOwnerId.trim(),workflowPath:e.workflowPath.trim(),refPatterns:XS(e.refPatterns),environment:e.environment.trim()||null,jobWorkflowRef:e.jobWorkflowRef.trim()||null,eventNames:XS(e.eventNames),runnerEnvironment:e.runnerEnvironment==="any"?null:e.runnerEnvironment}}function P5({enabled:e}){const[t,n]=p.useState(oC),[a,r]=p.useState(null),[i,o]=p.useState("load"),[l,c]=p.useState(null),[u,d]=p.useState(null);p.useEffect(()=>{if(!e){o(null);return}M.githubOidcTrust().then(({trust:y})=>{r(y),n(QS(y))}).catch(y=>d(y instanceof Error?y.message:"GitHub OIDC trust could not be loaded.")).finally(()=>o(null))},[e]);const h=(y,b)=>n(m=>({...m,[y]:b}));async function g(){o("save"),d(null),c(null);try{const y=await M.githubOidcTrustSave(A5(t));r(y.trust),n(QS(y.trust)),c("OIDC trust saved. Matching GitHub jobs can now obtain a short-lived Prooflane identity without a stored Prooflane token.")}catch(y){d(y instanceof Error?y.message:"GitHub OIDC trust could not be saved.")}finally{o(null)}}async function v(){o("revoke"),d(null),c(null);try{const y=await M.githubOidcTrustRevoke();r(y.trust),c("OIDC trust revoked. New GitHub identity exchanges are blocked.")}catch(y){d(y instanceof Error?y.message:"GitHub OIDC trust could not be revoked.")}finally{o(null)}}const f=!!(a&&!a.revokedAt);return s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"section-title",children:"GitHub Actions identity"}),s.jsx("div",{className:"muted",style:{marginTop:7,fontSize:13,maxWidth:720},children:"Bind this Prooflane project to one repository, workflow, and allowed refs. Matching jobs exchange GitHub's signed OIDC assertion for a ten-minute Prooflane identity; no long-lived Prooflane secret is required."})]}),s.jsx("span",{className:`tag ${f?"pass":"warn"}`,children:i==="load"?"loading":f?"OIDC active":"not configured"})]}),s.jsxs("div",{className:"card inset",style:{padding:14,marginTop:16,fontSize:12.5,lineHeight:1.55},children:["The workflow must grant ",s.jsx("span",{className:"mono",children:"contents: read"}),", ",s.jsx("span",{className:"mono",children:"id-token: write"}),", and ",s.jsx("span",{className:"mono",children:"checks: write"}),". Prooflane verifies GitHub's signature and every binding below before execution. OIDC assertions and GitHub tokens are never stored."]}),s.jsxs("details",{className:"card inset",style:{padding:14,marginTop:10,fontSize:12.5,lineHeight:1.55},children:[s.jsx("summary",{style:{cursor:"pointer",fontWeight:700},children:"Where to get the OIDC binding details"}),s.jsxs("div",{className:"muted",style:{marginTop:10},children:["Run this with GitHub CLI after replacing ",s.jsx("span",{className:"mono",children:"OWNER/REPO"}),". It returns the immutable repository and owner IDs used by GitHub's signed OIDC claims."]}),s.jsx("div",{className:"mono",style:{marginTop:8,padding:10,border:"1px solid var(--border)",borderRadius:8,overflowX:"auto"},children:"gh api repos/OWNER/REPO --jq '{repository: .full_name, repositoryId: (.id|tostring), ownerId: (.owner.id|tostring)}'"}),s.jsxs("div",{className:"muted",style:{marginTop:9},children:["Workflow path is the exact repository-relative file under ",s.jsx("span",{className:"mono",children:".github/workflows/"}),". Allowed refs and events must match that workflow's triggers. Set Environment only when the job declares one; set Reusable workflow ref only for an exact reusable-workflow binding."]})]}),s.jsxs("div",{className:"grid-2",style:{marginTop:16,gap:13},children:[s.jsx(br,{label:"Repository (owner/name)",value:t.repository,onChange:y=>h("repository",y),placeholder:"acme/payments"}),s.jsx(br,{label:"GitHub repository ID",value:t.repositoryId,onChange:y=>h("repositoryId",y),placeholder:"123456789",help:"The repository's immutable numeric id from the GitHub API command above."}),s.jsx(br,{label:"GitHub owner ID",value:t.repositoryOwnerId,onChange:y=>h("repositoryOwnerId",y),placeholder:"987654321",help:"The organization or user owner's immutable numeric id from the same command."}),s.jsx(br,{label:"Workflow path",value:t.workflowPath,onChange:y=>h("workflowPath",y),placeholder:".github/workflows/prooflane-assurance-gate.yml"}),s.jsx(br,{label:"Allowed refs (comma or newline)",value:t.refPatterns,onChange:y=>h("refPatterns",y),multiline:!0,placeholder:"refs/heads/main"}),s.jsx(br,{label:"Allowed events",value:t.eventNames,onChange:y=>h("eventNames",y),placeholder:"pull_request, push"}),s.jsx(br,{label:"Environment (optional exact match)",value:t.environment,onChange:y=>h("environment",y),placeholder:"production"}),s.jsx(br,{label:"Reusable workflow ref (optional exact match)",value:t.jobWorkflowRef,onChange:y=>h("jobWorkflowRef",y),placeholder:"acme/ci/.github/workflows/prooflane.yml@refs/heads/main"}),s.jsxs("label",{children:[s.jsx("span",{className:"label",children:"Runner environment"}),s.jsxs("select",{className:"field",value:t.runnerEnvironment,onChange:y=>h("runnerEnvironment",y.target.value),children:[s.jsx("option",{value:"any",children:"Any GitHub runner"}),s.jsx("option",{value:"github-hosted",children:"GitHub-hosted only"}),s.jsx("option",{value:"self-hosted",children:"Self-hosted only"})]})]})]}),f&&a&&s.jsxs("div",{className:"muted mono",style:{marginTop:13,fontSize:11},children:["Last updated ",new Date(a.updatedAt).toLocaleString()," · repository #",a.manifest.repositoryId]}),l&&s.jsx("div",{style:{color:"var(--pass)",marginTop:13,fontSize:12.5},children:l}),u&&s.jsx("div",{style:{color:"var(--fail)",marginTop:13,fontSize:12.5},children:u}),s.jsxs("div",{className:"row",style:{gap:8,marginTop:16,flexWrap:"wrap"},children:[s.jsx("button",{className:"btn primary",onClick:g,disabled:!e||i!==null,children:i==="save"?"Saving…":f?"Update OIDC trust":"Enable OIDC trust"}),f&&s.jsx("button",{className:"btn ghost",onClick:v,disabled:i!==null,children:i==="revoke"?"Revoking…":"Revoke trust"})]})]})}function br({label:e,value:t,onChange:n,placeholder:a,multiline:r=!1,help:i}){return s.jsxs("label",{children:[s.jsx("span",{className:"label",children:e}),r?s.jsx("textarea",{className:"field",rows:3,value:t,onChange:o=>n(o.target.value),placeholder:a}):s.jsx("input",{className:"field",value:t,onChange:o=>n(o.target.value),placeholder:a}),i&&s.jsx("small",{className:"muted",style:{display:"block",marginTop:5},children:i})]})}const $5="cloud-workspace-v1",lC="local-workspace-v1",cC="prooflane.localWorkspaceAgreement";function O5(e){try{const t=localStorage.getItem(cC);if(!t)return!1;const n=JSON.parse(t);return n.account===e&&n.version===lC}catch{return!1}}function L5(e){try{localStorage.setItem(cC,JSON.stringify({account:e,version:lC}))}catch{}}function M5({onEnabled:e,onClose:t}){const[n,a]=p.useState(!1),[r,i]=p.useState(!1),[o,l]=p.useState(null),c=async()=>{if(n){i(!0),l(null);try{await e()}catch(u){l(u instanceof Error?u.message:"Prooflane could not enable Cloud History & Recovery.")}finally{i(!1)}}};return s.jsx("div",{className:"modal-backdrop",role:"presentation",onMouseDown:t,children:s.jsxs("div",{className:"modal cloud-history-modal",role:"dialog","aria-modal":"true","aria-labelledby":"cloud-history-title",onMouseDown:u=>u.stopPropagation(),children:[s.jsxs("div",{className:"row spread",style:{alignItems:"flex-start",gap:18},children:[s.jsxs("div",{children:[s.jsx("div",{id:"cloud-history-title",className:"screen-title",style:{fontSize:20},children:"Cloud History & Recovery"}),s.jsx("div",{className:"screen-sub",style:{marginTop:7},children:"Keep assurance history securely so Prooflane can identify drift, compare regressions, and restore your workspace if this device is lost."})]}),s.jsx("button",{className:"btn sm ghost",onClick:t,"aria-label":"Close Cloud History and Recovery",children:"×"})]}),s.jsxs("div",{className:"card inset",style:{padding:14,marginTop:18,fontSize:13,lineHeight:1.55},children:[s.jsx("b",{children:"What is backed up:"})," selected assurance runs, contracts, prompts, and recorded sessions. Prooflane creates an encrypted snapshot at most once every 24 hours while Inspector is open and you are signed in."]}),s.jsxs("div",{className:"card inset",style:{padding:14,marginTop:10,fontSize:13,lineHeight:1.55},children:[s.jsx("b",{children:"What always stays on this device:"})," your MCP server URL and connection settings, OAuth tokens, LLM/API keys, authorization headers, passwords, and private keys. Prooflane never uploads these values, and Cloud Workspace rejects them again if they are ever included in a backup."]}),s.jsxs("label",{className:"row",style:{gap:10,alignItems:"flex-start",cursor:"pointer",marginTop:18},children:[s.jsx("input",{type:"checkbox",checked:n,onChange:u=>a(u.target.checked),style:{marginTop:3}}),s.jsx("span",{style:{fontSize:13,lineHeight:1.5},children:"I consent to encrypted Cloud History & Recovery backups of the approved assurance artifacts described above. I understand that my connection settings and credentials always stay on this device."})]}),o&&s.jsx("div",{style:{color:"var(--fail)",fontSize:12.5,marginTop:14},children:o}),s.jsxs("div",{className:"row",style:{justifyContent:"flex-end",gap:10,marginTop:20},children:[s.jsx("button",{className:"btn ghost",onClick:t,disabled:r,children:"Not now"}),s.jsx("button",{className:"btn primary",onClick:c,disabled:!n||r,children:r?"Enabling secure backup…":"Enable Cloud History"})]})]})})}function D5({account:e,enabled:t,configured:n,eligible:a,planLabel:r,onAccepted:i}){const o=t,[l,c]=p.useState(!1),[u,d]=p.useState(!1),[h,g]=p.useState(!1),[v,f]=p.useState(!1),[y,b]=p.useState(null),m=o&&!n,x=l&&u&&!m,j=async()=>{if(x){g(!0),b(null);try{o?(await M.workspaceConsent($5,!0,!0),f(!0),window.setTimeout(i,5e3)):(L5(e),i())}catch(S){b(S instanceof Error?S.message:"Could not save the workspace agreement."),g(!1)}}};return v?s.jsx("div",{className:"auth-gate workspace-splash","aria-live":"polite",children:s.jsxs("div",{className:"workspace-splash-brand",children:[s.jsx(ur,{}),s.jsx("div",{className:"workspace-splash-name",children:"prooflane"}),s.jsx("div",{className:"workspace-splash-welcome",children:"Welcome to your Cloud Workspace"}),s.jsx("div",{className:"workspace-splash-tag",children:"CLOUD WORKSPACE READY"})]})}):s.jsx("div",{className:"auth-gate",children:s.jsxs("div",{className:"auth-card",style:{maxWidth:640},children:[s.jsx("div",{className:"screen-title",style:{fontSize:21,marginBottom:7},children:o?"Set up Cloud Workspace":"Your Prooflane workspace"}),s.jsx("div",{className:"screen-sub",style:{marginBottom:20},children:o?s.jsxs(s.Fragment,{children:["Before using Prooflane Inspector, ",s.jsx("b",{children:e})," must accept the Cloud Workspace agreement. This creates your encrypted hosted workspace for assurance results, history and recovery."]}):s.jsxs(s.Fragment,{children:["Before using Prooflane Inspector, ",s.jsx("b",{children:e})," — here's how your ",s.jsx("b",{children:r??"Free"})," workspace works."]})}),s.jsx("div",{className:"drift dirty",style:{marginBottom:16},children:s.jsxs("div",{className:"drift-row",style:{alignItems:"flex-start"},children:[s.jsx("span",{className:"tag warn",children:"important"}),s.jsxs("span",{style:{fontSize:12.5,lineHeight:1.55},children:[o?s.jsxs(s.Fragment,{children:[s.jsx("b",{children:"Back up to keep your assurance history."})," Without a completed Cloud Workspace backup, Prooflane removes local runs, prompts, sessions, and snapshots when you sign in again or your login session expires. This prevents orphaned customer data from remaining on the device. After an encrypted backup has completed, approved assurance history remains available for recovery, drift analysis, and regressions."]}):s.jsxs(s.Fragment,{children:[s.jsx("b",{children:"Your workspace lives on this device."})," On ",r??"Free",", your runs, prompts, sessions, and snapshots are stored locally only — there is no cloud copy. ",s.jsx("b",{children:"Signing out or a session/token expiry clears them, and they cannot be recovered."})," To keep assurance history for recovery, drift analysis, and regressions, upgrade to a Cloud Workspace (Scale and above)."]}),s.jsx("br",{}),s.jsx("b",{children:"Prooflane never keeps your credentials."})," Your MCP URL and connection settings, OAuth tokens, LLM/API keys, PATs, authorization headers, passwords, and private keys are never sent to Prooflane — they stay on this device",o?" and are never backed up":"","."]})]})}),m&&s.jsx("div",{className:"drift dirty",style:{marginBottom:14},children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"setup"}),s.jsxs("span",{style:{fontSize:12.5},children:["Cloud Workspace is not configured for this Inspector. Set ",s.jsx("span",{className:"mono",children:"KAWACH_CONTROL_PLANE_URL"})," and restart."]})]})}),s.jsxs("label",{className:"row",style:{gap:10,alignItems:"flex-start",cursor:"pointer",marginTop:10},children:[s.jsx("input",{type:"checkbox",checked:l,onChange:S=>c(S.target.checked),style:{marginTop:3}}),s.jsx("span",{style:{fontSize:13},children:o?"I agree to the Prooflane Cloud Workspace Terms, including authorized-testing requirements, responsibility for my use of connected AI systems, and the local workspace lifecycle described above.":"I understand my workspace is stored locally on this device, and that signing out or a session expiry clears my local runs, prompts, sessions, and snapshots — they cannot be recovered without a Cloud Workspace."})]}),s.jsxs("label",{className:"row",style:{gap:10,alignItems:"flex-start",cursor:"pointer",marginTop:14},children:[s.jsx("input",{type:"checkbox",checked:u,onChange:S=>d(S.target.checked),style:{marginTop:3}}),s.jsx("span",{style:{fontSize:13},children:o?"I consent to Prooflane processing and retaining selected run output in my encrypted Cloud Workspace for assurance analysis and release decisions.":"I agree to the Prooflane Terms and Data Processing Agreement, and understand Prooflane never stores my passwords, API/LLM keys, OAuth tokens, PATs, MCP configuration, or other credentials."})]}),y&&s.jsx("div",{style:{color:"var(--fail)",fontSize:12.5,marginTop:14},children:y}),s.jsx("button",{className:"btn primary",style:{width:"100%",justifyContent:"center",marginTop:20},onClick:j,disabled:h||!x,children:h?"Saving agreement…":o?"Accept agreement & continue":"Acknowledge & continue"})]})})}function z5({account:e,enabled:t,emailVerified:n,caps:a,connected:r,planStatus:i,automaticBackupAccepted:o,backupCadenceHours:l}){var ue;const[c,u]=p.useState("security"),[d,h]=p.useState(""),[g,v]=p.useState(null),[f,y]=p.useState(null),[b,m]=p.useState(null),[x,j]=p.useState(null),[S,w]=p.useState(!1),[C,_]=p.useState(null),[N,$]=p.useState(!1),[E,k]=p.useState(null),[T,P]=p.useState(null),[W,R]=p.useState(!1),q=(a==null?void 0:a.tools)??[],Y=p.useMemo(()=>q.filter(re=>/search|retriev|query|lookup|find|fetch|get|read|list/i.test(re.name)),[q]);p.useEffect(()=>{!d&&Y.length&&h(Y[0].name)},[Y,d]),p.useEffect(()=>{!t||!n||M.workspaceLatestBackup(!0).then(({backup:re})=>{re&&j({createdAt:re.createdAt,counts:{runs:re.value.runs.length,sessions:re.value.sessions.length,snapshots:re.value.snapshots.length,prompts:re.value.prompts.length}})}).catch(()=>{})},[t,n]);async function K(){w(!0),_(null);try{if(!t||!n)throw new Error("Verify your email and finish Cloud Workspace setup before backing up data.");const re=await M.workspaceBackup();j({createdAt:re.capturedAt,counts:re.counts}),localStorage.setItem(`kawach.cloud-history.last-backup:${e}`,re.capturedAt)}catch(re){_(re instanceof Error?re.message:"Prooflane could not back up this workspace.")}finally{w(!1)}}async function ce(){$(!0),_(null),k(null);try{if(!t||!n)throw new Error("Verify your email and finish Cloud Workspace setup before restoring.");const re=await M.workspaceRestore();if(!re.ok)throw new Error(re.error??"No cloud backup was found to restore.");const V=re.restored;k(`Restored ${V.runs} runs · ${V.sessions} sessions · ${V.snapshots} contracts · ${V.prompts} prompts. Reloading…`),setTimeout(()=>window.location.reload(),1400)}catch(re){_(re instanceof Error?re.message:"Prooflane could not restore this workspace.")}finally{$(!1)}}async function B(){R(!0),_(null);try{if(!t||!n)throw new Error("Verify your email and finish Cloud Workspace setup first.");const{versions:re}=await M.workspaceBackupVersions(50);P(re.map(({id:V,capturedAt:ne,counts:te})=>({id:V,capturedAt:ne,counts:te})))}catch(re){_(re instanceof Error?re.message:"Prooflane could not load the backup history.")}finally{R(!1)}}async function ae(){v("run"),y(null),m(null);try{if(!t)throw new Error("Cloud Workspace is not configured for this Inspector. Set KAWACH_CONTROL_PLANE_URL and restart it.");if(!n)throw new Error("Verify your email with Prooflane first, then sign in again to use hosted Intelligence.");if(c==="security"&&!Ws())throw new Error("Connect an LLM locally before running the Security task.");if(c==="rag"&&(!r||!d))throw new Error("Connect a local MCP server and select its retriever tool before running the RAG task.");const V=(await M.intelligenceLease(c)).leases[0];if(!V)throw new Error("Prooflane did not return an Intelligence task. Try again.");const ne=await M.intelligenceExecute({lease:V.lease,llm:c==="security"?Es()??void 0:void 0,toolName:c==="rag"?d:void 0,dataHandling:"cloud-consented"});if(!ne.ok)throw new Error(ne.error??"The local Runner could not execute this task.");if(ne.execution){const te=await M.intelligenceEvaluation(V.lease,ne.execution);m({pillar:c,label:V.task.label,...te.evidence,stored:te.stored})}else if(ne.evidence){const te=await M.intelligenceEvidence(V.lease,ne.evidence);m({pillar:c,label:V.task.label,...ne.evidence,stored:te.stored})}else throw new Error("The local Runner did not return evidence.")}catch(re){y(re instanceof Error?re.message:"Hosted Intelligence could not complete this task.")}finally{v(null)}}return(i==null?void 0:i.tier)==="free"?s.jsx("div",{className:"stack",style:{gap:20,maxWidth:1e3},children:s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"section-title",children:"Local Inspector workspace"}),s.jsx("div",{className:"muted",style:{marginTop:7,fontSize:13,maxWidth:710},children:"Your Free plan keeps assurance data on this device only. Cloud History, recovery, and hosted Intelligence are available on Scale and above."})]}),s.jsx("span",{className:"tag",children:"free plan"})]}),s.jsxs("div",{className:"card inset",style:{padding:14,marginTop:16,fontSize:13,lineHeight:1.55},children:[s.jsx("b",{children:"Local workspace lifecycle."})," To protect data left on a shared or lost device, Prooflane removes local runs, prompts, sessions, and snapshots when you sign in again or your login session expires. Your MCP connection settings and credentials always stay local and are cleared as well."]})]})}):s.jsxs("div",{className:"stack",style:{gap:20,maxWidth:1e3},children:[s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"section-title",children:"Prooflane Cloud Workspace"}),s.jsx("div",{className:"muted",style:{marginTop:7,fontSize:13},children:"Hosted attack selection, grading and release policy. Your MCP connection and provider credentials remain on this machine."})]}),s.jsx("span",{className:`tag ${t?"pass":"warn"}`,children:t?"ready":"setup needed"})]}),s.jsxs("div",{className:"grid-2",style:{marginTop:20,gap:14},children:[s.jsxs("div",{className:"card inset",style:{padding:14},children:[s.jsx("div",{className:"muted",style:{fontSize:11,textTransform:"uppercase",letterSpacing:".08em"},children:"Signed-in account"}),s.jsx("div",{style:{marginTop:7,fontWeight:650},children:e})]}),s.jsxs("div",{className:"card inset",style:{padding:14},children:[s.jsx("div",{className:"muted",style:{fontSize:11,textTransform:"uppercase",letterSpacing:".08em"},children:"Email verification"}),s.jsx("div",{style:{marginTop:7,fontWeight:650,color:"var(--pass)"},children:"Verified"})]}),s.jsxs("div",{className:"card inset",style:{padding:14},children:[s.jsx("div",{className:"muted",style:{fontSize:11,textTransform:"uppercase",letterSpacing:".08em"},children:"Active plan"}),s.jsx("div",{style:{marginTop:7,fontWeight:650},children:(i==null?void 0:i.label)??"Checking…"}),(i==null?void 0:i.source)==="control-plane"&&s.jsx("div",{className:"muted",style:{marginTop:5,fontSize:12},children:"Confirmed by Prooflane Cloud Workspace"}),(i==null?void 0:i.source)==="local-dev"&&s.jsx("div",{className:"muted",style:{marginTop:5,fontSize:12},children:"Local development override"}),(i==null?void 0:i.source)==="fallback-free"&&s.jsxs("div",{style:{marginTop:5,fontSize:12,color:"var(--fail)"},children:["Free protections are active: ",((ue=i.reason)==null?void 0:ue.replaceAll("-"," "))??"plan could not be confirmed","."]}),(i==null?void 0:i.subject)&&s.jsxs("div",{className:"muted mono",style:{marginTop:8,fontSize:11},children:["Account key: ",i.subject]})]})]})]}),s.jsx(P5,{enabled:t&&n}),s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"section-title",children:"Cloud history & recovery"}),s.jsx("div",{className:"muted",style:{marginTop:7,fontSize:13,maxWidth:710},children:o?`Encrypted backup is enabled every ${l??24} hours while Inspector is open and signed in.`:"Back up selected assurance runs, contracts, prompts and recorded sessions to identify drift, compare regressions, and recover your workspace if this device is lost."})]}),s.jsxs("div",{className:"row",style:{gap:8,flexWrap:"wrap"},children:[s.jsx("button",{className:"btn ghost",onClick:ce,disabled:N||S||!t||!n,title:"Recover runs, contracts, prompts, and sessions from your latest encrypted cloud backup into this device.",children:N?"Restoring…":"Restore from Cloud"}),s.jsx("button",{className:"btn primary",onClick:K,disabled:S||N||!t||!n,children:S?"Backing up…":"Back up local workspace"})]})]}),s.jsxs("div",{className:"card inset",style:{padding:14,marginTop:16,fontSize:13},children:[s.jsx("b",{children:"Private by design."})," Your MCP connection details and credentials always stay on this device; Prooflane refuses them at the Cloud Workspace boundary. Without a completed backup, local assurance history is removed at your next sign-in or session expiry. After an encrypted backup, approved history can be recovered, but connection details and credentials are still cleared locally."]}),x&&s.jsxs("div",{className:"muted",style:{marginTop:13,fontSize:12.5},children:["Latest encrypted backup: ",new Date(x.createdAt).toLocaleString()," · ",x.counts.runs," runs · ",x.counts.sessions," sessions · ",x.counts.snapshots," contracts · ",x.counts.prompts," prompts. If your local workspace is blank, choose ",s.jsx("b",{children:"Restore from Cloud"})," to recover it."]}),E&&s.jsx("div",{style:{marginTop:13,color:"var(--pass)",fontSize:12.5},children:E}),C&&s.jsx("div",{style:{marginTop:13,color:"var(--fail)",fontSize:12.5},children:C}),s.jsx("div",{style:{marginTop:14},children:s.jsx("button",{className:"btn ghost sm",onClick:B,disabled:W||!t||!n,children:W?"Loading…":"Show backup history"})}),T&&s.jsx("div",{className:"card inset",style:{padding:14,marginTop:12,fontSize:12.5},children:T.length===0?s.jsx("div",{className:"muted",children:"No cloud backups exist for this account yet."}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"muted",style:{marginBottom:8},children:[T.length," cloud version",T.length===1?"":"s",", newest first. A version with non-zero counts is recoverable — ",s.jsx("b",{children:"Restore from Cloud"})," recovers the newest non-empty one."]}),s.jsx("div",{style:{display:"grid",gap:4},children:T.map(re=>{const V=re.counts.runs+re.counts.sessions+re.counts.snapshots+re.counts.prompts;return s.jsxs("div",{className:"mono",style:{display:"flex",justifyContent:"space-between",gap:12,color:V>0?"var(--pass)":"var(--muted)"},children:[s.jsx("span",{children:new Date(re.capturedAt).toLocaleString()}),s.jsxs("span",{children:[re.counts.runs," runs · ",re.counts.snapshots," contracts · ",re.counts.prompts," prompts · ",re.counts.sessions," sessions",V===0?" · (empty)":""]})]},re.id)})})]})})]}),s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start",flexWrap:"wrap"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"section-title",children:"Run hosted Intelligence"}),s.jsx("div",{className:"muted",style:{marginTop:7,fontSize:13},children:"Prooflane issues one signed, four-hour task. The local Runner executes it with your local connection."})]}),s.jsx(ei,{})]}),s.jsxs("div",{className:"row",style:{marginTop:18,gap:8},children:[s.jsx("button",{className:`btn sm ${c==="security"?"primary":"ghost"}`,onClick:()=>u("security"),children:"Security red-team"}),s.jsx("button",{className:`btn sm ${c==="rag"?"primary":"ghost"}`,onClick:()=>u("rag"),children:"RAG Assurance"})]}),c==="rag"&&s.jsxs("div",{style:{marginTop:15},children:[s.jsx("label",{className:"label",children:"Local retriever tool"}),s.jsxs("select",{className:"field",value:d,onChange:re=>h(re.target.value),disabled:!r,children:[!Y.length&&s.jsx("option",{value:"",children:r?"No likely retriever tool found":"Connect an MCP server first"}),Y.map(re=>s.jsx("option",{value:re.name,children:re.name},re.name))]})]}),s.jsx("button",{className:"btn primary",style:{marginTop:18},onClick:ae,disabled:g!==null,children:g==="run"?"Running locally…":"Request task & run"})]}),f&&s.jsx("div",{className:"drift dirty",children:s.jsxs("div",{className:"drift-row",children:[s.jsx("span",{className:"tag fail",children:"setup"}),s.jsx("span",{style:{fontSize:13},children:f})]})}),b&&s.jsxs("section",{className:"card",style:{padding:22},children:[s.jsxs("div",{className:"row spread",style:{gap:12},children:[s.jsx("div",{className:"section-title",children:"Latest hosted result"}),s.jsx("span",{className:`tag ${b.outcome==="pass"?"pass":b.outcome==="fail"?"fail":"warn"}`,children:b.outcome})]}),s.jsxs("div",{className:"grid-3",style:{marginTop:16,gap:12},children:[s.jsx(Af,{label:"Task",value:b.label}),s.jsx(Af,{label:"Score",value:`${b.score}/100`}),s.jsx(Af,{label:"Latency",value:`${b.latencyMs} ms`})]}),s.jsxs("div",{className:"muted",style:{marginTop:14,fontSize:13},children:[b.summary," ",b.stored?"Raw output was encrypted and saved to your cloud workspace.":"Only compact evidence was accepted; raw output stayed local."]})]})]})}function Af({label:e,value:t}){return s.jsxs("div",{className:"card inset",style:{padding:13},children:[s.jsx("div",{className:"muted",style:{fontSize:11,textTransform:"uppercase",letterSpacing:".08em"},children:e}),s.jsx("div",{style:{marginTop:7,fontSize:15,fontWeight:650},children:t})]})}const Pf="prooflane.mcp-tool-selector.collapsed";function U5({featureType:e,resourceId:t,value:n,activeConnectionId:a,onChange:r,onConnectionSelect:i,onConnect:o,onManageConnections:l,required:c=!1,compact:u=!1}){const[d,h]=p.useState([]),[g,v]=p.useState([]),[f,y]=p.useState(null),[b,m]=p.useState(null),[x,j]=p.useState(!0),[S,w]=p.useState(!1),[C,_]=p.useState(null),[N,$]=p.useState(""),[E,k]=p.useState(""),[T,P]=p.useState(null),[W,R]=p.useState(()=>{try{return localStorage.getItem(Pf)==="true"}catch{return!1}}),q=n===void 0?f:n,Y=A=>{R(A);try{localStorage.setItem(Pf,String(A))}catch{}},K=(A,L)=>{n===void 0&&y(A),r==null||r(A,L)},ce=async()=>{var A,L,ve;j(!0),P(null);try{const[D,J,oe]=await Promise.all([M.mcpConnections(),M.mcpTools(),M.mcpBinding(e,t)]);h(D.connections),m(D.entitlement),v(J.tools);const de=a&&D.connections.some(Se=>Se.id===a)?a:((A=oe.binding)==null?void 0:A.connectionId)??((L=D.connections.find(Se=>Se.status==="CONNECTED"))==null?void 0:L.id)??((ve=D.connections[0])==null?void 0:ve.id)??"";k(de),K(oe.binding);try{oe.binding&&localStorage.getItem(Pf)===null&&R(!0)}catch{}}catch(D){P(D instanceof Error?D.message:"MCP tools could not be loaded.")}finally{j(!1)}};p.useEffect(()=>{ce()},[e,t]),p.useEffect(()=>{a&&d.some(A=>A.id===a)&&k(a)},[a,d]),p.useEffect(()=>{!a&&(q!=null&&q.connectionId)&&d.some(A=>A.id===q.connectionId)&&k(q.connectionId)},[a,q==null?void 0:q.connectionId,d]);const B=p.useMemo(()=>{const A=N.trim().toLowerCase();return A?g.filter(L=>`${L.serverName} ${L.toolName} ${L.description??""}`.toLowerCase().includes(A)):g},[N,g]),ae=d.find(A=>A.id===E),ue=B.filter(A=>A.connectionId===E),re=(b==null?void 0:b.maxConnections)!==-1&&d.length>=((b==null?void 0:b.maxConnections)??0),V=A=>{k(A),$("");const L=d.find(ve=>ve.id===A);(L==null?void 0:L.status)==="CONNECTED"&&(i==null||i(A))},ne=async A=>{if(!S){w(!0),P(null);try{const L=await M.mcpPutBinding(e,t,{connectionId:A.connectionId,toolName:A.toolName,schemaDigest:A.schemaDigest});h(ve=>ve.map(D=>D.id===L.connection.id?L.connection:D)),k(L.connection.id),K(L.binding,{connection:L.connection,capabilities:L.capabilities}),Y(!0)}catch(L){P(L instanceof Error?L.message:"The MCP tool binding could not be saved.")}finally{w(!1)}}},te=async A=>{_(A),P(null);try{const L=await M.mcpRefreshTools(A);h(D=>D.map(J=>J.id===A?L.connection:J)),v(D=>[...D.filter(J=>J.connectionId!==A),...L.tools]);const ve=await M.mcpBinding(e,t);K(ve.binding)}catch(L){P(L instanceof Error?L.message:"Tool discovery refresh failed.")}finally{_(null)}};if(x)return s.jsx("div",{className:`mcp-selector ${u?"compact":""}`,children:s.jsx("span",{className:"muted",children:"Loading MCP connections and tools…"})});if(b&&!b.mcpEnabled)return s.jsxs("div",{className:`mcp-selector invalid ${u?"compact":""}`,children:[s.jsx("strong",{children:"MCP is not enabled for this workspace."}),s.jsx("span",{className:"muted",children:"Ask a workspace admin to enable the MCP entitlement."})]});if(!d.length)return s.jsxs("div",{className:`mcp-selector empty ${u?"compact":""}`,children:[s.jsxs("div",{children:[s.jsxs("strong",{children:["Select MCP tool",c?" · required":""]}),s.jsx("div",{className:"muted",children:"Connect and manage multiple MCP servers in Settings, then choose one server and one tool here."})]}),s.jsxs("div",{className:"row",style:{gap:8},children:[l&&s.jsx("button",{className:"btn sm ghost",onClick:l,children:"Open Settings"}),o&&s.jsx("button",{className:"btn sm primary",onClick:o,children:"Connect MCP server"})]})]});const fe=q?d.find(A=>A.id===q.connectionId):void 0,me=q&&q.status!=="VALID";return s.jsxs("section",{className:`mcp-selector ${u?"compact":""}`,"aria-label":"MCP tool selector",children:[s.jsxs("div",{className:"mcp-selector-head",children:[s.jsxs("div",{children:[s.jsxs("strong",{children:["Select MCP tool",c?" · required":""]}),s.jsx("div",{className:"muted",children:"One server + one tool is captured for this feature and every run."})]}),s.jsxs("div",{className:"row",style:{gap:8},children:[q&&s.jsx("span",{className:`tag ${q.status==="VALID"?"pass":"warn"}`,children:q.status.replaceAll("_"," ").toLowerCase()}),o&&s.jsx("button",{type:"button",className:"btn sm ghost",disabled:!!re,onClick:o,children:"+ Add server"}),s.jsxs("button",{type:"button",className:"btn sm ghost mcp-selector-toggle",onClick:()=>Y(!W),"aria-expanded":!W,"aria-controls":`${e}:${t}:mcp-selector-body`,children:[W?"Expand":"Collapse"," ",s.jsx("span",{"aria-hidden":"true",children:W?"+":"−"})]})]})]}),W&&s.jsxs("div",{className:"mcp-selector-summary",role:"status",children:[s.jsxs("div",{children:[s.jsx("strong",{children:(fe==null?void 0:fe.displayName)??(ae==null?void 0:ae.displayName)??"MCP target"}),s.jsx("span",{className:"muted",children:q?s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"mono",children:q.toolName})," · selected for this feature"]}):"Choose a tool before running this feature"})]}),(q==null?void 0:q.schemaDigest)&&s.jsxs("span",{className:"mono mcp-schema-digest",title:q.schemaDigest,children:[q.schemaDigest.slice(0,17),"…"]})]}),s.jsxs("div",{id:`${e}:${t}:mcp-selector-body`,className:"mcp-selector-body",hidden:W,children:[me&&s.jsxs("div",{className:"mcp-selector-warning",children:[s.jsx("strong",{children:"Saved MCP target needs attention."}),s.jsxs("span",{children:[(fe==null?void 0:fe.displayName)??q.connectionId," / ",q.toolName," · ",q.status.replaceAll("_"," ").toLowerCase()]}),s.jsx("span",{className:"mono",children:q.schemaDigest})]}),s.jsxs("div",{className:"mcp-server-choice",children:[s.jsx("label",{className:"label",htmlFor:`${e}:${t}:mcp-server`,children:"MCP server"}),s.jsx("select",{id:`${e}:${t}:mcp-server`,className:"field",value:E,onChange:A=>V(A.target.value),children:d.map(A=>s.jsxs("option",{value:A.id,children:[A.displayName," · ",A.status.toLowerCase().replaceAll("_"," ")," · ",A.toolCount," tools"]},A.id))}),s.jsxs("div",{className:"mcp-settings-hint",children:[s.jsx("span",{children:"Only tools from this server are shown below. Connect and manage multiple MCP servers in Settings."}),l&&s.jsx("button",{type:"button",className:"btn sm ghost",onClick:l,children:"Open Settings"})]})]}),s.jsx("input",{className:"field mcp-selector-search",value:N,onChange:A=>$(A.target.value),placeholder:"Search tools or MCP servers…","aria-label":"Search MCP tools"}),s.jsx("div",{className:"mcp-selector-groups",children:ae?(()=>{const A=ae.status!=="CONNECTED";return s.jsxs("fieldset",{className:"mcp-selector-group",disabled:A||S,children:[s.jsxs("legend",{children:[s.jsxs("span",{children:[s.jsx("strong",{children:ae.displayName}),s.jsx("span",{className:`mcp-health ${ae.healthStatus.toLowerCase()}`,children:ae.status.replaceAll("_"," ").toLowerCase()})]}),s.jsx("button",{type:"button",className:"btn sm ghost",disabled:A||C===ae.id,onClick:()=>void te(ae.id),children:C===ae.id?"Refreshing…":"Refresh tools"})]}),ue.length?ue.map(L=>{const ve=(q==null?void 0:q.connectionId)===L.connectionId&&q.toolName===L.toolName&&q.schemaDigest===L.schemaDigest;return s.jsxs("label",{className:`mcp-tool-option ${ve?"selected":""}`,children:[s.jsx("input",{type:"radio",name:`${e}:${t}:mcp-tool`,checked:ve,disabled:!L.enabled||A||S,onChange:()=>void ne(L)}),s.jsxs("span",{children:[s.jsx("strong",{className:"mono",children:L.toolName}),L.description&&s.jsx("small",{children:L.description})]}),s.jsxs("span",{className:"mono mcp-schema-digest",title:L.schemaDigest,children:[L.schemaDigest.slice(0,17),"…"]})]},L.canonicalToolKey)}):s.jsx("div",{className:"muted mcp-selector-none",children:N?"No matching tools on this server.":ae.toolCount===0?"This server advertises zero tools.":"Tools are unavailable; refresh discovery."})]},ae.id)})():s.jsx("div",{className:"muted mcp-selector-none",children:"Select an MCP server to see its tools."})}),T&&s.jsx("div",{className:"mcp-selector-error",children:T})]})]})}function F5({onConnect:e,onReconnect:t,onChanged:n}){const[a,r]=p.useState([]),[i,o]=p.useState(null),[l,c]=p.useState(null),u=()=>M.targets().then(h=>r(h.targets)).catch(h=>c(h instanceof Error?h.message:"Targets could not be loaded."));p.useEffect(()=>{u()},[]);const d=async(h,g)=>{if(!(g==="remove"&&!window.confirm("Remove this target connection? Governed Suites, Policies, Gates, Runs, reports, and audit history remain intact."))){o(`${h.id}:${g}`),c(null);try{g==="test"?await M.targetTest(h.id):g==="refresh"?await M.targetRefresh(h.id):g==="disconnect"?await M.targetDisconnect(h.id):await M.targetRemove(h.id),await u(),n==null||n()}catch(v){c(v instanceof Error?v.message:`Target ${g} failed.`)}finally{o(null)}}};return s.jsxs("section",{className:"card mcp-connections-view",children:[s.jsxs("div",{className:"row spread",style:{gap:12,alignItems:"flex-start"},children:[s.jsxs("div",{children:[s.jsx("div",{className:"eyebrow",children:"Local target registry"}),s.jsx("h3",{children:"Target Connections"}),s.jsx("p",{className:"muted",children:"Manage MCP, API, RAG, target-model, and agent connections. Only safe normalized surface metadata and fingerprints are registered; credentials remain in the local session."})]}),s.jsx("button",{className:"btn sm primary",onClick:()=>e(),children:"+ Connect a target"})]}),s.jsxs("div",{className:"mcp-connection-list",children:[!a.length&&s.jsx("div",{className:"muted",children:"No target connections are registered yet."}),a.map(h=>s.jsxs("article",{className:"mcp-connection-row",children:[s.jsx("span",{className:`conn-dot ${h.connectionStatus==="READY"?"on":""}`}),s.jsxs("div",{className:"mcp-connection-main",children:[s.jsx("strong",{children:h.displayName}),s.jsxs("span",{className:"muted",children:[h.type.replaceAll("_"," / ")," · ",h.connectionStatus.replaceAll("_"," ").toLowerCase()," · ",h.discoveryMetadata.capabilityCount," capabilities"]}),s.jsxs("small",{className:"muted",children:["Target ",eN(h.targetFingerprint)," · Surface ",eN(h.surfaceFingerprint)," · Auth ",h.authProfile.mode.toLowerCase().replaceAll("_"," ")]}),h.lastError&&s.jsx("small",{className:"mcp-selector-error",children:h.lastError})]}),s.jsxs("div",{className:"row",style:{gap:6,flexWrap:"wrap",justifyContent:"flex-end"},children:[h.connectionStatus==="READY"?s.jsxs(s.Fragment,{children:[s.jsx("button",{className:"btn sm ghost",disabled:i!==null,onClick:()=>void d(h,"test"),children:"Test"}),s.jsx("button",{className:"btn sm ghost",disabled:i!==null,onClick:()=>void d(h,"refresh"),children:"Refresh"}),s.jsx("button",{className:"btn sm ghost",disabled:i!==null,onClick:()=>void d(h,"disconnect"),children:"Disconnect"})]}):s.jsx("button",{className:"btn sm primary",disabled:i!==null,onClick:()=>t(h),children:"Reconnect"}),s.jsx("button",{className:"btn sm ghost danger",disabled:i!==null,onClick:()=>void d(h,"remove"),children:"Remove"})]})]},h.id))]}),l&&s.jsx("div",{className:"mcp-selector-error",children:l})]})}function eN(e){return e?`${e.slice(0,19)}…`:"pending"}const G5=[{type:"MCP",label:"MCP Server",description:"Tools, prompts, resources"},{type:"HTTP_API",label:"HTTP / API",description:"OpenAPI, REST, chat, inference APIs"},{type:"RAG",label:"RAG System",description:"Full-chain or retriever-only"},{type:"MODEL",label:"Model Endpoint",description:"Provider or compatible API"},{type:"AGENT",label:"AI Agent",description:"Agent invoke and trace adapter"}];function W5({availableTypes:e,workspaceId:t,projectId:n,targets:a,onChoose:r,onImport:i,onReconnect:o,onRemove:l,onSignOut:c}){return s.jsxs("div",{className:"target-onboarding",children:[s.jsxs("header",{children:[s.jsxs("div",{className:"brand",children:[s.jsx(ur,{}),s.jsxs("div",{children:[s.jsx("div",{className:"brand-name",children:"prooflane"}),s.jsx("div",{className:"brand-tag",children:"agent assurance spine"})]})]}),s.jsxs("div",{className:"row",children:[s.jsxs("span",{className:"tag informational",children:["Workspace · ",t]}),s.jsxs("span",{className:"tag informational",children:["Project · ",n]}),s.jsx("button",{className:"btn sm ghost",onClick:c,children:"Sign out"})]})]}),s.jsxs("main",{className:"target-onboarding-card",children:[s.jsx("div",{className:"eyebrow",children:"Required setup"}),s.jsx("h1",{children:"Connect your first target"}),s.jsx("p",{children:"Connect the AI system you want Prooflane to evaluate. Credentials and raw execution evidence remain local unless a feature explicitly tells you otherwise."}),s.jsx("div",{className:"target-type-grid onboarding-grid",children:G5.map(u=>{const d=e.includes(u.type);return s.jsxs("button",{className:"target-type-card",disabled:!d,onClick:()=>r(u.type),children:[s.jsx("span",{children:u.label}),s.jsx("small",{children:u.description}),d&&u.type==="MCP"&&s.jsx("b",{children:"AVAILABLE"}),d&&u.type!=="MCP"&&s.jsx("b",{children:"BETA"}),!d&&s.jsx("b",{children:"COMING SOON"})]},u.type)})}),s.jsxs("div",{className:"row",style:{marginTop:16,gap:8,flexWrap:"wrap"},children:[s.jsx("button",{className:"btn sm ghost",onClick:i,children:"Import connection config"}),s.jsx("button",{className:"btn sm ghost",onClick:()=>H5(),children:"Download sample config"})]}),a.length>0&&s.jsxs("div",{className:"target-onboarding-existing",children:[s.jsx("div",{className:"eyebrow",children:"Needs attention"}),a.map(u=>s.jsxs("div",{className:"row spread",children:[s.jsxs("span",{children:[s.jsx("strong",{children:u.displayName}),s.jsxs("small",{children:[u.type.replaceAll("_"," / ")," · ",u.connectionStatus.replaceAll("_"," ").toLowerCase()]})]}),s.jsxs("div",{className:"row",children:[s.jsx("button",{className:"btn sm primary",onClick:()=>o(u),children:"Reconnect"}),s.jsx("button",{className:"btn sm ghost danger",onClick:()=>l(u),children:"Remove"})]})]},u.id))]}),s.jsxs("details",{className:"target-help",children:[s.jsx("summary",{children:"Connection help"}),s.jsx("p",{children:"Choose MCP for stdio or remote MCP transports. API, RAG, model, and agent adapters test their configured endpoint locally before the product unlocks. A test connection is never governed evidence."})]})]})]})}function H5(){const e=URL.createObjectURL(new Blob([`${JSON.stringify(Rv,null,2)}
|
package/dist/ui/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600&family=IBM+Plex+Sans:wght@400;500&family=IBM+Plex+Mono:wght@400;500&display=swap"
|
|
12
12
|
rel="stylesheet"
|
|
13
13
|
/>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-LQjV2W1A.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/index-BbouSBNv.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
package/package.json
CHANGED