@viberaven/cli 1.4.4 → 1.5.0

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.
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
2
- <path fill="#412991" d="M32 5 11 16.8v13.7c0 12.2 8.9 23.3 21 27 12.1-3.7 21-14.8 21-27V16.8L32 5Z"/>
3
- <path fill="#EB5424" d="M32 5v48.7c-3.1-1.1-6.1-2.7-8.7-4.7L32 5Z"/>
4
- <path fill="#FBC22C" d="m32 5 8.7 44c-2.6 2-5.6 3.6-8.7 4.7V5Z"/>
5
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
2
+ <path fill="#412991" d="M32 5 11 16.8v13.7c0 12.2 8.9 23.3 21 27 12.1-3.7 21-14.8 21-27V16.8L32 5Z"/>
3
+ <path fill="#EB5424" d="M32 5v48.7c-3.1-1.1-6.1-2.7-8.7-4.7L32 5Z"/>
4
+ <path fill="#FBC22C" d="m32 5 8.7 44c-2.6 2-5.6 3.6-8.7 4.7V5Z"/>
5
+ </svg>
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 64" aria-hidden="true">
2
- <text x="48" y="31" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="21" font-weight="800" letter-spacing="-1.4" fill="#111827">AWS</text>
3
- <path fill="#FF9900" d="M23.6 42.4c13.9 7.5 31.5 7.5 45.1-.1 1.1-.6 2.2.8 1.3 1.7-12.3 12.5-34.3 12.6-47.2.8-.9-.8-.3-2.9.8-2.4Z"/>
4
- <path fill="#FF9900" d="M66.8 39.8c2.4-.3 7.8-.8 8.8 1 .9 1.6-1 5.8-2.5 8.2-.5.8-1.7.4-1.5-.6.5-2.1 1.3-4.8.5-5.8-.8-1-3.8-.8-5.4-.6-1 .1-1.2-2-.1-2.2h.2Z"/>
5
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 64" aria-hidden="true">
2
+ <text x="48" y="31" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="21" font-weight="800" letter-spacing="-1.4" fill="#111827">AWS</text>
3
+ <path fill="#FF9900" d="M23.6 42.4c13.9 7.5 31.5 7.5 45.1-.1 1.1-.6 2.2.8 1.3 1.7-12.3 12.5-34.3 12.6-47.2.8-.9-.8-.3-2.9.8-2.4Z"/>
4
+ <path fill="#FF9900" d="M66.8 39.8c2.4-.3 7.8-.8 8.8 1 .9 1.6-1 5.8-2.5 8.2-.5.8-1.7.4-1.5-.6.5-2.1 1.3-4.8.5-5.8-.8-1-3.8-.8-5.4-.6-1 .1-1.2-2-.1-2.2h.2Z"/>
5
+ </svg>
@@ -1,4 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
2
- <path fill="#764ABC" fill-rule="evenodd" clip-rule="evenodd" d="M26.8 12.9A20.8 20.8 0 0 1 32.3 7a20.5 20.5 0 0 1 5.5 5.8 29.3 29.3 0 0 1 5.1 17.1c1.1.9 2.3 1.8 3.4 2.7a6.2 6.2 0 0 1 2 5.7c-.5 2.6-1.1 5.2-1.6 7.8a2.2 2.2 0 0 1-3.3 1.1c-1.8-1.5-3.6-3-5.4-4.5a8.4 8.4 0 0 1-5.2 2.3 8.5 8.5 0 0 1-6.1-2.2c-1.3 1-2.5 2.1-3.8 3.2-.6.6-1.2 1-1.9 1.4a2.2 2.2 0 0 1-2.9-1.4c-.6-2.5-1.2-5.1-1.8-7.6a6.3 6.3 0 0 1 2.1-6c1-.8 2-1.6 3-2.3.3-.2.1-.5.2-.7a29.3 29.3 0 0 1 5.2-16.5Zm2.2 8.2a4.3 4.3 0 0 0 .4 5.8 4.8 4.8 0 0 0 6.5.1 4.3 4.3 0 0 0 1.1-4.8 4.4 4.4 0 0 0-3.9-2.9 4.5 4.5 0 0 0-4.1 1.8Zm3.3 4.9a2.1 2.1 0 1 0 0-4.2 2.1 2.1 0 0 0 0 4.2Z"/>
3
- <path fill="#764ABC" d="M26.4 48.1a1.1 1.1 0 0 1 1.6-.9 10.4 10.4 0 0 0 9 0 1.1 1.1 0 0 1 1.6.8v4.8a1.1 1.1 0 0 1-1.7.8c-.5-.4-.9-.9-1.4-1.3-.7 1.4-1.4 2.8-2.1 4.1a1.1 1.1 0 0 1-1.8 0c-.8-1.4-1.4-2.8-2.2-4.1-.4.4-.9.9-1.3 1.3a1.1 1.1 0 0 1-1.7-.8v-4.7Z"/>
4
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
2
+ <path fill="#764ABC" fill-rule="evenodd" clip-rule="evenodd" d="M26.8 12.9A20.8 20.8 0 0 1 32.3 7a20.5 20.5 0 0 1 5.5 5.8 29.3 29.3 0 0 1 5.1 17.1c1.1.9 2.3 1.8 3.4 2.7a6.2 6.2 0 0 1 2 5.7c-.5 2.6-1.1 5.2-1.6 7.8a2.2 2.2 0 0 1-3.3 1.1c-1.8-1.5-3.6-3-5.4-4.5a8.4 8.4 0 0 1-5.2 2.3 8.5 8.5 0 0 1-6.1-2.2c-1.3 1-2.5 2.1-3.8 3.2-.6.6-1.2 1-1.9 1.4a2.2 2.2 0 0 1-2.9-1.4c-.6-2.5-1.2-5.1-1.8-7.6a6.3 6.3 0 0 1 2.1-6c1-.8 2-1.6 3-2.3.3-.2.1-.5.2-.7a29.3 29.3 0 0 1 5.2-16.5Zm2.2 8.2a4.3 4.3 0 0 0 .4 5.8 4.8 4.8 0 0 0 6.5.1 4.3 4.3 0 0 0 1.1-4.8 4.4 4.4 0 0 0-3.9-2.9 4.5 4.5 0 0 0-4.1 1.8Zm3.3 4.9a2.1 2.1 0 1 0 0-4.2 2.1 2.1 0 0 0 0 4.2Z"/>
3
+ <path fill="#764ABC" d="M26.4 48.1a1.1 1.1 0 0 1 1.6-.9 10.4 10.4 0 0 0 9 0 1.1 1.1 0 0 1 1.6.8v4.8a1.1 1.1 0 0 1-1.7.8c-.5-.4-.9-.9-1.4-1.3-.7 1.4-1.4 2.8-2.1 4.1a1.1 1.1 0 0 1-1.8 0c-.8-1.4-1.4-2.8-2.2-4.1-.4.4-.9.9-1.3 1.3a1.1 1.1 0 0 1-1.7-.8v-4.7Z"/>
4
+ </svg>
@@ -7274,9 +7274,9 @@ function buildAgentPromptText(payload, nextMove, missing, files) {
7274
7274
 
7275
7275
  function buildChecklistText(payload, nextMove, missing, files) {
7276
7276
  const lines = [
7277
- '# VibeRaven production checklist',
7277
+ '# VibeRaven production checklist',
7278
7278
  '',
7279
- 'Generated from the latest VibeRaven run.',
7279
+ 'Generated from the latest VibeRaven run.',
7280
7280
  '',
7281
7281
  '## Next move',
7282
7282
  '',
@@ -0,0 +1,13 @@
1
+ "use strict";(()=>{function ee(e=document){return e.querySelector('meta[name="viberaven-token"]')?.content??""}async function C(e,i){let n=await fetch(e,{...i,credentials:"same-origin",headers:{"content-type":"application/json","x-viberaven-token":ee(),...i?.headers??{}}}),a=await n.text(),o=null;try{o=a?JSON.parse(a):null}catch{o={error:a}}if(!n.ok){let l=o?.error??o?.message??a??`HTTP ${n.status}`;throw new Error(String(l))}return o}var v=(e,i)=>C(e,{method:"POST",body:JSON.stringify(i)}),h={project:()=>C("/api/project"),scan:()=>v("/api/scan",{}),scanStatus:()=>C("/api/scan-status"),agents:()=>C("/api/cli-agents"),probe:e=>v("/api/cli-agents/probe",{cliId:e}),runSetup:(e,i)=>v("/api/cli-agents/run-setup",{cliId:e,step:i}),openTerminal:(e,i)=>v("/api/cli-agents/open-terminal",{cliId:e,step:i}),chat:e=>v("/api/agent-chat",e),catalog:()=>C("/api/provider-catalog"),verified:()=>C("/api/provider-verify"),stop:e=>v("/api/agent-chat/stop",{runId:e}),verify:e=>v("/api/provider-verify",e),connectMcp:e=>v("/api/mcp/connect",{providerId:e}),compare:(e,i)=>C(`/api/releases/compare?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`),fullCheckStatus:()=>C("/api/fullcheck/status"),fullCheckSignInStart:()=>v("/api/fullcheck/signin/start",{}),fullCheckSignInPoll:()=>v("/api/fullcheck/signin/poll",{}),fullCheckSignOut:()=>v("/api/fullcheck/signout",{}),fullCheckPrepare:()=>v("/api/fullcheck/prepare",{}),fullCheckRun:e=>v("/api/fullcheck/run",{previewId:e}),changelog:(e,i)=>C(`/api/releases/changelog?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`)};function t(e,i,...n){let a=document.createElement(e);if(i){for(let[o,l]of Object.entries(i))if(!(l==null||l===!1))if(o==="class")a.className=String(l);else if(o==="on")for(let[d,u]of Object.entries(l))a.addEventListener(d,u);else if(o==="dataset")for(let[d,u]of Object.entries(l))a.dataset[d]=u;else o==="html"?a.innerHTML=String(l):o==="style"&&typeof l=="object"?Object.assign(a.style,l):o in a&&typeof l!="string"?a[o]=l:a.setAttribute(o,String(l))}return H(a,n),a}function H(e,i){for(let n of i)n==null||n===!1||(Array.isArray(n)?H(e,n):n instanceof Node?e.appendChild(n):e.appendChild(document.createTextNode(String(n))))}function x(e){return e.replace(/[&<>"']/g,i=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[i])}function D(e){let n=x(e.replace(/\r\n/g,`
2
+ `)).split(/```/),a="";return n.forEach((o,l)=>{if(l%2===1){let s=o.replace(/^[a-z0-9-]*\n/i,"");a+=`<pre><code>${s}</code></pre>`;return}let d=o.split(`
3
+ `),u=null;for(let s of d){let r=s.trimEnd(),p=/^\s*[-*•]\s+(.*)$/.exec(r),c=/^\s*\d+[.)]\s+(.*)$/.exec(r),f=/^(#{1,3})\s+(.*)$/.exec(r),b=p?"ul":c?"ol":null;u&&b!==u&&(a+=`</${u}>`,u=null),b&&!u&&(a+=`<${b}>`,u=b),p||c?a+=`<li>${L((p??c)[1])}</li>`:f?a+=`<h4>${L(f[2])}</h4>`:r.trim()&&(a+=`<p>${L(r)}</p>`)}u&&(a+=`</${u}>`)}),a}function L(e){return e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>").replace(/`([^`]+)`/g,"<code>$1</code>")}function I(e){let i=Date.now()-new Date(e).getTime();if(!Number.isFinite(i)||i<0)return"just now";let n=Math.round(i/6e4);if(n<1)return"just now";if(n<60)return`${n} min ago`;let a=Math.round(n/60);return a<24?`${a} h ago`:`${Math.round(a/24)} d ago`}function A(){return{step:"closed",status:null,signIn:null,preview:null,result:null,limit:null,error:null,notice:null}}var te=new Set(["network","timeout","server","rate_limited","busy"]);function B(e,i={}){let n=i.wait??(g=>new Promise(m=>window.setTimeout(m,g))),a=0,o=()=>e.get().fullCheck,l=g=>e.set(m=>({fullCheck:{...m.fullCheck,...g}})),d=g=>g===a&&o().step!=="closed";async function u(g){try{return await g()}catch(m){return{kind:"error",reason:"unexpected",message:`The Studio did not answer: ${m instanceof Error?m.message:String(m)}`}}}async function s(){try{let g=await h.fullCheckStatus();return l({status:g}),g}catch{return null}}async function r(g,m,y){if(d(y))switch(g.kind){case"signin":l({step:"signin",signIn:{code:g.code,verificationUrl:g.verificationUrl,expiresAt:g.expiresAt,opened:g.opened},error:null}),p(y,g.pollIntervalSeconds);return;case"signin_pending":return;case"signed_in":if(l({signIn:null,notice:g.notice??(o().preview?"Signed in again. Confirm to send the same request.":null)}),await s(),!d(y))return;o().preview?l({step:"preview"}):await f(y);return;case"signin_expired":case"signin_denied":l({step:"error",signIn:null,error:{message:g.message,retry:"signin"}});return;case"signed_out":l({...A()}),e.toast("Signed out of VibeRaven on this computer.");return;case"signin_required":case"reauth":l({notice:g.message}),await c(y);return;case"preview":l({step:"preview",preview:g.preview,error:null});return;case"result":l({step:"result",result:g.result,preview:null,notice:null,error:null}),await s();return;case"plan_limit":l({step:"limit",preview:null,notice:null,limit:{plan:g.plan,message:g.message,pricingUrl:g.pricingUrl,usage:g.usage}}),await s();return;case"error":{let w=g.reason==="not_confirmed"||g.reason==="prepare_failed"?"prepare":g.reason==="no_signin"?"signin":m==="run"&&!te.has(g.reason)?"prepare":m;w==="prepare"&&m==="run"&&l({preview:null}),l({step:"error",error:{message:g.message,retry:w}});return}}}async function p(g,m){for(;d(g)&&o().step==="signin";){if(await n(Math.max(1,m)*1e3),!d(g)||o().step!=="signin")return;let y=await u(()=>h.fullCheckSignInPoll());if(y.kind!=="signin_pending"){await r(y,"signin",g);return}}}async function c(g){l({step:"loading",error:null}),await r(await u(()=>h.fullCheckSignInStart()),"signin",g)}async function f(g){l({step:"preparing",error:null,result:null,limit:null}),await r(await u(()=>h.fullCheckPrepare()),"prepare",g)}async function b(g){l({step:"loading",error:null});let m=await s();if(d(g)){if(!m){l({step:"error",error:{message:"The Studio server did not answer. Reload the page and try again.",retry:"status"}});return}m.signedIn?await f(g):await c(g)}}return{async openFullCheck(){let g=o().step;g!=="closed"&&g!=="result"&&g!=="limit"&&g!=="error"||(a+=1,l({...A(),step:"loading",status:o().status}),await b(a))},closeFullCheck(){a+=1,l({step:"closed",signIn:null,error:null,notice:null}),document.getElementById("run-full-check")?.focus({preventScroll:!0})},async fullCheckSignIn(){await c(a)},async fullCheckConfirm(){let g=o().preview;if(!g||o().step!=="preview")return;let m=a;l({step:"running",error:null}),await r(await u(()=>h.fullCheckRun(g.id)),"run",m)},async fullCheckRetry(){let g=o().error?.retry??"status",m=a;if(g==="run"&&o().preview){l({step:"preview",error:null});return}g==="signin"?await c(m):g==="prepare"?await f(m):await b(m)},async fullCheckSignOut(){await r(await u(()=>h.fullCheckSignOut()),"status",a),await s()},async copyFullCheckPrompt(g){try{await navigator.clipboard.writeText(g),e.toast("Fix prompt copied. Paste it into your coding agent.")}catch{e.toast("Could not copy. Select the text and copy it by hand.","err")}}}}function T(e){return e?e.plan==="pro"?`${e.used} of ${e.limit} Pro full checks used this month`:`${e.used} of ${e.limit} free full checks used`:null}function V(e){return e==="pro"?"Pro plan":"Free plan"}function N(e){return e<1024?`${e} B`:`${(e/1024).toFixed(1)} KB`}function ne(e){try{return new URL(e).host}catch{return e}}function j(e){return t("span",{class:`tag ${e==="critical"?"red":e==="warning"?"amber":"dim"}`},e==="critical"?"Critical":e==="warning"?"Important":"Nice to have")}function se(e,i){let n=e.status?.account;if(!n)return null;let a=T(e.status?.usage);return t("div",{class:"fc-account"},t("span",{},`Signed in as ${n.email}`),t("span",{class:"fc-dot"},V(n.plan)),e.status?.sessionOnly?t("span",{class:"fc-dot"},"this session only"):null,a?t("span",{class:"fc-dot"},a):null,t("button",{class:"fc-link",on:{click:()=>i.fullCheckSignOut()}},"Sign out"))}function ie(e,i){let n=e.signIn;return[t("p",{class:"fc-lead"},e.notice??"Full checks run on VibeRaven, so they need your VibeRaven account. Sign in once on this computer."),t("div",{class:"fc-code"},t("span",{class:"fc-code-label"},"Your code"),t("strong",{id:"fc-code"},n.code)),t("p",{class:"sub"},n.opened?"We opened the sign-in page in your browser. Check the code matches, then confirm it there.":"Open the sign-in page, check the code matches, then confirm it there."),t("div",{class:"fc-actions"},t("a",{class:"btn primary",href:n.verificationUrl,target:"_blank",rel:"noopener noreferrer"},"Open the sign-in page"),t("span",{class:"fc-wait",role:"status"},t("span",{class:"spin"}),"Waiting for you to confirm\u2026"),t("button",{class:"btn ghost",on:{click:()=>i.closeFullCheck()}},"Cancel"))]}function $(e,i,n){return t("div",{class:"fc-files"},t("h4",{},`${e} (${i.length})`),i.length?t("ul",{},...i.map(a=>t("li",{},t("code",{},a.path),t("span",{},a.meta)))):t("p",{class:"sub"},n))}function re(e,i){let n=e.preview;return[e.notice?t("p",{class:"fc-notice",role:"status"},e.notice):null,t("p",{class:"fc-lead"},`This is exactly what gets sent to ${ne(n.endpoint)} when you confirm. Nothing has been uploaded yet.`),se(e,i),t("dl",{class:"fc-facts"},t("div",{},t("dt",{},"Project folder"),t("dd",{},t("code",{},n.workspacePath))),t("div",{},t("dt",{},"Request size"),t("dd",{},N(n.bytes))),t("div",{},t("dt",{},"SPEC.md"),t("dd",{},n.spec.included?`Included (${n.spec.chars.toLocaleString()} characters)`:"Not found, not sent")),t("div",{},t("dt",{},"Dependencies"),t("dd",{},`${n.dependencyCount} package names`)),t("div",{},t("dt",{},"File tree"),t("dd",{},`${n.fileTreeEntries} paths, names only`))),t("div",{class:"fc-filegrid"},$("Files sent in full",n.promptFiles.map(a=>({path:a.path,meta:`${a.chars.toLocaleString()} chars${a.redactions?`, ${a.redactions} redacted`:""}`})),"No file contents are sent."),$("File snippets (first 200 characters)",n.snippetFiles.map(a=>({path:a.path,meta:a.heat})),"None."),$("Skipped as secret files (name sent, contents never read)",n.secretFilesNamedOnly.map(a=>({path:a,meta:"name only"})),"None found."),$("Request text by section",n.promptSections.map(a=>({path:a.title,meta:`${a.chars.toLocaleString()} chars`})),"Empty.")),t("p",{class:"sub"},"Most of the request text is written by VibeRaven on your machine from the local scan: stack notes and the check instructions."),t("p",{id:"fc-redaction",class:"fc-notice"},n.redactions>0?`VibeRaven replaced ${n.redactions} secret-looking value${n.redactions===1?"":"s"} with [REDACTED]. `:"VibeRaven found no secret-looking values to replace. ","This is pattern matching, not a guarantee. Other files are sent as they are, so read the exact request body below before you send it."),t("details",{class:"fc-raw"},t("summary",{},`Show the exact request body: the prompt, file snippets and SPEC.md. Shown formatted here; sent compact (${N(n.bytes)}), same content.`),t("pre",{id:"fc-request-json"},n.requestJson)),t("div",{class:"fc-actions"},t("button",{id:"fc-confirm",class:"btn primary",on:{click:()=>i.fullCheckConfirm()}},"Send and run full check"),t("button",{class:"btn ghost",on:{click:()=>i.closeFullCheck()}},"Cancel"))]}function ae(e,i){let n=e.result,a=n.areas.reduce((l,d)=>l+d.hiddenCount,0),o=n.nextFix;return[t("div",{class:"fc-score"},t("div",{class:"fc-score-num"},String(n.score)),t("div",{},t("div",{class:"fc-score-label"},n.scoreLabel,t("span",{class:"tag dim"},`${n.confidence} confidence`)),t("p",{},n.summary))),t("div",{class:"fc-account"},t("span",{},V(n.usage.plan)),t("span",{class:"fc-dot"},T(n.usage)),t("span",{class:"fc-dot"},`${n.usage.remaining} left${n.usage.period==="monthly"?" this month":""}`)),o?t("article",{class:"fc-next"},t("div",{class:"fix-top"},t("span",{class:"fc-eyebrow"},"Next fix"),j(o.severity),t("span",{class:"fix-meta"},o.areaTitle)),t("h3",{},o.title),o.detail?t("p",{},o.detail):null,o.prompt?t("button",{class:"btn sm",on:{click:()=>i.copyFullCheckPrompt(o.prompt)}},"Copy fix prompt"):null):t("p",{class:"fc-lead"},"No findings in the areas your plan covers."),t("h4",{class:"fc-h4"},"Findings by area"),t("div",{class:"fc-areas"},...n.areas.map(l=>t("section",{class:`fc-area${l.locked?" locked":""}`,"aria-label":l.title},t("div",{class:"fc-area-head"},t("h5",{},l.title),l.locked?t("span",{class:"tag dim"},"Pro area"):t("span",{class:`fc-count${l.findings.length?" on":""}`},String(l.findings.length))),l.locked?t("p",{class:"sub"},l.hiddenCount?`${l.hiddenCount} finding${l.hiddenCount===1?"":"s"} here. Pro shows every area.`:"Included with Pro."):l.findings.length?t("ul",{},...l.findings.map(d=>t("li",{},j(d.severity),t("span",{title:d.detail},d.title)))):t("p",{class:"sub"},"No findings.")))),a&&n.usage.plan==="free"?t("p",{class:"fc-upsell"},`${a} finding${a===1?" is":"s are"} in areas Pro covers. `,t("a",{href:"https://viberaven.dev/pricing",target:"_blank",rel:"noopener noreferrer"},"See Pro")):null,t("div",{class:"fc-actions"},t("button",{class:"btn",on:{click:()=>i.closeFullCheck()}},"Done"))]}function oe(e,i){let n=e.limit;return[t("h3",{class:"fc-limit",role:"alert"},n.message),T(n.usage)?t("p",{class:"sub"},T(n.usage)):null,n.plan==="free"?t("p",{class:"sub"},"The local Studio checks stay free and unlimited. Pro adds 50 full checks a month across all production areas."):t("p",{class:"sub"},"The local Studio checks keep working until your monthly allowance resets."),t("div",{class:"fc-actions"},n.pricingUrl?t("a",{id:"fc-see-pro",class:"btn primary",href:n.pricingUrl,target:"_blank",rel:"noopener noreferrer"},"See Pro"):null,t("button",{class:"btn ghost",on:{click:()=>i.closeFullCheck()}},"Close"))]}function le(e,i){let n=e.error;return[t("p",{class:"fc-error",role:"alert"},n.message),t("div",{class:"fc-actions"},t("button",{class:"btn primary",on:{click:()=>i.fullCheckRetry()}},n.retry==="signin"?"Sign in again":"Try again"),t("button",{class:"btn ghost",on:{click:()=>i.closeFullCheck()}},"Close"))]}function R(e){return t("p",{class:"fc-wait",role:"status"},t("span",{class:"spin"}),e)}var ce={closed:"",loading:"Full check",signin:"Sign in to run a full check",preparing:"Full check",preview:"Review what gets sent",running:"Running the full check",result:"Full check result",limit:"Full check limit reached",error:"Full check did not run"};function q(e,i){let n=e.fullCheck;if(n.step==="closed")return[];let a=n.step==="signin"&&n.signIn?ie(n,i):n.step==="preview"&&n.preview?re(n,i):n.step==="result"&&n.result?ae(n,i):n.step==="limit"&&n.limit?oe(n,i):n.step==="error"&&n.error?le(n,i):n.step==="preparing"?[R("Reading your project to build the request\u2026")]:n.step==="running"?[R("Sent. VibeRaven is checking your app\u2026")]:[R("Checking your VibeRaven sign-in\u2026")],o=n.step!=="running";return[t("div",{class:"fc-veil",on:{click:()=>{o&&i.closeFullCheck()}}}),t("section",{id:"full-check",class:"fc-sheet",role:"dialog","aria-modal":"true","aria-labelledby":"fc-title"},t("header",{class:"fc-head"},t("h2",{id:"fc-title"},ce[n.step]),o?t("button",{class:"btn ghost sm","aria-label":"Close full check",on:{click:()=>i.closeFullCheck()}},"Close"):null),t("div",{class:"fc-body"},...a))]}var _="viberaven.stack.";function P(e,i,n=localStorage){try{let a=n.getItem(_+e);return a?JSON.parse(a):i}catch{return i}}function M(e,i,n=localStorage){try{n.setItem(_+e,JSON.stringify(i))}catch{}}function K(e){let i=`chat.${e.project?.path??"project"}`,n={project:e,catalog:[],verified:{},agents:[],probes:{},cliId:P("cliId","codex"),accessMode:P("accessMode","approve"),modelId:P("modelId",""),messages:P(i,[],sessionStorage),draft:"",contextProviderId:null,busy:{chat:!1,scan:!1,probe:null,tile:null,compare:!1},terminalOutput:"",compare:{from:"",to:"HEAD",result:null,error:null},drawer:null,section:"stack",agentOpen:!1,showAll:!1,setup:{open:!1,initialized:!1,selected:[],running:!1,progress:[],error:null},scan:null,toasts:[],workingSince:null,runId:null,fullCheck:A()},a=new Set,o=0,l={get:()=>n,set(d){let u=typeof d=="function"?d(n):d;n={...n,...u},"cliId"in u&&M("cliId",n.cliId),"accessMode"in u&&M("accessMode",n.accessMode),"modelId"in u&&M("modelId",n.modelId),"messages"in u&&M(i,n.messages.slice(-60),sessionStorage);for(let s of a)s(n)},subscribe(d){return a.add(d),()=>a.delete(d)},toast(d,u="ok"){let s=++o;l.set(r=>({toasts:[...r.toasts,{id:s,text:d,kind:u}]})),window.setTimeout(()=>l.set(r=>({toasts:r.toasts.filter(p=>p.id!==s)})),u==="err"?7e3:3600)},push(d){let u={...d,id:`${Date.now()}-${Math.random().toString(36).slice(2,7)}`,at:new Date().toISOString()};return l.set(s=>({messages:[...s.messages,u]})),u}};return l}var z=["sentry","stripe","clerk","cloudflare","render","railway","neon","posthog","upstash","resend","authjs"];function de(e){return e?e.launchPath.filter(n=>n.state==="needs_fix"||n.state==="needs_connect"||n.state==="requires_user_action"||n.state==="blocked").length||(e.nextFix?1:0):0}function E(e,i,n){let a=new Map(e.providers.map(r=>[r.id,r])),o=new Set,l=[],d=(r,p)=>{let c=r?.id??p.id;if(o.has(c))return;o.add(c);let f=!!r?.detected||!!(p&&p.state!=="not_detected"),b=!!r?.mcpConfigured||p?.mcp?.status==="connected",g=n[c],m=f?de(p):0,y="absent",w="Not in this app";f&&(y="in_repo",w=b?"MCP configured \xB7 not verified live":"In repo \xB7 MCP not set up",b&&(y="mcp"),g&&(y=g.ok&&m===0?"ready":"verified",w=g.ok?"Verified live":"Verified live \xB7 issues found")),l.push({id:c,name:r?.name??p.name,area:r?.area??p.area,logoUrl:r?.logoUrl??ue(p?.iconHtml??""),step:y,statusText:w,fixes:m,hasRecipe:!!r?.hasRecipe||p?.mcp?.available===!0,mcpConfigured:b,note:r?.note,mcpSource:r?.mcpSource??p?.mcp?.source,verified:g,provider:p})};for(let r of i)d(r,a.get(r.id));for(let r of e.providers)d(null,r);let u=r=>r.step==="absent"?r.hasRecipe?1:2:0,s=r=>{let p=z.indexOf(r.id);return p===-1?z.length:p};return l.sort((r,p)=>u(r)-u(p)||p.fixes-r.fixes||s(r)-s(p)||r.name.localeCompare(p.name))}function ue(e){let i=/src="([^"]+)"/.exec(e);return i?i[1]:""}function W(e,i){let n=e.find(o=>o.provider?.nextFix?.id===i.id||o.provider?.launchPath.some(l=>l.id===i.id));if(n)return n;let a=`${i.title} ${i.detail??""}`.toLowerCase();return e.find(o=>o.step!=="absent"&&a.includes(o.name.toLowerCase()))??e.find(o=>o.step!=="absent"&&o.area.toLowerCase()===i.category.toLowerCase())}function Y(e,i,n){let a=e.setup,o=a.selected.length,l=e.probes[e.cliId]?.ready,d=a.running||e.busy.chat||!!e.busy.tile||e.busy.scan;return t("section",{class:"stack-setup","aria-label":"Connect my app"},t("div",{class:"setup-heading"},t("div",{},t("span",{class:"eyebrow"},"Your setup"),t("h2",{id:"stack-setup-heading",tabIndex:-1},"Set up your app"),t("ol",{class:"setup-steps"},t("li",{class:o?"done":""},t("i",{"aria-hidden":"true"},o?"\u2713":"1"),"Pick your services"),t("li",{class:l?"done":""},t("i",{"aria-hidden":"true"},l?"\u2713":"2"),"Connect your coding agent"),t("li",{},t("i",{"aria-hidden":"true"},"3"),e.accessMode==="ask"?"Get a plan":"Start setup"))),t("button",{class:"btn ghost sm",disabled:a.running,on:{click:()=>{i.set({setup:{...i.get().setup,open:!1}}),document.getElementById("connect-my-app")?.focus({preventScroll:!0})}}},"Close")),e.catalog.length?t("div",{class:"setup-services"},...e.catalog.map(u=>{let s=a.selected.includes(u.id);return t("button",{id:`setup-provider-${u.id}`,class:`setup-service${s?" selected":""}`,"aria-pressed":String(s),disabled:d,on:{click:()=>n.toggleSetupProvider(u.id)}},t("img",{src:u.logoUrl,alt:""}),t("span",{class:"setup-service-copy"},t("strong",{},u.name),t("small",{},u.detected?"In your app":u.area)),t("span",{class:"setup-check","aria-hidden":"true"},s?"\u2713":"+"))})):t("p",{class:"setup-note"},"Loading the service catalog\u2026"),t("div",{class:"setup-footer"},t("div",{},t("strong",{},o?l?`${o} service${o===1?"":"s"} ready to set up`:"Connect your agent to continue":"Pick at least one service"),t("p",{},e.accessMode==="ask"?"Ask mode only plans. It does not change your app.":"Your agent edits the repo. Provider sign-ins stay with you.")),a.running?t("button",{class:"btn",on:{click:()=>n.stop()}},"Stop setup"):l?t("button",{class:"btn primary",disabled:!o||d,on:{click:()=>n.startStackSetup()}},e.accessMode==="ask"?"Plan my setup":"Start setup",t("span",{"aria-hidden":"true"},"\u2197")):t("button",{class:"btn primary",disabled:e.busy.probe!==null,on:{click:()=>n.testConnection(e.cliId)}},e.busy.probe?"Testing agent\u2026":"Test agent connection")),a.progress.length?t("ol",{class:"setup-progress","aria-live":"polite"},...a.progress.map(u=>t("li",{class:u.state},t("span",{class:u.state==="working"&&a.running&&!a.error?"spin":"progress-dot","aria-hidden":"true"}),u.label))):null,a.error?t("p",{class:"setup-error",role:"alert"},a.error):null)}function J(e,i,n){let a=i.get(),o=e.contains(document.activeElement)?document.activeElement:null,l=o?.id,d=o instanceof HTMLTextAreaElement||o instanceof HTMLInputElement?[o.selectionStart,o.selectionEnd]:null;if(e.classList.toggle("agent-open",a.agentOpen),e.replaceChildren(pe(a,n),fe(a,i,n),...a.agentOpen?[ke(a,i,n)]:[],...a.drawer?[t("div",{class:"drawer-veil",on:{click:()=>n.toggleDrawer(null)}}),Ce(a,i,n)]:[],...q(a,n),$e(a)),l){let u=document.getElementById(l);u?.focus({preventScroll:!0}),d&&(u instanceof HTMLTextAreaElement||u instanceof HTMLInputElement)&&u.setSelectionRange(...d)}}function pe(e,i){let{project:n,gate:a}=e.project,o=e.project.releases?.[0],l=a.status==="clear"?t("span",{class:"pill green"},t("i"),"Code checks clear"):a.status==="not_clear"?t("span",{class:"pill amber"},t("i"),"Needs attention"):t("span",{class:"pill gray"},t("i"),e.project.empty?"Not checked":"Unknown");return t("header",{class:"top"},t("div",{class:"brand"},t("img",{src:"/manga/favicon.png?v=stack1",alt:""}),t("span",{class:"name"},"VibeRaven")),t("span",{class:"sep"}),t("span",{class:"meta"},[o?.branch,n.version?`v${n.version.replace(/^v/,"")}`:null].filter(Boolean).join(" \xB7 ")),l,t("span",{class:"spacer"}),t("button",{id:"open-terminal",class:`btn ghost${e.drawer==="terminal"?" on":""}`,on:{click:()=>i.toggleDrawer("terminal")}},"Terminal"),t("button",{id:"open-releases",class:`btn ghost${e.drawer==="releases"?" on":""}`,on:{click:()=>i.toggleDrawer("releases")}},"Releases"),t("button",{class:"btn sm",disabled:e.busy.scan||e.setup.running||e.busy.chat,on:{click:()=>i.recheck()}},e.busy.scan?t("span",{class:"spin"}):null,e.busy.scan?"Checking\u2026":"Check app"),t("button",{id:"run-full-check",class:"btn sm acid",title:"Hosted check on VibeRaven. Needs a VibeRaven account.",disabled:e.setup.running||e.fullCheck.step==="running",on:{click:()=>i.openFullCheck()}},e.fullCheck.step==="running"?t("span",{class:"spin"}):null,"Run full check"),t("button",{id:"toggle-agent",class:`btn agent-toggle${e.agentOpen?" on":""}`,"aria-expanded":String(e.agentOpen),"aria-controls":"agent-panel",on:{click:()=>i.toggleAgent()}},e.busy.chat?t("span",{class:"spin"}):null,e.agentOpen?"Hide agent":e.busy.chat?"Agent working":"Agent"))}function ge(e){return(e||"Project").replace(/^@[^/]+\//,"").split(/[-_\s]+/).filter(Boolean).map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join(" ")}function fe(e,i,n){let a=E(e.project,e.catalog,e.verified),o=a.filter(c=>c.step!=="absent"),l=a.filter(c=>c.step==="absent"),d=e.project.missionCards?.blockers??[],u=d.filter(c=>e.project.missionCards.planSteps.some(f=>f.id===c.id&&!f.requiresUserAction)),s=e.setup.running||e.busy.chat||e.busy.scan,r=[{id:"stack",label:"Your stack",count:o.length},{id:"services",label:"Services",count:l.length},{id:"findings",label:"Findings",count:d.length}],p=t("section",{id:`panel-${e.section}`,class:"workspace-panel",role:"tabpanel","aria-labelledby":`tab-${e.section}`,tabindex:-1},e.section==="stack"?[t("div",{class:"rail-head"},t("div",{},t("h2",{},"Everything your app runs on"),t("p",{class:"sub"},"Connect a service, check it live, and keep building."))),o.length?t("div",{class:"rail"},...o.map(c=>he(c,e,n))):t("div",{class:"empty"},t("h2",{},"Nothing set up yet"),t("p",{class:"sub"},"Choose Connect my app above to pick your services, connect your coding agent and start setup.")),l.length?t("button",{class:"browse-services",disabled:e.setup.running,on:{click:()=>n.setSection("services")}},"Explore all services",t("span",{"aria-hidden":"true"}," \u2192")):null]:e.section==="services"?[t("div",{class:"rail-head"},t("div",{},t("h2",{},"Build the stack you need"),t("p",{class:"sub"},"Your accounts. Your choice of providers."))),l.length?t("div",{class:"rail"},...l.map(c=>t("article",{class:"slab available"},t("div",{class:"face"},t("div",{class:"face-top"},t("span",{class:"tag"},"Available")),t("div",{class:"face-logo"},t("img",{src:c.logoUrl,alt:"",loading:"lazy"})),t("h3",{class:"face-name"},c.name),t("div",{class:"face-area"},c.area)),t("div",{class:"slab-act"},t("button",{class:"btn library-add",disabled:s,"aria-label":`Add ${c.name} to setup`,on:{click:()=>{n.openStackSetup(),i.get().setup.selected.includes(c.id)||n.toggleSetupProvider(c.id),document.getElementById("stack-setup-heading")?.focus()}}},"+ Add to setup"))))):t("p",{class:"empty"},"All available services are already in your stack.")]:[t("div",{class:"section-head"},t("div",{},t("h2",{},d.length?`${d.length} open finding${d.length===1?"":"s"}`:"No open code findings"),t("p",{class:"sub"},[be(d),"From your repository. Live service checks are separate."].filter(Boolean).join(" \xB7 "))),u.length?t("button",{class:"btn sm",disabled:s,on:{click:()=>n.fixAll()}},`Fix ${u.length} with ${S(e)}`):null),d.length?t("div",{class:"fixgrid"},...d.map(c=>ve(c,a,e,n))):t("div",{class:"empty"},e.project.empty?"Run Check app to find configuration issues.":"Your latest repository check has no open findings. Check your services live from Your stack.")]);return t("main",{class:"stage"},e.scan?.state==="running"?t("div",{class:"scanbar",role:"status"},t("span",{class:"spin"}),"Reading your app and its services\u2026"):e.scan?.state==="error"?t("div",{class:"scanbar",role:"alert"},e.scan.error??"The local check did not finish.",t("button",{class:"btn sm",on:{click:()=>n.recheck()}},"Try again")):null,t("section",{class:"workspace-heading"},t("div",{},t("span",{class:"eyebrow"},"Workspace"),t("h1",{},ge(e.project.project.name)),t("p",{},"Your app. All the pieces, together.")),t("button",{id:"connect-my-app",class:"btn primary lg",disabled:s,on:{click:()=>n.openStackSetup()}},"Connect my app",t("span",{"aria-hidden":"true"},"\u2197"))),t("div",{class:"workspace-tabs",role:"tablist","aria-label":"Workspace views",on:{keydown:c=>{let f=c.key;if(!["ArrowLeft","ArrowRight","Home","End"].includes(f))return;c.preventDefault();let b=r.findIndex(m=>m.id===e.section),g=f==="Home"?0:f==="End"?r.length-1:(b+(f==="ArrowRight"?1:-1)+r.length)%r.length;n.setSection(r[g].id)}}},...r.map(c=>t("button",{id:`tab-${c.id}`,role:"tab","aria-selected":String(e.section===c.id),"aria-controls":`panel-${c.id}`,tabindex:e.section===c.id?0:-1,disabled:e.setup.running,on:{click:()=>n.setSection(c.id)}},c.label,t("span",{},String(c.count))))),e.setup.open?Y(e,i,n):null,p)}function me(e){return e.step==="ready"?{text:`Agent reported checks passed ${e.verified?I(e.verified.at):""}.`,tone:"g"}:e.step==="verified"?{text:e.verified?.ok?`Agent check ${e.verified?I(e.verified.at):""}.`:"Agent check found issues.",tone:e.verified?.ok?"g":"a"}:e.step==="mcp"?{text:"Agent integration configured. Live check needed.",tone:"a"}:e.step==="in_repo"?{text:e.hasRecipe?"Found in your code. Not connected.":"Found in your code.",tone:"a"}:{text:"Not in this app.",tone:""}}function he(e,i,n){let a=i.busy.tile===e.id,o=a||i.setup.running||i.busy.chat,l=me(e),d=e.step==="ready"?t("span",{class:"tag acid"},"Agent checked"):e.step==="verified"?t("span",{class:"tag"},e.verified?.ok?"Checked":"Issues"):e.step==="mcp"?t("span",{class:"tag"},"Configured"):t("span",{class:"tag"},"In code"),u=e.step==="in_repo"&&e.hasRecipe?t("button",{class:"btn primary",disabled:o,on:{click:()=>n.connect(e)}},a?t("span",{class:"spin"}):null,a?"Configuring\u2026":"Configure agent"):e.step==="in_repo"?t("button",{class:"btn",disabled:o,on:{click:()=>n.verify(e)}},"Check with agent"):e.step==="mcp"?t("button",{class:"btn",disabled:o,on:{click:()=>n.verify(e)}},a?t("span",{class:"spin"}):null,a?"Checking\u2026":"Check live"):t("button",{class:"btn",disabled:o,on:{click:()=>n.verify(e)}},a?t("span",{class:"spin"}):null,a?"Checking\u2026":"Check again"),s=X(e.logoUrl)??"#9a9a9a";return t("article",{class:`slab${e.step==="ready"?" ready":""}${a?" scanning":""}`,dataset:{provider:e.id},style:{"--brand":s}},t("div",{class:"face"},t("div",{class:"face-top"},d),t("div",{class:"face-logo"},t("img",{src:e.logoUrl,alt:"",loading:"lazy"})),t("div",{class:"face-name"},e.name),t("div",{class:"face-area"},e.area)),t("div",{class:`slab-status ${l.tone}`},t("i",{class:l.tone}),t("span",{class:"txt"},l.text),e.fixes>0?t("button",{class:"fixlink",on:{click:()=>n.focusBlockers(e.id)}},`${e.fixes} to fix`):null),t("div",{class:"slab-act"},u))}function be(e){let i={critical:0,warning:0,info:0};for(let n of e)i[n.severity]+=1;return[i.critical?`${i.critical} critical`:null,i.warning?`${i.warning} important`:null,i.info?`${i.info} nice to have`:null].filter(Boolean).join(" \xB7 ")}function ye(e){return e==="repo"?"Found in your repository":e==="live"?"From a live provider check":e==="verify"?"From the last verification run":e==="manual"?"Recorded manually":null}function ve(e,i,n,a){let o=W(i,e),d=n.project.missionCards.planSteps.find(m=>m.id===e.id)?.requiresUserAction===!0,u=n.probes[n.cliId]?.ready===!0,s=n.busy.chat||n.setup.running,r=e.severity==="critical"?"r":e.severity==="warning"?"a":"",p=o?.provider?.nextFix?.id===e.id?o.provider.nextFix:void 0,c=o?.provider?.launchPath.find(m=>m.id===e.id),f=[];p?.whyItMatters&&f.push(["Why it matters",p.whyItMatters]),p?.whatToChange&&f.push(["What to change",p.whatToChange]),p?.verifyInstruction&&f.push(["How to verify",p.verifyInstruction]),c?.shortReason&&c.shortReason.trim()!==(e.detail??"").trim()&&f.push(["Check result",c.shortReason]);let b=(p?.artifactRefs??[]).filter(Boolean).slice(0,6),g=ye(c?.source);return t("article",{class:`fix ${r}`,tabindex:-1,dataset:{blocker:e.id,provider:o?.id??""},style:o?{"--brand":X(o.logoUrl)??"#9a9a9a"}:void 0},t("div",{class:"fix-main"},t("div",{class:"fix-top"},t("span",{class:`tag ${r==="r"?"red":r==="a"?"amber":"dim"}`},e.severity==="critical"?"Critical":e.severity==="warning"?"Important":"Nice to have"),o?t("span",{class:"fix-owner"},o.logoUrl?t("img",{src:o.logoUrl,alt:""}):t("i",{class:`dot ${r}`}),o.name):null,t("span",{class:"fix-meta"},e.category),g?t("span",{class:"fix-meta"},g):null),t("h3",{class:"fix-title"},e.title),e.detail?t("p",{class:"fix-detail"},e.detail):null,f.length?t("dl",{class:"fix-evidence"},...f.map(([m,y])=>t("div",{},t("dt",{},m),t("dd",{},y)))):null,b.length?t("div",{class:"fix-files"},t("span",{class:"fix-files-label"},"Evidence in your repo"),...b.map(m=>t("code",{},m))):null),t("div",{class:"fix-act"},d?t("button",{class:"btn",disabled:s,on:{click:()=>a.explain(e,o)}},"Show me the steps"):t("button",{class:"btn white",disabled:s,on:{click:()=>a.fix(e,o)}},`Fix with ${S(n)}`),t("p",{class:"fix-who"},d?"Needs you in the provider dashboard or account.":u?"Your agent can change this in the repo.":"Connect an agent to apply this, or make the change yourself.")))}function S(e){return e.agents.find(i=>i.id===e.cliId)?.label.replace(/ CLI$/,"")??e.cliId}function ke(e,i,n){let a=e.agents.find(c=>c.id===e.cliId),o=e.probes[e.cliId],l=o?.ready===!0,d=a?.modelOptions??(a?.models??[]).map(c=>({id:c,label:c})),u=t("div",{class:"thread"},e.messages.length?e.messages.map(c=>we(c,e,n)):t("div",{class:"welcome"},t("h3",{},"A little less setup. A lot more building."),t("p",{},"Start with Connect my app, or ask your agent to work on something specific."),t("div",{class:"suggest"},...["What does this app need next?","Check my service connections","Explain what changed since the last release"].map(c=>t("button",{class:"suggest-chip",disabled:!l||e.busy.chat||e.setup.running,on:{click:()=>n.send(c)}},c)))),e.busy.chat?t("div",{class:"working"},t("span",{class:"spin"}),t("span",{dataset:{working:"1"}},`${S(e)} is working\u2026`),t("button",{class:"btn sm stop",on:{click:()=>n.stop()}},t("i",{class:"sq"}),"Stop")):null,e.busy.chat?t("div",{class:"slow-run hint",hidden:!e.workingSince||Date.now()-e.workingSince<6e4,dataset:{slowRun:"1"}},t("p",{},"Taking longer than expected. CLI startup hooks or provider sign-in may be waiting. Stop this run and open Terminal to check your agent setup."),t("button",{class:"btn sm",on:{click:()=>n.toggleDrawer("terminal")}},"Open terminal")):null);(e.messages.length||e.busy.chat)&&queueMicrotask(()=>{u.scrollTop=u.scrollHeight});let s=e.contextProviderId?E(e.project,e.catalog,e.verified).find(c=>c.id===e.contextProviderId):null,r=t("textarea",{id:"agent-composer",placeholder:l?"Ask about this app, or tell the agent what to do\u2026":"Test the connection first, then chat.",rows:2,value:e.draft,disabled:e.busy.chat||e.setup.running,on:{input:c=>{i.get().draft=c.target.value},keydown:c=>{let f=c;f.key==="Enter"&&!f.shiftKey&&(f.preventDefault(),n.send(f.target.value))}}}),p=e.busy.probe===e.cliId;return t("aside",{id:"agent-panel",class:"side","aria-label":"Coding agent"},t("div",{class:"side-head"},t("span",{class:"who"},"Agent"),t("div",{class:"seg"},...(e.agents.length?e.agents:[]).map(c=>{let f=e.probes[c.id],b=f?.ready?"g":c.installed?"a":"";return t("button",{class:c.id===e.cliId?"on":"",disabled:e.setup.running||e.busy.chat,title:c.installed?f?.ready?"Connected":"Installed, not tested yet":"Not installed",on:{click:()=>n.selectCli(c.id)}},t("i",{class:b}),c.label.replace(/ CLI$/,"").replace("Claude Code","Claude"))}))),t("div",{class:"side-head tools"},d.length?t("label",{class:"model-field",for:"agent-model"},t("span",{},"Model"),t("select",{id:"agent-model",class:"sel",title:"Model",disabled:e.setup.running||e.busy.chat,on:{change:c=>i.set({modelId:c.target.value})}},t("option",{value:"",selected:!e.modelId},"Use agent default"),e.modelId&&!d.some(c=>c.id===e.modelId)?t("option",{value:e.modelId,selected:!0},`${e.modelId} (saved selection)`):null,...d.map(c=>t("option",{value:c.id,selected:c.id===e.modelId},c.label)))):null,e.cliId==="claude"?t("p",{class:"model-note"},"Versioned models. Availability depends on your Claude account and CLI."):null,t("div",{class:"agent-connection",role:"status"},p?t("span",{class:"pill"},t("span",{class:"spin"}),"Checking connection\u2026"):l?t("span",{class:"pill green",title:o?.message},t("i"),`${S(e).replace("Claude Code","Claude")} connected`):a&&!a.installed?t("span",{class:"pill amber",title:`${a.label} is not installed`},t("i"),"Not installed"):t("span",{class:"pill amber"},t("i"),"Not connected"),t("button",{id:"agent-test-connection",class:"connection-action",disabled:p||e.busy.chat||e.setup.running,on:{click:()=>n.testConnection(e.cliId)}},l?"Test again":"Test connection"))),u,o&&!o.ready?t("div",{class:"hint"},t("b",{},o.message)," ",t("button",{class:"btn sm",on:{click:()=>n.toggleDrawer("terminal")}},"Open terminal")):null,t("div",{class:"composer"},r,t("div",{class:"row"},s?t("span",{class:"chip"},s.logoUrl?t("img",{src:s.logoUrl,alt:""}):null,s.name,t("button",{title:"Remove context","aria-label":"Remove context",on:{click:()=>i.set({contextProviderId:null})},html:'<svg width="10" height="10" viewBox="0 0 10 10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path d="M1.5 1.5l7 7M8.5 1.5l-7 7"/></svg>'})):null,t("select",{id:"agent-access",class:"sel mode","aria-label":"Agent access",title:"What the agent may do",disabled:e.setup.running||e.busy.chat,on:{change:c=>n.setAccessMode(c.target.value)}},...["ask","approve","full"].map(c=>t("option",{value:c,selected:c===e.accessMode},c==="ask"?"Ask \xB7 plan only":c==="approve"?"Approve \xB7 edit files":"Full access"))),e.busy.chat?t("button",{class:"btn send stop",title:"Stop","aria-label":"Stop",on:{click:()=>n.stop()},html:'<svg width="14" height="14" viewBox="0 0 14 14"><rect x="2" y="2" width="10" height="10" rx="2" fill="currentColor"/></svg>'}):t("button",{class:"btn send",title:"Send","aria-label":"Send",disabled:!l||e.setup.running,on:{click:()=>n.send(r.value)},html:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 13V3M3.5 7.5 8 3l4.5 4.5"/></svg>'}))))}function G(e,i,n=Date.now()){if(!i)return;let a=Math.max(0,Math.floor((n-i)/1e3)),o=e.querySelector("[data-working]");o&&(o.textContent=`${o.textContent?.split(" \xB7")[0]??"Working\u2026"} \xB7 ${a}s`);let l=e.querySelector("[data-slow-run]");l&&(l.hidden=a<60)}function we(e,i,n){let a=e.role==="me"?"You":e.role==="agent"?i.agents.find(l=>l.id===e.cliId)?.label.replace(/ CLI$/,"").replace("Claude Code","Claude")??"Agent":e.role==="error"?"Something went wrong":"VibeRaven",o=e.card?t("div",{class:"card"},t("span",{},e.card.providerId?t("img",{src:E(i.project,i.catalog,i.verified).find(l=>l.id===e.card?.providerId)?.logoUrl??"",alt:""}):null,e.card.label),e.card.action==="verify"&&e.card.providerId?t("button",{class:"btn sm primary",disabled:i.busy.chat||i.setup.running,on:{click:()=>n.verifyById(e.card.providerId)}},"Verify live"):e.card.action==="recheck"?t("button",{class:"btn sm",disabled:i.busy.scan,on:{click:()=>n.recheck()}},"Re-check"):null):null;return t("div",{class:`msg ${e.role==="me"?"me":e.role==="error"?"err":""}`},t("div",{class:"who"},a,t("span",{class:"t"},I(e.at))),t("div",{class:"body",html:e.role==="me"?`<p>${x(e.text)}</p>`:D(e.text)}),o)}function Ce(e,i,n){let a=e.drawer==="terminal"?Se(e,n):xe(e,i,n);return t("div",{class:"drawer",dataset:{drawer:e.drawer??""},role:"dialog","aria-modal":"true","aria-labelledby":"drawer-heading",on:{keydown:o=>{let l=o;if(l.key==="Escape"&&(l.preventDefault(),l.stopPropagation(),n.toggleDrawer(null)),l.key!=="Tab")return;let d=Array.from(o.currentTarget.querySelectorAll("*")).filter(r=>r.matches('button:not(:disabled), input:not(:disabled), a[href], select:not(:disabled), [tabindex="0"]')),u=d[0],s=d[d.length-1];l.shiftKey&&document.activeElement===u&&(l.preventDefault(),s?.focus()),!l.shiftKey&&document.activeElement===s&&(l.preventDefault(),u?.focus())}}},t("div",{class:"drawer-head"},t("div",{class:"drawer-title"},t("h3",{id:"drawer-heading"},e.drawer==="terminal"?"Connect your coding agent":"Releases & changes"),t("p",{},e.drawer==="terminal"?"VibeRaven drives the agent CLI installed on this computer. Installed is not connected \u2014 test each one.":"Release points detected in this repository, and the real diff between any two of them.")),t("button",{id:"drawer-close",class:"btn ghost sm",style:{marginLeft:"auto"},on:{click:()=>n.toggleDrawer(null)}},"Close")),t("div",{class:"drawer-body"},a))}function U(e,i,n,a,...o){return t("li",{class:`step${n?" done":""}`},t("span",{class:"step-n","aria-hidden":"true"},n?"\u2713":String(e)),t("div",{class:"step-body"},t("div",{class:"step-title"},i,t("span",{class:`step-state${n?" ok":""}`},n?"Done":"Not confirmed")),t("p",{},a),o.some(Boolean)?t("div",{class:"row step-row"},...o):null))}function Se(e,i){return t("div",{},...e.agents.map(n=>{let a=e.probes[n.id],o=a?.ready===!0,l=e.busy.probe===n.id;return t("section",{class:"block agent-block","aria-label":n.label},t("div",{class:"block-head"},t("h4",{},n.label),t("span",{class:`pill ${o?"green":n.installed?"amber":"gray"}`},t("i"),o?"Connected":n.installed?"Installed \xB7 not tested":"Not installed"),t("a",{class:"btn sm ghost",style:{marginLeft:"auto"},href:n.setup.docsUrl,target:"_blank",rel:"noreferrer"},"Docs")),t("ol",{class:"steps"},U(1,"Install the CLI",n.installed,n.installed?`Found on this computer as ${n.command}.`:`Not found on this computer. Install command: ${n.setup.installCommand}`,n.installed?null:t("button",{class:"btn sm primary",on:{click:()=>i.runSetup(n.id,"install")}},"Install here")),U(2,"Sign in to your account",o,o?"Confirmed by the last connection test.":`VibeRaven cannot read your CLI session. Sign in with ${n.setup.signInCommand}, then test below.`,t("button",{class:"btn sm",on:{click:()=>i.openTerminal(n.id,"sign-in")}},"Open a terminal to sign in")),U(3,"Test the connection",o,a?.message??`Not tested in this session. VibeRaven runs ${n.setup.verifyCommand} and reads the result.`,t("button",{class:"btn sm",disabled:l,on:{click:()=>i.testConnection(n.id)}},l?t("span",{class:"spin"}):null,l?"Testing\u2026":o?"Test again":"Test connection"))))}),t("section",{class:"block","aria-label":"Terminal output"},t("div",{class:"block-head"},t("h4",{},"Terminal output"),t("span",{class:"block-meta"},"From the last install, sign-in or connection test")),t("pre",{class:"out",dataset:{terminalOut:"1"}},e.terminalOutput||"Nothing yet. Run a step above and the raw output appears here.")))}function xe(e,i,n){let a=e.project.releases??[],o=t("input",{id:"release-from",class:"sel","aria-label":"From revision",placeholder:"Tag, commit or branch",value:e.compare.from,on:{input:s=>{i.get().compare.from=s.target.value}}}),l=t("input",{id:"release-to",class:"sel","aria-label":"To revision",placeholder:"HEAD",value:e.compare.to,on:{input:s=>{i.get().compare.to=s.target.value}}}),d=e.compare.result,u=d?.stats;return t("div",{},t("section",{class:"block","aria-label":"Release history"},t("div",{class:"block-head"},t("h4",{},"History"),t("span",{class:"block-meta"},a.length?`${a.length} release point${a.length===1?"":"s"} \xB7 branch ${a[0].branch}`:"Nothing tagged yet")),a.length?t("ul",{class:"rel-list"},...a.map(s=>t("li",{class:"rel"},t("div",{class:"rel-main"},t("div",{class:"rel-line"},t("span",{class:"lbl"},s.label),t("span",{class:`tag ${s.tone==="current"?"amber":"dim"}`},s.tone==="current"?"Current":s.tone==="prod"?"Released":"Planned")),t("p",{class:"rel-sum"},s.summary),t("p",{class:"rel-meta"},`${s.meta} \xB7 ${s.branch}`)),t("button",{class:"btn sm ghost",on:{click:()=>{i.set({compare:{...i.get().compare,from:s.id}}),document.getElementById("release-from")?.focus()}}},"Compare from here")))):t("p",{class:"drawer-empty"},"No git tags yet. Tag a release (git tag v1.0.0) and it shows up here. You can still compare any branch or commit below.")),t("section",{class:"block","aria-label":"Compare"},t("div",{class:"block-head"},t("h4",{},"Compare two points"),t("span",{class:"block-meta"},"Any tag, branch or commit in this repository")),t("div",{class:"row compare-fields"},t("label",{},"From",o),t("label",{},"To",l),t("div",{class:"compare-actions"},t("button",{class:"btn sm primary",disabled:e.busy.compare,on:{click:()=>n.compare(o.value,l.value)}},e.busy.compare?t("span",{class:"spin"}):null,e.busy.compare?"Reading\u2026":"Diff"),t("button",{class:"btn sm",disabled:e.busy.chat||e.setup.running,on:{click:()=>n.explainDiff(o.value,l.value)}},`Explain with ${S(e)}`))),e.compare.error?t("p",{class:"compare-error",role:"alert"},e.compare.error):null,d?t("div",{class:"diff-result"},t("div",{class:"diff-stats"},t("span",{class:"diff-range"},`${d.fromLabel} \u2192 ${d.toLabel}`),u?t("span",{},`${u.files??0} file${u.files===1?"":"s"}`):null,u?t("span",{class:"add"},`+${u.insertions??0}`):null,u?t("span",{class:"del"},`\u2212${u.deletions??0}`):null),t("pre",{class:"out diff",tabindex:0,role:"region","aria-label":"Diff output",html:Ie(d.diff)})):t("p",{class:"drawer-empty"},"Pick two points and select Diff. The output is read straight from git \u2014 nothing is sent anywhere.")))}function X(e){let i=/cdn\.simpleicons\.org\/[a-z0-9.-]+\/([0-9a-f]{6})/i.exec(e);if(!i)return null;let n=i[1].toLowerCase();return n==="ffffff"?"#c8c8c8":`#${n}`}function Ie(e){return e.split(`
4
+ `).map(i=>{let n=x(i);return i.startsWith("+++")||i.startsWith("---")||i.startsWith("diff ")||i.startsWith("@@")?`<span class="hd">${n}</span>`:i.startsWith("+")?`<span class="add">${n}</span>`:i.startsWith("-")?`<span class="del">${n}</span>`:n}).join(`
5
+ `)}function $e(e){return t("div",{class:"toasts"},...e.toasts.map(i=>t("div",{class:`toast${i.kind==="err"?" err":""}`},i.text)))}function O(e){let i=e.filter(n=>n.detected);return(i.length?i:e.filter(n=>["github","supabase","vercel"].includes(n.id))).map(n=>n.id)}function Ae(e,i){return[i==="ask"?"Plan the setup of this app. Do not edit files, write configuration, provision resources, or change providers.":"Set up the selected services for this app using the current access mode.","Selected services:",...e.map(n=>`- ${n.name} (${n.area}): ${n.detected?"already detected; preserve and complete the existing integration":"requested addition; inspect the app before choosing the minimal integration"}. ${n.note??""}`),"First inspect the repo and reuse its existing architecture, accounts, and integrations. Do not replace an existing provider or add unselected services.","Shared MCP recipes may be available in .mcp.json. Check whether your CLI loads them. In editing modes, adapt the selected recipes to its project-local native configuration if necessary, preserving other entries. If a restart or authorization is required, report that as a remaining step; do not pretend the tools are available.","Use available provider MCP tools to inspect configuration. For repo work, use official SDKs, wire the necessary integration, and add placeholder variable names to .env.example. Never invent real secrets or print secret values.","If sign-in, account selection, a paid resource, broader permissions, or dashboard access is needed, stop that step and give the owner the exact next action. Do not purchase services, make financial transactions, push commits, publish packages, create releases, deploy, or alter production data as part of setup.","Run relevant local checks. Report separately: repo changes, provider evidence actually observed, and remaining user actions. MCP configuration alone does not prove a live connection. Do not claim the app is production-ready.","Keep the summary short and name the files changed."].join(`
6
+ `)}async function Q(e){let{providers:i,mode:n,connect:a,runAgent:o,onProgress:l,cancelled:d}=e;if(!i.length)throw new Error("Select at least one service.");let u=()=>{if(d())throw new Error("Setup stopped. Configuration already written is kept; no further steps will run.")};for(let r of i)if(u(),n==="ask")l({id:r.id,state:"pending",label:`${r.name} \xB7 planning only`});else if(r.mcpConfigured)l({id:r.id,state:"configured",label:`${r.name} \xB7 MCP configuration found`});else if(r.hasRecipe){l({id:r.id,state:"working",label:`${r.name} \xB7 preparing MCP configuration`});let p=await a(r.id);if(u(),!p.ok)throw new Error(`${r.name}: ${p.message}`);l({id:r.id,state:"configured",label:`${r.name} \xB7 shared MCP recipe saved`})}else l({id:r.id,state:"pending",label:`${r.name} \xB7 agent will inspect setup options`});u(),l({id:"agent",state:"working",label:n==="ask"?"Agent is preparing your plan":"Agent is working through your stack"});let s=await o(Ae(i,n));if(u(),!s)throw new Error("The agent did not complete the setup task. Review its output and try again.");l({id:"agent",state:"review",label:n==="ask"?"Plan returned \xB7 review it in the agent panel":"Setup response returned \xB7 review changes and remaining steps"})}function Z(e,i){if(e.length>1e3)return null;let n=new URLSearchParams(e.replace(/^[#?]/,"")).get("stack");return n===null?null:[...new Set(n.split(",").filter(a=>i.includes(a)))]}function Te(){let e=document.getElementById("vr-state");if(!e?.textContent)throw new Error("Missing initial state");return JSON.parse(e.textContent)}function Pe(e,i){let n=(e??"").trim();return n.length>i?`\u2026${n.slice(-i)}`:n}function k(e){return e instanceof Error?e.message:String(e)}function Me(e){let i=!1,n=new Set;function a(s=!1){e.set({agentOpen:!0,drawer:null}),document.getElementById(s?"agent-test-connection":"agent-composer")?.focus({preventScroll:!0}),document.getElementById("agent-panel")?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}async function o(){let[s,r,p]=await Promise.all([h.project(),h.catalog().catch(()=>({providers:[]})),h.verified().catch(()=>({verified:{}}))]);e.set({project:s,catalog:r.providers,verified:p.verified})}async function l(s,r,p){let c=e.get();if(c.busy.chat)return null;let f=c.probes[s.cliId];if(a(!f?.ready),!f?.ready)return e.toast(`Test the ${s.cliId} connection first.`,"err"),null;e.push({role:"me",text:r});let b=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},draft:"",workingSince:Date.now(),runId:b});try{let m=(await h.chat({...s,runId:b})).agentRun,y=m.output?.trim(),w=m.timedOut||m.exitCode!==null&&m.exitCode!==0||/Stopped by user/.test(m.stderr??"");if(!y&&/Stopped by user/.test(m.stderr??""))return e.push({role:"system",text:"Stopped."}),null;let F=y||(m.timedOut?`${s.cliId} did not finish in time and was stopped. Try a smaller task, or switch to ask mode for a read-only answer.`:`${s.cliId} exited with code ${m.exitCode??"unknown"} and no answer.
7
+
8
+ ${Pe(m.stderr,1200)}`);return!y||w?e.push({role:"error",text:F,cliId:s.cliId}):e.push({role:"agent",text:F,cliId:s.cliId,card:p}),(s.taskKind==="fix"||s.taskKind==="plan")&&await o().catch(()=>{}),w||!y?null:F}catch(g){return e.push({role:"error",text:k(g)}),null}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}}function d(){let s=e.get();return{cliId:s.cliId,accessMode:s.accessMode,modelId:s.modelId||void 0}}let u={...B(e),setSection(s){e.get().setup.running||(e.set(r=>({section:s,setup:{...r.setup,open:!1}})),document.getElementById(`tab-${s}`)?.focus({preventScroll:!0}))},toggleAgent(){let s=!e.get().agentOpen;e.set({agentOpen:s}),document.getElementById(s?"agent-composer":"toggle-agent")?.focus({preventScroll:!0}),s&&document.getElementById("agent-panel")?.scrollIntoView?.({behavior:"smooth",block:"nearest"})},openStackSetup(){let s=e.get();e.set({section:"stack",agentOpen:!0,setup:{...s.setup,open:!0,initialized:s.setup.initialized||s.catalog.length>0,selected:s.setup.initialized?s.setup.selected:O(s.catalog)}}),document.getElementById("stack-setup-heading")?.focus({preventScroll:!0})},toggleSetupProvider(s){let r=e.get();if(r.setup.running)return;let p=r.setup.selected.includes(s)?r.setup.selected.filter(c=>c!==s):[...r.setup.selected,s];e.set({setup:{...r.setup,initialized:!0,selected:p,progress:[],error:null}})},async startStackSetup(){let s=e.get();if(s.setup.running||s.busy.chat||s.busy.tile||s.busy.scan)return;if(a(!s.probes[s.cliId]?.ready),!s.probes[s.cliId]?.ready){e.toast(`Connect ${s.cliId} in the agent panel first.`,"err");return}let r=s.catalog.filter(c=>s.setup.selected.includes(c.id));if(!r.length){e.toast("Select at least one service.","err");return}let p=d();i=!1,e.set({setup:{...s.setup,running:!0,progress:[],error:null}});try{await Q({providers:r,mode:p.accessMode,connect:c=>h.connectMcp(c),cancelled:()=>i,onProgress:c=>e.set(f=>({setup:{...f.setup,progress:[...f.setup.progress.filter(b=>b.id!==c.id),c]}})),runAgent:c=>l({...p,taskKind:p.accessMode==="ask"?"plan":"fix",prompt:c},`${p.accessMode==="ask"?"Plan":"Set up"} my stack: ${r.map(f=>f.name).join(", ")}`,{label:"Review the response, then check your app",action:"recheck"})})}catch(c){e.set(f=>({setup:{...f.setup,error:k(c)}}))}finally{await o().catch(()=>{}),e.set(c=>({setup:{...c.setup,running:!1}}))}},async stop(){e.get().setup.running&&(i=!0);let s=e.get().runId;if(s)try{await h.stop(s),e.toast("Stopped.")}catch(r){e.toast(k(r),"err")}},async recheck(){if(!(e.get().setup.running||e.get().busy.chat||e.get().busy.scan)){e.set({busy:{...e.get().busy,scan:!0}});try{await h.scan(),await o(),e.toast("Check finished.")}catch(s){e.toast(`Check failed: ${k(s)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},toggleDrawer(s){let r=e.get().drawer;e.set(p=>({drawer:p.drawer===s?null:s})),document.getElementById(e.get().drawer?"drawer-close":`open-${r??"terminal"}`)?.focus({preventScroll:!0})},selectCli(s){if(e.get().setup.running||e.get().busy.chat)return;e.set({cliId:s,modelId:""}),e.get().agents.find(p=>p.id===s)?.installed&&!e.get().probes[s]&&u.testConnection(s)},setAccessMode(s){e.get().setup.running||e.get().busy.chat||e.set({accessMode:s})},async testConnection(s){if(!n.has(s)){n.add(s),e.set({busy:{...e.get().busy,probe:s}});try{let r=await h.probe(s);e.set(p=>({probes:{...p.probes,[s]:r},terminalOutput:r.output||r.message})),e.toast(r.message,r.ready?"ok":"err")}catch(r){e.set(p=>{let c={...p.probes};return delete c[s],{probes:c}}),e.toast(k(r),"err")}finally{n.delete(s),e.set(r=>({busy:{...r.busy,probe:r.busy.probe===s?null:r.busy.probe}}))}}},async runSetup(s,r){e.set({terminalOutput:`$ ${r}\u2026`});try{let p=await h.runSetup(s,r);e.set({terminalOutput:`$ ${p.command}
9
+ ${p.output}`.trim()});let c=await h.agents();e.set({agents:c.agents.filter(f=>f.id==="codex"||f.id==="claude"||f.id==="gemini")})}catch(p){e.set({terminalOutput:k(p)})}},async openTerminal(s,r){try{let p=await h.openTerminal(s,r);e.set({terminalOutput:`Opened a terminal with: ${p.command}
10
+ Sign in there, then press Test connection.`})}catch(p){e.toast(k(p),"err")}},async send(s){if(e.get().setup.running)return;let r=s.trim();if(!r)return;let p=e.get(),c=p.contextProviderId?p.catalog.find(f=>f.id===p.contextProviderId):null;await l({...d(),prompt:r,taskKind:"analyze",provider:c?{id:c.id,name:c.name,area:c.area}:void 0},r)},async connect(s){if(!(e.get().setup.running||e.get().busy.chat||e.get().busy.tile)){a(),e.set({busy:{...e.get().busy,tile:s.id}});try{let r=await h.connectMcp(s.id);e.toast(r.message,r.ok?"ok":"err"),await o(),r.ok&&e.push({role:"system",text:`${r.message} ${s.note??""}`.trim(),card:{providerId:s.id,label:`${s.name} \xB7 MCP configured`,action:"verify"}})}catch(r){e.toast(k(r),"err")}finally{e.set({busy:{...e.get().busy,tile:null}})}}},async verify(s){return u.verifyById(s.id)},async verifyById(s){let r=e.get();if(r.setup.running||r.busy.chat||r.busy.tile)return;let c=(r.catalog.find(g=>g.id===s)??r.project.providers.find(g=>g.id===s))?.name??s,f=r.probes[r.cliId];if(a(!f?.ready),!f?.ready){e.toast(`Test the ${r.cliId} connection first.`,"err");return}e.push({role:"me",text:`Check ${c} live`});let b=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,tile:s,chat:!0},workingSince:Date.now(),runId:b});try{let g=await h.verify({providerId:s,...d(),runId:b}),m=g.agentRun.output?.trim()||g.agentRun.stderr?.trim()||"No output.";e.push({role:"agent",text:m,cliId:r.cliId,card:{providerId:s,label:g.verified.ok?`${c} \xB7 verified live`:`${c} \xB7 issues found`}}),await o()}catch(g){e.push({role:"error",text:k(g)})}finally{e.set({busy:{...e.get().busy,tile:null,chat:!1},workingSince:null,runId:null})}},async addProvider(s){e.get().setup.running||await l({...d(),taskKind:"fix",provider:{id:s.id,name:s.name,area:s.area},prompt:`Add ${s.name} (${s.area}) to this app. Install the official SDK, wire the minimal integration the app needs, add the required keys to .env.example with placeholder values, and never invent real secrets. Then tell me exactly which dashboard steps remain.`},`Add ${s.name} to this app`,{providerId:s.id,label:`${s.name} \xB7 added to repo`,action:"recheck"})},async fix(s,r){if(e.get().setup.running)return;let p=r?.provider?.nextFix?.id===s.id&&r.provider.nextFix.prompt?r.provider.nextFix.prompt:`Fix this production blocker in the repo now: ${s.title}. ${s.detail??""} Make the minimal change, then summarize what you changed and which files.`;await l({...d(),taskKind:"fix",provider:r?{id:r.id,name:r.name,area:r.area}:void 0,prompt:p},`Fix: ${s.title}`,{providerId:r?.id,label:"Re-check to update the score",action:"recheck"})},async explain(s,r){e.get().setup.running||await l({...d(),taskKind:"analyze",provider:r?{id:r.id,name:r.name,area:r.area}:void 0,prompt:`This blocker needs dashboard work: ${s.title}. ${s.detail??""} Give me the exact steps: which page, which button, which value. If a provider MCP is available, do the read-only parts yourself first.`},`Steps for: ${s.title}`)},async fixAll(){if(e.get().setup.running)return;let{missionCards:s}=e.get().project,r=s.blockers.filter(p=>s.planSteps.some(c=>c.id===p.id&&!c.requiresUserAction));r.length&&await l({...d(),taskKind:"fix",prompt:`Fix these production blockers in the repo, one by one, minimal changes each:
11
+ ${r.map((p,c)=>`${c+1}. ${p.title}`).join(`
12
+ `)}
13
+ After each, note the files touched. Do not claim production-ready; I will re-check.`},`Fix all ${r.length} repo blockers`,{label:"Re-check to update the score",action:"recheck"})},focusBlockers(s){e.set(p=>({section:"findings",contextProviderId:s,setup:{...p.setup,open:!1}}));let r=Array.from(document.querySelectorAll(".fix")).find(p=>p.dataset.provider===s)??document.getElementById("panel-findings");r?.focus({preventScroll:!0}),r?.scrollIntoView?.({behavior:"smooth",block:"center"})},async compare(s,r){if(!s.trim()||!r.trim()){e.set({compare:{...e.get().compare,error:"Both refs are required."}});return}e.set({busy:{...e.get().busy,compare:!0},compare:{...e.get().compare,from:s,to:r,error:null}});try{let p=await h.compare(s.trim(),r.trim());e.set({compare:{from:s,to:r,result:p,error:null}})}catch(p){e.set({compare:{from:s,to:r,result:null,error:k(p)}})}finally{e.set({busy:{...e.get().busy,compare:!1}})}},async explainDiff(s,r){e.get().setup.running||await l({...d(),taskKind:"diff",release:{id:`${s.trim()}..${r.trim()}`,label:`${s.trim()} \u2192 ${r.trim()}`},prompt:`Explain what changed between ${s.trim()} and ${r.trim()} in this repo, in plain words. Call out anything risky for production: auth, database writes, webhooks, env, payments.`},`Explain ${s.trim()} \u2192 ${r.trim()}`)}};return u}function Ee(){let e=document.getElementById("app");if(!e)return;let i=K(Te()),n=Me(i),a=()=>J(e,i,n);i.subscribe(a),a(),document.addEventListener("keydown",d=>{let u=i.get().fullCheck.step;if(d.key==="Escape"&&u!=="closed"){u!=="running"&&n.closeFullCheck();return}d.key==="Escape"&&i.get().drawer&&n.toggleDrawer(null)});let o=()=>{let d=i.get();if(!d.catalog.length||d.setup.running||d.busy.chat)return;let u=Z(window.location.hash,d.catalog.map(s=>s.id));u!==null&&(i.set({section:"stack",agentOpen:!0,setup:{...d.setup,open:!0,initialized:!0,selected:u,progress:[],error:null}}),history.replaceState(null,"",window.location.pathname+window.location.search),document.getElementById("stack-setup-heading")?.focus())};window.addEventListener("hashchange",o),h.catalog().then(d=>{i.set(u=>({catalog:d.providers,setup:u.setup.open&&!u.setup.initialized?{...u.setup,initialized:!0,selected:O(d.providers)}:u.setup})),o()}).catch(()=>{}),h.verified().then(d=>i.set({verified:d.verified})).catch(()=>{}),h.agents().then(d=>{i.set({agents:d.agents.filter(s=>s.id==="codex"||s.id==="claude"||s.id==="gemini")});let u=d.agents.find(s=>s.id===i.get().cliId);if(u&&!u.installed){let s=d.agents.find(r=>r.installed);s&&i.set({cliId:s.id})}n.testConnection(i.get().cliId)}).catch(()=>{});let l=async()=>{try{let d=await h.scanStatus();if(i.set({scan:d}),d.state==="running")window.setTimeout(l,1500);else if(d.state==="done"&&i.get().project.empty){let u=await h.project();i.set({project:u})}}catch{}};l(),window.setInterval(()=>{G(document,i.get().workingSince)},1e3)}Ee();})();