@viberaven/cli 1.6.5 → 1.6.7

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/README.md CHANGED
@@ -10,10 +10,10 @@ Requires Node.js 20 or newer. Run from the app's project root:
10
10
 
11
11
  ```bash
12
12
  # Open the local Studio
13
- npx -y viberaven@1.6.5
13
+ npx -y viberaven@1.6.7
14
14
 
15
15
  # Fresh terminal check
16
- npx -y viberaven@1.6.5 check
16
+ npx -y viberaven@1.6.7 check
17
17
  ```
18
18
 
19
19
  The `viberaven` package launches this CLI. Studio combines findings, provider context and git comparisons. For chat, select an installed/authenticated Codex CLI, Claude Code or Gemini CLI and use **Test connection**. Access modes: `ask`, `approve`, `full`. Stop Studio with Ctrl+C.
@@ -27,10 +27,10 @@ Checks include migration tables without RLS, unrestricted policy conditions such
27
27
  `check --json` prints a findings summary and artifact paths. `--json` without `check` runs a fresh scan and prints the full gate object.
28
28
 
29
29
  ```bash
30
- npx -y viberaven@1.6.5 check --json
31
- npx -y viberaven@1.6.5 audit --vercel-supabase --json
32
- npx -y viberaven@1.6.5 fix --gap <gapId> --dry-run
33
- npx -y viberaven@1.6.5 init --agents all --dry-run
30
+ npx -y viberaven@1.6.7 check --json
31
+ npx -y viberaven@1.6.7 audit --vercel-supabase --json
32
+ npx -y viberaven@1.6.7 fix --gap <gapId> --dry-run
33
+ npx -y viberaven@1.6.7 init --agents all --dry-run
34
34
  ```
35
35
 
36
36
  Read tasks and source before targeted edits. Preview fixes first. The `rls_disabled` recipe adds an RLS migration without policies: agree before applying, because browser roles lose row access until policies exist. Apply/test through your database workflow; recheck after a batch. Provider actions require provider evidence.
@@ -41,9 +41,9 @@ Read tasks and source before targeted edits. Preview fixes first. The `rls_disab
41
41
 
42
42
  ```bash
43
43
  # Fail on blockers
44
- npx -y viberaven@1.6.5 --strict --json
44
+ npx -y viberaven@1.6.7 --strict --json
45
45
  # Also fail on warnings
46
- npx -y viberaven@1.6.5 --strict=warning --json
46
+ npx -y viberaven@1.6.7 --strict=warning --json
47
47
  ```
48
48
 
49
49
  Default `--strict` returns 0 for `clear`/`warning`, 1 for `not_clear`, 2 for `error`, 3 for `unknown` or unavailable results. `--strict=warning` also returns 1 for warnings.
package/dist/cli.js CHANGED
@@ -10796,14 +10796,19 @@ function buildGapSeeds(scan, audit, databaseEvidence, extra = {}) {
10796
10796
  signals.hasSupabase || signals.hasPrisma || signals.hasDrizzle || signals.hasMongoose || signals.hasNeon || signals.hasMongoDb || signals.hasPlanetScale || signals.hasTurso
10797
10797
  );
10798
10798
  const apiRoutes = hasApiRoutes(scan);
10799
- if (scan.secretsFound.length > 0) {
10799
+ const configurationPaths = scan.secretsFound.filter((path) => !isEnvTemplatePath(path));
10800
+ if (configurationPaths.length > 0) {
10801
+ const privateLikePaths = configurationPaths.filter(
10802
+ (path) => !AMBIGUOUS_CONFIGURATION_BASENAMES.has(import_node_path7.posix.basename(path.replace(/\\/g, "/")).toLowerCase())
10803
+ );
10804
+ const ambiguousOnly = privateLikePaths.length === 0;
10800
10805
  seeds.push({
10801
10806
  id: "secrets_in_repo",
10802
10807
  category: "SECURITY & AUTH",
10803
- severity: "critical",
10804
- title: "Secret files are not gitignored",
10805
- detail: `Files that normally hold live credentials are not covered by .gitignore (${scan.secretsFound.slice(0, 5).join(", ")}). One \`git add .\` away from leaking keys into history.`,
10806
- copyPrompt: "Add the listed secret files (.env and friends) to .gitignore, verify none of them are already tracked with `git ls-files`, and if any were ever committed, rotate those credentials with the provider and scrub git history.",
10808
+ severity: ambiguousOnly ? "warning" : "critical",
10809
+ title: ambiguousOnly ? "Configuration filenames need review" : "Private-credential-like filenames need review",
10810
+ detail: `This filename-only check found files not covered by .gitignore (${configurationPaths.slice(0, 5).join(", ")}). Contents and Git tracking were not checked by this finding. ${ambiguousOnly ? "Base configuration may be intentionally tracked; credential content remains unverified." : `Private-credential-like filenames requiring review: ${privateLikePaths.slice(0, 5).join(", ")}. Credential content remains unverified.`}`,
10811
+ copyPrompt: "Review the listed files locally without pasting their values. Keep intentionally tracked public/base configuration when appropriate, and ignore private overrides after review. Check for actual private credentials and their Git tracking/history locally (`git ls-files` checks tracking). Only if actual private credentials were committed or otherwise exposed, rotate them with the provider and review Git history cleanup.",
10807
10812
  primaryMapCategory: "security"
10808
10813
  });
10809
10814
  }
@@ -10944,14 +10949,18 @@ ${check.evidence.map((e2) => `- ${e2}`).join("\n")}` : "";
10944
10949
  primaryMapCategory: "frontend"
10945
10950
  });
10946
10951
  }
10947
- if (isNext && !hasFilePath(scan, /(not-found|404)\.(tsx|jsx|ts|js)$/)) {
10952
+ const notFoundPaths = [...scan.files.map((file) => file.path), ...scan.fileTree.split(/\r?\n/)];
10953
+ const hasNotFoundPage = notFoundPaths.some(
10954
+ (path) => /(^|\/)(?:app\/(?:[^/]+\/)*not-found|pages\/404)\.(tsx|jsx|ts|js)$/.test(path.replace(/\\/g, "/"))
10955
+ );
10956
+ if (isNext && !hasNotFoundPage) {
10948
10957
  seeds.push({
10949
10958
  id: "missing_404_page",
10950
10959
  category: "MISSING FEATURES",
10951
10960
  severity: "info",
10952
- title: "No custom 404 page",
10953
- detail: "No not-found.tsx / 404 page was detected. Broken links drop users on an unstyled framework page.",
10954
- copyPrompt: "Add an app/not-found.tsx page with the product's branding and a link back to the main flow.",
10961
+ title: "Custom not-found page not detected",
10962
+ detail: "The detected paths contain no App Router not-found file or Pages Router 404 file. This is file-presence evidence, not verification of deployed 404 behavior or coverage across every route.",
10963
+ copyPrompt: "Review the affected Next.js app's route structure. Add an app/not-found.tsx or pages/404.tsx page where appropriate, then test missing URLs at the app root and nested routes to verify the behavior.",
10955
10964
  primaryMapCategory: "frontend"
10956
10965
  });
10957
10966
  }
@@ -11185,7 +11194,7 @@ async function buildLocalStationOutput(input) {
11185
11194
  productionChecklist: checklistFrom(seeds)
11186
11195
  };
11187
11196
  }
11188
- var import_node_child_process3, import_node_util3, import_promises6, import_node_path7, execFileAsync3, ENV_DRIFT_IGNORE, ENV_DRIFT_IGNORE_PREFIX, SUPABASE_EDGE_ENV, ENV_TEMPLATE_NAME, ENV_CODE_FILE, ENV_NAME, ENV_REFERENCES, SVELTEKIT_STATIC_IMPORT, SVELTEKIT_DYNAMIC_IMPORT, ENV_DESTRUCTURE, CODE_FILE, STRIPE_VERIFY_CALL, STRIPE_VERIFY_JSON_BODY, STRIPE_SIGNATURE_HEADER, RAW_BODY, STRIPE_EVENT_TYPE, REQUEST_HANDLER, TEST_FILE, STRIPE_CODE_USE, STRIPE_EDGE_WEBHOOK_PROMPT, AUDIT_FINDING_GAPS, FINDING_SEVERITY_RANK, DETAIL_MAX_FINDINGS, SEVERITY_ORDER, FULL_READ_LIMITS, PAYMENT_PATH;
11197
+ var import_node_child_process3, import_node_util3, import_promises6, import_node_path7, execFileAsync3, ENV_DRIFT_IGNORE, ENV_DRIFT_IGNORE_PREFIX, SUPABASE_EDGE_ENV, ENV_TEMPLATE_NAME, ENV_CODE_FILE, ENV_NAME, ENV_REFERENCES, SVELTEKIT_STATIC_IMPORT, SVELTEKIT_DYNAMIC_IMPORT, ENV_DESTRUCTURE, CODE_FILE, STRIPE_VERIFY_CALL, STRIPE_VERIFY_JSON_BODY, STRIPE_SIGNATURE_HEADER, RAW_BODY, STRIPE_EVENT_TYPE, REQUEST_HANDLER, TEST_FILE, STRIPE_CODE_USE, STRIPE_EDGE_WEBHOOK_PROMPT, AUDIT_FINDING_GAPS, FINDING_SEVERITY_RANK, DETAIL_MAX_FINDINGS, SEVERITY_ORDER, AMBIGUOUS_CONFIGURATION_BASENAMES, FULL_READ_LIMITS, PAYMENT_PATH;
11189
11198
  var init_localStation = __esm({
11190
11199
  "src/localStation.ts"() {
11191
11200
  "use strict";
@@ -11332,6 +11341,14 @@ var init_localStation = __esm({
11332
11341
  FINDING_SEVERITY_RANK = { critical: 0, high: 1, warning: 2, info: 3 };
11333
11342
  DETAIL_MAX_FINDINGS = 10;
11334
11343
  SEVERITY_ORDER = { critical: 0, warning: 1, info: 2 };
11344
+ AMBIGUOUS_CONFIGURATION_BASENAMES = /* @__PURE__ */ new Set([
11345
+ ".env",
11346
+ ".env.development",
11347
+ ".env.production",
11348
+ ".env.test",
11349
+ ".npmrc",
11350
+ "npmrc"
11351
+ ]);
11335
11352
  FULL_READ_LIMITS = { files: 40, bytes: 512e3 };
11336
11353
  PAYMENT_PATH = /webhook|stripe|payment|billing|checkout/i;
11337
11354
  }
@@ -12103,6 +12120,10 @@ var init_repoFixes = __esm({
12103
12120
  service_role_key_in_client_env: [ROTATE_KEY],
12104
12121
  service_role_key_in_client_code: [ROTATE_KEY],
12105
12122
  env_var_drift: ["Set each of these variables in the environment where the app is deployed."],
12123
+ missing_stripe_webhook: [
12124
+ "Configure the deployed webhook endpoint and its required events in the Stripe dashboard.",
12125
+ "Set STRIPE_WEBHOOK_SECRET where the handler runs to the signing secret for that endpoint, deploy the handler, then verify delivery with Stripe."
12126
+ ],
12106
12127
  unverified_stripe_webhook: [
12107
12128
  "Set STRIPE_WEBHOOK_SECRET where the handler runs to the signing secret of this endpoint in the Stripe dashboard, then deploy the handler."
12108
12129
  ]
@@ -15023,7 +15044,7 @@ var VERSION;
15023
15044
  var init_version = __esm({
15024
15045
  "src/version.ts"() {
15025
15046
  "use strict";
15026
- VERSION = "1.6.5";
15047
+ VERSION = "1.6.7";
15027
15048
  }
15028
15049
  });
15029
15050
 
@@ -20731,6 +20752,20 @@ var init_providerGrade = __esm({
20731
20752
  }
20732
20753
  });
20733
20754
 
20755
+ // src/local-ui/types.ts
20756
+ function missionActionDestination(item4) {
20757
+ if (item4.actionDestination) return item4.actionDestination;
20758
+ if (item4.asksFirst || ["missing_stripe_webhook", "unverified_stripe_webhook"].includes(item4.id)) return "repo-code";
20759
+ const text = `${item4.id} ${item4.title} ${item4.detail ?? ""}`.replace(/[-_]/g, " ");
20760
+ if (/\bdashboard\b|\bdns\b|apex domain|\blive\b[^.\n]*\bproof\b|\bprovider action\b/i.test(text)) return "provider-action";
20761
+ return item4.requiresUserAction ? "manual-review" : "repo-code";
20762
+ }
20763
+ var init_types3 = __esm({
20764
+ "src/local-ui/types.ts"() {
20765
+ "use strict";
20766
+ }
20767
+ });
20768
+
20734
20769
  // src/local-ui/artifactAdapter.ts
20735
20770
  function blockerTone(severity) {
20736
20771
  if (severity === "critical") return "danger";
@@ -20758,7 +20793,7 @@ function gapRequiresUserAction(gap) {
20758
20793
  const extended = gap;
20759
20794
  if (typeof extended.requiresUserAction === "boolean") return extended.requiresUserAction;
20760
20795
  const text = gapSearchText(gap);
20761
- return text.includes("live") && text.includes("proof") || text.includes("dashboard") || text.includes("webhook") || text.includes("provider action");
20796
+ return text.includes("live") && text.includes("proof") || text.includes("dashboard") || text.includes("provider action");
20762
20797
  }
20763
20798
  function connectProviderStatus(provider2) {
20764
20799
  if (provider2.state === "live_verified") return "connected";
@@ -20781,19 +20816,30 @@ function buildConnectProviders(providers) {
20781
20816
  dashboardUrl: providerDashboardUrls[provider2.id]
20782
20817
  }));
20783
20818
  }
20784
- function asksFirstByGap(artifact) {
20819
+ function asksFirstByGap(tasks) {
20785
20820
  const asks = /* @__PURE__ */ new Map();
20786
- try {
20787
- for (const task of buildTaskList(artifact)) {
20788
- const sentence = task.fixType === "repo-code" && task.requiresUserAction ? task.action?.match(/^Ask the user first: [^.]+\./)?.[0] : void 0;
20789
- if (sentence) asks.set(task.gapId, sentence);
20790
- }
20791
- } catch {
20821
+ for (const task of tasks) {
20822
+ const sentence = task.fixType === "repo-code" && task.requiresUserAction ? task.action?.match(/^Ask the user first: [^.]+\./)?.[0] : void 0;
20823
+ if (sentence) asks.set(task.gapId, sentence);
20792
20824
  }
20793
20825
  return asks;
20794
20826
  }
20795
20827
  function buildMissionCards(artifact, providers) {
20796
- const asksFirst = asksFirstByGap(artifact);
20828
+ let taskList = [];
20829
+ try {
20830
+ taskList = buildTaskList(artifact);
20831
+ } catch {
20832
+ }
20833
+ const tasks = new Map(taskList.map((task) => [task.gapId, task]));
20834
+ const asksFirst = asksFirstByGap(taskList);
20835
+ const destinations = new Map(artifact.gaps.map((gap) => {
20836
+ const task = tasks.get(gap.id);
20837
+ return [gap.id, missionActionDestination({
20838
+ ...gap,
20839
+ requiresUserAction: gapRequiresUserAction(gap) || task?.requiresUserAction,
20840
+ actionDestination: task?.fixType === "repo-code" || task?.fixType === "provider-action" ? task.fixType : void 0
20841
+ })];
20842
+ }));
20797
20843
  const blockers = artifact.gaps.map((gap) => ({
20798
20844
  id: gap.id,
20799
20845
  title: gap.title,
@@ -20802,20 +20848,22 @@ function buildMissionCards(artifact, providers) {
20802
20848
  category: blockerCategoryLabel(gap),
20803
20849
  tone: blockerTone(gap.severity),
20804
20850
  prompt: gap.copyPrompt || void 0,
20805
- requiresUserAction: gapRequiresUserAction(gap),
20851
+ requiresUserAction: gapRequiresUserAction(gap) || destinations.get(gap.id) !== "repo-code",
20852
+ actionDestination: destinations.get(gap.id),
20806
20853
  ...asksFirst.has(gap.id) ? { asksFirst: asksFirst.get(gap.id) } : {}
20807
20854
  }));
20808
20855
  const planSteps = artifact.gaps.map((gap) => ({
20809
20856
  id: gap.id,
20810
20857
  title: gap.title,
20811
20858
  category: planStepCategoryLabel(gap),
20812
- requiresUserAction: gapRequiresUserAction(gap),
20859
+ requiresUserAction: gapRequiresUserAction(gap) || destinations.get(gap.id) !== "repo-code",
20860
+ actionDestination: destinations.get(gap.id),
20813
20861
  ...asksFirst.has(gap.id) ? { asksFirst: asksFirst.get(gap.id) } : {}
20814
20862
  }));
20815
20863
  const connectProviders = buildConnectProviders(providers);
20816
20864
  const blockerCount = blockers.length;
20817
20865
  const hasScan = Boolean(artifact.scannedAt) && artifact.scoreLabel !== "Not scanned";
20818
- const summary = !hasScan ? "VibeRaven is mapping your product \u2014 local production checks are running now (offline, no login)." : blockerCount === 0 ? "No launch blockers detected in the latest scan." : `I analyzed the production rollout and found ${blockerCount} blocker${blockerCount === 1 ? "" : "s"} preventing a safe deploy.`;
20866
+ const summary = !hasScan ? "VibeRaven is mapping your product \u2014 local production checks are running now (offline, no login)." : blockerCount === 0 ? "No blockers found in the latest repository checks." : `The latest repository checks found ${blockerCount} finding${blockerCount === 1 ? "" : "s"} to review.`;
20819
20867
  return {
20820
20868
  summary,
20821
20869
  blockerCount,
@@ -21257,6 +21305,7 @@ var init_artifactAdapter = __esm({
21257
21305
  init_launchRunway();
21258
21306
  init_providerGrade();
21259
21307
  init_gateResult();
21308
+ init_types3();
21260
21309
  GATE_LABEL = {
21261
21310
  clear: "No blockers in repo checks",
21262
21311
  warning: "Warnings to review",
package/dist/stack/app.js CHANGED
@@ -1,19 +1,21 @@
1
- "use strict";(()=>{function Ze(e=document){return e.querySelector('meta[name="viberaven-token"]')?.content??""}async function T(e,i){let n=await fetch(e,{...i,credentials:"same-origin",headers:{"content-type":"application/json","x-viberaven-token":Ze(),...i?.headers??{}}}),s=await n.text(),a=null;try{a=s?JSON.parse(s):null}catch{a={error:s}}if(!n.ok){let c=a?.error??a?.message??s??`HTTP ${n.status}`;throw new Error(String(c))}return a}var x=(e,i)=>T(e,{method:"POST",body:JSON.stringify(i)}),k={project:()=>T("/api/project"),scan:()=>x("/api/scan",{}),scanStatus:()=>T("/api/scan-status"),githubWorkflow:()=>T("/api/github-workflow"),addGithubWorkflow:()=>x("/api/github-workflow",{}),agents:()=>T("/api/cli-agents"),probe:e=>x("/api/cli-agents/probe",{cliId:e}),runSetup:(e,i)=>x("/api/cli-agents/run-setup",{cliId:e,step:i}),openTerminal:(e,i)=>x("/api/cli-agents/open-terminal",{cliId:e,step:i}),chat:e=>x("/api/agent-chat",e),catalog:()=>T("/api/provider-catalog"),verified:()=>T("/api/provider-verify"),stop:e=>x("/api/agent-chat/stop",{runId:e}),verify:e=>x("/api/provider-verify",e),connectMcp:e=>x("/api/mcp/connect",{providerId:e}),compare:(e,i)=>T(`/api/releases/compare?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`),fullCheckStatus:()=>T("/api/fullcheck/status"),fullCheckSignInStart:()=>x("/api/fullcheck/signin/start",{}),fullCheckSignInPoll:()=>x("/api/fullcheck/signin/poll",{}),fullCheckSignOut:()=>x("/api/fullcheck/signout",{}),fullCheckPrepare:()=>x("/api/fullcheck/prepare",{}),fullCheckRun:e=>x("/api/fullcheck/run",{previewId:e}),changelog:(e,i)=>T(`/api/releases/changelog?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`)};function t(e,i,...n){let s=document.createElement(e);if(i){for(let[a,c]of Object.entries(i))if(!(c==null||c===!1))if(a==="class")s.className=String(c);else if(a==="on")for(let[u,o]of Object.entries(c))s.addEventListener(u,o);else if(a==="dataset")for(let[u,o]of Object.entries(c))s.dataset[u]=o;else a==="html"?s.innerHTML=String(c):a==="style"&&typeof c=="object"?Object.assign(s.style,c):a in s&&typeof c!="string"?s[a]=c:s.setAttribute(a,String(c))}return ge(s,n),s}function ge(e,i){for(let n of i)n==null||n===!1||(Array.isArray(n)?ge(e,n):n instanceof Node?e.appendChild(n):e.appendChild(document.createTextNode(String(n))))}function G(e){return e.replace(/[&<>"']/g,i=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[i])}function Z(e){let n=G(e.replace(/\r\n/g,`
2
- `)).split(/```/),s="";return n.forEach((a,c)=>{if(c%2===1){let p=a.replace(/^[a-z0-9-]*\n/i,"");s+=`<pre><code>${p}</code></pre>`;return}let u=a.split(`
3
- `),o=null;for(let p of u){let r=p.trimEnd(),l=/^\s*[-*•]\s+(.*)$/.exec(r),d=/^\s*\d+[.)]\s+(.*)$/.exec(r),h=/^(#{1,3})\s+(.*)$/.exec(r),y=l?"ul":d?"ol":null;o&&y!==o&&(s+=`</${o}>`,o=null),y&&!o&&(s+=`<${y}>`,o=y),l||d?s+=`<li>${ee((l??d)[1])}</li>`:h?s+=`<h4>${ee(h[2])}</h4>`:r.trim()&&(s+=`<p>${ee(r)}</p>`)}o&&(s+=`</${o}>`)}),s}function ee(e){return e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>").replace(/`([^`]+)`/g,"<code>$1</code>")}function E(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 s=Math.round(n/60);return s<24?`${s} h ago`:`${Math.round(s/24)} d ago`}function W(){return{step:"closed",status:null,signIn:null,preview:null,result:null,limit:null,error:null,notice:null}}var Ve=new Set(["network","timeout","server","rate_limited","busy"]);function fe(e,i={}){let n=i.wait??(g=>new Promise(m=>window.setTimeout(m,g))),s=0,a=()=>e.get().fullCheck,c=g=>e.set(m=>({fullCheck:{...m.fullCheck,...g}})),u=g=>g===s&&a().step!=="closed";async function o(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 p(){try{let g=await k.fullCheckStatus();return c({status:g}),g}catch{return null}}async function r(g,m,M){if(u(M))switch(g.kind){case"signin":c({step:"signin",signIn:{code:g.code,verificationUrl:g.verificationUrl,expiresAt:g.expiresAt,opened:g.opened},error:null}),l(M,g.pollIntervalSeconds);return;case"signin_pending":return;case"signed_in":if(c({signIn:null,notice:g.notice??(a().preview?"Signed in again. Confirm to send the same request.":null)}),await p(),!u(M))return;a().preview?c({step:"preview"}):await h(M);return;case"signin_expired":case"signin_denied":c({step:"error",signIn:null,error:{message:g.message,retry:"signin"}});return;case"signed_out":c({...W()}),e.toast("Signed out of VibeRaven on this computer.");return;case"signin_required":case"reauth":c({notice:g.message}),await d(M);return;case"preview":c({step:"preview",preview:g.preview,error:null});return;case"result":c({step:"result",result:g.result,preview:null,notice:null,error:null}),await p();return;case"plan_limit":c({step:"limit",preview:null,notice:null,limit:{plan:g.plan,message:g.message,pricingUrl:g.pricingUrl,usage:g.usage}}),await p();return;case"error":{let w=g.reason==="not_confirmed"||g.reason==="prepare_failed"?"prepare":g.reason==="no_signin"?"signin":m==="run"&&!Ve.has(g.reason)?"prepare":m;w==="prepare"&&m==="run"&&c({preview:null}),c({step:"error",error:{message:g.message,retry:w}});return}}}async function l(g,m){for(;u(g)&&a().step==="signin";){if(await n(Math.max(1,m)*1e3),!u(g)||a().step!=="signin")return;let M=await o(()=>k.fullCheckSignInPoll());if(M.kind!=="signin_pending"){await r(M,"signin",g);return}}}async function d(g){c({step:"loading",error:null}),await r(await o(()=>k.fullCheckSignInStart()),"signin",g)}async function h(g){c({step:"preparing",error:null,result:null,limit:null}),await r(await o(()=>k.fullCheckPrepare()),"prepare",g)}async function y(g){c({step:"loading",error:null});let m=await p();if(u(g)){if(!m){c({step:"error",error:{message:"The Studio server did not answer. Reload the page and try again.",retry:"status"}});return}m.signedIn?await h(g):await d(g)}}return{async openFullCheck(){let g=a().step;g!=="closed"&&g!=="result"&&g!=="limit"&&g!=="error"||(s+=1,c({...W(),step:"loading",status:a().status}),await y(s))},closeFullCheck(){s+=1,c({step:"closed",signIn:null,error:null,notice:null}),document.getElementById("run-full-check")?.focus({preventScroll:!0})},async fullCheckSignIn(){await d(s)},async fullCheckConfirm(){let g=a().preview;if(!g||a().step!=="preview")return;let m=s;c({step:"running",error:null}),await r(await o(()=>k.fullCheckRun(g.id)),"run",m)},async fullCheckRetry(){let g=a().error?.retry??"status",m=s;if(g==="run"&&a().preview){c({step:"preview",error:null});return}g==="signin"?await d(m):g==="prepare"?await h(m):await y(m)},async fullCheckSignOut(){await r(await o(()=>k.fullCheckSignOut()),"status",s),await p()},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 z(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 me(e){return e==="pro"?"Pro plan":"Free plan"}function te(e){return e<1024?`${e} B`:`${(e/1024).toFixed(1)} KB`}function We(e){try{return new URL(e).host}catch{return e}}function he(e){return t("span",{class:`tag ${e==="critical"?"red":e==="warning"?"amber":"dim"}`},e==="critical"?"Critical":e==="warning"?"Important":"Nice to have")}function qe(e,i){let n=e.status?.account;if(!n)return null;let s=z(e.status?.usage);return t("div",{class:"fc-account"},t("span",{class:"fc-avatar","aria-hidden":"true"},n.email.slice(0,1).toUpperCase()),t("span",{class:"fc-who"},`Signed in as ${n.email}`),t("span",{class:`fc-plan is-${n.plan}`},me(n.plan)),e.status?.sessionOnly?t("span",{class:"fc-dot"},"this session only"):null,s?t("span",{class:"fc-dot"},s):null,t("button",{class:"fc-link",on:{click:()=>i.fullCheckSignOut()}},"Sign out"))}function Ke(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.split("").map(s=>t("span",{},s)))),t("p",{class:"fc-hint"},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 V(e,i,n,s=!1){return t("details",{class:"fc-files",open:s},t("summary",{},t("span",{},e),t("span",{class:"fc-files-count"},String(i.length))),i.length?t("ul",{},...i.map(a=>t("li",{},t("code",{},a.path),t("span",{},a.meta)))):t("p",{class:"fc-empty"},n))}function Xe(e,i){let n=e.preview,s=n.promptFiles.length;return[e.notice?t("p",{class:"fc-notice",role:"status"},e.notice):null,t("div",{class:"fc-summary"},t("div",{class:"fc-summary-main"},t("span",{class:"fc-summary-size"},te(n.bytes)),t("span",{class:"fc-summary-what"},`${s} file${s===1?"":"s"} in full, plus names and snippets`)),t("p",{class:"fc-lead"},`This is exactly what gets sent to ${We(n.endpoint)} when you confirm. Nothing has been uploaded yet.`)),qe(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",{},te(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"},V("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.",!0),V("File snippets (first 200 characters)",n.snippetFiles.map(a=>({path:a.path,meta:a.heat})),"None."),V("Skipped as secret files (name sent, contents never read)",n.secretFilesNamedOnly.map(a=>({path:a,meta:"name only"})),"None found."),V("Request text by section",n.promptSections.map(a=>({path:a.title,meta:`${a.chars.toLocaleString()} chars`})),"Empty.")),t("p",{id:"fc-redaction",class:`fc-shield${n.redactions>0?" is-on":""}`},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 (${te(n.bytes)}), same content.`),t("pre",{id:"fc-request-json"},n.requestJson)),t("p",{class:"fc-hint"},"Most of the request text is written by VibeRaven on your machine from the local scan: stack notes and the check instructions."),t("div",{class:"fc-actions fc-footer"},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 Je(e){return e<50?"fail":e<80?"warn":"pass"}function _e(e,i){let n=e.result,s=n.areas.reduce((o,p)=>o+p.hiddenCount,0),a=n.nextFix,c=n.areas.filter(o=>!o.locked&&o.findings.length),u=n.areas.filter(o=>o.locked||!o.findings.length);return[t("div",{class:`fc-score is-${Je(n.score)}`},t("div",{class:"fc-score-num",style:`--score:${Math.max(0,Math.min(100,n.score))}`},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",{class:`fc-plan is-${n.usage.plan}`},me(n.usage.plan)),t("span",{class:"fc-dot"},z(n.usage)),t("span",{class:"fc-dot"},`${n.usage.remaining} left${n.usage.period==="monthly"?" this month":""}`)),a?t("article",{class:`fc-next is-${a.severity}`},t("div",{class:"fix-top"},t("span",{class:"fc-eyebrow"},"Next fix"),he(a.severity),t("span",{class:"fix-meta"},a.areaTitle)),t("h3",{},a.title),a.detail?t("p",{},a.detail):null,a.prompt?t("button",{class:"btn primary sm",on:{click:()=>i.copyFullCheckPrompt(a.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"),c.length?t("div",{class:"fc-areas"},...c.map(o=>t("section",{class:"fc-area","aria-label":o.title},t("div",{class:"fc-area-head"},t("h5",{},o.title),t("span",{class:"fc-count on"},String(o.findings.length))),t("ul",{},...o.findings.map(p=>t("li",{},he(p.severity),t("span",{title:p.detail},p.title))))))):null,u.length?t("div",{class:"fc-quiet"},...u.map(o=>t("section",{class:`fc-chip${o.locked?" locked":""}`,"aria-label":o.title},t("span",{class:"fc-chip-mark","aria-hidden":"true"},o.locked?"":"\u2713"),t("span",{},o.title),o.locked?t("span",{class:"tag dim"},"Pro area"):t("span",{class:"fc-sr"},"No findings."),o.locked&&o.hiddenCount?t("span",{class:"fc-sr"},`${o.hiddenCount} finding${o.hiddenCount===1?"":"s"} here. Pro shows every area.`):null))):null,s&&n.usage.plan==="free"?t("p",{class:"fc-upsell"},`${s} finding${s===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 fc-footer"},t("button",{class:"btn",on:{click:()=>i.closeFullCheck()}},"Done"))]}function et(e,i){let n=e.limit;return[t("h3",{class:"fc-limit",role:"alert"},n.message),z(n.usage)?t("p",{class:"fc-hint"},z(n.usage)):null,n.plan==="free"?t("p",{class:"fc-hint"},"The local Studio checks stay free and unlimited. Pro adds 50 full checks a month across all production areas."):t("p",{class:"fc-hint"},"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 tt(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 ne(e){return t("p",{class:"fc-wait",role:"status"},t("span",{class:"spin"}),e)}var nt={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 ye(e,i){let n=e.fullCheck;if(n.step==="closed")return[];let s=n.step==="signin"&&n.signIn?Ke(n,i):n.step==="preview"&&n.preview?Xe(n,i):n.step==="result"&&n.result?_e(n,i):n.step==="limit"&&n.limit?et(n,i):n.step==="error"&&n.error?tt(n,i):n.step==="preparing"?[ne("Reading your project to build the request\u2026")]:n.step==="running"?[ne("Sent. VibeRaven is checking your app\u2026")]:[ne("Checking your VibeRaven sign-in\u2026")],a=n.step!=="running";return[t("div",{class:"fc-veil",on:{click:()=>{a&&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"},nt[n.step]),a?t("button",{class:"btn ghost sm","aria-label":"Close full check",on:{click:()=>i.closeFullCheck()}},"Close"):null),t("div",{class:"fc-body"},...s))]}var Me="viberaven.stack.";function R(e,i,n=localStorage){try{let s=n.getItem(Me+e);return s?JSON.parse(s):i}catch{return i}}function H(e,i,n=localStorage){try{n.setItem(Me+e,JSON.stringify(i))}catch{}}function it(e){return!e.empty&&!!e.project?.scannedAt?(e.missionCards?.blockers??[]).length?"findings":"ready":"app"}function be(e){let i=`chat.${e.project?.path??"project"}`,n=`checklist.${e.project?.path??"project"}`,s={project:e,catalog:[],verified:{},agents:[],probes:{},cliId:R("cliId","codex"),accessMode:R("accessMode","approve"),modelId:R("modelId",""),messages:R(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,moreOpen:!1,showAll:!1,setup:{open:!1,initialized:!1,selected:[],running:!1,progress:[],error:null},scan:null,toasts:[],workingSince:null,runId:null,fullCheck:W(),prChecks:{status:null,open:!1,busy:!1,written:!1,error:null},flow:{step:it(e),fixId:null,handoff:null,recheck:null,checklist:R(n,{})}},a=new Set,c=0,u={get:()=>s,set(o){let p=typeof o=="function"?o(s):o;s={...s,...p},"cliId"in p&&H("cliId",s.cliId),"accessMode"in p&&H("accessMode",s.accessMode),"modelId"in p&&H("modelId",s.modelId),"messages"in p&&H(i,s.messages.slice(-60),sessionStorage),"flow"in p&&H(n,s.flow.checklist);for(let r of a)r(s)},flow(o){u.set(p=>({flow:{...p.flow,...o}}))},subscribe(o){return a.add(o),()=>a.delete(o)},toast(o,p="ok"){let r=++c;u.set(l=>({toasts:[...l.toasts,{id:r,text:o,kind:p}]})),window.setTimeout(()=>u.set(l=>({toasts:l.toasts.filter(d=>d.id!==r)})),p==="err"?7e3:3600)},push(o){let p={...o,id:`${Date.now()}-${Math.random().toString(36).slice(2,7)}`,at:new Date().toISOString()};return u.set(r=>({messages:[...r.messages,p]})),p}};return u}var ke=["sentry","stripe","clerk","cloudflare","render","railway","neon","posthog","upstash","resend","authjs"];function st(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 P(e,i,n){let s=new Map(e.providers.map(r=>[r.id,r])),a=new Set,c=[],u=(r,l)=>{let d=r?.id??l.id;if(a.has(d))return;a.add(d);let h=!!r?.detected||!!(l&&l.state!=="not_detected"),y=!!r?.mcpConfigured||l?.mcp?.status==="connected",g=n[d],m=h?st(l):0,M="absent",w="Not in this app";h&&(M="in_repo",w=y?"MCP configured \xB7 not verified live":"In repo \xB7 MCP not set up",y&&(M="mcp"),g&&(M=g.ok&&m===0?"ready":"verified",w=g.ok?"Verified live":"Verified live \xB7 issues found")),c.push({id:d,name:r?.name??l.name,area:r?.area??l.area,logoUrl:r?.logoUrl??rt(l?.iconHtml??""),step:M,statusText:w,fixes:m,hasRecipe:!!r?.hasRecipe||l?.mcp?.available===!0,mcpConfigured:y,note:r?.note,mcpSource:r?.mcpSource??l?.mcp?.source,verified:g,provider:l})};for(let r of i)u(r,s.get(r.id));for(let r of e.providers)u(null,r);let o=r=>r.step==="absent"?r.hasRecipe?1:2:0,p=r=>{let l=ke.indexOf(r.id);return l===-1?ke.length:l};return c.sort((r,l)=>o(r)-o(l)||l.fixes-r.fixes||p(r)-p(l)||r.name.localeCompare(l.name))}function rt(e){let i=/src="([^"]+)"/.exec(e);return i?i[1]:""}function we(e,i,n){let s=e.setup,a=s.selected.length,c=e.probes[e.cliId]?.ready,u=s.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("h2",{id:"stack-setup-heading",tabIndex:-1},"Set up your app"),t("ol",{class:"setup-steps"},t("li",{class:a?"done":""},t("i",{"aria-hidden":"true"},a?"\u2713":"1"),"Pick your services"),t("li",{class:c?"done":""},t("i",{"aria-hidden":"true"},c?"\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:s.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(o=>{let p=s.selected.includes(o.id);return t("button",{id:`setup-provider-${o.id}`,class:`setup-service${p?" selected":""}`,"aria-pressed":String(p),disabled:u,on:{click:()=>n.toggleSetupProvider(o.id)}},t("img",{src:o.logoUrl,alt:""}),t("span",{class:"setup-service-copy"},t("strong",{},o.name),t("small",{},o.detected?"In your app":o.area)),t("span",{class:"setup-check","aria-hidden":"true"},p?"\u2713":"+"))})):t("p",{class:"setup-note"},"Loading the service catalog\u2026"),t("div",{class:"setup-footer"},t("div",{},t("strong",{},a?c?`${a} service${a===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.")),s.running?t("button",{class:"btn",on:{click:()=>n.stop()}},"Stop setup"):c?t("button",{class:"btn primary",disabled:!a||u,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")),s.progress.length?t("ol",{class:"setup-progress","aria-live":"polite"},...s.progress.map(o=>t("li",{class:o.state},t("span",{class:o.state==="working"&&s.running&&!s.error?"spin":"progress-dot","aria-hidden":"true"}),o.label))):null,s.error?t("p",{class:"setup-error",role:"alert"},s.error):null)}var at={authjs:"data:image/webp;base64,UklGRtANAABXRUJQVlA4WAoAAAAQAAAAVgAAXwAAQUxQSEIEAAABoETbtmnbmRvftl2LbSffthGVbNu2bdu2bdvGY5K91prBw73n7KAYEROAajsfPYBuk856r7Gh9tlD1wkAQvQotQsBAAbNv+QjNisvnTC2OwAXvSuJjwGAX3XP+2tJmhhJFZL8+rothwNADK5ozkcHoOvoE14lSRFl85qUZN1De60WAIToi+NCBIChi674jCSTGFtrIiT5xqkTegBw0bsC+BgA+FX3fLCOpCY1VtYkkeSX1ywbDgAhuGo4Hx2ArqNPeIUkRZTV1aQk6x/eZ80IIERfGRciAAxdes0XJJnEWEQTIck3Th3XFYCL3rXChwAAK+12Xw1JTWosrkkiyc+uXDwMAGJwTTkfPYBuY0542UiKGIuvSUnWP7TXagFAiB4IADBk0ZWfk2QSY1lVhCRfPXF0VwDew62y+/01JDWpsdwmiSS/uHrpMGDmCyQpYsyiaVKStbctX09LYsypiZBXNCoznOTKBuZYeMX/Wpfn6opfM3XWt7Qs7f8yNUPKre/LknHK5ZQM0dY5JkfGmlE7UvOj/KzbLFqOXvRrKfMrvAtDfqJlJ/EcdPyQmqH9gMcp2RHOBy5nyo5xXeCQ/BgbhgBL8qP8qB2wIS03wkfgMLiBlpnEcxDR5j1qdnZC9LiTkhnlGISIY5jyYmwcDh+xiJIX5Ttt4DxWVuZVeCMCHDp/QctK4v6IgMcdlKwoxyAAEQcw5cRYMwAeCNicmhPh084BcOj5PS0jiSciAoDHfZSMKKch/C3iQKZ8GOsGwf0tYD1aPpRPweHvDh0+pmYj8TDEJhBwqaVsGDdCaCpiNjUXyg87wDXl0PN7WiaSnY+AZgOuspQJ5aSWRDeLkgflF13gmnPo8T0tC8kuREALAy5lyoJyfGtGU3OgfL89XEuca/suNQOJRyKixREHMpXP7Pfl4FvmMazerHTCu+DRyoDLmUqnnITQurVMy6b2ZhvnWgOPB0xKJtwOEa0OGE0tl9rXPZxrHbx/wqRUwn0RUMGATVkqta97OFcJeFxPKZFwewRUxg2tUSuN2BvtvKsMAg6ilIfTEFBh5zt/aFoS4b0IqHjARKZymPy2PHzlEHEFUykS90dAFb3v87lpCYTPxuCqgYCxTFY404aV4FHdiMOYCpe4LQKq7KK7g6lgiRciourO9XyXUijhM+2Dqx4CVvyZWiDhl8PgUcSILRpVC6OsXQMBxYyYTbWCKBvHIqKoEctoWghlw1hEFDdiye+UAggbxiKiyBHj6ilVS/xxNCKKHbHep0xVSnx/FUQUPWLoExStggrvG4CA4ge0P5OUigl5YkRAGT0w/yuqVkSVn0yH8yinCxh8NSnWKhXywr4IDqUNwOw3yGQt0kS+OAUIKLP36LT716RoMyrkR9u1Q3AoeQAGHPoVaWpmQvLD/XoAAeV3Aei93fNsUh9e0hkIDll0EQhTb/z4y7fP3QhAdCgiVlA4IGgJAACQKgCdASpXAGAAPjEUiEMiISEUCOcYIAMEtgBb9btga9m/F/8lvlUrX9I+6H9A/7/+X64o7XZd+G+2730f4D2x/mT/Je4B+j39l/Nb++d1zzB/y7+r/8b+y+8h6D/QA/oH9m6w79xvYA/Wb1Xv9P+2HwMfsb+z/wG/y3+u/+T8/+QA/gHWgdv/+Wsj/yt/p+e835uFekU+L+wB/Hf7b6FX/D/hPPR9K+wF/LP6l/wOwt+0Xsv/rSii5S8mBgqDE9JYE5GwzUAX2+kH5rOaaGyBjiEOqYZp2/3oMM2MZ9Z25/cW7PIHm7SM1zg/rmtdN7/64GMeqOWQfMCHS5mIfhKHUyQ8rVwv9fCfxKKvxVzcR7mHuW6q3uJdqXrJ03kAIgNpyjAZh6cyGDNbrY5G5TG/QLuu+0mdbwHlCLyvUac4IefZELWfpbeKopFlmLbzK9nQwsLY5xcGeoqNwZ4AAP7/9B2hxR6Nv+96k7HnwXIU6NhYpJ4++OmPwDq5NhMqm6W0/+SQ1k8VFzPgnHwC3ARvXoUhmxvrWlWAW69hhbhGQ+lCfzY8LU3fl9D0HCatWJA1gkxZBApdjoO3+Gx2FRcyg9blPD7VxRO7TX/bW337xiyh1EKzMrPzrek/hOrQZ4+6TBb20sqsdTf7pjGXRTexJy4xQc75YQVHTOmeUnwqq6Vxu5P/eA9VtkMMoZCnRgYjdkLAhaxR6wl9/bpcWboojaym4/UpMvPTVQ8swaoh4wMsT1wwY0ZlGSKP2ZyhGguKWOz/Z+FKtl5Lykyb7BTw/QBXZJW+A3dV3SiuuyrtfBqwDc9PjZX1FfrKMvkV+W2QEWRBz/HQz7lTfIxatFHfVGxB3jzKdS697ElzPcUVW3msBtFoEPch/GtE9Dr1ENxdNAHiuZF+0QKgayyKxWhKF7NBq/aLPiHt+vtH8pf46+AOfJiUfm6tBLwrsrLh2i6Ygk3xN2j1aa6pZI2a31M3zKpyocR7HvePPJAJSyVl+0dRlYACwUkZspLylJytFCL//PiJQj9auS9F5+mdiR8J9PsN8F6BowKGfRQqz24+n+AWtENMzUHfzPrb3qlFv1nxu47WKD9UAjf71v9ZBvmeeoM+v+drzy9X8MwKYCr24T+gSvRpP7RCl+UsMz5WtNP470E0f6hkfLRGQhPgcVIZlk0JurDD1mNhPsuivVO/AWpQhbSbQoJpmjr/qYL3PGfyfEl54O4dplISqo1oPwyT+wzo7na/IpKMppUCRdl7KVbg0rP7KTx9qopVkZTyEObSRiJSqPnF8MCHiOrDTBch3nbGFXIXXrQpqhoDX4adUqGwHyOxrJu0HHy4gPCjPmFseNjf5XJ+O85iXVeEugyeW/2525fL9omsGRT9g+P/xT48n6uaBlauXOQdzh+QjZZ576SXx3r7coWlqm69q/V67SapkTaWkSLIvjPik/r/0Ku4htOGplVrme1k+d6hD9R8XEVy0KwEiBscrJxoLVzvHbjFmQFrC5aPBvwpzBcu0ubsLUZ3lou15LvGrocjDrzzvKpM+wru4OXrHng//zOx1Z1thEYfO2bz+aFQdJLbQAy+i9aDJE2WsIQaNIb0C92CoTm+Z3K1SqWuasGrJZq6FU1MZpjHveIKr0D98xneeH3nlOsd7SkHPUAzRQWjJ3F4rd07G7i7WtTtgU39NmE4RFoQV8OneCAiM3+PvUnBcSRaWq/TlO1cF3fiNPXODbZvgRlKj362hlbwLudL7VPNq4M4R4Obt9ft+zUdd70NMYSN1CxomVvXFAGn1/zjLi4Wx9tPwV39hI+2Y3/oIYZFWr8uQV4DCp/JxhtTQGFSaaiX9RroKpRkiEs5gYsRjyV7x/bUNjEaRdA4E/kHZZNCu36tqgqkveuICoMixSElB8YV2VJM7WZeO+egf/4HQuLYj/whvwUqYUbluhQ0lTmu3Nap6QagyE1L3SCCh8ExLW4HKFI2D7GOY2wntFXO1iEqcb/u6NqBS6H/4hW5f8OgB8Zejwp8sfMBjkgICaDtjM9jY4Rvfjq3CxFIXKbDGDiGaItOefEpbZ3ZUcoXATTURn+LR9Pf2m2OM7ClM7u9fbZFHvgUMpu7KaZY+jkcGBbXrK48dVedxSQqTo7OyKdt8V7dQ9v90+LhYn9GJrvCSpSp8APmiUCKkjx0r1RbV2MMHF0GHnr+kefH8bYztriXbB1u6q0DmRH76N0Jc8eKKg1u2axOyH00EKciX29601289ajP8lGxGb2xJet9MXYDQZYDEsaTf+pRxMadxoPIdrMT9jsDFl0S4SKPjRQzhzRZ5wtvwz1/zKIuDhzFM4VhK55VLDIDh+YFFD3qphfLvso7c/jMXRqOvTQ35Jp5eQdyBNvZxBPxxF6TCrrkcVnVi2LgvSdDtQnpDx0sceHIuhLZZFwGuB+toA4rE09HSiQvoNnh65uH70b1LObmc9h/cR4jOeYB9n6V6mayg79aiHnOGal6//yqPgY7OgleYQK+eopgZI1d4KHiOSvVNyIn/6v8Pj3F50MatXhPn5GR3JXqYnY3Gt4+UEQSwSRWWpZGdyhfk1zziuCATrHfZhGxw7lvfir8JpqNX4jt2ONXy58Ob3cSGo3c5eGRns5qjF5dgRiWU1Wjv6JYK/EM/rXOTU1XWIlho2b4h4z/RU9ZjIvl867Ik6s2KhCh1N00fig3mhs5f+SXamN3WXEaf2BL9BRzW/i2mjSSRySOUi9U80PB3f3xFieqzOJH9RmSN5WS6WHFkoJDtsIan2CNnxnK1kxc1fjPCwCmjuiRmzdL2ZOkfoGoNhofuIdaErLC4dJ5zWaLyOgbGFv/MQMMt4JwkzOvpEWEr5ifEIFOB50DgfJNfXHXh0SH2GtQLJG8GYpEDv7nOxyyjqJkP/TaTtsn2IAx/+zDn1YlR//F/veEcMU2wv7I4iYcgBhkVAjFtQWOX/2UyYl77otOaea7I4ydaNjCI8dxtK+m1HSUFMmI3T1b7BVkKOFCf38cdgGF1uOYBA5Rw9hGhyK9qJwLzVOd5o3Ng9E2p4YsjYP9IdaDRtLq/CJ5s2340OFH561h6d82y/CaPthB1HN/99LaXLZv8Gfvh5vJ2vDJ+XaYFIS3QIlLUNjVg1BfqBwShMmTQjFd9/wT3uig+TLNZGOmFjxI9bP/KB90o/6HSFDp6PWPx7Fc3xoqLNRxjsJyo8lIiYMEkZ+SAAAAAA==",clerk:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjNkM0N0ZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Q2xlcms8L3RpdGxlPjxwYXRoIGQ9Im0yMS40NyAyMC44MjktMi44ODEtMi44ODFhLjU3Mi41NzIgMCAwIDAtLjctLjA4NCA2Ljg1NCA2Ljg1NCAwIDAgMS03LjA4MSAwIC41NzYuNTc2IDAgMCAwLS43LjA4NGwtMi44ODEgMi44ODFhLjU3Ni41NzYgMCAwIDAtLjEwMy42OS41Ny41NyAwIDAgMCAuMTY2LjE4NiAxMiAxMiAwIDAgMCAxNC4xMTMgMCAuNTguNTggMCAwIDAgLjIzOS0uNDIzLjU3Ni41NzYgMCAwIDAtLjE3Mi0uNDUzWm0uMDAyLTE3LjY2OC0yLjg4IDIuODhhLjU2OS41NjkgMCAwIDEtLjcwMS4wODRBNi44NTcgNi44NTcgMCAwIDAgOC43MjQgOC4wOGE2Ljg2MiA2Ljg2MiAwIDAgMC0xLjIyMiAzLjY5MiA2Ljg2IDYuODYgMCAwIDAgLjk3OCAzLjc2NC41NzMuNTczIDAgMCAxLS4wODMuNjk5bC0yLjg4MSAyLjg4YS41NjcuNTY3IDAgMCAxLS44NjQtLjA2M0ExMS45OTMgMTEuOTkzIDAgMCAxIDYuNzcxIDIuN2ExMS45OSAxMS45OSAwIDAgMSAxNC42MzctLjQwNS41NjYuNTY2IDAgMCAxIC4yMzIuNDE4LjU3LjU3IDAgMCAxLS4xNjguNDQ4Wm0tNy4xMTggMTIuMjYxYTMuNDI3IDMuNDI3IDAgMSAwIDAtNi44NTQgMy40MjcgMy40MjcgMCAwIDAgMCA2Ljg1NFoiLz48L3N2Zz4=",cloudflare:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRjM4MDIwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Q2xvdWRmbGFyZTwvdGl0bGU+PHBhdGggZD0iTTE2LjUwODggMTYuODQ0N2MuMTQ3NS0uNTA2OC4wOTA4LS45NzA3LS4xNTUzLTEuMzE1NC0uMjI0Ni0uMzE2NC0uNjA0NS0uNDk5LTEuMDYxNS0uNTIwNWwtOC42NTkyLS4xMTIzYS4xNTU5LjE1NTkgMCAwIDEtLjEzMzMtLjA3MTNjLS4wMjgzLS4wNDItLjAzNTEtLjA5ODYtLjAyMS0uMTU1My4wMjc4LS4wODQuMTEyMy0uMTQ4NC4yMDM2LS4xNTYybDguNzM1OS0uMTEyM2MxLjAzNTEtLjA0ODkgMi4xNjAxLS44ODY4IDIuNTUzNy0xLjkxMzZsLjQ5OS0xLjMwMTNjLjAyMTUtLjA1NjEuMDI5My0uMTEyOC4wMTQ3LS4xNjgtLjU2MjUtMi41NDYzLTIuODM1LTQuNDQ1My01LjU0OTktNC40NDUzLTIuNTAzOSAwLTQuNjI4NCAxLjYxNzctNS4zODc2IDMuODYxNC0uNDkyNy0uMzY1OC0xLjExODctLjU2MjUtMS43OTQtLjQ5OS0xLjIwMjYuMTE5LTIuMTY2NSAxLjA4My0yLjI4NjEgMi4yODU2LS4wMjgzLjMxLS4wMDY5LjYxMjguMDYzNS44OTRDMS41NjgzIDEzLjE3MSAwIDE0Ljc3NTQgMCAxNi43NTJjMCAuMTc0OC4wMTQyLjM1MTUuMDM1Mi41MjczLjAxNDEuMDgzLjA4NDQuMTQ3NS4xNjg5LjE0NzVoMTUuOTgxNGMuMDkwOSAwIC4xNzU4LS4wNjQ1LjIwMzItLjE1NTNsLjEyLS40MjY4em0yLjc1NjgtNS41NjM0Yy0uMDc3MSAwLS4xNjExIDAtLjIzODMuMDExMi0uMDU2NiAwLS4xMDU0LjA0MTUtLjEyNy4wOTc2bC0uMzM3OCAxLjE3NDRjLS4xNDc1LjUwNjgtLjA5MTguOTcwNy4xNTQzIDEuMzE2NC4yMjU2LjMxNjQuNjA1NS40OTggMS4wNjI1LjUxOTVsMS44NDM3LjExMzNjLjA1NTcgMCAuMTA1NS4wMjYzLjEzMjkuMDcwMy4wMjgzLjA0My4wMzUxLjEwNzQuMDIxNC4xNTYyLS4wMjgzLjA4NC0uMTEzMi4xNDg1LS4yMDQuMTU1M2wtMS45MjEuMTEyM2MtMS4wNDEuMDQ4OC0yLjE1ODIuODg2Ny0yLjU1MjcgMS45MTRsLS4xNDA2LjM1ODVjLS4wMjgzLjA3MTMuMDIxNS4xNDE2LjA5ODYuMTQxNmg2LjU5NzdjLjA3NzEgMCAuMTQ3NC0uMDQ4OS4xNjktLjEyNi4xMTIyLS40MDgyLjE3NTctLjgzNy4xNzU3LTEuMjgwMyAwLTIuNjAyNS0yLjEyNS00LjcyNy00LjczNDQtNC43MjciLz48L3N2Zz4=",github:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViPC90aXRsZT48cGF0aCBkPSJNMTIgLjI5N2MtNi42MyAwLTEyIDUuMzczLTEyIDEyIDAgNS4zMDMgMy40MzggOS44IDguMjA1IDExLjM4NS42LjExMy44Mi0uMjU4LjgyLS41NzcgMC0uMjg1LS4wMS0xLjA0LS4wMTUtMi4wNC0zLjMzOC43MjQtNC4wNDItMS42MS00LjA0Mi0xLjYxQzQuNDIyIDE4LjA3IDMuNjMzIDE3LjcgMy42MzMgMTcuN2MtMS4wODctLjc0NC4wODQtLjcyOS4wODQtLjcyOSAxLjIwNS4wODQgMS44MzggMS4yMzYgMS44MzggMS4yMzYgMS4wNyAxLjgzNSAyLjgwOSAxLjMwNSAzLjQ5NS45OTguMTA4LS43NzYuNDE3LTEuMzA1Ljc2LTEuNjA1LTIuNjY1LS4zLTUuNDY2LTEuMzMyLTUuNDY2LTUuOTMgMC0xLjMxLjQ2NS0yLjM4IDEuMjM1LTMuMjItLjEzNS0uMzAzLS41NC0xLjUyMy4xMDUtMy4xNzYgMCAwIDEuMDA1LS4zMjIgMy4zIDEuMjMuOTYtLjI2NyAxLjk4LS4zOTkgMy0uNDA1IDEuMDIuMDA2IDIuMDQuMTM4IDMgLjQwNSAyLjI4LTEuNTUyIDMuMjg1LTEuMjMgMy4yODUtMS4yMy42NDUgMS42NTMuMjQgMi44NzMuMTIgMy4xNzYuNzY1Ljg0IDEuMjMgMS45MSAxLjIzIDMuMjIgMCA0LjYxLTIuODA1IDUuNjI1LTUuNDc1IDUuOTIuNDIuMzYuODEgMS4wOTYuODEgMi4yMiAwIDEuNjA2LS4wMTUgMi44OTYtLjAxNSAzLjI4NiAwIC4zMTUuMjEuNjkuODI1LjU3QzIwLjU2NSAyMi4wOTIgMjQgMTcuNTkyIDI0IDEyLjI5N2MwLTYuNjI3LTUuMzczLTEyLTEyLTEyIi8+PC9zdmc+",neon:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDBFNTk5IiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+TmVvbjwvdGl0bGU+PHBhdGggZD0iTTI0IDBWMjRsLTkuMzY1LTguMDQ1VjI0SDBWMFpNMi45NDIgMjEuMDg3aDguNzUxVjkuNTYzbDkuMzY1IDguMjA0VjIuOTE5TDIuOTQyIDIuOTE0WiIvPjwvc3ZnPg==",posthog:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRjU0RTAwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UG9zdEhvZzwvdGl0bGU+PHBhdGggZD0iTTkuODU0IDE0LjUgNSA5LjY0Ny44NTQgNS41QS41LjUgMCAwIDAgMCA1Ljg1NFY4LjQ0YS41LjUgMCAwIDAgLjE0Ni4zNTNMNSAxMy42NDdsLjE0Ny4xNDZMOS44NTQgMTguNWwuMTQ2LjE0N3YtLjA0OWMuMDY1LjAzLjEzNC4wNDkuMjA3LjA0OWgyLjU4NmEuNS41IDAgMCAwIC4zNTMtLjg1NEw5Ljg1NCAxNC41em0wLTUtNC00YS40ODcuNDg3IDAgMCAwLS40MDktLjE0NC41MTUuNTE1IDAgMCAwLS4zNTYuMjEuNDkzLjQ5MyAwIDAgMC0uMDg5LjI4OFY4LjQ0YS41LjUgMCAwIDAgLjE0Ny4zNTNsOSA5YS41LjUgMCAwIDAgLjg1My0uMzU0di0yLjU4NWEuNS41IDAgMCAwLS4xNDYtLjM1NGwtNS01em0xLTRhLjUuNSAwIDAgMC0uODU0LjM1NFY4LjQ0YS41LjUgMCAwIDAgLjE0Ny4zNTNsNCA0YS41LjUgMCAwIDAgLjg1My0uMzU0VjkuODU0YS41LjUgMCAwIDAtLjE0Ni0uMzU0bC00LTR6bTEyLjY0NyAxMS41MTVhMy44NjMgMy44NjMgMCAwIDEtMi4yMzItMS4xbC00LjcwOC00LjcwN2EuNS41IDAgMCAwLS44NTQuMzU0djYuNTg1YS41LjUgMCAwIDAgLjUuNUgyMy41YS41LjUgMCAwIDAgLjUtLjV2LS42YzAtLjI3Ni0uMjI1LS40OTctLjQ5OS0uNTMyem0tNS4zOTQuMDMyYS44LjggMCAxIDEgMC0xLjYuOC44IDAgMCAxIDAgMS42ek0uODU0IDE1LjVhLjUuNSAwIDAgMC0uODU0LjM1NHYyLjI5M2EuNS41IDAgMCAwIC41LjVoMi4yOTNjLjIyMiAwIC4zOS0uMTM1LjQ2Mi0uMzA5YS40OTMuNDkzIDAgMCAwLS4xMDktLjU0NUwuODU0IDE1LjUwMXpNNSAxNC42NDcuODU0IDEwLjVhLjUuNSAwIDAgMC0uODU0LjM1M3YyLjU4NmEuNS41IDAgMCAwIC4xNDYuMzUzTDQuODU0IDE4LjVsLjE0Ni4xNDdoMi43OTNhLjUuNSAwIDAgMCAuMzUzLS44NTRMNSAxNC42NDd6Ii8+PC9zdmc+",railway:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmFpbHdheTwvdGl0bGU+PHBhdGggZD0iTS4xMTMgMTAuMjdBMTMuMDI2IDEzLjAyNiAwIDAwMCAxMS40OGgxOC4yM2MtLjA2NC0uMTI1LS4xNS0uMjM3LS4yMzUtLjM0Ny0zLjExNy00LjAyNy00Ljc5My0zLjY3Ny03LjE5LTMuNzgtLjgtLjAzNC0xLjM0LS4wNDgtNC41MjQtLjA0OC0xLjcwNCAwLTMuNTU1LjAwNS01LjM1OC4wMS0uMjM0LjYzLS40NTkgMS4yNC0uNTY3IDEuNzM3aDkuMzQydjEuMjE2SC4xMTN2LjAwMnptMTguMjYgMi40MjZILjAwOWMuMDIuMzI2LjA1LjY0NS4wOTQuOTYxaDE2Ljk1NWMuNzU0IDAgMS4xNzktLjQyOSAxLjMxNS0uOTZ6bS0xNy4zMTggNC4yOHMyLjgxIDYuOTAyIDEwLjkzIDcuMDI0YzQuODU1IDAgOS4wMjctMi44ODMgMTAuOTItNy4wMjRIMS4wNTZ6TTExLjk4OCAwQzcuNSAwIDMuNTkzIDIuNDY2IDEuNTMxIDYuMTA4bDQuNzUtLjAwNXYtLjAwMmMzLjcxIDAgMy44NDkuMDE2IDQuNTczLjA0N2wuNDQ4LjAxNmMxLjU2My4wNTIgMy40ODUuMjIgNC45OTYgMS4zNjQuODIuNjIxIDIuMDA3IDEuOTkgMi43MTIgMi45NjUuNjU0LjkwMi44NDIgMS45NC4zOTYgMi45MzQtLjQwOC45MTQtMS4yODkgMS40NTgtMi4zNTMgMS40NThILjM5MXMuMDk5LjQyLjI0OS44ODZoMjIuNzQ4QTEyLjAyNiAxMi4wMjYgMCAwMDI0IDEyLjAwNUMyNCA1LjM3NyAxOC42MjEgMCAxMS45ODggMHoiLz48L3N2Zz4=",render:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmVuZGVyPC90aXRsZT48cGF0aCBkPSJNMTguMjYzLjAwN2MtMy4xMjEtLjE0Ny01Ljc0NCAyLjEwOS02LjE5MiA1LjA4Mi0uMDE4LjEzOC0uMDQ1LjI3Mi0uMDY3LjQwNS0uNjk2IDMuNzAzLTMuOTM2IDYuNTA3LTcuODI3IDYuNTA3LTEuMzg4IDAtMi42OTEtLjM1Ni0zLjgyNS0uOTc5YS4yMDI0LjIwMjQgMCAwIDAtLjMwMi4xNzhWMjRIMTJ2LTguOTk5YzAtMS42NTYgMS4zMzgtMyAyLjk4Ny0zaDIuOTg4YzMuMzgyIDAgNi4xMDMtMi44MTcgNS45Ny02LjI0NC0uMTItMy4wODQtMi42MS01LjYwMy01LjY4Mi01Ljc1Ii8+PC9zdmc+",resend:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmVzZW5kPC90aXRsZT48cGF0aCBkPSJNMTQuNjc5IDBjNC42NDggMCA3LjQxMyAyLjc2NSA3LjQxMyA2LjQzNHMtMi43NjUgNi40MzQtNy40MTMgNi40MzRIMTIuMzNMMjQgMjRoLTguMjQ1bC04Ljg4LTguNDRjLS42MzYtLjU4OC0uOTMtMS4yNzMtLjkzLTEuODYgMC0uODMxLjU4Ny0xLjU2NSAxLjcxMy0xLjg4M2w0LjU3NC0xLjIyNGMxLjczNy0uNDY1IDIuOTM2LTEuODEgMi45MzYtMy41NzIgMC0yLjE1My0xLjc2MS0zLjQtMy45MzktMy40SDBWMHoiLz48L3N2Zz4=",sentry:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjOEI1Q0Y2IiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U2VudHJ5PC90aXRsZT48cGF0aCBkPSJNMTMuOTEgMi41MDVjLS44NzMtMS40NDgtMi45NzItMS40NDgtMy44NDQgMEw2LjkwNCA3LjkyYTE1LjQ3OCAxNS40NzggMCAwIDEgOC41MyAxMi44MTFoLTIuMjIxQTEzLjMwMSAxMy4zMDEgMCAwIDAgNS43ODQgOS44MTRsLTIuOTI2IDUuMDZhNy42NSA3LjY1IDAgMCAxIDQuNDM1IDUuODQ4SDIuMTk0YS4zNjUuMzY1IDAgMCAxLS4yOTgtLjUzNGwxLjQxMy0yLjQwMmE1LjE2IDUuMTYgMCAwIDAtMS42MTQtLjkxM0wuMjk2IDE5LjI3NWEyLjE4MiAyLjE4MiAwIDAgMCAuODEyIDIuOTk5IDIuMjQgMi4yNCAwIDAgMCAxLjA4Ni4yODhoNi45ODNhOS4zMjIgOS4zMjIgMCAwIDAtMy44NDUtOC4zMThsMS4xMS0xLjkyMmExMS40NyAxMS40NyAwIDAgMSA0Ljk1IDEwLjI0aDUuOTE1YTE3LjI0MiAxNy4yNDIgMCAwIDAtNy44ODUtMTUuMjhsMi4yNDQtMy44NDVhLjM3LjM3IDAgMCAxIC41MDQtLjEzYy4yNTUuMTQgOS43NSAxNi43MDggOS45MjggMTYuOWEuMzY1LjM2NSAwIDAgMS0uMzI3LjU0M2gtMi4yODdjLjAyOS42MTIuMDI5IDEuMjIzIDAgMS44MzFoMi4yOTdhMi4yMDYgMi4yMDYgMCAwIDAgMS45MjItMy4zMXoiLz48L3N2Zz4=",stripe:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjNjM1QkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U3RyaXBlPC90aXRsZT48cGF0aCBkPSJNMTMuOTc2IDkuMTVjLTIuMTcyLS44MDYtMy4zNTYtMS40MjYtMy4zNTYtMi40MDkgMC0uODMxLjY4My0xLjMwNSAxLjkwMS0xLjMwNSAyLjIyNyAwIDQuNTE1Ljg1OCA2LjA5IDEuNjMxbC44OS01LjQ5NEMxOC4yNTIuOTc1IDE1LjY5NyAwIDEyLjE2NSAwIDkuNjY3IDAgNy41ODkuNjU0IDYuMTA0IDEuODcyIDQuNTYgMy4xNDcgMy43NTcgNC45OTIgMy43NTcgNy4yMThjMCA0LjAzOSAyLjQ2NyA1Ljc2IDYuNDc2IDcuMjE5IDIuNTg1LjkyIDMuNDQ1IDEuNTc0IDMuNDQ1IDIuNTgzIDAgLjk4LS44NCAxLjU0NS0yLjM1NCAxLjU0NS0xLjg3NSAwLTQuOTY1LS45MjEtNi45OS0yLjEwOWwtLjkgNS41NTVDNS4xNzUgMjIuOTkgOC4zODUgMjQgMTEuNzE0IDI0YzIuNjQxIDAgNC44NDMtLjYyNCA2LjMyOC0xLjgxMyAxLjY2NC0xLjMwNSAyLjUyNS0zLjIzNiAyLjUyNS01LjczMiAwLTQuMTI4LTIuNTI0LTUuODUxLTYuNTk0LTcuMzA1aC4wMDN6Ii8+PC9zdmc+",supabase:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjM0VDRjhFIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U3VwYWJhc2U8L3RpdGxlPjxwYXRoIGQ9Ik0xMS45IDEuMDM2Yy0uMDE1LS45ODYtMS4yNi0xLjQxLTEuODc0LS42MzdMLjc2NCAxMi4wNUMtLjMzIDEzLjQyNy42NSAxNS40NTUgMi40MDkgMTUuNDU1aDkuNTc5bC4xMTMgNy41MWMuMDE0Ljk4NSAxLjI1OSAxLjQwOCAxLjg3My42MzZsOS4yNjItMTEuNjUzYzEuMDkzLTEuMzc1LjExMy0zLjQwMy0xLjY0NS0zLjQwM2gtOS42NDJ6Ii8+PC9zdmc+",upstash:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDBFOUEzIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VXBzdGFzaDwvdGl0bGU+PHBhdGggZD0iTTEzLjgwMjcgMEMxMS4xOTMgMCA4LjU4My45OTUyIDYuNTkxOCAyLjk4NjNjLTMuOTgyMyAzLjk4MjMtMy45ODIzIDEwLjQzOTYgMCAxNC40MjE5IDEuOTkxMSAxLjk5MTEgNS4yMTk4IDEuOTkxMSA3LjIxMSAwIDEuOTkxLTEuOTkxMSAxLjk5MS01LjIxOTggMC03LjIxMUwxMiAxMmMuOTk1Ni45OTU2Ljk5NTYgMi42MDk4IDAgMy42MDU1LS45OTU2Ljk5NTUtMi42MDk5Ljk5NTUtMy42MDU1IDAtMi45ODY2LTIuOTg2OC0yLjk4NjYtNy44Mjk3IDAtMTAuODE2NCAyLjk4NjgtMi45ODY4IDcuODI5Ny0yLjk4NjggMTAuODE2NCAwbDEuODAyOC0xLjgwMjhDMTkuMDIyNS45OTUyIDE2LjQxMjUgMCAxMy44MDI3IDB6TTEyIDEyYy0uOTk1Ni0uOTk1Ni0uOTk1Ni0yLjYwOTggMC0zLjYwNTUuOTk1Ni0uOTk1NSAyLjYwOTgtLjk5NTUgMy42MDU1IDAgMi45ODY3IDIuOTg2OCAyLjk4NjcgNy44Mjk3IDAgMTAuODE2NC0yLjk4NjcgMi45ODY4LTcuODI5NyAyLjk4NjgtMTAuODE2NCAwbC0xLjgwMjggMS44MDI4YzMuOTgyMyAzLjk4MjIgMTAuNDM5NiAzLjk4MjIgMTQuNDIxOSAwIDMuOTgyMy0zLjk4MjQgMy45ODIzLTEwLjQzOTYgMC0xNC40MjE5LS45OTU2LS45OTU2LTIuMzAwNi0xLjQ5MjItMy42MDU1LTEuNDkyMi0xLjMwNDggMC0yLjYwOTkuNDk2Ni0zLjYwNTQgMS40OTIyLTEuOTkxMiAxLjk5MTItMS45OTEyIDUuMjE5OCAwIDcuMjExeiIvPjwvc3ZnPg==",vercel:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VmVyY2VsPC90aXRsZT48cGF0aCBkPSJtMTIgMS42MDggMTIgMjAuNzg0SDBaIi8+PC9zdmc+"};function ve(e){return at[e]??null}var Y={critical:0,warning:1,info:2},Se={supabase:"https://supabase.com/dashboard/projects",vercel:"https://vercel.com/dashboard",stripe:"https://dashboard.stripe.com",github:"https://github.com/settings/profile",sentry:"https://sentry.io",posthog:"https://app.posthog.com",clerk:"https://dashboard.clerk.com",resend:"https://resend.com/emails",upstash:"https://console.upstash.com",neon:"https://console.neon.tech",railway:"https://railway.com/dashboard",render:"https://dashboard.render.com",cloudflare:"https://dash.cloudflare.com"},ot="sql|ts|tsx|js|jsx|mjs|cjs|json|toml|ya?ml|env|py|rb|go|rs|vue|svelte|astro|html|css|md|prisma|php|java|kt|sh|lock",lt=new RegExp(String.raw`((?:[\w.@-]+[\\/])*[\w.@-]+\.(?:${ot})):(\d{1,6})\b`,"g");function ct(e){if(!e)return[];let i=new Set;for(let n of e.matchAll(lt))i.add(`${n[1].split("\\").join("/")}:${n[2]}`);return[...i]}function dt(e){let i=(e??"").split(`
4
- `).map(a=>a.trim()).filter(Boolean),[n="",...s]=i;return{summary:n,evidence:s.filter(a=>a!=="Evidence:").map(a=>a.replace(/^-\s*/,""))}}function q(e){return ve(e.id)??e.logoUrl}function ut(e,i){let n=i?.provider?.nextFix;return n?.id===e.id&&n.prompt?n.prompt:[e.asksFirst?`${e.asksFirst} Tell the user this before you change anything, and make the change only if they confirm.`:"",`Fix this production blocker in the repo now: ${e.title}.`,e.detail??"",e.prompt?`How to fix it: ${e.prompt}`:"","Make the minimal change, then summarize what you changed and which files. Do not claim the app is production-ready; VibeRaven will check again."].filter(Boolean).join(`
5
- `)}function pt(e,i){let n=e.find(a=>a.provider?.nextFix?.id===i.id);if(n)return n;let s=`${i.title} ${i.detail??""}`.toLowerCase();return e.find(a=>s.includes(a.name.toLowerCase())||s.includes(`${a.id}/`))}function Ie(e){let[i,n]=[e.slice(0,e.lastIndexOf(":")),e.slice(e.lastIndexOf(":")+1)];return`${i.split("/").pop()??i}:${n}`}function gt(e){return!e.project.empty&&!!e.project.project?.scannedAt}function ht(e){return e.busy.scan||e.scan?.state==="running"}function S(e){let i=gt(e),n=ht(e),a=P(e.project,e.catalog,e.verified).filter(f=>f.step!=="absent"),c=i?e.project.missionCards?.blockers??[]:[],u=new Set((e.project.missionCards?.planSteps??[]).filter(f=>f.requiresUserAction).map(f=>f.id)),o=c.map(f=>{let b=pt(a,f),{summary:L,evidence:A}=dt(f.detail);return{id:f.id,title:f.title,severity:f.severity,summary:L,evidence:A,locations:ct(f.detail),service:b?{id:b.id,name:b.name,mark:q(b)}:null,dashboard:f.requiresUserAction===!0||u.has(f.id),prompt:ut(f,b)}}),p=new Map;for(let f of o){let b=f.service?.id??"app",L=p.get(b)??{key:b,name:f.service?.name??"Your code",mark:f.service?.mark??null,findings:[]};L.findings.push(f),p.set(b,L)}let r=f=>Math.min(...f.findings.map(b=>Y[b.severity])),l=[...p.values()].map(f=>({...f,findings:[...f.findings].sort((b,L)=>Y[b.severity]-Y[L.severity])})).sort((f,b)=>r(f)-r(b)||b.findings.length-f.findings.length),d=l.flatMap(f=>f.findings),h=d.filter(f=>!f.dashboard).sort((f,b)=>Y[f.severity]-Y[b.severity]),y={critical:0,warning:0,info:0};for(let f of o)y[f.severity]+=1;let g=a.map(f=>{let b=o.filter(_=>_.service?.id===f.id),L=b.filter(_=>_.severity==="critical").length,A=e.verified[f.id],N="pending",$="Unknown \xB7 not checked yet";return n?$="Checking":i&&(L?(N="fail",$=`Not ready \xB7 ${L} blocker${L===1?"":"s"}`):b.length?(N="warn",$=`${b.length} to review`):(N="pass",$=A?.ok?"Ready \xB7 checked live":"Ready \xB7 no blockers found")),{id:f.id,name:f.name,area:f.area,mark:q(f),tone:N,stateText:$,findings:b.length,verified:A}}),m=h.find(f=>f.id===e.flow.fixId)??null,M=[];for(let f of a){let b=e.verified[f.id];M.push({id:`live:${f.id}`,label:`Check ${f.name} live`,detail:b?b.ok?`Your agent checked the real ${f.name} project and it matched.`:`Your agent checked ${f.name} and found issues.`:`Your agent reads your real ${f.name} project and confirms it matches the code.`,kind:"live",done:b?.ok===!0,doneBy:"viberaven",providerId:f.id});let L=f.provider?.cockpit?.proof.checks.filter(A=>A.source==="dashboard"&&A.status!=="yes")??[];for(let A of L){let N=`dash:${f.id}:${A.label}`;M.push({id:N,label:A.label==="Production secret proof"?`Production keys for ${f.name} are set where you deploy`:`${f.name}: ${A.label}`,detail:A.label==="Production secret proof"?`The keys your app reads for ${f.name} go in your hosting provider's environment settings for production. VibeRaven cannot see your dashboards, so you tick this.`:`VibeRaven cannot see your ${f.name} dashboard, so you tick this.`,kind:"dashboard",done:e.flow.checklist[N]===!0,doneBy:"you",providerId:f.id,href:Se[f.id]})}}for(let f of d.filter(b=>b.dashboard))M.push({id:`finding:${f.id}`,label:f.title,detail:`${f.summary} This clears when the next check no longer finds it.`,kind:"finding",done:!1,doneBy:"viberaven",providerId:f.service?.id,href:f.service?Se[f.service.id]:void 0});let w=h.filter(f=>f.severity==="critical").length,D={app:!0,findings:i,fix:i&&h.length>0,recheck:i&&e.flow.recheck!==null,ready:i&&w===0};return{scanned:i,scanning:n,services:g,findings:o,groups:l,fixable:h,counts:y,current:m,checklist:M,gateClear:i&&e.project.gate?.status==="clear",available:D}}function ie(e){return e.scanned?e.findings.length===0||!e.available.fix?"ready":"findings":"app"}function Le(e,i){let n=i.flow.recheck,s=e.checklist.filter(a=>!a.done).length;return{app:e.scanning?"Checking now":e.services.length?`${e.services.length} service${e.services.length===1?"":"s"} found`:"No services found",findings:e.scanned?e.findings.length===0?"Nothing found":[e.counts.critical?`${e.counts.critical} critical`:null,`${e.findings.length} total`].filter(Boolean).join(" \xB7 "):"After the check",fix:e.scanned?e.fixable.length===0?"Nothing to fix in code":`${e.fixable.length} to fix`:"After the check",recheck:n?n.status==="running"?"Checking now":n.status==="fixed"?"Last fix held":n.status==="open"?"Still open":"Did not finish":"After a fix",ready:e.scanned?e.available.ready?e.gateClear?"No blockers found":s?`${s} step${s===1?"":"s"} left`:"Checklist done":"After the critical fixes":"After the check"}}var se=new Map,xe=()=>{};function re(e){return`vr-canvas:${e}`}function B(e){let i=se.get(e);if(i)return i;let n={pan:{x:0,y:0},zoom:1,cards:{}};try{let s=localStorage.getItem(re(e));if(s){let a=JSON.parse(s);n={pan:a.pan??n.pan,zoom:je(a.zoom??1),cards:a.cards??{}}}}catch{}return se.set(e,n),n}function Ce(e){try{localStorage.setItem(re(e),JSON.stringify(B(e)))}catch{}}function je(e){return Math.min(1.6,Math.max(.5,Math.round(e*100)/100))}function ft(e){return`translate(${e.pan.x}px, ${e.pan.y}px) scale(${e.zoom})`}function mt(e,i){let n=e.cards[i];return n?`translate(${n.x}px, ${n.y}px)`:void 0}function yt(e){return e.zoom!==1||e.pan.x!==0||e.pan.y!==0||Object.keys(e.cards).length>0}function K(e){return e.querySelector(".board")}function U(e){let i=K(e);if(!i)return;let n=B(i.dataset.layoutKey??"default");i.style.transform=ft(n);for(let s of Array.from(i.querySelectorAll("[data-card]")))s.style.transform=mt(n,s.dataset.card??"")??"";e.classList.toggle("is-moved",yt(n)),xe(i)}function X(e,i){let n=K(e);if(!n)return;let s=n.dataset.layoutKey??"default",a=B(s);a.zoom=je(a.zoom*i),U(e),Ce(s)}function Ne(e){let i=K(e);if(!i)return;let n=i.dataset.layoutKey??"default";se.set(n,{pan:{x:0,y:0},zoom:1,cards:{}}),U(e);try{localStorage.removeItem(re(n))}catch{}}var Ae=new WeakSet;function Te(e,i){if(xe=i,Ae.has(e)){U(e);return}Ae.add(e);let n=null,s=0;e.addEventListener("pointerdown",c=>{if(c.button!==0)return;let u=c.target;if(u.closest("button, a, input, select, textarea, pre, .canvas-tools, .pr-checks"))return;let o=K(e);if(!o)return;let p=o.dataset.layoutKey??"default",r=B(p),l=u.closest("[data-card]"),d=l?.dataset.card??"";n={kind:l?"card":"pan",id:d,key:p,startX:c.clientX,startY:c.clientY,origin:l?{...r.cards[d]??{x:0,y:0}}:{...r.pan},moved:!1,pointer:c.pointerId,target:l??e}}),e.addEventListener("pointermove",c=>{if(!n||c.pointerId!==n.pointer)return;let u=c.clientX-n.startX,o=c.clientY-n.startY;if(!n.moved){if(Math.hypot(u,o)<4)return;n.moved=!0,e.setPointerCapture?.(n.pointer),e.classList.add("is-dragging"),n.target.classList.add("is-lifted")}let p=B(n.key);n.kind==="pan"?p.pan={x:Math.round(n.origin.x+u),y:Math.round(n.origin.y+o)}:p.cards[n.id]={x:Math.round(n.origin.x+u/p.zoom),y:Math.round(n.origin.y+o/p.zoom)},s||(s=requestAnimationFrame(()=>{s=0,U(e)}))});let a=c=>{!n||c.pointerId!==n.pointer||(n.moved&&(e.releasePointerCapture?.(n.pointer),e.classList.remove("is-dragging"),n.target.classList.remove("is-lifted"),U(e),Ce(n.key)),n=null)};e.addEventListener("pointerup",a),e.addEventListener("pointercancel",a),e.addEventListener("wheel",c=>{!c.ctrlKey&&!c.metaKey||(c.preventDefault(),X(e,c.deltaY<0?1.1:1/1.1))},{passive:!1}),U(e)}var v={check:'<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>',arrow:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8h10M9 4l4 4-4 4"/></svg>',back:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 8H3M7 4L3 8l4 4"/></svg>',copy:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.6"/><path d="M10.5 5.5V3.6c0-.6-.5-1.1-1.1-1.1H3.6c-.6 0-1.1.5-1.1 1.1v5.8c0 .6.5 1.1 1.1 1.1h1.9"/></svg>',more:'<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>',out:'<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3H3v10h10v-3M9 3h4v4M13 3L7.5 8.5"/></svg>',scan:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 5V3.5C2 2.7 2.7 2 3.5 2H5M11 2h1.5c.8 0 1.5.7 1.5 1.5V5M14 11v1.5c0 .8-.7 1.5-1.5 1.5H11M5 14H3.5C2.7 14 2 13.3 2 12.5V11"/><circle cx="7.6" cy="7.6" r="2.4"/><path d="M9.4 9.4 11 11"/></svg>',fix:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.8 2.3a3.4 3.4 0 0 0-3.9 4.5L2.4 10.3a1.4 1.4 0 0 0 2 2l3.5-3.5a3.4 3.4 0 0 0 4.5-3.9l-2 2-1.8-.5-.5-1.8z"/></svg>',recheck:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.5 8a5.5 5.5 0 0 1-9.6 3.7M2.5 8a5.5 5.5 0 0 1 9.6-3.7"/><path d="M12.5 1.8v2.7H9.8M3.5 14.2v-2.7h2.7"/></svg>',launch:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 2.5v11M3 3h8.5l-1.8 2.8L11.5 8.6H3"/></svg>',pr:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="4" cy="3.5" r="1.6"/><circle cx="4" cy="12.5" r="1.6"/><circle cx="12" cy="12.5" r="1.6"/><path d="M4 5.1v5.8M12 10.9V6.5a2 2 0 0 0-2-2H7.5M9 3 7.5 4.5 9 6"/></svg>',zoomIn:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="M8 3.5v9M3.5 8h9"/></svg>',zoomOut:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="M3.5 8h9"/></svg>',reset:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.5 6V2.5H6M13.5 10v3.5H10M2.5 2.5l4 4M13.5 13.5l-4-4"/></svg>',app:'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="1.8" y="2.5" width="12.4" height="11" rx="2"/><path d="M1.8 5.5h12.4M6 8.4 4.6 9.8 6 11.2M10 8.4l1.4 1.4-1.4 1.4"/></svg>'},Mt={critical:"Critical",warning:"Important",info:"Nice to have"};function O(e){return t("span",{class:"ico",html:e})}function Q(e){return(e||"Project").replace(/^@[^/]+\//,"").split(/[-_\s]+/).filter(Boolean).map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join(" ")}function F(e){let i=e.project.project;return(i?.name&&i.name!=="Project"?i.name:(i?.path??"").split(/[\\/]/).filter(Boolean).pop())||"your-app"}function J(e,i=e.cliId){return e.agents.find(n=>n.id===i)?.label.replace(/ CLI$/,"")??(i==="claude"?"Claude Code":i==="gemini"?"Gemini":"Codex")}function Ee(e,i){let n=e.project.project,s=e.project.releases?.[0],a=ze(e,S(e));return t("header",{class:"top",dataset:{slot:"top"}},t("span",{class:"wordmark"},"Vibe",t("b",{},"Raven")),t("span",{class:"top-project"},t("span",{class:"top-sep","aria-hidden":"true"},"/"),t("strong",{},Q(F(e))),t("span",{class:"top-sep","aria-hidden":"true"},"/"),t("code",{},[s?.branch,n?.version?`v${n.version.replace(/^v/,"")}`:null].filter(Boolean).join(" \xB7 ")||"local")),t("span",{class:"spacer"}),bt(e,i),t("span",{class:`top-verdict is-${a.tone}`},t("i",{"aria-hidden":"true"}),a.text),t("div",{class:"more-wrap"},t("button",{id:"open-more",class:`quiet more-button${e.moreOpen?" on":""}`,"aria-haspopup":"menu","aria-expanded":String(e.moreOpen),"aria-controls":"more-menu",on:{click:()=>i.toggleMore()}},"More",O(v.more)),e.moreOpen?kt(e,i):null))}function bt(e,i){let n=S(e),s=e.flow.step,a=(c,u,o,p,r={})=>t("button",{id:c,class:"top-tab","aria-current":o?"page":void 0,disabled:r.disabled,on:{click:p}},u,r.count?t("span",{class:"top-tab-count"},String(r.count)):null);return t("nav",{class:"top-tabs","aria-label":"Views"},a("tab-stack","Stack",s==="app"&&!e.drawer,()=>{e.drawer&&i.toggleDrawer(null),i.goToStep("app")}),a("tab-findings","Findings",s==="findings"&&!e.drawer,()=>{e.drawer&&i.toggleDrawer(null),i.goToStep("findings")},{disabled:!n.available.findings,count:n.findings.length}),a("tab-terminal","Terminal",e.drawer==="terminal",()=>i.openMore("terminal")),a("tab-releases","Releases",e.drawer==="releases",()=>i.openMore("releases")))}function kt(e,i){let n=e.agents.filter(a=>e.probes[a.id]?.ready).length,s=[{id:"services",label:"Services",note:"Browse, add and check services live"},{id:"terminal",label:"Coding agents",note:n?`${n} connected`:"Install, sign in, test"},{id:"chat",label:"Agent chat",note:"Ask your agent anything about this app"},{id:"releases",label:"Releases",note:(e.project.releases??[]).length?"History and diffs":"Compare any two commits"}];return t("div",{id:"more-menu",class:"more-menu",role:"menu","aria-label":"More",on:{keydown:a=>{let c=a.key;if(c!=="ArrowDown"&&c!=="ArrowUp")return;a.preventDefault();let u=Array.from(a.currentTarget.querySelectorAll('[role="menuitem"]')),o=u.indexOf(document.activeElement);u[(o+(c==="ArrowDown"?1:-1)+u.length)%u.length]?.focus()}}},...s.map(a=>t("button",{role:"menuitem",class:"more-item",on:{click:()=>i.openMore(a.id)}},t("strong",{},a.label),t("span",{},a.note))))}function Oe(e,i,n){let s=Le(i,e),a=e.flow.step,c=i.scanning||e.setup.running,u=()=>{a==="fix"&&i.current?n.checkAgain():i.available.recheck?n.goToStep("recheck"):n.checkMyApp()},o=[{key:"scan",id:"check-my-app",label:i.scanning?"Scanning":"Scan",svg:v.scan,meta:s.app,current:a==="app",disabled:c,passed:i.scanned,onClick:()=>void n.checkMyApp()},{key:"fix",label:"Fix",svg:v.fix,meta:s.fix,current:a==="fix",disabled:!i.available.fix||c,passed:!1,onClick:()=>n.goToStep("fix")},{key:"recheck",label:"Re-check",svg:v.recheck,meta:s.recheck,current:a==="recheck",disabled:!i.scanned||c,passed:e.flow.recheck?.status==="fixed",onClick:u},{key:"ready",label:"Launch",svg:v.launch,meta:s.ready,current:a==="ready",disabled:!i.available.ready,passed:!1,onClick:()=>n.goToStep("ready")}];return t("nav",{class:`rail${i.scanning?" is-scanning":""}`,"aria-label":"Launch path",dataset:{slot:"rail"}},t("ol",{},...o.map(p=>t("li",{class:`rail-step is-${p.current?"current":p.disabled?"locked":p.passed?"passed":"open"}`},t("button",{id:p.id,class:"rail-button",title:p.meta,"aria-current":p.current?"step":void 0,disabled:p.disabled,on:{click:p.onClick}},t("span",{class:"rail-mark","aria-hidden":"true",html:p.svg}),t("span",{class:"rail-copy"},t("span",{class:"rail-label"},p.label),t("span",{class:"rail-meta"},p.meta)),p.key==="scan"&&i.scanning?t("i",{class:"rail-time","aria-hidden":"true"}):null)))))}function ze(e,i){if(i.scanning)return{text:"Checking your app",tone:"pending"};if(!i.scanned)return{text:"Not checked yet",tone:"pending"};if(i.counts.critical)return{text:`${i.counts.critical} blocker${i.counts.critical===1?"":"s"}`,tone:"fail"};if(i.findings.length)return{text:`${i.findings.length} to review`,tone:"warn"};let n=i.checklist.filter(a=>!a.done).length,s=n?` \xB7 ${n} unknown${n===1?"":"s"}`:"";return{text:i.gateClear?`No blockers found${s}`:"No blockers in the code",tone:"pass"}}var wt={pending:"Unknown",pass:"Ready",warn:"Review",fail:"Not ready"};function vt(e){let i=e.stateText.replace(/^(Not ready|Ready|Unknown)\s*·\s*/,"")||e.stateText;return i.charAt(0).toUpperCase()+i.slice(1)}function De(e,i=null){return t("li",{class:`node is-${e.tone}${e.id===i?" is-focus":""}`,dataset:{provider:e.id,card:e.id}},t("span",{class:"node-head"},e.mark?t("img",{src:e.mark,alt:"",width:18,height:18}):t("span",{class:"node-fallback"},e.name.slice(0,1)),t("span",{class:"node-name"},e.name)),e.area?t("code",{class:"node-detail"},e.area.toLowerCase()):null,t("span",{class:"node-state"},t("i",{"aria-hidden":"true"}),t("span",{class:"node-text"},vt(e)),t("span",{class:"node-verdict"},wt[e.tone])))}function St(){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.setAttribute("class","board-lines"),e.setAttribute("aria-hidden","true"),e}function It(e,i){let n=e.project.project,s=ze(e,i),a=i.services.length<=3,c=a?[]:i.services.filter((l,d)=>d%2===0),u=a?i.services:i.services.filter((l,d)=>d%2===1),o=i.scanned?[n?.archetype&&n.archetype!=="unknown"?n.archetype:null,n?.scannedAt?`Checked ${E(n.scannedAt)}`:null,typeof e.project.gate?.score=="number"?`Readiness ${e.project.gate.score} of 100`:null].filter(l=>!!l):[],p=e.flow.step==="app"?null:e.flow.step==="fix"?i.current?.service?.id??null:e.contextProviderId,r=JSON.stringify([i.services.map(l=>[l.id,l.tone,l.stateText]),s,o,i.scanning,p]);return t("figure",{class:`board${i.scanning?" is-scanning":""}${i.services.length?a?" is-side":"":" is-solo"}`,dataset:{sig:r,lines:i.services.length?"1":"",layoutKey:e.project.project?.path||F(e)},"aria-label":`${Q(F(e))} and the services found in its code`},St(),c.length?t("ul",{class:"board-col left"},...c.map(l=>De(l,p))):null,t("div",{class:`board-app is-${s.tone}`,dataset:{card:"app"}},t("span",{class:"node-head"},O(v.app),t("span",{class:"node-name"},Q(F(e)))),t("code",{class:"board-app-name"},[F(e),e.project.releases?.[0]?.branch].filter(Boolean).join(" \xB7 ")),t("p",{class:"board-status"},t("strong",{},s.text)),o.length?t("ul",{class:"board-checks"},...o.map(l=>t("li",{},t("i",{"aria-hidden":"true"}),l))):null),u.length?t("ul",{class:"board-col right"},...u.map(l=>De(l,p))):null)}function le(e){let i=e.querySelector(".board-lines"),n=e.querySelector(".board-app");if(!i||!n)return;let s=e.getBoundingClientRect(),a=e.offsetWidth,c=e.offsetHeight;if(!s.width||!a)return;let u=s.width/a;if(i.setAttribute("viewBox",`0 0 ${Math.round(a)} ${Math.round(c)}`),i.setAttribute("width",String(Math.round(a))),i.setAttribute("height",String(Math.round(c))),getComputedStyle(i).display==="none"){i.innerHTML="";return}let o=n.getBoundingClientRect(),p=o.left+o.width/2,r=Array.from(e.querySelectorAll(".node")),l=y=>(y-s.left)/u,d=y=>(y-s.top)/u,h=r.map((y,g)=>{let m=y.getBoundingClientRect(),M=m.left+m.width/2<p,w=l(M?o.left:o.right),D=d(o.top+o.height/2)+(g%4-1.5)*Math.min(22,o.height/u/7),f=l(M?m.right:m.left),b=d(m.top+m.height/2),L=(w+f)/2,A=/is-(pass|warn|fail|pending)/.exec(y.className)?.[1]??"pending",N=`M ${w.toFixed(1)} ${D.toFixed(1)} C ${L.toFixed(1)} ${D.toFixed(1)} ${L.toFixed(1)} ${b.toFixed(1)} ${f.toFixed(1)} ${b.toFixed(1)}`;return`<path class="line is-${A}" d="${N}"/><path class="pulse" pathLength="1" style="animation-delay:${(g*.6).toFixed(2)}s" d="${N}"/>`});i.innerHTML=h.join("")}function j(e,i){let n=[t("h1",{id:"stage-heading",tabindex:-1},e)];return i&&n.push(t("p",{class:"stage-sub"},i)),n}function I(e,i,n={}){return t("div",{class:"primary-row"},t("button",{id:n.id??"primary-action",class:"primary",disabled:n.disabled,on:{click:i}},n.busy?t("span",{class:"spin","aria-hidden":"true"}):null,e,n.busy?null:O(v.arrow)),n.note?t("span",{class:"primary-note"},n.note):null)}function ae(e,i,n={}){return t("button",{class:"quiet",disabled:n.disabled,on:{click:i}},n.icon?O(n.icon):null,e)}function Pe(e){return t("span",{class:`sev is-${e.severity}`},t("i",{"aria-hidden":"true"}),Mt[e.severity])}function Ue(e,i=!1){if(!e.locations.length)return null;let[n,...s]=e.locations;return t("span",{class:"where"},t("code",{title:e.locations.join(`
6
- `)},i?n:Ie(n)),s.length?t("span",{class:"where-more"},`+${s.length} more`):null)}function Lt(e,i){let n=e.project.project,s=i.services.length,a=i.scanning?"Reading your code and the services it uses. Nothing leaves this computer.":s?`${s} service${s===1?"":"s"} found in this code.`:"No hosted services found in this code yet.",c=i.scanning?"Checking on this computer, offline.":i.scanned?`Last check ${E(n.scannedAt)} \xB7 runs on this computer, offline`:"Press Scan to check your app. It runs on this computer, offline.";return[t("h1",{id:"stage-heading",tabindex:-1,class:"sr-only"},Q(F(e))),t("p",{class:"sr-only"},a),t("p",{class:"canvas-note",role:"status"},c)]}function At(e,i,n){let s=i.fixable[0],a=e.project.project?.scannedAt;if(!i.findings.length)return[...j("Nothing to fix",`The check ${a?E(a):""} found no blockers in this code.`),I("Go to the launch checklist",()=>n.goToStep("ready"))];let c=[i.counts.critical?`${i.counts.critical} critical`:null,i.counts.warning?`${i.counts.warning} important`:null,i.counts.info?`${i.counts.info} nice to have`:null].filter(Boolean).join(", ");return[...j(`${i.findings.length} finding${i.findings.length===1?"":"s"}`,`${c}. Critical first, grouped by service. From the check ${a?E(a):""}.`),t("div",{class:"findings"},...i.groups.map(u=>t("section",{class:"group","aria-label":u.name},t("header",{class:"group-head"},u.mark?t("img",{src:u.mark,alt:"",width:22,height:22}):t("span",{class:"group-code","aria-hidden":"true"},"</>"),t("h2",{},u.name),t("span",{class:"group-count"},String(u.findings.length))),t("ul",{},...u.findings.map(o=>{let p=o.id===s?.id,r=[Pe(o),t("span",{class:"finding-title"},o.title),o.dashboard?t("span",{class:"finding-tag"},"Dashboard step"):Ue(o)];return t("li",{},o.dashboard?t("div",{class:`finding is-${o.severity} is-static`,dataset:{provider:o.service?.id??""}},...r):t("button",{class:`finding is-${o.severity}${p?" is-first":""}`,dataset:{provider:o.service?.id??""},on:{click:()=>n.fixFinding(o.id)}},...r,O(v.arrow)))}))))),s?I("Fix the first blocker",()=>n.fixFinding(),{id:"fix-first",note:s.title}):I("Go to the launch checklist",()=>n.goToStep("ready"),{note:"What is left needs your dashboards, not your code."})]}function xt(e,i,n){let s=e.agents.filter(a=>a.installed);return s.length?t("div",{class:"agent-choice",role:"radiogroup","aria-label":"Coding agent"},...s.map(a=>{let c=e.probes[a.id],u=a.id===e.cliId;return t("button",{role:"radio","aria-checked":String(u),class:`agent-option${u?" on":""}`,disabled:n,on:{click:()=>i.selectCli(a.id)}},t("i",{class:c?.ready?"ok":c?"no":"","aria-hidden":"true"}),a.label.replace(/ CLI$/,""))})):null}function Ct(e,i,n){let s=i.current;if(!s)return[...j("Nothing to fix in code","Every finding left needs a dashboard, not the repo."),I("Go to the launch checklist",()=>n.goToStep("ready"))];let a=i.fixable.findIndex(h=>h.id===s.id),c=e.flow.handoff?.findingId===s.id?e.flow.handoff:null,u=J(e),o=e.probes[e.cliId],p=e.agents.filter(h=>h.installed),r=c?.status==="running",l=e.busy.probe===e.cliId,d;return r?d=I(`${u} is working`,()=>{},{disabled:!0,busy:!0,note:"It edits files in this repo. You review the change."}):c?.status==="done"?d=I("Check again",()=>void n.checkAgain(),{id:"check-again",note:"Runs the same local check to see if the fix held."}):p.length?o?.ready?d=I(c?.status==="failed"?`Send to ${u} again`:`Send to ${u}`,()=>void n.sendFix(),{id:"send-fix",note:e.accessMode==="ask"?"Ask mode is on: the agent will only plan, not edit. Change it in More, Agent chat.":`${u} edits files in this repo. You review the change.`}):d=I(l?`Connecting ${u}`:`Connect ${u}`,()=>void n.testConnection(e.cliId),{disabled:l,busy:l,note:o?o.message:`VibeRaven runs ${u} on this computer with your own sign-in.`}):d=I("Copy the prompt",()=>void n.copyFix(),{note:"No coding agent found on this computer. Paste it into any agent."}),[...j(s.title),t("div",{class:"fix-meta"},Pe(s),t("span",{class:"fix-count"},`Blocker ${a+1} of ${i.fixable.length}${s.service?` \xB7 ${s.service.name}`:""}`),Ue(s,!0)),s.summary?t("p",{class:"fix-summary"},s.summary):null,s.evidence.length?t("ul",{class:"fix-evidence"},...s.evidence.slice(0,4).map(h=>t("li",{},h))):null,t("section",{class:"prompt","aria-label":"Prompt for your agent"},t("header",{},t("h2",{},"Prompt for your agent"),ae("Copy",()=>void n.copyFix(),{icon:v.copy})),t("pre",{tabindex:0},s.prompt)),xt(e,n,r||e.busy.chat),r?t("p",{class:"working-line",role:"status"},t("span",{dataset:{working:"1"}},`${u} is working\u2026`),t("button",{class:"quiet stop",on:{click:()=>void n.stop()}},"Stop")):null,c&&c.status!=="running"?t("section",{class:`agent-reply is-${c.status}`,"aria-label":`${J(e,c.cliId)} replied`},t("h2",{},c.status==="done"?`${J(e,c.cliId)} replied`:`${J(e,c.cliId)} did not finish`),t("div",{class:"agent-reply-body",html:Z(c.output)})):null,d,t("div",{class:"quiet-row"},ae("Back to findings",()=>n.goToStep("findings"),{icon:v.back}),c?.status!=="done"?ae("Fixed it yourself? Check again",()=>void n.checkAgain(),{disabled:r||i.scanning}):null)].filter(h=>h!==null)}function jt(e,i,n){let s=e.flow.recheck;if(!s)return[...j("Nothing to check yet","Fix a blocker first, then check again here."),I("Back to findings",()=>n.goToStep("findings"))];let a=typeof s.scoreBefore=="number"&&typeof s.scoreAfter=="number"&&s.scoreBefore!==s.scoreAfter?t("p",{class:"score-move"},`Readiness ${s.scoreBefore} \u2192 ${s.scoreAfter}`):null;if(s.status==="running")return[...j("Checking again",`Running the same local check to see if \u201C${s.title}\u201D is gone.`),t("div",{class:"recheck-meter",role:"status"},t("span",{class:"spin"}),"Reading the repo"),I("Checking",()=>{},{disabled:!0,busy:!0})];if(s.status==="fixed"){let c=i.fixable.find(u=>u.id===s.nextId);return[...j("Scenario passed locally",`\u201C${s.title}\u201D no longer shows up in the check.`),a,t("p",{class:"recheck-next",role:"status"},c?`Next: ${c.title}`:"That was the last blocker in the code."),c?I("Next blocker",()=>n.fixFinding(c.id),{note:"Moving on by itself in a moment."}):I("Go to the launch checklist",()=>n.goToStep("ready"),{note:"Moving on by itself in a moment."})].filter(u=>u!==null)}return s.status==="open"?[...j("Still open",`The check still finds \u201C${s.title}\u201D.`),s.message?t("p",{class:"fix-summary"},s.message):null,a,I("Back to the fix",()=>n.fixFinding(s.findingId))].filter(c=>c!==null):[...j("The check did not finish",s.message??""),I("Check again",()=>void n.checkAgain())]}function Nt(e,i,n){if(!i.checklist.length)return t("section",{class:"checklist","aria-label":"Launch checklist"},t("h2",{},"Launch checklist"),t("p",{class:"empty-line"},"No dashboard steps found for this app: VibeRaven found no hosted services in the code."));let s=i.checklist.filter(a=>!a.done).length;return t("section",{class:"checklist","aria-label":"Launch checklist"},t("h2",{},"Launch checklist",t("span",{class:"checklist-count"},s?`${s} left`:"All done")),t("ul",{},...i.checklist.map(a=>t("li",{class:`check-item${a.done?" is-done":""}`},a.doneBy==="you"?t("button",{class:"tick",role:"checkbox","aria-checked":String(a.done),"aria-label":a.label,on:{click:()=>n.toggleChecklistItem(a.id)},html:a.done?v.check:""}):t("span",{class:`tick is-auto${a.done?" on":""}`,"aria-hidden":"true",html:a.done?v.check:""}),t("div",{class:"check-copy"},t("strong",{},a.label),t("span",{},a.detail),t("span",{class:"check-who"},a.doneBy==="you"?"You confirm this":a.kind==="live"?"VibeRaven confirms this with your agent":"VibeRaven confirms this on the next check")),a.kind==="live"&&!a.done&&a.providerId?t("button",{class:"quiet",disabled:e.busy.chat||!e.probes[e.cliId]?.ready,title:e.probes[e.cliId]?.ready?void 0:"Connect a coding agent first",on:{click:()=>void n.verifyById(a.providerId)}},"Check live"):a.href?t("a",{class:"quiet",href:a.href,target:"_blank",rel:"noreferrer"},"Open dashboard",O(v.out)):null))))}function Tt(e,i){let n=e.fullCheck.status,s=z(n?.usage),a=n?.account?n.account.plan==="pro"?"Pro plan":"Free plan":null;return t("section",{class:"final","aria-label":"Full check"},t("h2",{},"Final confirmation"),t("p",{},"The full check runs on VibeRaven across every production area. You see exactly what gets sent before anything leaves this computer."),t("p",{class:"final-quota"},[a,s??"Free accounts get 2 full checks. Pro gets 50 a month."].filter(Boolean).join(" \xB7 ")),t("button",{id:"run-full-check",class:"primary",disabled:e.fullCheck.step==="running",on:{click:()=>void i.openFullCheck()}},"Run full check",O(v.arrow)))}function Dt(e,i,n){if(!i.available.ready)return[...j("Not yet","Fix the critical blockers first. The launch checklist opens when none are left."),I("Back to findings",()=>n.goToStep("findings"))];let s=i.findings.filter(o=>!o.dashboard).length,a=i.gateClear?"No blockers found within tested scope":"No critical blockers left",c=i.checklist.filter(o=>!o.done).length,u=i.gateClear?c?`${c} unknown${c===1?"":"s"}: the checklist items below, which VibeRaven cannot test from this computer.`:"Every item on the checklist is confirmed.":`The code has no critical blockers.${s?` ${s} other finding${s===1?" is":"s are"} still open in Findings.`:""} What is left lives in your dashboards.`;return[...j(a,u),i.services.length?t("ul",{class:"strip","aria-label":"Services"},...i.services.map(o=>t("li",{class:`strip-item is-${o.tone}`},o.mark?t("img",{src:o.mark,alt:"",width:20,height:20}):null,o.name))):null,t("div",{class:"ready-grid"},Nt(e,i,n),Tt(e,n))].filter(o=>o!==null)}function Et(e,i){let n=e.prChecks;if(!n.status)return null;let s=n.status.exists,a=`git add ${n.status.path} && git commit -m "Check pull requests with VibeRaven"`,c=null;if(n.open){let u=n.written?[t("h3",{},"Workflow added"),t("p",{},"Commit and push it. From the next pull request on, VibeRaven comments with what the change added and what it fixed."),t("pre",{class:"pr-command",tabindex:0},a),n.status.onGithub?null:t("p",{class:"pr-muted"},"This repository has no GitHub remote yet. The check runs once it is on GitHub."),t("div",{class:"pr-actions"},t("button",{id:"pr-checks-copy",class:"btn sm primary",on:{click:()=>void i.copyPrCommit()}},"Copy command"),t("button",{class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Done"))]:s?[t("h3",{},"Pull request checks are set up"),t("p",{},`The workflow is in ${n.status.path}. Once it is pushed, each pull request gets one comment with what it added and fixed.`),t("div",{class:"pr-actions"},t("button",{id:"pr-checks-action",class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Close"))]:[t("h3",{},"Check every pull request"),t("p",{},"VibeRaven adds one file to this repo, ",t("code",{},n.status.path),". Each pull request then gets one comment: what the change added and what it fixed."),t("ul",{class:"pr-points"},t("li",{},"Runs in your own GitHub Actions: private repos work and the code is never uploaded."),t("li",{},"Advice by default. It only blocks a merge if you turn that on.")),n.error?t("p",{class:"pr-error",role:"alert"},n.error):null,t("div",{class:"pr-actions"},t("button",{id:"pr-checks-action",class:"btn sm primary",disabled:n.busy,on:{click:()=>void i.addPrChecks()}},n.busy?"Adding\u2026":"Add the workflow"),t("button",{class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Not now"))];c=t("div",{id:"pr-checks-card",class:"pr-card",role:"dialog","aria-labelledby":"pr-checks-button"},...u)}return t("div",{class:"pr-checks"},t("button",{id:"pr-checks-button",class:`pr-checks-button${s?" is-on":""}`,"aria-expanded":String(n.open),"aria-controls":"pr-checks-card",on:{click:()=>i.togglePrChecks()}},O(v.pr),s?"Pull request checks added":"Check every pull request"),c)}function Ot(){let e=n=>n.currentTarget.closest(".canvas"),i=(n,s,a,c="")=>t("button",{class:`canvas-tool${c}`,title:n,"aria-label":n,html:s,on:{click:u=>{let o=e(u);o&&a(o)}}});return t("div",{class:"canvas-tools",dataset:{sig:"tools"}},i("Zoom in",v.zoomIn,n=>X(n,1.15)),i("Zoom out",v.zoomOut,n=>X(n,1/1.15)),i("Reset layout",v.reset,n=>Ne(n)," is-reset"))}var oe=null;function Fe(e,i){let n=S(e),s=e.flow.step,a=oe!==null&&oe!==s;oe=s;let c=s==="app"?Lt(e,n):s==="findings"?At(e,n,i):s==="fix"?Ct(e,n,i):s==="recheck"?jt(e,n,i):Dt(e,n,i),u=s!=="app";return t("main",{class:`stage${u?" has-panel":""}`,dataset:{slot:"stage",step:s}},e.scan?.state==="error"?t("p",{class:"stage-alert",role:"alert"},e.scan.error??"The first check did not finish."):null,t("div",{class:"canvas",dataset:{slot:"canvas"}},It(e,n),Ot(),Et(e,i)),t("div",{class:`stage-body step-${s}${u?" panel":""}${a?" arrive":""}`,dataset:{slot:`body-${s}`}},u?t("button",{class:"panel-close quiet",on:{click:()=>i.goToStep("app")}},O(v.back),"Stack"):null,...c))}function $e(e){return S(e)}function Re(e,i){let n=Array.from(e.children);i.forEach((s,a)=>{let c=n[a];if(!c){e.appendChild(s);return}let u=s.dataset?.sig;if(u&&c.dataset?.sig===u&&c.tagName===s.tagName)return;let o=s.dataset?.slot;if(o&&c.dataset?.slot===o&&c.tagName===s.tagName){for(let p of Array.from(c.attributes))s.hasAttribute(p.name)||c.removeAttribute(p.name);for(let p of Array.from(s.attributes))c.getAttribute(p.name)!==p.value&&c.setAttribute(p.name,p.value);Re(c,Array.from(s.children));return}e.replaceChild(s,c)});for(let s of Array.from(e.children).slice(i.length))s.remove()}var ce=new WeakMap;function zt(e){for(let i of Array.from(e.querySelectorAll(".canvas")))Te(i,le);for(let i of Array.from(e.querySelectorAll('.board[data-lines="1"]'))){if(ce.has(i))continue;let n=()=>le(i);if(requestAnimationFrame(n),typeof ResizeObserver<"u"){let s=new ResizeObserver(n);s.observe(i),ce.set(i,s)}else ce.set(i,{disconnect(){}})}}function He(e,i,n){let s=i.get(),a=e.contains(document.activeElement)?document.activeElement:null,c=a?.id,u=a instanceof HTMLTextAreaElement||a instanceof HTMLInputElement?[a.selectionStart,a.selectionEnd]:null,o=$e(s);if(Re(e,[Ee(s,n),Oe(s,o,n),Fe(s,n),...s.agentOpen?[t("div",{class:"sheet-veil",on:{click:()=>n.toggleAgent()}}),$t(s,i,n)]:[],...s.drawer?[t("div",{class:"drawer-veil",on:{click:()=>n.toggleDrawer(null)}}),Ht(s,i,n)]:[],...ye(s,n),Zt(s)]),zt(e),c&&document.activeElement?.id!==c){let p=document.getElementById(c);p?.focus({preventScroll:!0}),u&&(p instanceof HTMLTextAreaElement||p instanceof HTMLInputElement)&&p.setSelectionRange(...u)}}function Pt(e,i,n){let s=P(e.project,e.catalog,e.verified),a=s.filter(o=>o.step!=="absent"),c=s.filter(o=>o.step==="absent"),u=e.setup.running||e.busy.chat||e.busy.scan;return t("div",{},e.setup.open?we(e,i,n):null,t("section",{class:"block","aria-label":"In your app"},t("div",{class:"block-head"},t("h4",{},"In your app"),t("button",{id:"connect-my-app",class:"btn sm",disabled:u,on:{click:()=>n.openStackSetup()}},"Set up with your agent")),a.length?t("div",{class:"rail-grid"},...a.map(o=>Ft(o,e,n))):t("p",{class:"drawer-empty"},"No services found in this code yet.")),c.length?t("section",{class:"block","aria-label":"Available services"},t("div",{class:"block-head"},t("h4",{},"Available"),t("span",{class:"block-meta"},"Your accounts, your choice of providers")),t("div",{class:"rail-grid"},...c.map(o=>t("article",{class:"slab available"},t("div",{class:"face"},t("div",{class:"face-logo"},t("img",{src:q(o),alt:"",loading:"lazy"})),t("h3",{class:"face-name"},o.name),t("div",{class:"face-area"},o.area)),t("div",{class:"slab-act"},t("button",{class:"btn library-add",disabled:u,"aria-label":`Add ${o.name} to setup`,on:{click:()=>{n.openStackSetup(),i.get().setup.selected.includes(o.id)||n.toggleSetupProvider(o.id),document.getElementById("stack-setup-heading")?.focus()}}},"+ Add to setup")))))):null)}function Ut(e){return e.step==="ready"?{text:`Agent reported checks passed ${e.verified?E(e.verified.at):""}.`,tone:"g"}:e.step==="verified"?{text:e.verified?.ok?`Agent check ${e.verified?E(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 Ft(e,i,n){let s=i.busy.tile===e.id,a=s||i.setup.running||i.busy.chat,c=Ut(e),u=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"),o=e.step==="in_repo"&&e.hasRecipe?t("button",{class:"btn primary",disabled:a,on:{click:()=>n.connect(e)}},s?t("span",{class:"spin"}):null,s?"Configuring\u2026":"Configure agent"):e.step==="in_repo"?t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},"Check with agent"):e.step==="mcp"?t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},s?t("span",{class:"spin"}):null,s?"Checking\u2026":"Check live"):t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},s?t("span",{class:"spin"}):null,s?"Checking\u2026":"Check again"),p=Qt(e.logoUrl)??"#9a9a9a";return t("article",{class:`slab${e.step==="ready"?" ready":""}${s?" scanning":""}`,dataset:{provider:e.id},style:{"--brand":p}},t("div",{class:"face"},t("div",{class:"face-top"},u),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 ${c.tone}`},t("i",{class:c.tone}),t("span",{class:"txt"},c.text),e.fixes>0?t("button",{class:"fixlink",on:{click:()=>n.focusBlockers(e.id)}},`${e.fixes} to fix`):null),t("div",{class:"slab-act"},o))}function ue(e){return e.agents.find(i=>i.id===e.cliId)?.label.replace(/ CLI$/,"")??e.cliId}function $t(e,i,n){let s=e.agents.find(d=>d.id===e.cliId),a=e.probes[e.cliId],c=a?.ready===!0,u=s?.modelOptions??(s?.models??[]).map(d=>({id:d,label:d})),o=t("div",{class:"thread"},e.messages.length?e.messages.map(d=>Rt(d,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(d=>t("button",{class:"suggest-chip",disabled:!c||e.busy.chat||e.setup.running,on:{click:()=>n.send(d)}},d)))),e.busy.chat?t("div",{class:"working"},t("span",{class:"spin"}),t("span",{dataset:{working:"1"}},`${ue(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(()=>{o.scrollTop=o.scrollHeight});let p=e.contextProviderId?P(e.project,e.catalog,e.verified).find(d=>d.id===e.contextProviderId):null,r=t("textarea",{id:"agent-composer",placeholder:c?"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:d=>{i.get().draft=d.target.value},keydown:d=>{let h=d;h.key==="Enter"&&!h.shiftKey&&(h.preventDefault(),n.send(h.target.value))}}}),l=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(d=>{let h=e.probes[d.id],y=h?.ready?"g":d.installed?"a":"";return t("button",{class:d.id===e.cliId?"on":"",disabled:e.setup.running||e.busy.chat,title:d.installed?h?.ready?"Connected":"Installed, not tested yet":"Not installed",on:{click:()=>n.selectCli(d.id)}},t("i",{class:y}),d.label.replace(/ CLI$/,"").replace("Claude Code","Claude"))}))),t("div",{class:"side-head tools"},u.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:d=>i.set({modelId:d.target.value})}},t("option",{value:"",selected:!e.modelId},"Use agent default"),e.modelId&&!u.some(d=>d.id===e.modelId)?t("option",{value:e.modelId,selected:!0},`${e.modelId} (saved selection)`):null,...u.map(d=>t("option",{value:d.id,selected:d.id===e.modelId},d.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"},l?t("span",{class:"pill"},t("span",{class:"spin"}),"Checking connection\u2026"):c?t("span",{class:"pill green",title:a?.message},t("i"),`${ue(e).replace("Claude Code","Claude")} connected`):s&&!s.installed?t("span",{class:"pill amber",title:`${s.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:l||e.busy.chat||e.setup.running,on:{click:()=>n.testConnection(e.cliId)}},c?"Test again":"Test connection"))),o,a&&!a.ready?t("div",{class:"hint"},t("b",{},a.message)," ",t("button",{class:"btn sm",on:{click:()=>n.toggleDrawer("terminal")}},"Open terminal")):null,t("div",{class:"composer"},r,t("div",{class:"row"},p?t("span",{class:"chip"},p.logoUrl?t("img",{src:p.logoUrl,alt:""}):null,p.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:d=>n.setAccessMode(d.target.value)}},...["ask","approve","full"].map(d=>t("option",{value:d,selected:d===e.accessMode},d==="ask"?"Ask \xB7 plan only":d==="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:!c||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 Ye(e,i,n=Date.now()){if(!i)return;let s=Math.max(0,Math.floor((n-i)/1e3)),a=e.querySelector("[data-working]");a&&(a.textContent=`${a.textContent?.split(" \xB7")[0]??"Working\u2026"} \xB7 ${s}s`);let c=e.querySelector("[data-slow-run]");c&&(c.hidden=s<60)}function Rt(e,i,n){let s=e.role==="me"?"You":e.role==="agent"?i.agents.find(c=>c.id===e.cliId)?.label.replace(/ CLI$/,"").replace("Claude Code","Claude")??"Agent":e.role==="error"?"Something went wrong":"VibeRaven",a=e.card?t("div",{class:"card"},t("span",{},e.card.providerId?t("img",{src:P(i.project,i.catalog,i.verified).find(c=>c.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"},s,t("span",{class:"t"},E(e.at))),t("div",{class:"body",html:e.role==="me"?`<p>${G(e.text)}</p>`:Z(e.text)}),a)}function Ht(e,i,n){let s=e.drawer==="terminal"?Yt(e,n):e.drawer==="services"?Pt(e,i,n):Bt(e,i,n),a=e.drawer==="terminal"?"Coding agents":e.drawer==="services"?"Services":"Releases",c=e.drawer==="terminal"?"VibeRaven drives the agent CLI installed on this computer. Installed is not connected: test each one.":e.drawer==="services"?"What your app runs on, and what you could add. Check a service live through your agent.":"Release points in this repository, and the real diff between any two of them.";return t("div",{class:"drawer",dataset:{drawer:e.drawer??""},role:"dialog","aria-modal":"true","aria-labelledby":"drawer-heading",on:{keydown:u=>{let o=u;if(o.key==="Escape"&&(o.preventDefault(),o.stopPropagation(),n.toggleDrawer(null)),o.key!=="Tab")return;let p=Array.from(u.currentTarget.querySelectorAll("*")).filter(d=>d.matches('button:not(:disabled), input:not(:disabled), a[href], select:not(:disabled), [tabindex="0"]')),r=p[0],l=p[p.length-1];o.shiftKey&&document.activeElement===r&&(o.preventDefault(),l?.focus()),!o.shiftKey&&document.activeElement===l&&(o.preventDefault(),r?.focus())}}},t("div",{class:"drawer-head"},t("div",{class:"drawer-title"},t("h3",{id:"drawer-heading"},a),t("p",{},c)),t("button",{id:"drawer-close",class:"quiet",on:{click:()=>n.toggleDrawer(null)}},"Close")),t("div",{class:"drawer-body"},s))}function de(e,i,n,s,...a){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",{},s),a.some(Boolean)?t("div",{class:"row step-row"},...a):null))}function Yt(e,i){return t("div",{},...e.agents.map(n=>{let s=e.probes[n.id],a=s?.ready===!0,c=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 ${a?"green":n.installed?"amber":"gray"}`},t("i"),a?"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"},de(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")),de(2,"Sign in to your account",a,a?"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")),de(3,"Test the connection",a,s?.message??`Not tested in this session. VibeRaven runs ${n.setup.verifyCommand} and reads the result.`,t("button",{class:"btn sm",disabled:c,on:{click:()=>i.testConnection(n.id)}},c?t("span",{class:"spin"}):null,c?"Testing\u2026":a?"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 Bt(e,i,n){let s=e.project.releases??[],a=t("input",{id:"release-from",class:"sel","aria-label":"From revision",placeholder:"Tag, commit or branch",value:e.compare.from,on:{input:p=>{i.get().compare.from=p.target.value}}}),c=t("input",{id:"release-to",class:"sel","aria-label":"To revision",placeholder:"HEAD",value:e.compare.to,on:{input:p=>{i.get().compare.to=p.target.value}}}),u=e.compare.result,o=u?.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"},s.length?`${s.length} release point${s.length===1?"":"s"} \xB7 branch ${s[0].branch}`:"Nothing tagged yet")),s.length?t("ul",{class:"rel-list"},...s.map(p=>t("li",{class:"rel"},t("div",{class:"rel-main"},t("div",{class:"rel-line"},t("span",{class:"lbl"},p.label),t("span",{class:`tag ${p.tone==="current"?"amber":"dim"}`},p.tone==="current"?"Current":p.tone==="prod"?"Released":"Planned")),t("p",{class:"rel-sum"},p.summary),t("p",{class:"rel-meta"},`${p.meta} \xB7 ${p.branch}`)),t("button",{class:"btn sm ghost",on:{click:()=>{i.set({compare:{...i.get().compare,from:p.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",a),t("label",{},"To",c),t("div",{class:"compare-actions"},t("button",{class:"btn sm primary",disabled:e.busy.compare,on:{click:()=>n.compare(a.value,c.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(a.value,c.value)}},`Explain with ${ue(e)}`))),e.compare.error?t("p",{class:"compare-error",role:"alert"},e.compare.error):null,u?t("div",{class:"diff-result"},t("div",{class:"diff-stats"},t("span",{class:"diff-range"},`${u.fromLabel} \u2192 ${u.toLabel}`),o?t("span",{},`${o.files??0} file${o.files===1?"":"s"}`):null,o?t("span",{class:"add"},`+${o.insertions??0}`):null,o?t("span",{class:"del"},`\u2212${o.deletions??0}`):null),t("pre",{class:"out diff",tabindex:0,role:"region","aria-label":"Diff output",html:Gt(u.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 Qt(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 Gt(e){return e.split(`
1
+ "use strict";(()=>{function Ve(e=document){return e.querySelector('meta[name="viberaven-token"]')?.content??""}async function T(e,i){let n=await fetch(e,{...i,credentials:"same-origin",headers:{"content-type":"application/json","x-viberaven-token":Ve(),...i?.headers??{}}}),r=await n.text(),a=null;try{a=r?JSON.parse(r):null}catch{a={error:r}}if(!n.ok){let c=a?.error??a?.message??r??`HTTP ${n.status}`;throw new Error(String(c))}return a}var A=(e,i)=>T(e,{method:"POST",body:JSON.stringify(i)}),k={project:()=>T("/api/project"),scan:()=>A("/api/scan",{}),scanStatus:()=>T("/api/scan-status"),githubWorkflow:()=>T("/api/github-workflow"),addGithubWorkflow:()=>A("/api/github-workflow",{}),agents:()=>T("/api/cli-agents"),probe:e=>A("/api/cli-agents/probe",{cliId:e}),runSetup:(e,i)=>A("/api/cli-agents/run-setup",{cliId:e,step:i}),openTerminal:(e,i)=>A("/api/cli-agents/open-terminal",{cliId:e,step:i}),chat:e=>A("/api/agent-chat",e),catalog:()=>T("/api/provider-catalog"),verified:()=>T("/api/provider-verify"),stop:e=>A("/api/agent-chat/stop",{runId:e}),verify:e=>A("/api/provider-verify",e),connectMcp:e=>A("/api/mcp/connect",{providerId:e}),compare:(e,i)=>T(`/api/releases/compare?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`),fullCheckStatus:()=>T("/api/fullcheck/status"),fullCheckSignInStart:()=>A("/api/fullcheck/signin/start",{}),fullCheckSignInPoll:()=>A("/api/fullcheck/signin/poll",{}),fullCheckSignOut:()=>A("/api/fullcheck/signout",{}),fullCheckPrepare:()=>A("/api/fullcheck/prepare",{}),fullCheckRun:e=>A("/api/fullcheck/run",{previewId:e}),changelog:(e,i)=>T(`/api/releases/changelog?from=${encodeURIComponent(e)}&to=${encodeURIComponent(i)}`)};function t(e,i,...n){let r=document.createElement(e);if(i){for(let[a,c]of Object.entries(i))if(!(c==null||c===!1))if(a==="class")r.className=String(c);else if(a==="on")for(let[u,o]of Object.entries(c))r.addEventListener(u,o);else if(a==="dataset")for(let[u,o]of Object.entries(c))r.dataset[u]=o;else a==="html"?r.innerHTML=String(c):a==="style"&&typeof c=="object"?Object.assign(r.style,c):a in r&&typeof c!="string"?r[a]=c:r.setAttribute(a,String(c))}return ge(r,n),r}function ge(e,i){for(let n of i)n==null||n===!1||(Array.isArray(n)?ge(e,n):n instanceof Node?e.appendChild(n):e.appendChild(document.createTextNode(String(n))))}function G(e){return e.replace(/[&<>"']/g,i=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[i])}function Z(e){let n=G(e.replace(/\r\n/g,`
2
+ `)).split(/```/),r="";return n.forEach((a,c)=>{if(c%2===1){let p=a.replace(/^[a-z0-9-]*\n/i,"");r+=`<pre><code>${p}</code></pre>`;return}let u=a.split(`
3
+ `),o=null;for(let p of u){let s=p.trimEnd(),l=/^\s*[-*•]\s+(.*)$/.exec(s),d=/^\s*\d+[.)]\s+(.*)$/.exec(s),h=/^(#{1,3})\s+(.*)$/.exec(s),y=l?"ul":d?"ol":null;o&&y!==o&&(r+=`</${o}>`,o=null),y&&!o&&(r+=`<${y}>`,o=y),l||d?r+=`<li>${ee((l??d)[1])}</li>`:h?r+=`<h4>${ee(h[2])}</h4>`:s.trim()&&(r+=`<p>${ee(s)}</p>`)}o&&(r+=`</${o}>`)}),r}function ee(e){return e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>").replace(/`([^`]+)`/g,"<code>$1</code>")}function O(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 r=Math.round(n/60);return r<24?`${r} h ago`:`${Math.round(r/24)} d ago`}function q(){return{step:"closed",status:null,signIn:null,preview:null,result:null,limit:null,error:null,notice:null}}var qe=new Set(["network","timeout","server","rate_limited","busy"]);function fe(e,i={}){let n=i.wait??(g=>new Promise(m=>window.setTimeout(m,g))),r=0,a=()=>e.get().fullCheck,c=g=>e.set(m=>({fullCheck:{...m.fullCheck,...g}})),u=g=>g===r&&a().step!=="closed";async function o(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 p(){try{let g=await k.fullCheckStatus();return c({status:g}),g}catch{return null}}async function s(g,m,M){if(u(M))switch(g.kind){case"signin":c({step:"signin",signIn:{code:g.code,verificationUrl:g.verificationUrl,expiresAt:g.expiresAt,opened:g.opened},error:null}),l(M,g.pollIntervalSeconds);return;case"signin_pending":return;case"signed_in":if(c({signIn:null,notice:g.notice??(a().preview?"Signed in again. Confirm to send the same request.":null)}),await p(),!u(M))return;a().preview?c({step:"preview"}):await h(M);return;case"signin_expired":case"signin_denied":c({step:"error",signIn:null,error:{message:g.message,retry:"signin"}});return;case"signed_out":c({...q()}),e.toast("Signed out of VibeRaven on this computer.");return;case"signin_required":case"reauth":c({notice:g.message}),await d(M);return;case"preview":c({step:"preview",preview:g.preview,error:null});return;case"result":c({step:"result",result:g.result,preview:null,notice:null,error:null}),await p();return;case"plan_limit":c({step:"limit",preview:null,notice:null,limit:{plan:g.plan,message:g.message,pricingUrl:g.pricingUrl,usage:g.usage}}),await p();return;case"error":{let v=g.reason==="not_confirmed"||g.reason==="prepare_failed"?"prepare":g.reason==="no_signin"?"signin":m==="run"&&!qe.has(g.reason)?"prepare":m;v==="prepare"&&m==="run"&&c({preview:null}),c({step:"error",error:{message:g.message,retry:v}});return}}}async function l(g,m){for(;u(g)&&a().step==="signin";){if(await n(Math.max(1,m)*1e3),!u(g)||a().step!=="signin")return;let M=await o(()=>k.fullCheckSignInPoll());if(M.kind!=="signin_pending"){await s(M,"signin",g);return}}}async function d(g){c({step:"loading",error:null}),await s(await o(()=>k.fullCheckSignInStart()),"signin",g)}async function h(g){c({step:"preparing",error:null,result:null,limit:null}),await s(await o(()=>k.fullCheckPrepare()),"prepare",g)}async function y(g){c({step:"loading",error:null});let m=await p();if(u(g)){if(!m){c({step:"error",error:{message:"The Studio server did not answer. Reload the page and try again.",retry:"status"}});return}m.signedIn?await h(g):await d(g)}}return{async openFullCheck(){let g=a().step;g!=="closed"&&g!=="result"&&g!=="limit"&&g!=="error"||(r+=1,c({...q(),step:"loading",status:a().status}),await y(r))},closeFullCheck(){r+=1,c({step:"closed",signIn:null,error:null,notice:null}),document.getElementById("run-full-check")?.focus({preventScroll:!0})},async fullCheckSignIn(){await d(r)},async fullCheckConfirm(){let g=a().preview;if(!g||a().step!=="preview")return;let m=r;c({step:"running",error:null}),await s(await o(()=>k.fullCheckRun(g.id)),"run",m)},async fullCheckRetry(){let g=a().error?.retry??"status",m=r;if(g==="run"&&a().preview){c({step:"preview",error:null});return}g==="signin"?await d(m):g==="prepare"?await h(m):await y(m)},async fullCheckSignOut(){await s(await o(()=>k.fullCheckSignOut()),"status",r),await p()},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 P(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 me(e){return e==="pro"?"Pro plan":"Free plan"}function te(e){return e<1024?`${e} B`:`${(e/1024).toFixed(1)} KB`}function We(e){try{return new URL(e).host}catch{return e}}function he(e){return t("span",{class:`tag ${e==="critical"?"red":e==="warning"?"amber":"dim"}`},e==="critical"?"Critical":e==="warning"?"Important":"Nice to have")}function Ke(e,i){let n=e.status?.account;if(!n)return null;let r=P(e.status?.usage);return t("div",{class:"fc-account"},t("span",{class:"fc-avatar","aria-hidden":"true"},n.email.slice(0,1).toUpperCase()),t("span",{class:"fc-who"},`Signed in as ${n.email}`),t("span",{class:`fc-plan is-${n.plan}`},me(n.plan)),e.status?.sessionOnly?t("span",{class:"fc-dot"},"this session only"):null,r?t("span",{class:"fc-dot"},r):null,t("button",{class:"fc-link",on:{click:()=>i.fullCheckSignOut()}},"Sign out"))}function Xe(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.split("").map(r=>t("span",{},r)))),t("p",{class:"fc-hint"},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 V(e,i,n,r=!1){return t("details",{class:"fc-files",open:r},t("summary",{},t("span",{},e),t("span",{class:"fc-files-count"},String(i.length))),i.length?t("ul",{},...i.map(a=>t("li",{},t("code",{},a.path),t("span",{},a.meta)))):t("p",{class:"fc-empty"},n))}function Je(e,i){let n=e.preview,r=n.promptFiles.length;return[e.notice?t("p",{class:"fc-notice",role:"status"},e.notice):null,t("div",{class:"fc-summary"},t("div",{class:"fc-summary-main"},t("span",{class:"fc-summary-size"},te(n.bytes)),t("span",{class:"fc-summary-what"},`${r} file${r===1?"":"s"} in full, plus names and snippets`)),t("p",{class:"fc-lead"},`This is exactly what gets sent to ${We(n.endpoint)} when you confirm. Nothing has been uploaded yet.`)),Ke(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",{},te(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"},V("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.",!0),V("File snippets (first 200 characters)",n.snippetFiles.map(a=>({path:a.path,meta:a.heat})),"None."),V("Skipped as secret files (name sent, contents never read)",n.secretFilesNamedOnly.map(a=>({path:a,meta:"name only"})),"None found."),V("Request text by section",n.promptSections.map(a=>({path:a.title,meta:`${a.chars.toLocaleString()} chars`})),"Empty.")),t("p",{id:"fc-redaction",class:`fc-shield${n.redactions>0?" is-on":""}`},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 (${te(n.bytes)}), same content.`),t("pre",{id:"fc-request-json"},n.requestJson)),t("p",{class:"fc-hint"},"Most of the request text is written by VibeRaven on your machine from the local scan: stack notes and the check instructions."),t("div",{class:"fc-actions fc-footer"},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 _e(e){return e<50?"fail":e<80?"warn":"pass"}function et(e,i){let n=e.result,r=n.areas.reduce((o,p)=>o+p.hiddenCount,0),a=n.nextFix,c=n.areas.filter(o=>!o.locked&&o.findings.length),u=n.areas.filter(o=>o.locked||!o.findings.length);return[t("div",{class:`fc-score is-${_e(n.score)}`},t("div",{class:"fc-score-num",style:`--score:${Math.max(0,Math.min(100,n.score))}`},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",{class:`fc-plan is-${n.usage.plan}`},me(n.usage.plan)),t("span",{class:"fc-dot"},P(n.usage)),t("span",{class:"fc-dot"},`${n.usage.remaining} left${n.usage.period==="monthly"?" this month":""}`)),a?t("article",{class:`fc-next is-${a.severity}`},t("div",{class:"fix-top"},t("span",{class:"fc-eyebrow"},"Next fix"),he(a.severity),t("span",{class:"fix-meta"},a.areaTitle)),t("h3",{},a.title),a.detail?t("p",{},a.detail):null,a.prompt?t("button",{class:"btn primary sm",on:{click:()=>i.copyFullCheckPrompt(a.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"),c.length?t("div",{class:"fc-areas"},...c.map(o=>t("section",{class:"fc-area","aria-label":o.title},t("div",{class:"fc-area-head"},t("h5",{},o.title),t("span",{class:"fc-count on"},String(o.findings.length))),t("ul",{},...o.findings.map(p=>t("li",{},he(p.severity),t("span",{title:p.detail},p.title))))))):null,u.length?t("div",{class:"fc-quiet"},...u.map(o=>t("section",{class:`fc-chip${o.locked?" locked":""}`,"aria-label":o.title},t("span",{class:"fc-chip-mark","aria-hidden":"true"},o.locked?"":"\u2713"),t("span",{},o.title),o.locked?t("span",{class:"tag dim"},"Pro area"):t("span",{class:"fc-sr"},"No findings."),o.locked&&o.hiddenCount?t("span",{class:"fc-sr"},`${o.hiddenCount} finding${o.hiddenCount===1?"":"s"} here. Pro shows every area.`):null))):null,r&&n.usage.plan==="free"?t("p",{class:"fc-upsell"},`${r} finding${r===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 fc-footer"},t("button",{class:"btn",on:{click:()=>i.closeFullCheck()}},"Done"))]}function tt(e,i){let n=e.limit;return[t("h3",{class:"fc-limit",role:"alert"},n.message),P(n.usage)?t("p",{class:"fc-hint"},P(n.usage)):null,n.plan==="free"?t("p",{class:"fc-hint"},"The local Studio checks stay free and unlimited. Pro adds 50 full checks a month across all production areas."):t("p",{class:"fc-hint"},"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 nt(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 ne(e){return t("p",{class:"fc-wait",role:"status"},t("span",{class:"spin"}),e)}var it={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 ye(e,i){let n=e.fullCheck;if(n.step==="closed")return[];let r=n.step==="signin"&&n.signIn?Xe(n,i):n.step==="preview"&&n.preview?Je(n,i):n.step==="result"&&n.result?et(n,i):n.step==="limit"&&n.limit?tt(n,i):n.step==="error"&&n.error?nt(n,i):n.step==="preparing"?[ne("Reading your project to build the request\u2026")]:n.step==="running"?[ne("Sent. VibeRaven is checking your app\u2026")]:[ne("Checking your VibeRaven sign-in\u2026")],a=n.step!=="running";return[t("div",{class:"fc-veil",on:{click:()=>{a&&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"},it[n.step]),a?t("button",{class:"btn ghost sm","aria-label":"Close full check",on:{click:()=>i.closeFullCheck()}},"Close"):null),t("div",{class:"fc-body"},...r))]}var Me="viberaven.stack.";function R(e,i,n=localStorage){try{let r=n.getItem(Me+e);return r?JSON.parse(r):i}catch{return i}}function H(e,i,n=localStorage){try{n.setItem(Me+e,JSON.stringify(i))}catch{}}function rt(e){return!e.empty&&!!e.project?.scannedAt?(e.missionCards?.blockers??[]).length?"findings":"ready":"app"}function be(e){let i=`chat.${e.project?.path??"project"}`,n=`checklist.${e.project?.path??"project"}`,r={project:e,catalog:[],verified:{},agents:[],probes:{},cliId:R("cliId","codex"),accessMode:R("accessMode","approve"),modelId:R("modelId",""),messages:R(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,moreOpen:!1,showAll:!1,setup:{open:!1,initialized:!1,selected:[],running:!1,progress:[],error:null},scan:null,toasts:[],workingSince:null,runId:null,fullCheck:q(),prChecks:{status:null,open:!1,busy:!1,written:!1,error:null},flow:{step:rt(e),fixId:null,handoff:null,recheck:null,checklist:R(n,{})}},a=new Set,c=0,u={get:()=>r,set(o){let p=typeof o=="function"?o(r):o;r={...r,...p},"cliId"in p&&H("cliId",r.cliId),"accessMode"in p&&H("accessMode",r.accessMode),"modelId"in p&&H("modelId",r.modelId),"messages"in p&&H(i,r.messages.slice(-60),sessionStorage),"flow"in p&&H(n,r.flow.checklist);for(let s of a)s(r)},flow(o){u.set(p=>({flow:{...p.flow,...o}}))},subscribe(o){return a.add(o),()=>a.delete(o)},toast(o,p="ok"){let s=++c;u.set(l=>({toasts:[...l.toasts,{id:s,text:o,kind:p}]})),window.setTimeout(()=>u.set(l=>({toasts:l.toasts.filter(d=>d.id!==s)})),p==="err"?7e3:3600)},push(o){let p={...o,id:`${Date.now()}-${Math.random().toString(36).slice(2,7)}`,at:new Date().toISOString()};return u.set(s=>({messages:[...s.messages,p]})),p}};return u}var ke=["sentry","stripe","clerk","cloudflare","render","railway","neon","posthog","upstash","resend","authjs"];function st(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 z(e,i,n){let r=new Map(e.providers.map(s=>[s.id,s])),a=new Set,c=[],u=(s,l)=>{let d=s?.id??l.id;if(a.has(d))return;a.add(d);let h=!!s?.detected||!!(l&&l.state!=="not_detected"),y=!!s?.mcpConfigured||l?.mcp?.status==="connected",g=n[d],m=h?st(l):0,M="absent",v="Not in this app";h&&(M="in_repo",v=y?"MCP configured \xB7 not verified live":"In repo \xB7 MCP not set up",y&&(M="mcp"),g&&(M=g.ok&&m===0?"ready":"verified",v=g.ok?"Verified live":"Verified live \xB7 issues found")),c.push({id:d,name:s?.name??l.name,area:s?.area??l.area,logoUrl:s?.logoUrl??at(l?.iconHtml??""),step:M,statusText:v,fixes:m,hasRecipe:!!s?.hasRecipe||l?.mcp?.available===!0,mcpConfigured:y,note:s?.note,mcpSource:s?.mcpSource??l?.mcp?.source,verified:g,provider:l})};for(let s of i)u(s,r.get(s.id));for(let s of e.providers)u(null,s);let o=s=>s.step==="absent"?s.hasRecipe?1:2:0,p=s=>{let l=ke.indexOf(s.id);return l===-1?ke.length:l};return c.sort((s,l)=>o(s)-o(l)||l.fixes-s.fixes||p(s)-p(l)||s.name.localeCompare(l.name))}function at(e){let i=/src="([^"]+)"/.exec(e);return i?i[1]:""}function ve(e,i,n){let r=e.setup,a=r.selected.length,c=e.probes[e.cliId]?.ready,u=r.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("h2",{id:"stack-setup-heading",tabIndex:-1},"Set up your app"),t("ol",{class:"setup-steps"},t("li",{class:a?"done":""},t("i",{"aria-hidden":"true"},a?"\u2713":"1"),"Pick your services"),t("li",{class:c?"done":""},t("i",{"aria-hidden":"true"},c?"\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:r.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(o=>{let p=r.selected.includes(o.id);return t("button",{id:`setup-provider-${o.id}`,class:`setup-service${p?" selected":""}`,"aria-pressed":String(p),disabled:u,on:{click:()=>n.toggleSetupProvider(o.id)}},t("img",{src:o.logoUrl,alt:""}),t("span",{class:"setup-service-copy"},t("strong",{},o.name),t("small",{},o.detected?"In your app":o.area)),t("span",{class:"setup-check","aria-hidden":"true"},p?"\u2713":"+"))})):t("p",{class:"setup-note"},"Loading the service catalog\u2026"),t("div",{class:"setup-footer"},t("div",{},t("strong",{},a?c?`${a} service${a===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.")),r.running?t("button",{class:"btn",on:{click:()=>n.stop()}},"Stop setup"):c?t("button",{class:"btn primary",disabled:!a||u,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")),r.progress.length?t("ol",{class:"setup-progress","aria-live":"polite"},...r.progress.map(o=>t("li",{class:o.state},t("span",{class:o.state==="working"&&r.running&&!r.error?"spin":"progress-dot","aria-hidden":"true"}),o.label))):null,r.error?t("p",{class:"setup-error",role:"alert"},r.error):null)}function we(e){if(e.actionDestination)return e.actionDestination;if(e.asksFirst||["missing_stripe_webhook","unverified_stripe_webhook"].includes(e.id))return"repo-code";let i=`${e.id} ${e.title} ${e.detail??""}`.replace(/[-_]/g," ");return/\bdashboard\b|\bdns\b|apex domain|\blive\b[^.\n]*\bproof\b|\bprovider action\b/i.test(i)?"provider-action":e.requiresUserAction?"manual-review":"repo-code"}var ot={authjs:"data:image/webp;base64,UklGRtANAABXRUJQVlA4WAoAAAAQAAAAVgAAXwAAQUxQSEIEAAABoETbtmnbmRvftl2LbSffthGVbNu2bdu2bdvGY5K91prBw73n7KAYEROAajsfPYBuk856r7Gh9tlD1wkAQvQotQsBAAbNv+QjNisvnTC2OwAXvSuJjwGAX3XP+2tJmhhJFZL8+rothwNADK5ozkcHoOvoE14lSRFl85qUZN1De60WAIToi+NCBIChi674jCSTGFtrIiT5xqkTegBw0bsC+BgA+FX3fLCOpCY1VtYkkeSX1ywbDgAhuGo4Hx2ArqNPeIUkRZTV1aQk6x/eZ80IIERfGRciAAxdes0XJJnEWEQTIck3Th3XFYCL3rXChwAAK+12Xw1JTWosrkkiyc+uXDwMAGJwTTkfPYBuY0542UiKGIuvSUnWP7TXagFAiB4IADBk0ZWfk2QSY1lVhCRfPXF0VwDew62y+/01JDWpsdwmiSS/uHrpMGDmCyQpYsyiaVKStbctX09LYsypiZBXNCoznOTKBuZYeMX/Wpfn6opfM3XWt7Qs7f8yNUPKre/LknHK5ZQM0dY5JkfGmlE7UvOj/KzbLFqOXvRrKfMrvAtDfqJlJ/EcdPyQmqH9gMcp2RHOBy5nyo5xXeCQ/BgbhgBL8qP8qB2wIS03wkfgMLiBlpnEcxDR5j1qdnZC9LiTkhnlGISIY5jyYmwcDh+xiJIX5Ttt4DxWVuZVeCMCHDp/QctK4v6IgMcdlKwoxyAAEQcw5cRYMwAeCNicmhPh084BcOj5PS0jiSciAoDHfZSMKKch/C3iQKZ8GOsGwf0tYD1aPpRPweHvDh0+pmYj8TDEJhBwqaVsGDdCaCpiNjUXyg87wDXl0PN7WiaSnY+AZgOuspQJ5aSWRDeLkgflF13gmnPo8T0tC8kuREALAy5lyoJyfGtGU3OgfL89XEuca/suNQOJRyKixREHMpXP7Pfl4FvmMazerHTCu+DRyoDLmUqnnITQurVMy6b2ZhvnWgOPB0xKJtwOEa0OGE0tl9rXPZxrHbx/wqRUwn0RUMGATVkqta97OFcJeFxPKZFwewRUxg2tUSuN2BvtvKsMAg6ilIfTEFBh5zt/aFoS4b0IqHjARKZymPy2PHzlEHEFUykS90dAFb3v87lpCYTPxuCqgYCxTFY404aV4FHdiMOYCpe4LQKq7KK7g6lgiRciourO9XyXUijhM+2Dqx4CVvyZWiDhl8PgUcSILRpVC6OsXQMBxYyYTbWCKBvHIqKoEctoWghlw1hEFDdiye+UAggbxiKiyBHj6ilVS/xxNCKKHbHep0xVSnx/FUQUPWLoExStggrvG4CA4ge0P5OUigl5YkRAGT0w/yuqVkSVn0yH8yinCxh8NSnWKhXywr4IDqUNwOw3yGQt0kS+OAUIKLP36LT716RoMyrkR9u1Q3AoeQAGHPoVaWpmQvLD/XoAAeV3Aei93fNsUh9e0hkIDll0EQhTb/z4y7fP3QhAdCgiVlA4IGgJAACQKgCdASpXAGAAPjEUiEMiISEUCOcYIAMEtgBb9btga9m/F/8lvlUrX9I+6H9A/7/+X64o7XZd+G+2730f4D2x/mT/Je4B+j39l/Nb++d1zzB/y7+r/8b+y+8h6D/QA/oH9m6w79xvYA/Wb1Xv9P+2HwMfsb+z/wG/y3+u/+T8/+QA/gHWgdv/+Wsj/yt/p+e835uFekU+L+wB/Hf7b6FX/D/hPPR9K+wF/LP6l/wOwt+0Xsv/rSii5S8mBgqDE9JYE5GwzUAX2+kH5rOaaGyBjiEOqYZp2/3oMM2MZ9Z25/cW7PIHm7SM1zg/rmtdN7/64GMeqOWQfMCHS5mIfhKHUyQ8rVwv9fCfxKKvxVzcR7mHuW6q3uJdqXrJ03kAIgNpyjAZh6cyGDNbrY5G5TG/QLuu+0mdbwHlCLyvUac4IefZELWfpbeKopFlmLbzK9nQwsLY5xcGeoqNwZ4AAP7/9B2hxR6Nv+96k7HnwXIU6NhYpJ4++OmPwDq5NhMqm6W0/+SQ1k8VFzPgnHwC3ARvXoUhmxvrWlWAW69hhbhGQ+lCfzY8LU3fl9D0HCatWJA1gkxZBApdjoO3+Gx2FRcyg9blPD7VxRO7TX/bW337xiyh1EKzMrPzrek/hOrQZ4+6TBb20sqsdTf7pjGXRTexJy4xQc75YQVHTOmeUnwqq6Vxu5P/eA9VtkMMoZCnRgYjdkLAhaxR6wl9/bpcWboojaym4/UpMvPTVQ8swaoh4wMsT1wwY0ZlGSKP2ZyhGguKWOz/Z+FKtl5Lykyb7BTw/QBXZJW+A3dV3SiuuyrtfBqwDc9PjZX1FfrKMvkV+W2QEWRBz/HQz7lTfIxatFHfVGxB3jzKdS697ElzPcUVW3msBtFoEPch/GtE9Dr1ENxdNAHiuZF+0QKgayyKxWhKF7NBq/aLPiHt+vtH8pf46+AOfJiUfm6tBLwrsrLh2i6Ygk3xN2j1aa6pZI2a31M3zKpyocR7HvePPJAJSyVl+0dRlYACwUkZspLylJytFCL//PiJQj9auS9F5+mdiR8J9PsN8F6BowKGfRQqz24+n+AWtENMzUHfzPrb3qlFv1nxu47WKD9UAjf71v9ZBvmeeoM+v+drzy9X8MwKYCr24T+gSvRpP7RCl+UsMz5WtNP470E0f6hkfLRGQhPgcVIZlk0JurDD1mNhPsuivVO/AWpQhbSbQoJpmjr/qYL3PGfyfEl54O4dplISqo1oPwyT+wzo7na/IpKMppUCRdl7KVbg0rP7KTx9qopVkZTyEObSRiJSqPnF8MCHiOrDTBch3nbGFXIXXrQpqhoDX4adUqGwHyOxrJu0HHy4gPCjPmFseNjf5XJ+O85iXVeEugyeW/2525fL9omsGRT9g+P/xT48n6uaBlauXOQdzh+QjZZ576SXx3r7coWlqm69q/V67SapkTaWkSLIvjPik/r/0Ku4htOGplVrme1k+d6hD9R8XEVy0KwEiBscrJxoLVzvHbjFmQFrC5aPBvwpzBcu0ubsLUZ3lou15LvGrocjDrzzvKpM+wru4OXrHng//zOx1Z1thEYfO2bz+aFQdJLbQAy+i9aDJE2WsIQaNIb0C92CoTm+Z3K1SqWuasGrJZq6FU1MZpjHveIKr0D98xneeH3nlOsd7SkHPUAzRQWjJ3F4rd07G7i7WtTtgU39NmE4RFoQV8OneCAiM3+PvUnBcSRaWq/TlO1cF3fiNPXODbZvgRlKj362hlbwLudL7VPNq4M4R4Obt9ft+zUdd70NMYSN1CxomVvXFAGn1/zjLi4Wx9tPwV39hI+2Y3/oIYZFWr8uQV4DCp/JxhtTQGFSaaiX9RroKpRkiEs5gYsRjyV7x/bUNjEaRdA4E/kHZZNCu36tqgqkveuICoMixSElB8YV2VJM7WZeO+egf/4HQuLYj/whvwUqYUbluhQ0lTmu3Nap6QagyE1L3SCCh8ExLW4HKFI2D7GOY2wntFXO1iEqcb/u6NqBS6H/4hW5f8OgB8Zejwp8sfMBjkgICaDtjM9jY4Rvfjq3CxFIXKbDGDiGaItOefEpbZ3ZUcoXATTURn+LR9Pf2m2OM7ClM7u9fbZFHvgUMpu7KaZY+jkcGBbXrK48dVedxSQqTo7OyKdt8V7dQ9v90+LhYn9GJrvCSpSp8APmiUCKkjx0r1RbV2MMHF0GHnr+kefH8bYztriXbB1u6q0DmRH76N0Jc8eKKg1u2axOyH00EKciX29601289ajP8lGxGb2xJet9MXYDQZYDEsaTf+pRxMadxoPIdrMT9jsDFl0S4SKPjRQzhzRZ5wtvwz1/zKIuDhzFM4VhK55VLDIDh+YFFD3qphfLvso7c/jMXRqOvTQ35Jp5eQdyBNvZxBPxxF6TCrrkcVnVi2LgvSdDtQnpDx0sceHIuhLZZFwGuB+toA4rE09HSiQvoNnh65uH70b1LObmc9h/cR4jOeYB9n6V6mayg79aiHnOGal6//yqPgY7OgleYQK+eopgZI1d4KHiOSvVNyIn/6v8Pj3F50MatXhPn5GR3JXqYnY3Gt4+UEQSwSRWWpZGdyhfk1zziuCATrHfZhGxw7lvfir8JpqNX4jt2ONXy58Ob3cSGo3c5eGRns5qjF5dgRiWU1Wjv6JYK/EM/rXOTU1XWIlho2b4h4z/RU9ZjIvl867Ik6s2KhCh1N00fig3mhs5f+SXamN3WXEaf2BL9BRzW/i2mjSSRySOUi9U80PB3f3xFieqzOJH9RmSN5WS6WHFkoJDtsIan2CNnxnK1kxc1fjPCwCmjuiRmzdL2ZOkfoGoNhofuIdaErLC4dJ5zWaLyOgbGFv/MQMMt4JwkzOvpEWEr5ifEIFOB50DgfJNfXHXh0SH2GtQLJG8GYpEDv7nOxyyjqJkP/TaTtsn2IAx/+zDn1YlR//F/veEcMU2wv7I4iYcgBhkVAjFtQWOX/2UyYl77otOaea7I4ydaNjCI8dxtK+m1HSUFMmI3T1b7BVkKOFCf38cdgGF1uOYBA5Rw9hGhyK9qJwLzVOd5o3Ng9E2p4YsjYP9IdaDRtLq/CJ5s2340OFH561h6d82y/CaPthB1HN/99LaXLZv8Gfvh5vJ2vDJ+XaYFIS3QIlLUNjVg1BfqBwShMmTQjFd9/wT3uig+TLNZGOmFjxI9bP/KB90o/6HSFDp6PWPx7Fc3xoqLNRxjsJyo8lIiYMEkZ+SAAAAAA==",clerk:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjNkM0N0ZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Q2xlcms8L3RpdGxlPjxwYXRoIGQ9Im0yMS40NyAyMC44MjktMi44ODEtMi44ODFhLjU3Mi41NzIgMCAwIDAtLjctLjA4NCA2Ljg1NCA2Ljg1NCAwIDAgMS03LjA4MSAwIC41NzYuNTc2IDAgMCAwLS43LjA4NGwtMi44ODEgMi44ODFhLjU3Ni41NzYgMCAwIDAtLjEwMy42OS41Ny41NyAwIDAgMCAuMTY2LjE4NiAxMiAxMiAwIDAgMCAxNC4xMTMgMCAuNTguNTggMCAwIDAgLjIzOS0uNDIzLjU3Ni41NzYgMCAwIDAtLjE3Mi0uNDUzWm0uMDAyLTE3LjY2OC0yLjg4IDIuODhhLjU2OS41NjkgMCAwIDEtLjcwMS4wODRBNi44NTcgNi44NTcgMCAwIDAgOC43MjQgOC4wOGE2Ljg2MiA2Ljg2MiAwIDAgMC0xLjIyMiAzLjY5MiA2Ljg2IDYuODYgMCAwIDAgLjk3OCAzLjc2NC41NzMuNTczIDAgMCAxLS4wODMuNjk5bC0yLjg4MSAyLjg4YS41NjcuNTY3IDAgMCAxLS44NjQtLjA2M0ExMS45OTMgMTEuOTkzIDAgMCAxIDYuNzcxIDIuN2ExMS45OSAxMS45OSAwIDAgMSAxNC42MzctLjQwNS41NjYuNTY2IDAgMCAxIC4yMzIuNDE4LjU3LjU3IDAgMCAxLS4xNjguNDQ4Wm0tNy4xMTggMTIuMjYxYTMuNDI3IDMuNDI3IDAgMSAwIDAtNi44NTQgMy40MjcgMy40MjcgMCAwIDAgMCA2Ljg1NFoiLz48L3N2Zz4=",cloudflare:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRjM4MDIwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Q2xvdWRmbGFyZTwvdGl0bGU+PHBhdGggZD0iTTE2LjUwODggMTYuODQ0N2MuMTQ3NS0uNTA2OC4wOTA4LS45NzA3LS4xNTUzLTEuMzE1NC0uMjI0Ni0uMzE2NC0uNjA0NS0uNDk5LTEuMDYxNS0uNTIwNWwtOC42NTkyLS4xMTIzYS4xNTU5LjE1NTkgMCAwIDEtLjEzMzMtLjA3MTNjLS4wMjgzLS4wNDItLjAzNTEtLjA5ODYtLjAyMS0uMTU1My4wMjc4LS4wODQuMTEyMy0uMTQ4NC4yMDM2LS4xNTYybDguNzM1OS0uMTEyM2MxLjAzNTEtLjA0ODkgMi4xNjAxLS44ODY4IDIuNTUzNy0xLjkxMzZsLjQ5OS0xLjMwMTNjLjAyMTUtLjA1NjEuMDI5My0uMTEyOC4wMTQ3LS4xNjgtLjU2MjUtMi41NDYzLTIuODM1LTQuNDQ1My01LjU0OTktNC40NDUzLTIuNTAzOSAwLTQuNjI4NCAxLjYxNzctNS4zODc2IDMuODYxNC0uNDkyNy0uMzY1OC0xLjExODctLjU2MjUtMS43OTQtLjQ5OS0xLjIwMjYuMTE5LTIuMTY2NSAxLjA4My0yLjI4NjEgMi4yODU2LS4wMjgzLjMxLS4wMDY5LjYxMjguMDYzNS44OTRDMS41NjgzIDEzLjE3MSAwIDE0Ljc3NTQgMCAxNi43NTJjMCAuMTc0OC4wMTQyLjM1MTUuMDM1Mi41MjczLjAxNDEuMDgzLjA4NDQuMTQ3NS4xNjg5LjE0NzVoMTUuOTgxNGMuMDkwOSAwIC4xNzU4LS4wNjQ1LjIwMzItLjE1NTNsLjEyLS40MjY4em0yLjc1NjgtNS41NjM0Yy0uMDc3MSAwLS4xNjExIDAtLjIzODMuMDExMi0uMDU2NiAwLS4xMDU0LjA0MTUtLjEyNy4wOTc2bC0uMzM3OCAxLjE3NDRjLS4xNDc1LjUwNjgtLjA5MTguOTcwNy4xNTQzIDEuMzE2NC4yMjU2LjMxNjQuNjA1NS40OTggMS4wNjI1LjUxOTVsMS44NDM3LjExMzNjLjA1NTcgMCAuMTA1NS4wMjYzLjEzMjkuMDcwMy4wMjgzLjA0My4wMzUxLjEwNzQuMDIxNC4xNTYyLS4wMjgzLjA4NC0uMTEzMi4xNDg1LS4yMDQuMTU1M2wtMS45MjEuMTEyM2MtMS4wNDEuMDQ4OC0yLjE1ODIuODg2Ny0yLjU1MjcgMS45MTRsLS4xNDA2LjM1ODVjLS4wMjgzLjA3MTMuMDIxNS4xNDE2LjA5ODYuMTQxNmg2LjU5NzdjLjA3NzEgMCAuMTQ3NC0uMDQ4OS4xNjktLjEyNi4xMTIyLS40MDgyLjE3NTctLjgzNy4xNzU3LTEuMjgwMyAwLTIuNjAyNS0yLjEyNS00LjcyNy00LjczNDQtNC43MjciLz48L3N2Zz4=",github:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViPC90aXRsZT48cGF0aCBkPSJNMTIgLjI5N2MtNi42MyAwLTEyIDUuMzczLTEyIDEyIDAgNS4zMDMgMy40MzggOS44IDguMjA1IDExLjM4NS42LjExMy44Mi0uMjU4LjgyLS41NzcgMC0uMjg1LS4wMS0xLjA0LS4wMTUtMi4wNC0zLjMzOC43MjQtNC4wNDItMS42MS00LjA0Mi0xLjYxQzQuNDIyIDE4LjA3IDMuNjMzIDE3LjcgMy42MzMgMTcuN2MtMS4wODctLjc0NC4wODQtLjcyOS4wODQtLjcyOSAxLjIwNS4wODQgMS44MzggMS4yMzYgMS44MzggMS4yMzYgMS4wNyAxLjgzNSAyLjgwOSAxLjMwNSAzLjQ5NS45OTguMTA4LS43NzYuNDE3LTEuMzA1Ljc2LTEuNjA1LTIuNjY1LS4zLTUuNDY2LTEuMzMyLTUuNDY2LTUuOTMgMC0xLjMxLjQ2NS0yLjM4IDEuMjM1LTMuMjItLjEzNS0uMzAzLS41NC0xLjUyMy4xMDUtMy4xNzYgMCAwIDEuMDA1LS4zMjIgMy4zIDEuMjMuOTYtLjI2NyAxLjk4LS4zOTkgMy0uNDA1IDEuMDIuMDA2IDIuMDQuMTM4IDMgLjQwNSAyLjI4LTEuNTUyIDMuMjg1LTEuMjMgMy4yODUtMS4yMy42NDUgMS42NTMuMjQgMi44NzMuMTIgMy4xNzYuNzY1Ljg0IDEuMjMgMS45MSAxLjIzIDMuMjIgMCA0LjYxLTIuODA1IDUuNjI1LTUuNDc1IDUuOTIuNDIuMzYuODEgMS4wOTYuODEgMi4yMiAwIDEuNjA2LS4wMTUgMi44OTYtLjAxNSAzLjI4NiAwIC4zMTUuMjEuNjkuODI1LjU3QzIwLjU2NSAyMi4wOTIgMjQgMTcuNTkyIDI0IDEyLjI5N2MwLTYuNjI3LTUuMzczLTEyLTEyLTEyIi8+PC9zdmc+",neon:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDBFNTk5IiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+TmVvbjwvdGl0bGU+PHBhdGggZD0iTTI0IDBWMjRsLTkuMzY1LTguMDQ1VjI0SDBWMFpNMi45NDIgMjEuMDg3aDguNzUxVjkuNTYzbDkuMzY1IDguMjA0VjIuOTE5TDIuOTQyIDIuOTE0WiIvPjwvc3ZnPg==",posthog:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRjU0RTAwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UG9zdEhvZzwvdGl0bGU+PHBhdGggZD0iTTkuODU0IDE0LjUgNSA5LjY0Ny44NTQgNS41QS41LjUgMCAwIDAgMCA1Ljg1NFY4LjQ0YS41LjUgMCAwIDAgLjE0Ni4zNTNMNSAxMy42NDdsLjE0Ny4xNDZMOS44NTQgMTguNWwuMTQ2LjE0N3YtLjA0OWMuMDY1LjAzLjEzNC4wNDkuMjA3LjA0OWgyLjU4NmEuNS41IDAgMCAwIC4zNTMtLjg1NEw5Ljg1NCAxNC41em0wLTUtNC00YS40ODcuNDg3IDAgMCAwLS40MDktLjE0NC41MTUuNTE1IDAgMCAwLS4zNTYuMjEuNDkzLjQ5MyAwIDAgMC0uMDg5LjI4OFY4LjQ0YS41LjUgMCAwIDAgLjE0Ny4zNTNsOSA5YS41LjUgMCAwIDAgLjg1My0uMzU0di0yLjU4NWEuNS41IDAgMCAwLS4xNDYtLjM1NGwtNS01em0xLTRhLjUuNSAwIDAgMC0uODU0LjM1NFY4LjQ0YS41LjUgMCAwIDAgLjE0Ny4zNTNsNCA0YS41LjUgMCAwIDAgLjg1My0uMzU0VjkuODU0YS41LjUgMCAwIDAtLjE0Ni0uMzU0bC00LTR6bTEyLjY0NyAxMS41MTVhMy44NjMgMy44NjMgMCAwIDEtMi4yMzItMS4xbC00LjcwOC00LjcwN2EuNS41IDAgMCAwLS44NTQuMzU0djYuNTg1YS41LjUgMCAwIDAgLjUuNUgyMy41YS41LjUgMCAwIDAgLjUtLjV2LS42YzAtLjI3Ni0uMjI1LS40OTctLjQ5OS0uNTMyem0tNS4zOTQuMDMyYS44LjggMCAxIDEgMC0xLjYuOC44IDAgMCAxIDAgMS42ek0uODU0IDE1LjVhLjUuNSAwIDAgMC0uODU0LjM1NHYyLjI5M2EuNS41IDAgMCAwIC41LjVoMi4yOTNjLjIyMiAwIC4zOS0uMTM1LjQ2Mi0uMzA5YS40OTMuNDkzIDAgMCAwLS4xMDktLjU0NUwuODU0IDE1LjUwMXpNNSAxNC42NDcuODU0IDEwLjVhLjUuNSAwIDAgMC0uODU0LjM1M3YyLjU4NmEuNS41IDAgMCAwIC4xNDYuMzUzTDQuODU0IDE4LjVsLjE0Ni4xNDdoMi43OTNhLjUuNSAwIDAgMCAuMzUzLS44NTRMNSAxNC42NDd6Ii8+PC9zdmc+",railway:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmFpbHdheTwvdGl0bGU+PHBhdGggZD0iTS4xMTMgMTAuMjdBMTMuMDI2IDEzLjAyNiAwIDAwMCAxMS40OGgxOC4yM2MtLjA2NC0uMTI1LS4xNS0uMjM3LS4yMzUtLjM0Ny0zLjExNy00LjAyNy00Ljc5My0zLjY3Ny03LjE5LTMuNzgtLjgtLjAzNC0xLjM0LS4wNDgtNC41MjQtLjA0OC0xLjcwNCAwLTMuNTU1LjAwNS01LjM1OC4wMS0uMjM0LjYzLS40NTkgMS4yNC0uNTY3IDEuNzM3aDkuMzQydjEuMjE2SC4xMTN2LjAwMnptMTguMjYgMi40MjZILjAwOWMuMDIuMzI2LjA1LjY0NS4wOTQuOTYxaDE2Ljk1NWMuNzU0IDAgMS4xNzktLjQyOSAxLjMxNS0uOTZ6bS0xNy4zMTggNC4yOHMyLjgxIDYuOTAyIDEwLjkzIDcuMDI0YzQuODU1IDAgOS4wMjctMi44ODMgMTAuOTItNy4wMjRIMS4wNTZ6TTExLjk4OCAwQzcuNSAwIDMuNTkzIDIuNDY2IDEuNTMxIDYuMTA4bDQuNzUtLjAwNXYtLjAwMmMzLjcxIDAgMy44NDkuMDE2IDQuNTczLjA0N2wuNDQ4LjAxNmMxLjU2My4wNTIgMy40ODUuMjIgNC45OTYgMS4zNjQuODIuNjIxIDIuMDA3IDEuOTkgMi43MTIgMi45NjUuNjU0LjkwMi44NDIgMS45NC4zOTYgMi45MzQtLjQwOC45MTQtMS4yODkgMS40NTgtMi4zNTMgMS40NThILjM5MXMuMDk5LjQyLjI0OS44ODZoMjIuNzQ4QTEyLjAyNiAxMi4wMjYgMCAwMDI0IDEyLjAwNUMyNCA1LjM3NyAxOC42MjEgMCAxMS45ODggMHoiLz48L3N2Zz4=",render:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmVuZGVyPC90aXRsZT48cGF0aCBkPSJNMTguMjYzLjAwN2MtMy4xMjEtLjE0Ny01Ljc0NCAyLjEwOS02LjE5MiA1LjA4Mi0uMDE4LjEzOC0uMDQ1LjI3Mi0uMDY3LjQwNS0uNjk2IDMuNzAzLTMuOTM2IDYuNTA3LTcuODI3IDYuNTA3LTEuMzg4IDAtMi42OTEtLjM1Ni0zLjgyNS0uOTc5YS4yMDI0LjIwMjQgMCAwIDAtLjMwMi4xNzhWMjRIMTJ2LTguOTk5YzAtMS42NTYgMS4zMzgtMyAyLjk4Ny0zaDIuOTg4YzMuMzgyIDAgNi4xMDMtMi44MTcgNS45Ny02LjI0NC0uMTItMy4wODQtMi42MS01LjYwMy01LjY4Mi01Ljc1Ii8+PC9zdmc+",resend:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UmVzZW5kPC90aXRsZT48cGF0aCBkPSJNMTQuNjc5IDBjNC42NDggMCA3LjQxMyAyLjc2NSA3LjQxMyA2LjQzNHMtMi43NjUgNi40MzQtNy40MTMgNi40MzRIMTIuMzNMMjQgMjRoLTguMjQ1bC04Ljg4LTguNDRjLS42MzYtLjU4OC0uOTMtMS4yNzMtLjkzLTEuODYgMC0uODMxLjU4Ny0xLjU2NSAxLjcxMy0xLjg4M2w0LjU3NC0xLjIyNGMxLjczNy0uNDY1IDIuOTM2LTEuODEgMi45MzYtMy41NzIgMC0yLjE1My0xLjc2MS0zLjQtMy45MzktMy40SDBWMHoiLz48L3N2Zz4=",sentry:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjOEI1Q0Y2IiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U2VudHJ5PC90aXRsZT48cGF0aCBkPSJNMTMuOTEgMi41MDVjLS44NzMtMS40NDgtMi45NzItMS40NDgtMy44NDQgMEw2LjkwNCA3LjkyYTE1LjQ3OCAxNS40NzggMCAwIDEgOC41MyAxMi44MTFoLTIuMjIxQTEzLjMwMSAxMy4zMDEgMCAwIDAgNS43ODQgOS44MTRsLTIuOTI2IDUuMDZhNy42NSA3LjY1IDAgMCAxIDQuNDM1IDUuODQ4SDIuMTk0YS4zNjUuMzY1IDAgMCAxLS4yOTgtLjUzNGwxLjQxMy0yLjQwMmE1LjE2IDUuMTYgMCAwIDAtMS42MTQtLjkxM0wuMjk2IDE5LjI3NWEyLjE4MiAyLjE4MiAwIDAgMCAuODEyIDIuOTk5IDIuMjQgMi4yNCAwIDAgMCAxLjA4Ni4yODhoNi45ODNhOS4zMjIgOS4zMjIgMCAwIDAtMy44NDUtOC4zMThsMS4xMS0xLjkyMmExMS40NyAxMS40NyAwIDAgMSA0Ljk1IDEwLjI0aDUuOTE1YTE3LjI0MiAxNy4yNDIgMCAwIDAtNy44ODUtMTUuMjhsMi4yNDQtMy44NDVhLjM3LjM3IDAgMCAxIC41MDQtLjEzYy4yNTUuMTQgOS43NSAxNi43MDggOS45MjggMTYuOWEuMzY1LjM2NSAwIDAgMS0uMzI3LjU0M2gtMi4yODdjLjAyOS42MTIuMDI5IDEuMjIzIDAgMS44MzFoMi4yOTdhMi4yMDYgMi4yMDYgMCAwIDAgMS45MjItMy4zMXoiLz48L3N2Zz4=",stripe:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjNjM1QkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U3RyaXBlPC90aXRsZT48cGF0aCBkPSJNMTMuOTc2IDkuMTVjLTIuMTcyLS44MDYtMy4zNTYtMS40MjYtMy4zNTYtMi40MDkgMC0uODMxLjY4My0xLjMwNSAxLjkwMS0xLjMwNSAyLjIyNyAwIDQuNTE1Ljg1OCA2LjA5IDEuNjMxbC44OS01LjQ5NEMxOC4yNTIuOTc1IDE1LjY5NyAwIDEyLjE2NSAwIDkuNjY3IDAgNy41ODkuNjU0IDYuMTA0IDEuODcyIDQuNTYgMy4xNDcgMy43NTcgNC45OTIgMy43NTcgNy4yMThjMCA0LjAzOSAyLjQ2NyA1Ljc2IDYuNDc2IDcuMjE5IDIuNTg1LjkyIDMuNDQ1IDEuNTc0IDMuNDQ1IDIuNTgzIDAgLjk4LS44NCAxLjU0NS0yLjM1NCAxLjU0NS0xLjg3NSAwLTQuOTY1LS45MjEtNi45OS0yLjEwOWwtLjkgNS41NTVDNS4xNzUgMjIuOTkgOC4zODUgMjQgMTEuNzE0IDI0YzIuNjQxIDAgNC44NDMtLjYyNCA2LjMyOC0xLjgxMyAxLjY2NC0xLjMwNSAyLjUyNS0zLjIzNiAyLjUyNS01LjczMiAwLTQuMTI4LTIuNTI0LTUuODUxLTYuNTk0LTcuMzA1aC4wMDN6Ii8+PC9zdmc+",supabase:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjM0VDRjhFIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+U3VwYWJhc2U8L3RpdGxlPjxwYXRoIGQ9Ik0xMS45IDEuMDM2Yy0uMDE1LS45ODYtMS4yNi0xLjQxLTEuODc0LS42MzdMLjc2NCAxMi4wNUMtLjMzIDEzLjQyNy42NSAxNS40NTUgMi40MDkgMTUuNDU1aDkuNTc5bC4xMTMgNy41MWMuMDE0Ljk4NSAxLjI1OSAxLjQwOCAxLjg3My42MzZsOS4yNjItMTEuNjUzYzEuMDkzLTEuMzc1LjExMy0zLjQwMy0xLjY0NS0zLjQwM2gtOS42NDJ6Ii8+PC9zdmc+",upstash:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDBFOUEzIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VXBzdGFzaDwvdGl0bGU+PHBhdGggZD0iTTEzLjgwMjcgMEMxMS4xOTMgMCA4LjU4My45OTUyIDYuNTkxOCAyLjk4NjNjLTMuOTgyMyAzLjk4MjMtMy45ODIzIDEwLjQzOTYgMCAxNC40MjE5IDEuOTkxMSAxLjk5MTEgNS4yMTk4IDEuOTkxMSA3LjIxMSAwIDEuOTkxLTEuOTkxMSAxLjk5MS01LjIxOTggMC03LjIxMUwxMiAxMmMuOTk1Ni45OTU2Ljk5NTYgMi42MDk4IDAgMy42MDU1LS45OTU2Ljk5NTUtMi42MDk5Ljk5NTUtMy42MDU1IDAtMi45ODY2LTIuOTg2OC0yLjk4NjYtNy44Mjk3IDAtMTAuODE2NCAyLjk4NjgtMi45ODY4IDcuODI5Ny0yLjk4NjggMTAuODE2NCAwbDEuODAyOC0xLjgwMjhDMTkuMDIyNS45OTUyIDE2LjQxMjUgMCAxMy44MDI3IDB6TTEyIDEyYy0uOTk1Ni0uOTk1Ni0uOTk1Ni0yLjYwOTggMC0zLjYwNTUuOTk1Ni0uOTk1NSAyLjYwOTgtLjk5NTUgMy42MDU1IDAgMi45ODY3IDIuOTg2OCAyLjk4NjcgNy44Mjk3IDAgMTAuODE2NC0yLjk4NjcgMi45ODY4LTcuODI5NyAyLjk4NjgtMTAuODE2NCAwbC0xLjgwMjggMS44MDI4YzMuOTgyMyAzLjk4MjIgMTAuNDM5NiAzLjk4MjIgMTQuNDIxOSAwIDMuOTgyMy0zLjk4MjQgMy45ODIzLTEwLjQzOTYgMC0xNC40MjE5LS45OTU2LS45OTU2LTIuMzAwNi0xLjQ5MjItMy42MDU1LTEuNDkyMi0xLjMwNDggMC0yLjYwOTkuNDk2Ni0zLjYwNTQgMS40OTIyLTEuOTkxMiAxLjk5MTItMS45OTEyIDUuMjE5OCAwIDcuMjExeiIvPjwvc3ZnPg==",vercel:"data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjRkZGRkZGIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VmVyY2VsPC90aXRsZT48cGF0aCBkPSJtMTIgMS42MDggMTIgMjAuNzg0SDBaIi8+PC9zdmc+"};function Le(e){return ot[e]??null}var Y={critical:0,warning:1,info:2},Se={supabase:"https://supabase.com/dashboard/projects",vercel:"https://vercel.com/dashboard",stripe:"https://dashboard.stripe.com",github:"https://github.com/settings/profile",sentry:"https://sentry.io",posthog:"https://app.posthog.com",clerk:"https://dashboard.clerk.com",resend:"https://resend.com/emails",upstash:"https://console.upstash.com",neon:"https://console.neon.tech",railway:"https://railway.com/dashboard",render:"https://dashboard.render.com",cloudflare:"https://dash.cloudflare.com"},lt="sql|ts|tsx|js|jsx|mjs|cjs|json|toml|ya?ml|env|py|rb|go|rs|vue|svelte|astro|html|css|md|prisma|php|java|kt|sh|lock",ct=new RegExp(String.raw`((?:[\w.@-]+[\\/])*[\w.@-]+\.(?:${lt})):(\d{1,6})\b`,"g");function dt(e){if(!e)return[];let i=new Set;for(let n of e.matchAll(ct))i.add(`${n[1].split("\\").join("/")}:${n[2]}`);return[...i]}function ut(e){let i=(e??"").split(`
4
+ `).map(a=>a.trim()).filter(Boolean),[n="",...r]=i;return{summary:n,evidence:r.filter(a=>a!=="Evidence:").map(a=>a.replace(/^-\s*/,""))}}function W(e){return Le(e.id)??e.logoUrl}function pt(e,i,n){let r=i?.provider?.nextFix,a=e.asksFirst?`${e.asksFirst} Tell the user this before you change anything, and make the change only if they confirm.`:"";return n==="manual-review"?[a,`Review this finding: ${e.title}. Do not edit files or change provider settings. Identify what evidence is missing and whether the next step belongs in the repo or with a provider, then ask the user before any change.`,e.detail,e.prompt?`Scanner guidance to review, not authorization to execute: ${e.prompt}`:""].filter(Boolean).join(`
5
+ `):!e.prompt&&r?.id===e.id&&r.prompt?[a,r.prompt].filter(Boolean).join(`
6
+ `):[a,`Address this repository finding: ${e.title}.`,e.detail??"",e.prompt?`How to fix it: ${e.prompt}`:"","Make the minimal change, then summarize what you changed and which files. Do not claim the app is production-ready; VibeRaven will check again."].filter(Boolean).join(`
7
+ `)}function gt(e,i){let n=e.find(a=>a.provider?.nextFix?.id===i.id);if(n)return n;let r=`${i.title} ${i.detail??""}`.toLowerCase();return e.find(a=>r.includes(a.name.toLowerCase())||r.includes(`${a.id}/`))}function xe(e){let[i,n]=[e.slice(0,e.lastIndexOf(":")),e.slice(e.lastIndexOf(":")+1)];return`${i.split("/").pop()??i}:${n}`}function ht(e){return!e.project.empty&&!!e.project.project?.scannedAt}function ft(e){return e.busy.scan||e.scan?.state==="running"}function L(e){let i=ht(e),n=ft(e),a=z(e.project,e.catalog,e.verified).filter(f=>f.step!=="absent"),c=i?e.project.missionCards?.blockers??[]:[],u=new Map((e.project.missionCards?.planSteps??[]).map(f=>[f.id,f])),o=c.map(f=>{let b=gt(a,f),{summary:x,evidence:j}=ut(f.detail),I=u.get(f.id),E=we({...f,asksFirst:f.asksFirst??I?.asksFirst,actionDestination:f.actionDestination??I?.actionDestination,requiresUserAction:f.requiresUserAction===!0||I?.requiresUserAction===!0});return{id:f.id,title:f.title,severity:f.severity,summary:x,evidence:j,locations:dt(f.detail),service:b?{id:b.id,name:b.name,mark:W(b)}:null,dashboard:E==="provider-action",actionDestination:E,prompt:pt({...f,asksFirst:f.asksFirst??I?.asksFirst},b,E)}}),p=new Map;for(let f of o){let b=f.service?.id??"app",x=p.get(b)??{key:b,name:f.service?.name??"Your code",mark:f.service?.mark??null,findings:[]};x.findings.push(f),p.set(b,x)}let s=f=>Math.min(...f.findings.map(b=>Y[b.severity])),l=[...p.values()].map(f=>({...f,findings:[...f.findings].sort((b,x)=>Y[b.severity]-Y[x.severity])})).sort((f,b)=>s(f)-s(b)||b.findings.length-f.findings.length),d=l.flatMap(f=>f.findings),h=d.filter(f=>!f.dashboard).sort((f,b)=>Y[f.severity]-Y[b.severity]),y={critical:0,warning:0,info:0};for(let f of o)y[f.severity]+=1;let g=a.map(f=>{let b=o.filter(_=>_.service?.id===f.id),x=b.filter(_=>_.severity==="critical").length,j=e.verified[f.id],I="pending",E="Unknown \xB7 not checked yet";return n?E="Checking":i&&(x?(I="fail",E=`Repo checks \xB7 ${x} blocker${x===1?"":"s"}`):b.length?(I="warn",E=`${b.length} to review`):(I="pass",E="Repo checks \xB7 no blockers found")),{id:f.id,name:f.name,area:f.area,mark:W(f),tone:I,stateText:E,findings:b.length,verified:j}}),m=h.find(f=>f.id===e.flow.fixId)??null,M=[];for(let f of a){let b=e.verified[f.id];M.push({id:`live:${f.id}`,label:`Check ${f.name} live`,detail:b?`Recorded ${f.name} check (${b.at}): ${b.summary}`:`Your agent reads your real ${f.name} project and confirms it matches the code.`,kind:"live",done:b?.ok===!0,doneBy:"viberaven",providerId:f.id});let x=f.provider?.cockpit?.proof.checks.filter(j=>j.source==="dashboard"&&j.status!=="yes")??[];for(let j of x){let I=`dash:${f.id}:${j.label}`;M.push({id:I,label:j.label==="Production secret proof"?`Production keys for ${f.name} are set where you deploy`:`${f.name}: ${j.label}`,detail:j.label==="Production secret proof"?`The keys your app reads for ${f.name} go in your hosting provider's environment settings for production. VibeRaven cannot see your dashboards, so you tick this.`:`VibeRaven cannot see your ${f.name} dashboard, so you tick this.`,kind:"dashboard",done:e.flow.checklist[I]===!0,doneBy:"you",providerId:f.id,href:Se[f.id]})}}for(let f of d.filter(b=>b.dashboard))M.push({id:`finding:${f.id}`,label:f.title,detail:`${f.summary} This clears when the next check no longer finds it.`,kind:"finding",done:!1,doneBy:"viberaven",providerId:f.service?.id,href:f.service?Se[f.service.id]:void 0});let v=h.filter(f=>f.severity==="critical").length,D={app:!0,findings:i,fix:i&&h.length>0,recheck:i&&e.flow.recheck!==null,ready:i&&v===0};return{scanned:i,scanning:n,services:g,findings:o,groups:l,fixable:h,counts:y,current:m,checklist:M,gateClear:i&&e.project.gate?.status==="clear",available:D}}function ie(e){return e.scanned?e.findings.length===0||!e.available.fix?"ready":"findings":"app"}function Ie(e,i){let n=i.flow.recheck,r=e.checklist.filter(a=>!a.done).length;return{app:e.scanning?"Checking now":e.services.length?`${e.services.length} service${e.services.length===1?"":"s"} found`:"No services found",findings:e.scanned?e.findings.length===0?"Nothing found":[e.counts.critical?`${e.counts.critical} critical`:null,`${e.findings.length} total`].filter(Boolean).join(" \xB7 "):"After the check",fix:e.scanned?e.fixable.length===0?"Nothing to fix in code":`${e.fixable.length} to fix`:"After the check",recheck:n?n.status==="running"?"Checking now":n.status==="fixed"?"Last fix held":n.status==="open"?"Still open":"Did not finish":"After a fix",ready:e.scanned?e.available.ready?e.gateClear?"No blockers found":r?`${r} step${r===1?"":"s"} left`:"Checklist done":"After the critical fixes":"After the check"}}var re=new Map,Ce=()=>{};function se(e){return`vr-canvas:${e}`}function B(e){let i=re.get(e);if(i)return i;let n={pan:{x:0,y:0},zoom:1,cards:{}};try{let r=localStorage.getItem(se(e));if(r){let a=JSON.parse(r);n={pan:a.pan??n.pan,zoom:Ne(a.zoom??1),cards:a.cards??{}}}}catch{}return re.set(e,n),n}function je(e){try{localStorage.setItem(se(e),JSON.stringify(B(e)))}catch{}}function Ne(e){return Math.min(1.6,Math.max(.5,Math.round(e*100)/100))}function mt(e){return`translate(${e.pan.x}px, ${e.pan.y}px) scale(${e.zoom})`}function yt(e,i){let n=e.cards[i];return n?`translate(${n.x}px, ${n.y}px)`:void 0}function Mt(e){return e.zoom!==1||e.pan.x!==0||e.pan.y!==0||Object.keys(e.cards).length>0}function K(e){return e.querySelector(".board")}function F(e){let i=K(e);if(!i)return;let n=B(i.dataset.layoutKey??"default");i.style.transform=mt(n);for(let r of Array.from(i.querySelectorAll("[data-card]")))r.style.transform=yt(n,r.dataset.card??"")??"";e.classList.toggle("is-moved",Mt(n)),Ce(i)}function X(e,i){let n=K(e);if(!n)return;let r=n.dataset.layoutKey??"default",a=B(r);a.zoom=Ne(a.zoom*i),F(e),je(r)}function Te(e){let i=K(e);if(!i)return;let n=i.dataset.layoutKey??"default";re.set(n,{pan:{x:0,y:0},zoom:1,cards:{}}),F(e);try{localStorage.removeItem(se(n))}catch{}}var Ae=new WeakSet;function De(e,i){if(Ce=i,Ae.has(e)){F(e);return}Ae.add(e);let n=null,r=0;e.addEventListener("pointerdown",c=>{if(c.button!==0)return;let u=c.target;if(u.closest("button, a, input, select, textarea, pre, .canvas-tools, .pr-checks"))return;let o=K(e);if(!o)return;let p=o.dataset.layoutKey??"default",s=B(p),l=u.closest("[data-card]"),d=l?.dataset.card??"";n={kind:l?"card":"pan",id:d,key:p,startX:c.clientX,startY:c.clientY,origin:l?{...s.cards[d]??{x:0,y:0}}:{...s.pan},moved:!1,pointer:c.pointerId,target:l??e}}),e.addEventListener("pointermove",c=>{if(!n||c.pointerId!==n.pointer)return;let u=c.clientX-n.startX,o=c.clientY-n.startY;if(!n.moved){if(Math.hypot(u,o)<4)return;n.moved=!0,e.setPointerCapture?.(n.pointer),e.classList.add("is-dragging"),n.target.classList.add("is-lifted")}let p=B(n.key);n.kind==="pan"?p.pan={x:Math.round(n.origin.x+u),y:Math.round(n.origin.y+o)}:p.cards[n.id]={x:Math.round(n.origin.x+u/p.zoom),y:Math.round(n.origin.y+o/p.zoom)},r||(r=requestAnimationFrame(()=>{r=0,F(e)}))});let a=c=>{!n||c.pointerId!==n.pointer||(n.moved&&(e.releasePointerCapture?.(n.pointer),e.classList.remove("is-dragging"),n.target.classList.remove("is-lifted"),F(e),je(n.key)),n=null)};e.addEventListener("pointerup",a),e.addEventListener("pointercancel",a),e.addEventListener("wheel",c=>{!c.ctrlKey&&!c.metaKey||(c.preventDefault(),X(e,c.deltaY<0?1.1:1/1.1))},{passive:!1}),F(e)}var w={check:'<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg>',arrow:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8h10M9 4l4 4-4 4"/></svg>',back:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 8H3M7 4L3 8l4 4"/></svg>',copy:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.6"/><path d="M10.5 5.5V3.6c0-.6-.5-1.1-1.1-1.1H3.6c-.6 0-1.1.5-1.1 1.1v5.8c0 .6.5 1.1 1.1 1.1h1.9"/></svg>',more:'<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>',out:'<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3H3v10h10v-3M9 3h4v4M13 3L7.5 8.5"/></svg>',scan:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 5V3.5C2 2.7 2.7 2 3.5 2H5M11 2h1.5c.8 0 1.5.7 1.5 1.5V5M14 11v1.5c0 .8-.7 1.5-1.5 1.5H11M5 14H3.5C2.7 14 2 13.3 2 12.5V11"/><circle cx="7.6" cy="7.6" r="2.4"/><path d="M9.4 9.4 11 11"/></svg>',fix:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.8 2.3a3.4 3.4 0 0 0-3.9 4.5L2.4 10.3a1.4 1.4 0 0 0 2 2l3.5-3.5a3.4 3.4 0 0 0 4.5-3.9l-2 2-1.8-.5-.5-1.8z"/></svg>',recheck:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.5 8a5.5 5.5 0 0 1-9.6 3.7M2.5 8a5.5 5.5 0 0 1 9.6-3.7"/><path d="M12.5 1.8v2.7H9.8M3.5 14.2v-2.7h2.7"/></svg>',launch:'<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 2.5v11M3 3h8.5l-1.8 2.8L11.5 8.6H3"/></svg>',pr:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="4" cy="3.5" r="1.6"/><circle cx="4" cy="12.5" r="1.6"/><circle cx="12" cy="12.5" r="1.6"/><path d="M4 5.1v5.8M12 10.9V6.5a2 2 0 0 0-2-2H7.5M9 3 7.5 4.5 9 6"/></svg>',zoomIn:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="M8 3.5v9M3.5 8h9"/></svg>',zoomOut:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="M3.5 8h9"/></svg>',reset:'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.5 6V2.5H6M13.5 10v3.5H10M2.5 2.5l4 4M13.5 13.5l-4-4"/></svg>',app:'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="1.8" y="2.5" width="12.4" height="11" rx="2"/><path d="M1.8 5.5h12.4M6 8.4 4.6 9.8 6 11.2M10 8.4l1.4 1.4-1.4 1.4"/></svg>'},bt={critical:"Critical",warning:"Important",info:"Nice to have"};function U(e){return t("span",{class:"ico",html:e})}function Q(e){return(e||"Project").replace(/^@[^/]+\//,"").split(/[-_\s]+/).filter(Boolean).map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join(" ")}function $(e){let i=e.project.project;return(i?.name&&i.name!=="Project"?i.name:(i?.path??"").split(/[\\/]/).filter(Boolean).pop())||"your-app"}function J(e,i=e.cliId){return e.agents.find(n=>n.id===i)?.label.replace(/ CLI$/,"")??(i==="claude"?"Claude Code":i==="gemini"?"Gemini":"Codex")}function Oe(e,i){let n=e.project.project,r=e.project.releases?.[0],a=Pe(e,L(e));return t("header",{class:"top",dataset:{slot:"top"}},t("span",{class:"wordmark"},"Vibe",t("b",{},"Raven")),t("span",{class:"top-project"},t("span",{class:"top-sep","aria-hidden":"true"},"/"),t("strong",{},Q($(e))),t("span",{class:"top-sep","aria-hidden":"true"},"/"),t("code",{},[r?.branch,n?.version?`v${n.version.replace(/^v/,"")}`:null].filter(Boolean).join(" \xB7 ")||"local")),t("span",{class:"spacer"}),kt(e,i),t("span",{class:`top-verdict is-${a.tone}`},t("i",{"aria-hidden":"true"}),a.text),t("div",{class:"more-wrap"},t("button",{id:"open-more",class:`quiet more-button${e.moreOpen?" on":""}`,"aria-haspopup":"menu","aria-expanded":String(e.moreOpen),"aria-controls":"more-menu",on:{click:()=>i.toggleMore()}},"More",U(w.more)),e.moreOpen?vt(e,i):null))}function kt(e,i){let n=L(e),r=e.flow.step,a=(c,u,o,p,s={})=>t("button",{id:c,class:"top-tab","aria-current":o?"page":void 0,disabled:s.disabled,on:{click:p}},u,s.count?t("span",{class:"top-tab-count"},String(s.count)):null);return t("nav",{class:"top-tabs","aria-label":"Views"},a("tab-stack","Stack",r==="app"&&!e.drawer,()=>{e.drawer&&i.toggleDrawer(null),i.goToStep("app")}),a("tab-findings","Findings",r==="findings"&&!e.drawer,()=>{e.drawer&&i.toggleDrawer(null),i.goToStep("findings")},{disabled:!n.available.findings,count:n.findings.length}),a("tab-terminal","Terminal",e.drawer==="terminal",()=>i.openMore("terminal")),a("tab-releases","Releases",e.drawer==="releases",()=>i.openMore("releases")))}function vt(e,i){let n=e.agents.filter(a=>e.probes[a.id]?.ready).length,r=[{id:"services",label:"Services",note:"Browse, add and check services live"},{id:"terminal",label:"Coding agents",note:n?`${n} connected`:"Install, sign in, test"},{id:"chat",label:"Agent chat",note:"Ask your agent anything about this app"},{id:"releases",label:"Releases",note:(e.project.releases??[]).length?"History and diffs":"Compare any two commits"}];return t("div",{id:"more-menu",class:"more-menu",role:"menu","aria-label":"More",on:{keydown:a=>{let c=a.key;if(c!=="ArrowDown"&&c!=="ArrowUp")return;a.preventDefault();let u=Array.from(a.currentTarget.querySelectorAll('[role="menuitem"]')),o=u.indexOf(document.activeElement);u[(o+(c==="ArrowDown"?1:-1)+u.length)%u.length]?.focus()}}},...r.map(a=>t("button",{role:"menuitem",class:"more-item",on:{click:()=>i.openMore(a.id)}},t("strong",{},a.label),t("span",{},a.note))))}function Ue(e,i,n){let r=Ie(i,e),a=e.flow.step,c=i.scanning||e.setup.running,u=()=>{a==="fix"&&i.current?n.checkAgain():i.available.recheck?n.goToStep("recheck"):n.checkMyApp()},o=[{key:"scan",id:"check-my-app",label:i.scanning?"Scanning":"Scan",svg:w.scan,meta:r.app,current:a==="app",disabled:c,passed:i.scanned,onClick:()=>void n.checkMyApp()},{key:"fix",label:"Fix",svg:w.fix,meta:r.fix,current:a==="fix",disabled:!i.available.fix||c,passed:!1,onClick:()=>n.goToStep("fix")},{key:"recheck",label:"Re-check",svg:w.recheck,meta:r.recheck,current:a==="recheck",disabled:!i.scanned||c,passed:e.flow.recheck?.status==="fixed",onClick:u},{key:"ready",label:"Launch",svg:w.launch,meta:r.ready,current:a==="ready",disabled:!i.available.ready,passed:!1,onClick:()=>n.goToStep("ready")}];return t("nav",{class:`rail${i.scanning?" is-scanning":""}`,"aria-label":"Launch path",dataset:{slot:"rail"}},t("ol",{},...o.map(p=>t("li",{class:`rail-step is-${p.current?"current":p.disabled?"locked":p.passed?"passed":"open"}`},t("button",{id:p.id,class:"rail-button",title:p.meta,"aria-current":p.current?"step":void 0,disabled:p.disabled,on:{click:p.onClick}},t("span",{class:"rail-mark","aria-hidden":"true",html:p.svg}),t("span",{class:"rail-copy"},t("span",{class:"rail-label"},p.label),t("span",{class:"rail-meta"},p.meta)),p.key==="scan"&&i.scanning?t("i",{class:"rail-time","aria-hidden":"true"}):null)))))}function Pe(e,i){if(i.scanning)return{text:"Checking your app",tone:"pending"};if(!i.scanned)return{text:"Not checked yet",tone:"pending"};if(i.counts.critical)return{text:`${i.counts.critical} blocker${i.counts.critical===1?"":"s"}`,tone:"fail"};if(i.findings.length)return{text:`${i.findings.length} to review`,tone:"warn"};let n=i.checklist.filter(a=>!a.done).length,r=n?` \xB7 ${n} unknown${n===1?"":"s"}`:"";return{text:i.gateClear?`No blockers in repo checks${r}`:"No blockers in repo checks",tone:"pass"}}var wt={pending:"Unknown",pass:"Repo checked",warn:"Review",fail:"Blockers"};function Lt(e){let i=e.stateText.replace(/^(Repo checks|Unknown)\s*·\s*/,"")||e.stateText;return i.charAt(0).toUpperCase()+i.slice(1)}function Ee(e,i=null){return t("li",{class:`node is-${e.tone}${e.id===i?" is-focus":""}`,dataset:{provider:e.id,card:e.id}},t("span",{class:"node-head"},e.mark?t("img",{src:e.mark,alt:"",width:18,height:18}):t("span",{class:"node-fallback"},e.name.slice(0,1)),t("span",{class:"node-name"},e.name)),e.area?t("code",{class:"node-detail"},e.area.toLowerCase()):null,t("span",{class:"node-state"},t("i",{"aria-hidden":"true"}),t("span",{class:"node-text"},Lt(e)),t("span",{class:"node-verdict"},wt[e.tone])))}function St(){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.setAttribute("class","board-lines"),e.setAttribute("aria-hidden","true"),e}function xt(e,i){let n=e.project.project,r=Pe(e,i),a=i.services.length<=3,c=a?[]:i.services.filter((l,d)=>d%2===0),u=a?i.services:i.services.filter((l,d)=>d%2===1),o=i.scanned?[n?.archetype&&n.archetype!=="unknown"?n.archetype:null,n?.scannedAt?`Checked ${O(n.scannedAt)}`:null,typeof e.project.gate?.score=="number"?`Heuristic repo-check score ${e.project.gate.score} of 100`:null].filter(l=>!!l):[],p=e.flow.step==="app"?null:e.flow.step==="fix"?i.current?.service?.id??null:e.contextProviderId,s=JSON.stringify([i.services.map(l=>[l.id,l.tone,l.stateText]),r,o,i.scanning,p]);return t("figure",{class:`board${i.scanning?" is-scanning":""}${i.services.length?a?" is-side":"":" is-solo"}`,dataset:{sig:s,lines:i.services.length?"1":"",layoutKey:e.project.project?.path||$(e)},"aria-label":`${Q($(e))} and the services found in its code`},St(),c.length?t("ul",{class:"board-col left"},...c.map(l=>Ee(l,p))):null,t("div",{class:`board-app is-${r.tone}`,dataset:{card:"app"}},t("span",{class:"node-head"},U(w.app),t("span",{class:"node-name"},Q($(e)))),t("code",{class:"board-app-name"},[$(e),e.project.releases?.[0]?.branch].filter(Boolean).join(" \xB7 ")),t("p",{class:"board-status"},t("strong",{},r.text)),o.length?t("ul",{class:"board-checks"},...o.map(l=>t("li",{},t("i",{"aria-hidden":"true"}),l))):null),u.length?t("ul",{class:"board-col right"},...u.map(l=>Ee(l,p))):null)}function le(e){let i=e.querySelector(".board-lines"),n=e.querySelector(".board-app");if(!i||!n)return;let r=e.getBoundingClientRect(),a=e.offsetWidth,c=e.offsetHeight;if(!r.width||!a)return;let u=r.width/a;if(i.setAttribute("viewBox",`0 0 ${Math.round(a)} ${Math.round(c)}`),i.setAttribute("width",String(Math.round(a))),i.setAttribute("height",String(Math.round(c))),getComputedStyle(i).display==="none"){i.innerHTML="";return}let o=n.getBoundingClientRect(),p=o.left+o.width/2,s=Array.from(e.querySelectorAll(".node")),l=y=>(y-r.left)/u,d=y=>(y-r.top)/u,h=s.map((y,g)=>{let m=y.getBoundingClientRect(),M=m.left+m.width/2<p,v=l(M?o.left:o.right),D=d(o.top+o.height/2)+(g%4-1.5)*Math.min(22,o.height/u/7),f=l(M?m.right:m.left),b=d(m.top+m.height/2),x=(v+f)/2,j=/is-(pass|warn|fail|pending)/.exec(y.className)?.[1]??"pending",I=`M ${v.toFixed(1)} ${D.toFixed(1)} C ${x.toFixed(1)} ${D.toFixed(1)} ${x.toFixed(1)} ${b.toFixed(1)} ${f.toFixed(1)} ${b.toFixed(1)}`;return`<path class="line is-${j}" d="${I}"/><path class="pulse" pathLength="1" style="animation-delay:${(g*.6).toFixed(2)}s" d="${I}"/>`});i.innerHTML=h.join("")}function N(e,i){let n=[t("h1",{id:"stage-heading",tabindex:-1},e)];return i&&n.push(t("p",{class:"stage-sub"},i)),n}function S(e,i,n={}){return t("div",{class:"primary-row"},t("button",{id:n.id??"primary-action",class:"primary",disabled:n.disabled,on:{click:i}},n.busy?t("span",{class:"spin","aria-hidden":"true"}):null,e,n.busy?null:U(w.arrow)),n.note?t("span",{class:"primary-note"},n.note):null)}function ae(e,i,n={}){return t("button",{class:"quiet",disabled:n.disabled,on:{click:i}},n.icon?U(n.icon):null,e)}function ze(e){return t("span",{class:`sev is-${e.severity}`},t("i",{"aria-hidden":"true"}),bt[e.severity])}function Fe(e,i=!1){if(!e.locations.length)return null;let[n,...r]=e.locations;return t("span",{class:"where"},t("code",{title:e.locations.join(`
8
+ `)},i?n:xe(n)),r.length?t("span",{class:"where-more"},`+${r.length} more`):null)}function It(e,i){let n=e.project.project,r=i.services.length,a=i.scanning?"Reading your code and the services it uses. Nothing leaves this computer.":r?`${r} service${r===1?"":"s"} found in this code.`:"No hosted services found in this code yet.",c=i.scanning?"Checking on this computer, offline.":i.scanned?`Last check ${O(n.scannedAt)} \xB7 runs on this computer, offline`:"Press Scan to check your app. It runs on this computer, offline.";return[t("h1",{id:"stage-heading",tabindex:-1,class:"sr-only"},Q($(e))),t("p",{class:"sr-only"},a),t("p",{class:"canvas-note",role:"status"},c)]}function At(e,i,n){let r=i.fixable[0],a=e.project.project?.scannedAt;if(!i.findings.length)return[...N("Nothing to fix",`The check ${a?O(a):""} found no blockers in this code.`),S("Go to the launch checklist",()=>n.goToStep("ready"))];let c=[i.counts.critical?`${i.counts.critical} critical`:null,i.counts.warning?`${i.counts.warning} important`:null,i.counts.info?`${i.counts.info} nice to have`:null].filter(Boolean).join(", ");return[...N(`${i.findings.length} finding${i.findings.length===1?"":"s"}`,`${c}. Critical first, grouped by service. From the check ${a?O(a):""}.`),t("div",{class:"findings"},...i.groups.map(u=>t("section",{class:"group","aria-label":u.name},t("header",{class:"group-head"},u.mark?t("img",{src:u.mark,alt:"",width:22,height:22}):t("span",{class:"group-code","aria-hidden":"true"},"</>"),t("h2",{},u.name),t("span",{class:"group-count"},String(u.findings.length))),t("ul",{},...u.findings.map(o=>{let p=o.id===r?.id,s=[ze(o),t("span",{class:"finding-title"},o.title),o.dashboard?t("span",{class:"finding-tag"},"Dashboard step"):o.actionDestination==="manual-review"?t("span",{class:"finding-tag"},"Review first"):Fe(o)];return t("li",{},o.dashboard?t("div",{class:`finding is-${o.severity} is-static`,dataset:{provider:o.service?.id??""}},...s):t("button",{class:`finding is-${o.severity}${p?" is-first":""}`,dataset:{provider:o.service?.id??""},on:{click:()=>n.fixFinding(o.id)}},...s,U(w.arrow)))}))))),r?S("Fix the first blocker",()=>n.fixFinding(),{id:"fix-first",note:r.title}):S("Go to the launch checklist",()=>n.goToStep("ready"),{note:"Review the remaining provider and live-evidence steps."})]}function Ct(e,i,n){let r=e.agents.filter(a=>a.installed);return r.length?t("div",{class:"agent-choice",role:"radiogroup","aria-label":"Coding agent"},...r.map(a=>{let c=e.probes[a.id],u=a.id===e.cliId;return t("button",{role:"radio","aria-checked":String(u),class:`agent-option${u?" on":""}`,disabled:n,on:{click:()=>i.selectCli(a.id)}},t("i",{class:c?.ready?"ok":c?"no":"","aria-hidden":"true"}),a.label.replace(/ CLI$/,""))})):null}function jt(e,i,n){let r=i.current;if(!r)return[...N("Nothing to fix in code","Choose a finding to review, or inspect the remaining checklist steps."),S("Go to the launch checklist",()=>n.goToStep("ready"))];let a=i.fixable.findIndex(h=>h.id===r.id),c=e.flow.handoff?.findingId===r.id?e.flow.handoff:null,u=J(e),o=e.probes[e.cliId],p=e.agents.filter(h=>h.installed),s=c?.status==="running",l=e.busy.probe===e.cliId,d;return s?d=S(`${u} is working`,()=>{},{disabled:!0,busy:!0,note:"It edits files in this repo. You review the change."}):c?.status==="done"?d=S("Check again",()=>void n.checkAgain(),{id:"check-again",note:"Runs the same local check to see if the fix held."}):p.length?o?.ready?d=S(c?.status==="failed"?`Send to ${u} again`:`Send to ${u}`,()=>void n.sendFix(),{id:"send-fix",note:e.accessMode==="ask"?"Ask mode is on: the agent will only plan, not edit. Change it in More, Agent chat.":`${u} edits files in this repo. You review the change.`}):d=S(l?`Connecting ${u}`:`Connect ${u}`,()=>void n.testConnection(e.cliId),{disabled:l,busy:l,note:o?o.message:`VibeRaven runs ${u} on this computer with your own sign-in.`}):d=S("Copy the prompt",()=>void n.copyFix(),{note:"No coding agent found on this computer. Paste it into any agent."}),[...N(r.title),t("div",{class:"fix-meta"},ze(r),t("span",{class:"fix-count"},`Blocker ${a+1} of ${i.fixable.length}${r.service?` \xB7 ${r.service.name}`:""}`),Fe(r,!0)),r.summary?t("p",{class:"fix-summary"},r.summary):null,r.evidence.length?t("ul",{class:"fix-evidence"},...r.evidence.slice(0,4).map(h=>t("li",{},h))):null,t("section",{class:"prompt","aria-label":"Prompt for your agent"},t("header",{},t("h2",{},"Prompt for your agent"),ae("Copy",()=>void n.copyFix(),{icon:w.copy})),t("pre",{tabindex:0},r.prompt)),Ct(e,n,s||e.busy.chat),s?t("p",{class:"working-line",role:"status"},t("span",{dataset:{working:"1"}},`${u} is working\u2026`),t("button",{class:"quiet stop",on:{click:()=>void n.stop()}},"Stop")):null,c&&c.status!=="running"?t("section",{class:`agent-reply is-${c.status}`,"aria-label":`${J(e,c.cliId)} replied`},t("h2",{},c.status==="done"?`${J(e,c.cliId)} replied`:`${J(e,c.cliId)} did not finish`),t("div",{class:"agent-reply-body",html:Z(c.output)})):null,d,t("div",{class:"quiet-row"},ae("Back to findings",()=>n.goToStep("findings"),{icon:w.back}),c?.status!=="done"?ae("Fixed it yourself? Check again",()=>void n.checkAgain(),{disabled:s||i.scanning}):null)].filter(h=>h!==null)}function Nt(e,i,n){let r=e.flow.recheck;if(!r)return[...N("Nothing to check yet","Fix a blocker first, then check again here."),S("Back to findings",()=>n.goToStep("findings"))];let a=typeof r.scoreBefore=="number"&&typeof r.scoreAfter=="number"&&r.scoreBefore!==r.scoreAfter?t("p",{class:"score-move"},`Heuristic repo-check score ${r.scoreBefore} \u2192 ${r.scoreAfter}`):null;if(r.status==="running")return[...N("Checking again",`Running the same local check to see if \u201C${r.title}\u201D is gone.`),t("div",{class:"recheck-meter",role:"status"},t("span",{class:"spin"}),"Reading the repo"),S("Checking",()=>{},{disabled:!0,busy:!0})];if(r.status==="fixed"){let c=i.fixable.find(u=>u.id===r.nextId);return[...N("Scenario passed locally",`\u201C${r.title}\u201D no longer shows up in the check.`),a,t("p",{class:"recheck-next",role:"status"},c?`Next: ${c.title}`:"That was the last blocker in the code."),c?S("Next blocker",()=>n.fixFinding(c.id),{note:"Moving on by itself in a moment."}):S("Go to the launch checklist",()=>n.goToStep("ready"),{note:"Moving on by itself in a moment."})].filter(u=>u!==null)}return r.status==="open"?[...N("Still open",`The check still finds \u201C${r.title}\u201D.`),r.message?t("p",{class:"fix-summary"},r.message):null,a,S("Back to the fix",()=>n.fixFinding(r.findingId))].filter(c=>c!==null):[...N("The check did not finish",r.message??""),S("Check again",()=>void n.checkAgain())]}function Tt(e,i,n){if(!i.checklist.length)return t("section",{class:"checklist","aria-label":"Launch checklist"},t("h2",{},"Launch checklist"),t("p",{class:"empty-line"},"No dashboard steps found for this app: VibeRaven found no hosted services in the code."));let r=i.checklist.filter(a=>!a.done).length;return t("section",{class:"checklist","aria-label":"Launch checklist"},t("h2",{},"Launch checklist",t("span",{class:"checklist-count"},r?`${r} left`:"All done")),t("ul",{},...i.checklist.map(a=>t("li",{class:`check-item${a.done?" is-done":""}`},a.doneBy==="you"?t("button",{class:"tick",role:"checkbox","aria-checked":String(a.done),"aria-label":a.label,on:{click:()=>n.toggleChecklistItem(a.id)},html:a.done?w.check:""}):t("span",{class:`tick is-auto${a.done?" on":""}`,"aria-hidden":"true",html:a.done?w.check:""}),t("div",{class:"check-copy"},t("strong",{},a.label),t("span",{},a.detail),t("span",{class:"check-who"},a.doneBy==="you"?"You confirm this":a.kind==="live"?"VibeRaven confirms this with your agent":"VibeRaven confirms this on the next check")),a.kind==="live"&&!a.done&&a.providerId?t("button",{class:"quiet",disabled:e.busy.chat||!e.probes[e.cliId]?.ready,title:e.probes[e.cliId]?.ready?void 0:"Connect a coding agent first",on:{click:()=>void n.verifyById(a.providerId)}},"Check live"):a.href?t("a",{class:"quiet",href:a.href,target:"_blank",rel:"noreferrer"},"Open dashboard",U(w.out)):null))))}function Dt(e,i){let n=e.fullCheck.status,r=P(n?.usage),a=n?.account?n.account.plan==="pro"?"Pro plan":"Free plan":null;return t("section",{class:"final","aria-label":"Full check"},t("h2",{},"Optional deeper repository review"),t("p",{},"A hosted model reviews selected repository context after you preview and confirm the upload. This does not verify live deployment behavior or capacity."),t("p",{class:"final-quota"},[a,r??"Free accounts get 2 full checks. Pro gets 50 a month."].filter(Boolean).join(" \xB7 ")),t("button",{id:"run-full-check",class:"primary",disabled:e.fullCheck.step==="running",on:{click:()=>void i.openFullCheck()}},"Run full check",U(w.arrow)))}function Et(e,i,n){if(!i.available.ready)return[...N("Not yet","Fix the critical blockers first. The launch checklist opens when none are left."),S("Back to findings",()=>n.goToStep("findings"))];let r=i.findings.filter(o=>!o.dashboard).length,a=i.gateClear?"No blockers found within tested scope":"No critical blockers left",c=i.checklist.filter(o=>!o.done).length,u=i.gateClear?c?`${c} unknown${c===1?"":"s"}: the checklist items below, which VibeRaven cannot test from this computer.`:"The listed checks are recorded or marked done by you. This is not confirmation that production is ready.":`The repository checks found no critical blockers.${r?` ${r} other finding${r===1?" is":"s are"} still open in Findings.`:""} Review the remaining findings and live-evidence checklist.`;return[...N(a,u),i.services.length?t("ul",{class:"strip","aria-label":"Services"},...i.services.map(o=>t("li",{class:`strip-item is-${o.tone}`},o.mark?t("img",{src:o.mark,alt:"",width:20,height:20}):null,o.name))):null,t("div",{class:"ready-grid"},Tt(e,i,n),Dt(e,n))].filter(o=>o!==null)}function Ot(e,i){let n=e.prChecks;if(!n.status)return null;let r=n.status.exists,a=`git add ${n.status.path} && git commit -m "Check pull requests with VibeRaven"`,c=null;if(n.open){let u=n.written?[t("h3",{},"Workflow added"),t("p",{},"Commit and push it. From the next pull request on, VibeRaven comments with what the change added and what it fixed."),t("pre",{class:"pr-command",tabindex:0},a),n.status.onGithub?null:t("p",{class:"pr-muted"},"This repository has no GitHub remote yet. The check runs once it is on GitHub."),t("div",{class:"pr-actions"},t("button",{id:"pr-checks-copy",class:"btn sm primary",on:{click:()=>void i.copyPrCommit()}},"Copy command"),t("button",{class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Done"))]:r?[t("h3",{},"Pull request checks are set up"),t("p",{},`The workflow is in ${n.status.path}. Once it is pushed, each pull request gets one comment with what it added and fixed.`),t("div",{class:"pr-actions"},t("button",{id:"pr-checks-action",class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Close"))]:[t("h3",{},"Check every pull request"),t("p",{},"VibeRaven adds one file to this repo, ",t("code",{},n.status.path),". Each pull request then gets one comment: what the change added and what it fixed."),t("ul",{class:"pr-points"},t("li",{},"Runs in your own GitHub Actions: private repos work and the code is never uploaded."),t("li",{},"Advice by default. It only blocks a merge if you turn that on.")),n.error?t("p",{class:"pr-error",role:"alert"},n.error):null,t("div",{class:"pr-actions"},t("button",{id:"pr-checks-action",class:"btn sm primary",disabled:n.busy,on:{click:()=>void i.addPrChecks()}},n.busy?"Adding\u2026":"Add the workflow"),t("button",{class:"btn sm",on:{click:()=>i.togglePrChecks(!1)}},"Not now"))];c=t("div",{id:"pr-checks-card",class:"pr-card",role:"dialog","aria-labelledby":"pr-checks-button"},...u)}return t("div",{class:"pr-checks"},t("button",{id:"pr-checks-button",class:`pr-checks-button${r?" is-on":""}`,"aria-expanded":String(n.open),"aria-controls":"pr-checks-card",on:{click:()=>i.togglePrChecks()}},U(w.pr),r?"Pull request checks added":"Check every pull request"),c)}function Ut(){let e=n=>n.currentTarget.closest(".canvas"),i=(n,r,a,c="")=>t("button",{class:`canvas-tool${c}`,title:n,"aria-label":n,html:r,on:{click:u=>{let o=e(u);o&&a(o)}}});return t("div",{class:"canvas-tools",dataset:{sig:"tools"}},i("Zoom in",w.zoomIn,n=>X(n,1.15)),i("Zoom out",w.zoomOut,n=>X(n,1/1.15)),i("Reset layout",w.reset,n=>Te(n)," is-reset"))}var oe=null;function $e(e,i){let n=L(e),r=e.flow.step,a=oe!==null&&oe!==r;oe=r;let c=r==="app"?It(e,n):r==="findings"?At(e,n,i):r==="fix"?jt(e,n,i):r==="recheck"?Nt(e,n,i):Et(e,n,i),u=r!=="app";return t("main",{class:`stage${u?" has-panel":""}`,dataset:{slot:"stage",step:r}},e.scan?.state==="error"?t("p",{class:"stage-alert",role:"alert"},e.scan.error??"The first check did not finish."):null,t("div",{class:"canvas",dataset:{slot:"canvas"}},xt(e,n),Ut(),Ot(e,i)),t("div",{class:`stage-body step-${r}${u?" panel":""}${a?" arrive":""}`,dataset:{slot:`body-${r}`}},u?t("button",{class:"panel-close quiet",on:{click:()=>i.goToStep("app")}},U(w.back),"Stack"):null,...c))}function Re(e){return L(e)}function He(e,i){let n=Array.from(e.children);i.forEach((r,a)=>{let c=n[a];if(!c){e.appendChild(r);return}let u=r.dataset?.sig;if(u&&c.dataset?.sig===u&&c.tagName===r.tagName)return;let o=r.dataset?.slot;if(o&&c.dataset?.slot===o&&c.tagName===r.tagName){for(let p of Array.from(c.attributes))r.hasAttribute(p.name)||c.removeAttribute(p.name);for(let p of Array.from(r.attributes))c.getAttribute(p.name)!==p.value&&c.setAttribute(p.name,p.value);He(c,Array.from(r.children));return}e.replaceChild(r,c)});for(let r of Array.from(e.children).slice(i.length))r.remove()}var ce=new WeakMap;function Pt(e){for(let i of Array.from(e.querySelectorAll(".canvas")))De(i,le);for(let i of Array.from(e.querySelectorAll('.board[data-lines="1"]'))){if(ce.has(i))continue;let n=()=>le(i);if(requestAnimationFrame(n),typeof ResizeObserver<"u"){let r=new ResizeObserver(n);r.observe(i),ce.set(i,r)}else ce.set(i,{disconnect(){}})}}function Ye(e,i,n){let r=i.get(),a=e.contains(document.activeElement)?document.activeElement:null,c=a?.id,u=a instanceof HTMLTextAreaElement||a instanceof HTMLInputElement?[a.selectionStart,a.selectionEnd]:null,o=Re(r);if(He(e,[Oe(r,n),Ue(r,o,n),$e(r,n),...r.agentOpen?[t("div",{class:"sheet-veil",on:{click:()=>n.toggleAgent()}}),Rt(r,i,n)]:[],...r.drawer?[t("div",{class:"drawer-veil",on:{click:()=>n.toggleDrawer(null)}}),Yt(r,i,n)]:[],...ye(r,n),Vt(r)]),Pt(e),c&&document.activeElement?.id!==c){let p=document.getElementById(c);p?.focus({preventScroll:!0}),u&&(p instanceof HTMLTextAreaElement||p instanceof HTMLInputElement)&&p.setSelectionRange(...u)}}function zt(e,i,n){let r=z(e.project,e.catalog,e.verified),a=r.filter(o=>o.step!=="absent"),c=r.filter(o=>o.step==="absent"),u=e.setup.running||e.busy.chat||e.busy.scan;return t("div",{},e.setup.open?ve(e,i,n):null,t("section",{class:"block","aria-label":"In your app"},t("div",{class:"block-head"},t("h4",{},"In your app"),t("button",{id:"connect-my-app",class:"btn sm",disabled:u,on:{click:()=>n.openStackSetup()}},"Set up with your agent")),a.length?t("div",{class:"rail-grid"},...a.map(o=>$t(o,e,n))):t("p",{class:"drawer-empty"},"No services found in this code yet.")),c.length?t("section",{class:"block","aria-label":"Available services"},t("div",{class:"block-head"},t("h4",{},"Available"),t("span",{class:"block-meta"},"Your accounts, your choice of providers")),t("div",{class:"rail-grid"},...c.map(o=>t("article",{class:"slab available"},t("div",{class:"face"},t("div",{class:"face-logo"},t("img",{src:W(o),alt:"",loading:"lazy"})),t("h3",{class:"face-name"},o.name),t("div",{class:"face-area"},o.area)),t("div",{class:"slab-act"},t("button",{class:"btn library-add",disabled:u,"aria-label":`Add ${o.name} to setup`,on:{click:()=>{n.openStackSetup(),i.get().setup.selected.includes(o.id)||n.toggleSetupProvider(o.id),document.getElementById("stack-setup-heading")?.focus()}}},"+ Add to setup")))))):null)}function Ft(e){return e.step==="ready"?{text:`Agent reported checks passed ${e.verified?O(e.verified.at):""}.`,tone:"g"}:e.step==="verified"?{text:e.verified?.ok?`Agent check ${e.verified?O(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 $t(e,i,n){let r=i.busy.tile===e.id,a=r||i.setup.running||i.busy.chat,c=Ft(e),u=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"),o=e.step==="in_repo"&&e.hasRecipe?t("button",{class:"btn primary",disabled:a,on:{click:()=>n.connect(e)}},r?t("span",{class:"spin"}):null,r?"Configuring\u2026":"Configure agent"):e.step==="in_repo"?t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},"Check with agent"):e.step==="mcp"?t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},r?t("span",{class:"spin"}):null,r?"Checking\u2026":"Check live"):t("button",{class:"btn",disabled:a,on:{click:()=>n.verify(e)}},r?t("span",{class:"spin"}):null,r?"Checking\u2026":"Check again"),p=Gt(e.logoUrl)??"#9a9a9a";return t("article",{class:`slab${e.step==="ready"?" ready":""}${r?" scanning":""}`,dataset:{provider:e.id},style:{"--brand":p}},t("div",{class:"face"},t("div",{class:"face-top"},u),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 ${c.tone}`},t("i",{class:c.tone}),t("span",{class:"txt"},c.text),e.fixes>0?t("button",{class:"fixlink",on:{click:()=>n.focusBlockers(e.id)}},`${e.fixes} to fix`):null),t("div",{class:"slab-act"},o))}function ue(e){return e.agents.find(i=>i.id===e.cliId)?.label.replace(/ CLI$/,"")??e.cliId}function Rt(e,i,n){let r=e.agents.find(d=>d.id===e.cliId),a=e.probes[e.cliId],c=a?.ready===!0,u=r?.modelOptions??(r?.models??[]).map(d=>({id:d,label:d})),o=t("div",{class:"thread"},e.messages.length?e.messages.map(d=>Ht(d,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(d=>t("button",{class:"suggest-chip",disabled:!c||e.busy.chat||e.setup.running,on:{click:()=>n.send(d)}},d)))),e.busy.chat?t("div",{class:"working"},t("span",{class:"spin"}),t("span",{dataset:{working:"1"}},`${ue(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(()=>{o.scrollTop=o.scrollHeight});let p=e.contextProviderId?z(e.project,e.catalog,e.verified).find(d=>d.id===e.contextProviderId):null,s=t("textarea",{id:"agent-composer",placeholder:c?"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:d=>{i.get().draft=d.target.value},keydown:d=>{let h=d;h.key==="Enter"&&!h.shiftKey&&(h.preventDefault(),n.send(h.target.value))}}}),l=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(d=>{let h=e.probes[d.id],y=h?.ready?"g":d.installed?"a":"";return t("button",{class:d.id===e.cliId?"on":"",disabled:e.setup.running||e.busy.chat,title:d.installed?h?.ready?"Connected":"Installed, not tested yet":"Not installed",on:{click:()=>n.selectCli(d.id)}},t("i",{class:y}),d.label.replace(/ CLI$/,"").replace("Claude Code","Claude"))}))),t("div",{class:"side-head tools"},u.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:d=>i.set({modelId:d.target.value})}},t("option",{value:"",selected:!e.modelId},"Use agent default"),e.modelId&&!u.some(d=>d.id===e.modelId)?t("option",{value:e.modelId,selected:!0},`${e.modelId} (saved selection)`):null,...u.map(d=>t("option",{value:d.id,selected:d.id===e.modelId},d.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"},l?t("span",{class:"pill"},t("span",{class:"spin"}),"Checking connection\u2026"):c?t("span",{class:"pill green",title:a?.message},t("i"),`${ue(e).replace("Claude Code","Claude")} connected`):r&&!r.installed?t("span",{class:"pill amber",title:`${r.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:l||e.busy.chat||e.setup.running,on:{click:()=>n.testConnection(e.cliId)}},c?"Test again":"Test connection"))),o,a&&!a.ready?t("div",{class:"hint"},t("b",{},a.message)," ",t("button",{class:"btn sm",on:{click:()=>n.toggleDrawer("terminal")}},"Open terminal")):null,t("div",{class:"composer"},s,t("div",{class:"row"},p?t("span",{class:"chip"},p.logoUrl?t("img",{src:p.logoUrl,alt:""}):null,p.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:d=>n.setAccessMode(d.target.value)}},...["ask","approve","full"].map(d=>t("option",{value:d,selected:d===e.accessMode},d==="ask"?"Ask \xB7 plan only":d==="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:!c||e.setup.running,on:{click:()=>n.send(s.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 Be(e,i,n=Date.now()){if(!i)return;let r=Math.max(0,Math.floor((n-i)/1e3)),a=e.querySelector("[data-working]");a&&(a.textContent=`${a.textContent?.split(" \xB7")[0]??"Working\u2026"} \xB7 ${r}s`);let c=e.querySelector("[data-slow-run]");c&&(c.hidden=r<60)}function Ht(e,i,n){let r=e.role==="me"?"You":e.role==="agent"?i.agents.find(c=>c.id===e.cliId)?.label.replace(/ CLI$/,"").replace("Claude Code","Claude")??"Agent":e.role==="error"?"Something went wrong":"VibeRaven",a=e.card?t("div",{class:"card"},t("span",{},e.card.providerId?t("img",{src:z(i.project,i.catalog,i.verified).find(c=>c.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"},r,t("span",{class:"t"},O(e.at))),t("div",{class:"body",html:e.role==="me"?`<p>${G(e.text)}</p>`:Z(e.text)}),a)}function Yt(e,i,n){let r=e.drawer==="terminal"?Bt(e,n):e.drawer==="services"?zt(e,i,n):Qt(e,i,n),a=e.drawer==="terminal"?"Coding agents":e.drawer==="services"?"Services":"Releases",c=e.drawer==="terminal"?"VibeRaven drives the agent CLI installed on this computer. Installed is not connected: test each one.":e.drawer==="services"?"What your app runs on, and what you could add. Check a service live through your agent.":"Release points in this repository, and the real diff between any two of them.";return t("div",{class:"drawer",dataset:{drawer:e.drawer??""},role:"dialog","aria-modal":"true","aria-labelledby":"drawer-heading",on:{keydown:u=>{let o=u;if(o.key==="Escape"&&(o.preventDefault(),o.stopPropagation(),n.toggleDrawer(null)),o.key!=="Tab")return;let p=Array.from(u.currentTarget.querySelectorAll("*")).filter(d=>d.matches('button:not(:disabled), input:not(:disabled), a[href], select:not(:disabled), [tabindex="0"]')),s=p[0],l=p[p.length-1];o.shiftKey&&document.activeElement===s&&(o.preventDefault(),l?.focus()),!o.shiftKey&&document.activeElement===l&&(o.preventDefault(),s?.focus())}}},t("div",{class:"drawer-head"},t("div",{class:"drawer-title"},t("h3",{id:"drawer-heading"},a),t("p",{},c)),t("button",{id:"drawer-close",class:"quiet",on:{click:()=>n.toggleDrawer(null)}},"Close")),t("div",{class:"drawer-body"},r))}function de(e,i,n,r,...a){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",{},r),a.some(Boolean)?t("div",{class:"row step-row"},...a):null))}function Bt(e,i){return t("div",{},...e.agents.map(n=>{let r=e.probes[n.id],a=r?.ready===!0,c=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 ${a?"green":n.installed?"amber":"gray"}`},t("i"),a?"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"},de(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")),de(2,"Sign in to your account",a,a?"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")),de(3,"Test the connection",a,r?.message??`Not tested in this session. VibeRaven runs ${n.setup.verifyCommand} and reads the result.`,t("button",{class:"btn sm",disabled:c,on:{click:()=>i.testConnection(n.id)}},c?t("span",{class:"spin"}):null,c?"Testing\u2026":a?"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 Qt(e,i,n){let r=e.project.releases??[],a=t("input",{id:"release-from",class:"sel","aria-label":"From revision",placeholder:"Tag, commit or branch",value:e.compare.from,on:{input:p=>{i.get().compare.from=p.target.value}}}),c=t("input",{id:"release-to",class:"sel","aria-label":"To revision",placeholder:"HEAD",value:e.compare.to,on:{input:p=>{i.get().compare.to=p.target.value}}}),u=e.compare.result,o=u?.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"},r.length?`${r.length} release point${r.length===1?"":"s"} \xB7 branch ${r[0].branch}`:"Nothing tagged yet")),r.length?t("ul",{class:"rel-list"},...r.map(p=>t("li",{class:"rel"},t("div",{class:"rel-main"},t("div",{class:"rel-line"},t("span",{class:"lbl"},p.label),t("span",{class:`tag ${p.tone==="current"?"amber":"dim"}`},p.tone==="current"?"Current":p.tone==="prod"?"Released":"Planned")),t("p",{class:"rel-sum"},p.summary),t("p",{class:"rel-meta"},`${p.meta} \xB7 ${p.branch}`)),t("button",{class:"btn sm ghost",on:{click:()=>{i.set({compare:{...i.get().compare,from:p.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",a),t("label",{},"To",c),t("div",{class:"compare-actions"},t("button",{class:"btn sm primary",disabled:e.busy.compare,on:{click:()=>n.compare(a.value,c.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(a.value,c.value)}},`Explain with ${ue(e)}`))),e.compare.error?t("p",{class:"compare-error",role:"alert"},e.compare.error):null,u?t("div",{class:"diff-result"},t("div",{class:"diff-stats"},t("span",{class:"diff-range"},`${u.fromLabel} \u2192 ${u.toLabel}`),o?t("span",{},`${o.files??0} file${o.files===1?"":"s"}`):null,o?t("span",{class:"add"},`+${o.insertions??0}`):null,o?t("span",{class:"del"},`\u2212${o.deletions??0}`):null),t("pre",{class:"out diff",tabindex:0,role:"region","aria-label":"Diff output",html:Zt(u.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 Gt(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 Zt(e){return e.split(`
7
9
  `).map(i=>{let n=G(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(`
8
- `)}function Zt(e){return t("div",{class:"toasts"},...e.toasts.map(i=>t("div",{class:`toast${i.kind==="err"?" err":""}`},i.text)))}function pe(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 Vt(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(`
9
- `)}async function Be(e){let{providers:i,mode:n,connect:s,runAgent:a,onProgress:c,cancelled:u}=e;if(!i.length)throw new Error("Select at least one service.");let o=()=>{if(u())throw new Error("Setup stopped. Configuration already written is kept; no further steps will run.")};for(let r of i)if(o(),n==="ask")c({id:r.id,state:"pending",label:`${r.name} \xB7 planning only`});else if(r.mcpConfigured)c({id:r.id,state:"configured",label:`${r.name} \xB7 MCP configuration found`});else if(r.hasRecipe){c({id:r.id,state:"working",label:`${r.name} \xB7 preparing MCP configuration`});let l=await s(r.id);if(o(),!l.ok)throw new Error(`${r.name}: ${l.message}`);c({id:r.id,state:"configured",label:`${r.name} \xB7 shared MCP recipe saved`})}else c({id:r.id,state:"pending",label:`${r.name} \xB7 agent will inspect setup options`});o(),c({id:"agent",state:"working",label:n==="ask"?"Agent is preparing your plan":"Agent is working through your stack"});let p=await a(Vt(i,n));if(o(),!p)throw new Error("The agent did not complete the setup task. Review its output and try again.");c({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 Qe(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(s=>i.includes(s)))]}function Wt(){let e=document.getElementById("vr-state");if(!e?.textContent)throw new Error("Missing initial state");return JSON.parse(e.textContent)}function Ge(e,i){let n=(e??"").trim();return n.length>i?`\u2026${n.slice(-i)}`:n}function C(e){return e instanceof Error?e.message:String(e)}function qt(e){let i=!1,n=new Set;function s(r=!1){e.set({agentOpen:!0,drawer:null}),document.getElementById(r?"agent-test-connection":"agent-composer")?.focus({preventScroll:!0}),document.getElementById("agent-panel")?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}async function a(){let[r,l,d]=await Promise.all([k.project(),k.catalog().catch(()=>({providers:[]})),k.verified().catch(()=>({verified:{}}))]);e.set({project:r,catalog:l.providers,verified:d.verified})}async function c(r,l,d){let h=e.get();if(h.busy.chat)return null;let y=h.probes[r.cliId];if(s(!y?.ready),!y?.ready)return e.toast(`Test the ${r.cliId} connection first.`,"err"),null;e.push({role:"me",text:l});let g=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},draft:"",workingSince:Date.now(),runId:g});try{let M=(await k.chat({...r,runId:g})).agentRun,w=M.output?.trim(),D=M.timedOut||M.exitCode!==null&&M.exitCode!==0||/Stopped by user/.test(M.stderr??"");if(!w&&/Stopped by user/.test(M.stderr??""))return e.push({role:"system",text:"Stopped."}),null;let f=w||(M.timedOut?`${r.cliId} did not finish in time and was stopped. Try a smaller task, or switch to ask mode for a read-only answer.`:`${r.cliId} exited with code ${M.exitCode??"unknown"} and no answer.
10
+ `)}function Vt(e){return t("div",{class:"toasts"},...e.toasts.map(i=>t("div",{class:`toast${i.kind==="err"?" err":""}`},i.text)))}function pe(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 qt(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(`
11
+ `)}async function Qe(e){let{providers:i,mode:n,connect:r,runAgent:a,onProgress:c,cancelled:u}=e;if(!i.length)throw new Error("Select at least one service.");let o=()=>{if(u())throw new Error("Setup stopped. Configuration already written is kept; no further steps will run.")};for(let s of i)if(o(),n==="ask")c({id:s.id,state:"pending",label:`${s.name} \xB7 planning only`});else if(s.mcpConfigured)c({id:s.id,state:"configured",label:`${s.name} \xB7 MCP configuration found`});else if(s.hasRecipe){c({id:s.id,state:"working",label:`${s.name} \xB7 preparing MCP configuration`});let l=await r(s.id);if(o(),!l.ok)throw new Error(`${s.name}: ${l.message}`);c({id:s.id,state:"configured",label:`${s.name} \xB7 shared MCP recipe saved`})}else c({id:s.id,state:"pending",label:`${s.name} \xB7 agent will inspect setup options`});o(),c({id:"agent",state:"working",label:n==="ask"?"Agent is preparing your plan":"Agent is working through your stack"});let p=await a(qt(i,n));if(o(),!p)throw new Error("The agent did not complete the setup task. Review its output and try again.");c({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 Ge(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(r=>i.includes(r)))]}function Wt(){let e=document.getElementById("vr-state");if(!e?.textContent)throw new Error("Missing initial state");return JSON.parse(e.textContent)}function Ze(e,i){let n=(e??"").trim();return n.length>i?`\u2026${n.slice(-i)}`:n}function C(e){return e instanceof Error?e.message:String(e)}function Kt(e){let i=!1,n=new Set;function r(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 a(){let[s,l,d]=await Promise.all([k.project(),k.catalog().catch(()=>({providers:[]})),k.verified().catch(()=>({verified:{}}))]);e.set({project:s,catalog:l.providers,verified:d.verified})}async function c(s,l,d){let h=e.get();if(h.busy.chat)return null;let y=h.probes[s.cliId];if(r(!y?.ready),!y?.ready)return e.toast(`Test the ${s.cliId} connection first.`,"err"),null;e.push({role:"me",text:l});let g=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},draft:"",workingSince:Date.now(),runId:g});try{let M=(await k.chat({...s,runId:g})).agentRun,v=M.output?.trim(),D=M.timedOut||M.exitCode!==null&&M.exitCode!==0||/Stopped by user/.test(M.stderr??"");if(!v&&/Stopped by user/.test(M.stderr??""))return e.push({role:"system",text:"Stopped."}),null;let f=v||(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.
10
12
 
11
- ${Ge(M.stderr,1200)}`);return!w||D?e.push({role:"error",text:f,cliId:r.cliId}):e.push({role:"agent",text:f,cliId:r.cliId,card:d}),(r.taskKind==="fix"||r.taskKind==="plan")&&await a().catch(()=>{}),D||!w?null:f}catch(m){return e.push({role:"error",text:C(m)}),null}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}}function u(){queueMicrotask(()=>document.getElementById("stage-heading")?.focus({preventScroll:!0}))}function o(){let r=e.get();return{cliId:r.cliId,accessMode:r.accessMode,modelId:r.modelId||void 0}}let p={...fe(e),setSection(r){e.get().setup.running||(e.set(l=>({section:r,setup:{...l.setup,open:!1}})),document.getElementById(`tab-${r}`)?.focus({preventScroll:!0}))},toggleAgent(){let r=!e.get().agentOpen;e.set({agentOpen:r}),document.getElementById(r?"agent-composer":"open-more")?.focus({preventScroll:!0}),r&&document.getElementById("agent-panel")?.scrollIntoView?.({behavior:"smooth",block:"nearest"})},openStackSetup(){let r=e.get();e.set({section:"stack",drawer:"services",moreOpen:!1,setup:{...r.setup,open:!0,initialized:r.setup.initialized||r.catalog.length>0,selected:r.setup.initialized?r.setup.selected:pe(r.catalog)}}),document.getElementById("stack-setup-heading")?.focus({preventScroll:!0})},toggleSetupProvider(r){let l=e.get();if(l.setup.running)return;let d=l.setup.selected.includes(r)?l.setup.selected.filter(h=>h!==r):[...l.setup.selected,r];e.set({setup:{...l.setup,initialized:!0,selected:d,progress:[],error:null}})},async startStackSetup(){let r=e.get();if(r.setup.running||r.busy.chat||r.busy.tile||r.busy.scan)return;if(s(!r.probes[r.cliId]?.ready),!r.probes[r.cliId]?.ready){e.toast(`Connect ${r.cliId} in the agent panel first.`,"err");return}let l=r.catalog.filter(h=>r.setup.selected.includes(h.id));if(!l.length){e.toast("Select at least one service.","err");return}let d=o();i=!1,e.set({setup:{...r.setup,running:!0,progress:[],error:null}});try{await Be({providers:l,mode:d.accessMode,connect:h=>k.connectMcp(h),cancelled:()=>i,onProgress:h=>e.set(y=>({setup:{...y.setup,progress:[...y.setup.progress.filter(g=>g.id!==h.id),h]}})),runAgent:h=>c({...d,taskKind:d.accessMode==="ask"?"plan":"fix",prompt:h},`${d.accessMode==="ask"?"Plan":"Set up"} my stack: ${l.map(y=>y.name).join(", ")}`,{label:"Review the response, then check your app",action:"recheck"})})}catch(h){e.set(y=>({setup:{...y.setup,error:C(h)}}))}finally{await a().catch(()=>{}),e.set(h=>({setup:{...h.setup,running:!1}}))}},async stop(){e.get().setup.running&&(i=!0);let r=e.get().runId;if(r)try{await k.stop(r),e.toast("Stopped.")}catch(l){e.toast(C(l),"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 k.scan(),await a(),e.toast("Check finished.")}catch(r){e.toast(`Check failed: ${C(r)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},toggleDrawer(r){let l=e.get().drawer;e.set(d=>({drawer:d.drawer===r?null:r})),document.getElementById(e.get().drawer?"drawer-close":"open-more")?.focus({preventScroll:!0})},selectCli(r){if(e.get().setup.running||e.get().busy.chat)return;e.set({cliId:r,modelId:""}),e.get().agents.find(d=>d.id===r)?.installed&&!e.get().probes[r]&&p.testConnection(r)},setAccessMode(r){e.get().setup.running||e.get().busy.chat||e.set({accessMode:r})},async testConnection(r,l){if(!n.has(r)){n.add(r),e.set({busy:{...e.get().busy,probe:r}});try{let d=await k.probe(r);e.set(h=>({probes:{...h.probes,[r]:d},terminalOutput:d.output||d.message})),l?.silent||e.toast(d.message,d.ready?"ok":"err")}catch(d){e.set(h=>{let y={...h.probes};return delete y[r],{probes:y}}),e.toast(C(d),"err")}finally{n.delete(r),e.set(d=>({busy:{...d.busy,probe:d.busy.probe===r?null:d.busy.probe}}))}}},async runSetup(r,l){e.set({terminalOutput:`$ ${l}\u2026`});try{let d=await k.runSetup(r,l);e.set({terminalOutput:`$ ${d.command}
12
- ${d.output}`.trim()});let h=await k.agents();e.set({agents:h.agents.filter(y=>y.id==="codex"||y.id==="claude"||y.id==="gemini")})}catch(d){e.set({terminalOutput:C(d)})}},async openTerminal(r,l){try{let d=await k.openTerminal(r,l);e.set({terminalOutput:`Opened a terminal with: ${d.command}
13
- Sign in there, then press Test connection.`})}catch(d){e.toast(C(d),"err")}},async send(r){if(e.get().setup.running)return;let l=r.trim();if(!l)return;let d=e.get(),h=d.contextProviderId?d.catalog.find(y=>y.id===d.contextProviderId):null;await c({...o(),prompt:l,taskKind:"analyze",provider:h?{id:h.id,name:h.name,area:h.area}:void 0},l)},async connect(r){if(!(e.get().setup.running||e.get().busy.chat||e.get().busy.tile)){s(),e.set({busy:{...e.get().busy,tile:r.id}});try{let l=await k.connectMcp(r.id);e.toast(l.message,l.ok?"ok":"err"),await a(),l.ok&&e.push({role:"system",text:`${l.message} ${r.note??""}`.trim(),card:{providerId:r.id,label:`${r.name} \xB7 MCP configured`,action:"verify"}})}catch(l){e.toast(C(l),"err")}finally{e.set({busy:{...e.get().busy,tile:null}})}}},async verify(r){return p.verifyById(r.id)},async verifyById(r){let l=e.get();if(l.setup.running||l.busy.chat||l.busy.tile)return;let h=(l.catalog.find(m=>m.id===r)??l.project.providers.find(m=>m.id===r))?.name??r,y=l.probes[l.cliId];if(s(!y?.ready),!y?.ready){e.toast(`Test the ${l.cliId} connection first.`,"err");return}e.push({role:"me",text:`Check ${h} live`});let g=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,tile:r,chat:!0},workingSince:Date.now(),runId:g});try{let m=await k.verify({providerId:r,...o(),runId:g}),M=m.agentRun.output?.trim()||m.agentRun.stderr?.trim()||"No output.";e.push({role:"agent",text:M,cliId:l.cliId,card:{providerId:r,label:m.verified.ok?`${h} \xB7 verified live`:`${h} \xB7 issues found`}}),await a()}catch(m){e.push({role:"error",text:C(m)})}finally{e.set({busy:{...e.get().busy,tile:null,chat:!1},workingSince:null,runId:null})}},async addProvider(r){e.get().setup.running||await c({...o(),taskKind:"fix",provider:{id:r.id,name:r.name,area:r.area},prompt:`Add ${r.name} (${r.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 ${r.name} to this app`,{providerId:r.id,label:`${r.name} \xB7 added to repo`,action:"recheck"})},async fix(r,l){if(e.get().setup.running)return;let d=l?.provider?.nextFix?.id===r.id&&l.provider.nextFix.prompt?l.provider.nextFix.prompt:`Fix this production blocker in the repo now: ${r.title}. ${r.detail??""} Make the minimal change, then summarize what you changed and which files.`,h=r.asksFirst?`${r.asksFirst} Tell the user this before you change anything, and make the change only if they confirm.
14
- ${d}`:d;await c({...o(),taskKind:"fix",provider:l?{id:l.id,name:l.name,area:l.area}:void 0,prompt:h},`Fix: ${r.title}`,{providerId:l?.id,label:"Re-check to update the score",action:"recheck"})},async explain(r,l){e.get().setup.running||await c({...o(),taskKind:"analyze",provider:l?{id:l.id,name:l.name,area:l.area}:void 0,prompt:`This blocker needs dashboard work: ${r.title}. ${r.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: ${r.title}`)},async fixAll(){if(e.get().setup.running)return;let{missionCards:r}=e.get().project,l=r.blockers.filter(d=>!d.asksFirst&&r.planSteps.some(h=>h.id===d.id&&!h.requiresUserAction&&!h.asksFirst));l.length&&await c({...o(),taskKind:"fix",prompt:`Fix these production blockers in the repo, one by one, minimal changes each:
13
+ ${Ze(M.stderr,1200)}`);return!v||D?e.push({role:"error",text:f,cliId:s.cliId}):e.push({role:"agent",text:f,cliId:s.cliId,card:d}),(s.taskKind==="fix"||s.taskKind==="plan")&&await a().catch(()=>{}),D||!v?null:f}catch(m){return e.push({role:"error",text:C(m)}),null}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}}function u(){queueMicrotask(()=>document.getElementById("stage-heading")?.focus({preventScroll:!0}))}function o(){let s=e.get();return{cliId:s.cliId,accessMode:s.accessMode,modelId:s.modelId||void 0}}let p={...fe(e),setSection(s){e.get().setup.running||(e.set(l=>({section:s,setup:{...l.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":"open-more")?.focus({preventScroll:!0}),s&&document.getElementById("agent-panel")?.scrollIntoView?.({behavior:"smooth",block:"nearest"})},openStackSetup(){let s=e.get();e.set({section:"stack",drawer:"services",moreOpen:!1,setup:{...s.setup,open:!0,initialized:s.setup.initialized||s.catalog.length>0,selected:s.setup.initialized?s.setup.selected:pe(s.catalog)}}),document.getElementById("stack-setup-heading")?.focus({preventScroll:!0})},toggleSetupProvider(s){let l=e.get();if(l.setup.running)return;let d=l.setup.selected.includes(s)?l.setup.selected.filter(h=>h!==s):[...l.setup.selected,s];e.set({setup:{...l.setup,initialized:!0,selected:d,progress:[],error:null}})},async startStackSetup(){let s=e.get();if(s.setup.running||s.busy.chat||s.busy.tile||s.busy.scan)return;if(r(!s.probes[s.cliId]?.ready),!s.probes[s.cliId]?.ready){e.toast(`Connect ${s.cliId} in the agent panel first.`,"err");return}let l=s.catalog.filter(h=>s.setup.selected.includes(h.id));if(!l.length){e.toast("Select at least one service.","err");return}let d=o();i=!1,e.set({setup:{...s.setup,running:!0,progress:[],error:null}});try{await Qe({providers:l,mode:d.accessMode,connect:h=>k.connectMcp(h),cancelled:()=>i,onProgress:h=>e.set(y=>({setup:{...y.setup,progress:[...y.setup.progress.filter(g=>g.id!==h.id),h]}})),runAgent:h=>c({...d,taskKind:d.accessMode==="ask"?"plan":"fix",prompt:h},`${d.accessMode==="ask"?"Plan":"Set up"} my stack: ${l.map(y=>y.name).join(", ")}`,{label:"Review the response, then check your app",action:"recheck"})})}catch(h){e.set(y=>({setup:{...y.setup,error:C(h)}}))}finally{await a().catch(()=>{}),e.set(h=>({setup:{...h.setup,running:!1}}))}},async stop(){e.get().setup.running&&(i=!0);let s=e.get().runId;if(s)try{await k.stop(s),e.toast("Stopped.")}catch(l){e.toast(C(l),"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 k.scan(),await a(),e.toast("Check finished.")}catch(s){e.toast(`Check failed: ${C(s)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},toggleDrawer(s){let l=e.get().drawer;e.set(d=>({drawer:d.drawer===s?null:s})),document.getElementById(e.get().drawer?"drawer-close":"open-more")?.focus({preventScroll:!0})},selectCli(s){if(e.get().setup.running||e.get().busy.chat)return;e.set({cliId:s,modelId:""}),e.get().agents.find(d=>d.id===s)?.installed&&!e.get().probes[s]&&p.testConnection(s)},setAccessMode(s){e.get().setup.running||e.get().busy.chat||e.set({accessMode:s})},async testConnection(s,l){if(!n.has(s)){n.add(s),e.set({busy:{...e.get().busy,probe:s}});try{let d=await k.probe(s);e.set(h=>({probes:{...h.probes,[s]:d},terminalOutput:d.output||d.message})),l?.silent||e.toast(d.message,d.ready?"ok":"err")}catch(d){e.set(h=>{let y={...h.probes};return delete y[s],{probes:y}}),e.toast(C(d),"err")}finally{n.delete(s),e.set(d=>({busy:{...d.busy,probe:d.busy.probe===s?null:d.busy.probe}}))}}},async runSetup(s,l){e.set({terminalOutput:`$ ${l}\u2026`});try{let d=await k.runSetup(s,l);e.set({terminalOutput:`$ ${d.command}
14
+ ${d.output}`.trim()});let h=await k.agents();e.set({agents:h.agents.filter(y=>y.id==="codex"||y.id==="claude"||y.id==="gemini")})}catch(d){e.set({terminalOutput:C(d)})}},async openTerminal(s,l){try{let d=await k.openTerminal(s,l);e.set({terminalOutput:`Opened a terminal with: ${d.command}
15
+ Sign in there, then press Test connection.`})}catch(d){e.toast(C(d),"err")}},async send(s){if(e.get().setup.running)return;let l=s.trim();if(!l)return;let d=e.get(),h=d.contextProviderId?d.catalog.find(y=>y.id===d.contextProviderId):null;await c({...o(),prompt:l,taskKind:"analyze",provider:h?{id:h.id,name:h.name,area:h.area}:void 0},l)},async connect(s){if(!(e.get().setup.running||e.get().busy.chat||e.get().busy.tile)){r(),e.set({busy:{...e.get().busy,tile:s.id}});try{let l=await k.connectMcp(s.id);e.toast(l.message,l.ok?"ok":"err"),await a(),l.ok&&e.push({role:"system",text:`${l.message} ${s.note??""}`.trim(),card:{providerId:s.id,label:`${s.name} \xB7 MCP configured`,action:"verify"}})}catch(l){e.toast(C(l),"err")}finally{e.set({busy:{...e.get().busy,tile:null}})}}},async verify(s){return p.verifyById(s.id)},async verifyById(s){let l=e.get();if(l.setup.running||l.busy.chat||l.busy.tile)return;let h=(l.catalog.find(m=>m.id===s)??l.project.providers.find(m=>m.id===s))?.name??s,y=l.probes[l.cliId];if(r(!y?.ready),!y?.ready){e.toast(`Test the ${l.cliId} connection first.`,"err");return}e.push({role:"me",text:`Check ${h} live`});let g=`${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:g});try{let m=await k.verify({providerId:s,...o(),runId:g}),M=m.agentRun.output?.trim()||m.agentRun.stderr?.trim()||"No output.";e.push({role:"agent",text:M,cliId:l.cliId,card:{providerId:s,label:m.verified.ok?`${h} \xB7 verified live`:`${h} \xB7 issues found`}}),await a()}catch(m){e.push({role:"error",text:C(m)})}finally{e.set({busy:{...e.get().busy,tile:null,chat:!1},workingSince:null,runId:null})}},async addProvider(s){e.get().setup.running||await c({...o(),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,l){if(e.get().setup.running)return;let d=l?.provider?.nextFix?.id===s.id&&l.provider.nextFix.prompt?l.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.`,h=s.asksFirst?`${s.asksFirst} Tell the user this before you change anything, and make the change only if they confirm.
16
+ ${d}`:d;await c({...o(),taskKind:"fix",provider:l?{id:l.id,name:l.name,area:l.area}:void 0,prompt:h},`Fix: ${s.title}`,{providerId:l?.id,label:"Re-check to update the score",action:"recheck"})},async explain(s,l){e.get().setup.running||await c({...o(),taskKind:"analyze",provider:l?{id:l.id,name:l.name,area:l.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,l=s.blockers.filter(d=>!d.asksFirst&&s.planSteps.some(h=>h.id===d.id&&!h.requiresUserAction&&!h.asksFirst));l.length&&await c({...o(),taskKind:"fix",prompt:`Fix these production blockers in the repo, one by one, minimal changes each:
15
17
  ${l.map((d,h)=>`${h+1}. ${d.title}`).join(`
16
18
  `)}
17
- After each, note the files touched. Do not claim production-ready; I will re-check.`},`Fix all ${l.length} repo blockers`,{label:"Re-check to update the score",action:"recheck"})},focusBlockers(r){if(!S(e.get()).available.findings)return;e.set(d=>({section:"findings",drawer:null,contextProviderId:r,setup:{...d.setup,open:!1},flow:{...d.flow,step:"findings"}}));let l=Array.from(document.querySelectorAll(".finding")).find(d=>d.dataset.provider===r)??document.getElementById("stage-heading");l?.focus({preventScroll:!0}),l?.scrollIntoView?.({behavior:"smooth",block:"center"})},async compare(r,l){if(!r.trim()||!l.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:r,to:l,error:null}});try{let d=await k.compare(r.trim(),l.trim());e.set({compare:{from:r,to:l,result:d,error:null}})}catch(d){e.set({compare:{from:r,to:l,result:null,error:C(d)}})}finally{e.set({busy:{...e.get().busy,compare:!1}})}},async explainDiff(r,l){e.get().setup.running||await c({...o(),taskKind:"diff",release:{id:`${r.trim()}..${l.trim()}`,label:`${r.trim()} \u2192 ${l.trim()}`},prompt:`Explain what changed between ${r.trim()} and ${l.trim()} in this repo, in plain words. Call out anything risky for production: auth, database writes, webhooks, env, payments.`},`Explain ${r.trim()} \u2192 ${l.trim()}`)},goToStep(r){let l=S(e.get());l.available[r]&&(r==="fix"&&!l.current&&e.flow({fixId:l.fixable[0]?.id??null,handoff:null}),e.flow({step:r}),u())},async checkMyApp(){let r=e.get();if(!(r.busy.scan||r.setup.running)){e.set({busy:{...r.busy,scan:!0}});try{await k.scan(),await a();let l=S(e.get());e.flow({step:ie(l),fixId:null,handoff:null,recheck:null}),u()}catch(l){e.toast(`The check did not finish: ${C(l)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},fixFinding(r){let l=S(e.get()),d=r?l.fixable.find(h=>h.id===r):l.fixable[0];d&&(e.flow({step:"fix",fixId:d.id,handoff:e.get().flow.handoff?.findingId===d.id?e.get().flow.handoff:null}),u())},async sendFix(){let r=e.get(),l=S(r).current;if(!l||r.busy.chat||r.setup.running||!r.probes[r.cliId]?.ready&&(await p.testConnection(r.cliId),!e.get().probes[r.cliId]?.ready))return;let d=e.get().cliId,h=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},workingSince:Date.now(),runId:h}),e.flow({handoff:{findingId:l.id,cliId:d,status:"running",output:""}}),e.push({role:"me",text:`Fix: ${l.title}`});try{let g=(await k.chat({...o(),runId:h,taskKind:"fix",prompt:l.prompt,displayPrompt:`Fix: ${l.title}`,provider:l.service?{id:l.service.id,name:l.service.name,area:""}:void 0})).agentRun,m=/Stopped by user/.test(g.stderr??""),M=g.timedOut||m||g.exitCode!==null&&g.exitCode!==0||!g.output?.trim(),w=g.output?.trim()||(m?"Stopped.":g.timedOut?`${d} did not finish in time and was stopped.`:`${d} exited with code ${g.exitCode??"unknown"} and no answer.
19
+ After each, note the files touched. Do not claim production-ready; I will re-check.`},`Fix all ${l.length} repo blockers`,{label:"Re-check to update the score",action:"recheck"})},focusBlockers(s){if(!L(e.get()).available.findings)return;e.set(d=>({section:"findings",drawer:null,contextProviderId:s,setup:{...d.setup,open:!1},flow:{...d.flow,step:"findings"}}));let l=Array.from(document.querySelectorAll(".finding")).find(d=>d.dataset.provider===s)??document.getElementById("stage-heading");l?.focus({preventScroll:!0}),l?.scrollIntoView?.({behavior:"smooth",block:"center"})},async compare(s,l){if(!s.trim()||!l.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:l,error:null}});try{let d=await k.compare(s.trim(),l.trim());e.set({compare:{from:s,to:l,result:d,error:null}})}catch(d){e.set({compare:{from:s,to:l,result:null,error:C(d)}})}finally{e.set({busy:{...e.get().busy,compare:!1}})}},async explainDiff(s,l){e.get().setup.running||await c({...o(),taskKind:"diff",release:{id:`${s.trim()}..${l.trim()}`,label:`${s.trim()} \u2192 ${l.trim()}`},prompt:`Explain what changed between ${s.trim()} and ${l.trim()} in this repo, in plain words. Call out anything risky for production: auth, database writes, webhooks, env, payments.`},`Explain ${s.trim()} \u2192 ${l.trim()}`)},goToStep(s){let l=L(e.get());l.available[s]&&(s==="fix"&&!l.current&&e.flow({fixId:l.fixable[0]?.id??null,handoff:null}),e.flow({step:s}),u())},async checkMyApp(){let s=e.get();if(!(s.busy.scan||s.setup.running)){e.set({busy:{...s.busy,scan:!0}});try{await k.scan(),await a();let l=L(e.get());e.flow({step:ie(l),fixId:null,handoff:null,recheck:null}),u()}catch(l){e.toast(`The check did not finish: ${C(l)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},fixFinding(s){let l=L(e.get()),d=s?l.fixable.find(h=>h.id===s):l.fixable[0];d&&(e.flow({step:"fix",fixId:d.id,handoff:e.get().flow.handoff?.findingId===d.id?e.get().flow.handoff:null}),u())},async sendFix(){let s=e.get(),l=L(s).current;if(!l||s.busy.chat||s.setup.running||!s.probes[s.cliId]?.ready&&(await p.testConnection(s.cliId),!e.get().probes[s.cliId]?.ready))return;let d=e.get().cliId,h=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},workingSince:Date.now(),runId:h}),e.flow({handoff:{findingId:l.id,cliId:d,status:"running",output:""}}),e.push({role:"me",text:`Fix: ${l.title}`});try{let g=(await k.chat({...o(),runId:h,taskKind:"fix",prompt:l.prompt,displayPrompt:`Fix: ${l.title}`,provider:l.service?{id:l.service.id,name:l.service.name,area:""}:void 0})).agentRun,m=/Stopped by user/.test(g.stderr??""),M=g.timedOut||m||g.exitCode!==null&&g.exitCode!==0||!g.output?.trim(),v=g.output?.trim()||(m?"Stopped.":g.timedOut?`${d} did not finish in time and was stopped.`:`${d} exited with code ${g.exitCode??"unknown"} and no answer.
18
20
 
19
- ${Ge(g.stderr,1200)}`);e.flow({handoff:{findingId:l.id,cliId:d,status:M?"failed":"done",output:w}}),e.push({role:M?"error":"agent",text:w,cliId:d})}catch(y){e.flow({handoff:{findingId:l.id,cliId:d,status:"failed",output:C(y)}})}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}},async copyFix(){let r=S(e.get()).current;if(r)try{await navigator.clipboard.writeText(r.prompt),e.toast("Prompt copied. Paste it into your coding agent.")}catch{e.toast("Could not copy. Select the prompt and copy it by hand.","err")}},async checkAgain(){let r=e.get(),l=S(r).current;if(!l||r.busy.scan)return;let d=r.project.gate?.score;e.flow({step:"recheck",recheck:{findingId:l.id,title:l.title,status:"running",scoreBefore:d}}),e.set({busy:{...e.get().busy,scan:!0}}),u();try{await k.scan(),await a();let h=S(e.get()),y=h.findings.find(M=>M.id===l.id),g=e.get().project.gate?.score;if(y){e.flow({recheck:{findingId:l.id,title:l.title,status:"open",message:y.summary,scoreBefore:d,scoreAfter:g}});return}let m=h.fixable[0]??null;e.flow({recheck:{findingId:l.id,title:l.title,status:"fixed",nextId:m?.id??null,scoreBefore:d,scoreAfter:g}}),window.setTimeout(()=>{let M=e.get().flow;if(M.step!=="recheck"||M.recheck?.findingId!==l.id||M.recheck.status!=="fixed")return;let w=S(e.get());m&&w.fixable.some(D=>D.id===m.id)?e.flow({step:"fix",fixId:m.id,handoff:null}):e.flow({step:"ready",fixId:null,handoff:null}),u()},1600)}catch(h){e.flow({recheck:{findingId:l.id,title:l.title,status:"error",message:C(h),scoreBefore:d}})}finally{e.set({busy:{...e.get().busy,scan:!1}})}},toggleChecklistItem(r){let l={...e.get().flow.checklist,[r]:!e.get().flow.checklist[r]};e.flow({checklist:l})},togglePrChecks(r){let l=r??!e.get().prChecks.open;e.set(d=>({prChecks:{...d.prChecks,open:l,error:null}})),l?queueMicrotask(()=>document.getElementById("pr-checks-action")?.focus({preventScroll:!0})):document.getElementById("pr-checks-button")?.focus({preventScroll:!0})},async addPrChecks(){if(!e.get().prChecks.busy){e.set(r=>({prChecks:{...r.prChecks,busy:!0,error:null}}));try{let r=await k.addGithubWorkflow();e.set(l=>({prChecks:{...l.prChecks,status:r.status,written:r.written,busy:!1}})),queueMicrotask(()=>document.getElementById("pr-checks-copy")?.focus({preventScroll:!0}))}catch(r){e.set(l=>({prChecks:{...l.prChecks,busy:!1,error:C(r)}}))}}},async copyPrCommit(){let r=e.get().prChecks.status?.path??".github/workflows/viberaven.yml";try{await navigator.clipboard.writeText(`git add ${r} && git commit -m "Check pull requests with VibeRaven"`),e.toast("Copied. Run it, then push.")}catch{e.toast("Could not copy. Select the command and copy it by hand.","err")}},toggleMore(r){let l=r??!e.get().moreOpen;e.set({moreOpen:l}),l?queueMicrotask(()=>document.querySelector('#more-menu [role="menuitem"]')?.focus({preventScroll:!0})):document.getElementById("open-more")?.focus({preventScroll:!0})},openMore(r){if(e.set({moreOpen:!1}),r==="chat"){s();return}if(r==="services"){e.set({drawer:"services",agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}));return}e.set({drawer:r,agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}))}};return p}function Kt(){let e=document.getElementById("app");if(!e)return;let i=be(Wt()),n=qt(i),s=()=>He(e,i,n);i.subscribe(s),s(),document.addEventListener("keydown",u=>{let o=i.get().fullCheck.step;if(u.key==="Escape"&&o!=="closed"){o!=="running"&&n.closeFullCheck();return}if(u.key==="Escape"&&i.get().moreOpen){n.toggleMore(!1);return}if(u.key==="Escape"&&i.get().prChecks.open){n.togglePrChecks(!1);return}if(u.key==="Escape"&&i.get().agentOpen){n.toggleAgent();return}u.key==="Escape"&&i.get().drawer&&n.toggleDrawer(null)}),document.addEventListener("pointerdown",u=>{!i.get().moreOpen||u.target?.closest("#more-menu, #open-more")||i.set({moreOpen:!1})});let a=()=>{let u=i.get();if(!u.catalog.length||u.setup.running||u.busy.chat)return;let o=Qe(window.location.hash,u.catalog.map(p=>p.id));o!==null&&(i.set({section:"stack",drawer:"services",agentOpen:!1,moreOpen:!1,setup:{...u.setup,open:!0,initialized:!0,selected:o,progress:[],error:null}}),history.replaceState(null,"",window.location.pathname+window.location.search),document.getElementById("stack-setup-heading")?.focus())};window.addEventListener("hashchange",a),k.catalog().then(u=>{i.set(o=>({catalog:u.providers,setup:o.setup.open&&!o.setup.initialized?{...o.setup,initialized:!0,selected:pe(u.providers)}:o.setup})),a()}).catch(()=>{}),k.verified().then(u=>i.set({verified:u.verified})).catch(()=>{}),k.githubWorkflow().then(u=>i.set(o=>({prChecks:{...o.prChecks,status:u}}))).catch(()=>{}),k.agents().then(u=>{i.set({agents:u.agents.filter(p=>p.id==="codex"||p.id==="claude"||p.id==="gemini")});let o=u.agents.find(p=>p.id===i.get().cliId);if(o&&!o.installed){let p=u.agents.find(r=>r.installed);p&&i.set({cliId:p.id})}n.testConnection(i.get().cliId,{silent:!0})}).catch(()=>{});let c=async()=>{try{let u=await k.scanStatus();if(i.set({scan:u}),u.state==="running")window.setTimeout(c,1500);else if(u.state==="done"&&i.get().project.empty){let o=await k.project();i.set({project:o}),i.get().flow.step==="app"&&i.flow({step:ie(S(i.get()))})}}catch{}};c(),window.setInterval(()=>{Ye(document,i.get().workingSince)},1e3)}Kt();})();
21
+ ${Ze(g.stderr,1200)}`);e.flow({handoff:{findingId:l.id,cliId:d,status:M?"failed":"done",output:v}}),e.push({role:M?"error":"agent",text:v,cliId:d})}catch(y){e.flow({handoff:{findingId:l.id,cliId:d,status:"failed",output:C(y)}})}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}},async copyFix(){let s=L(e.get()).current;if(s)try{await navigator.clipboard.writeText(s.prompt),e.toast("Prompt copied. Paste it into your coding agent.")}catch{e.toast("Could not copy. Select the prompt and copy it by hand.","err")}},async checkAgain(){let s=e.get(),l=L(s).current;if(!l||s.busy.scan)return;let d=s.project.gate?.score;e.flow({step:"recheck",recheck:{findingId:l.id,title:l.title,status:"running",scoreBefore:d}}),e.set({busy:{...e.get().busy,scan:!0}}),u();try{await k.scan(),await a();let h=L(e.get()),y=h.findings.find(M=>M.id===l.id),g=e.get().project.gate?.score;if(y){e.flow({recheck:{findingId:l.id,title:l.title,status:"open",message:y.summary,scoreBefore:d,scoreAfter:g}});return}let m=h.fixable[0]??null;e.flow({recheck:{findingId:l.id,title:l.title,status:"fixed",nextId:m?.id??null,scoreBefore:d,scoreAfter:g}}),window.setTimeout(()=>{let M=e.get().flow;if(M.step!=="recheck"||M.recheck?.findingId!==l.id||M.recheck.status!=="fixed")return;let v=L(e.get());m&&v.fixable.some(D=>D.id===m.id)?e.flow({step:"fix",fixId:m.id,handoff:null}):e.flow({step:"ready",fixId:null,handoff:null}),u()},1600)}catch(h){e.flow({recheck:{findingId:l.id,title:l.title,status:"error",message:C(h),scoreBefore:d}})}finally{e.set({busy:{...e.get().busy,scan:!1}})}},toggleChecklistItem(s){let l={...e.get().flow.checklist,[s]:!e.get().flow.checklist[s]};e.flow({checklist:l})},togglePrChecks(s){let l=s??!e.get().prChecks.open;e.set(d=>({prChecks:{...d.prChecks,open:l,error:null}})),l?queueMicrotask(()=>document.getElementById("pr-checks-action")?.focus({preventScroll:!0})):document.getElementById("pr-checks-button")?.focus({preventScroll:!0})},async addPrChecks(){if(!e.get().prChecks.busy){e.set(s=>({prChecks:{...s.prChecks,busy:!0,error:null}}));try{let s=await k.addGithubWorkflow();e.set(l=>({prChecks:{...l.prChecks,status:s.status,written:s.written,busy:!1}})),queueMicrotask(()=>document.getElementById("pr-checks-copy")?.focus({preventScroll:!0}))}catch(s){e.set(l=>({prChecks:{...l.prChecks,busy:!1,error:C(s)}}))}}},async copyPrCommit(){let s=e.get().prChecks.status?.path??".github/workflows/viberaven.yml";try{await navigator.clipboard.writeText(`git add ${s} && git commit -m "Check pull requests with VibeRaven"`),e.toast("Copied. Run it, then push.")}catch{e.toast("Could not copy. Select the command and copy it by hand.","err")}},toggleMore(s){let l=s??!e.get().moreOpen;e.set({moreOpen:l}),l?queueMicrotask(()=>document.querySelector('#more-menu [role="menuitem"]')?.focus({preventScroll:!0})):document.getElementById("open-more")?.focus({preventScroll:!0})},openMore(s){if(e.set({moreOpen:!1}),s==="chat"){r();return}if(s==="services"){e.set({drawer:"services",agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}));return}e.set({drawer:s,agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}))}};return p}function Xt(){let e=document.getElementById("app");if(!e)return;let i=be(Wt()),n=Kt(i),r=()=>Ye(e,i,n);i.subscribe(r),r(),document.addEventListener("keydown",u=>{let o=i.get().fullCheck.step;if(u.key==="Escape"&&o!=="closed"){o!=="running"&&n.closeFullCheck();return}if(u.key==="Escape"&&i.get().moreOpen){n.toggleMore(!1);return}if(u.key==="Escape"&&i.get().prChecks.open){n.togglePrChecks(!1);return}if(u.key==="Escape"&&i.get().agentOpen){n.toggleAgent();return}u.key==="Escape"&&i.get().drawer&&n.toggleDrawer(null)}),document.addEventListener("pointerdown",u=>{!i.get().moreOpen||u.target?.closest("#more-menu, #open-more")||i.set({moreOpen:!1})});let a=()=>{let u=i.get();if(!u.catalog.length||u.setup.running||u.busy.chat)return;let o=Ge(window.location.hash,u.catalog.map(p=>p.id));o!==null&&(i.set({section:"stack",drawer:"services",agentOpen:!1,moreOpen:!1,setup:{...u.setup,open:!0,initialized:!0,selected:o,progress:[],error:null}}),history.replaceState(null,"",window.location.pathname+window.location.search),document.getElementById("stack-setup-heading")?.focus())};window.addEventListener("hashchange",a),k.catalog().then(u=>{i.set(o=>({catalog:u.providers,setup:o.setup.open&&!o.setup.initialized?{...o.setup,initialized:!0,selected:pe(u.providers)}:o.setup})),a()}).catch(()=>{}),k.verified().then(u=>i.set({verified:u.verified})).catch(()=>{}),k.githubWorkflow().then(u=>i.set(o=>({prChecks:{...o.prChecks,status:u}}))).catch(()=>{}),k.agents().then(u=>{i.set({agents:u.agents.filter(p=>p.id==="codex"||p.id==="claude"||p.id==="gemini")});let o=u.agents.find(p=>p.id===i.get().cliId);if(o&&!o.installed){let p=u.agents.find(s=>s.installed);p&&i.set({cliId:p.id})}n.testConnection(i.get().cliId,{silent:!0})}).catch(()=>{});let c=async()=>{try{let u=await k.scanStatus();if(i.set({scan:u}),u.state==="running")window.setTimeout(c,1500);else if(u.state==="done"&&i.get().project.empty){let o=await k.project();i.set({project:o}),i.get().flow.step==="app"&&i.flow({step:ie(L(i.get()))})}}catch{}};c(),window.setInterval(()=>{Be(document,i.get().workingSince)},1e3)}Xt();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viberaven/cli",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "VibeRaven CLI and local Studio: Supabase RLS and security check for AI-built Vercel + Supabase apps, with an agent task list and fix prompts.",
5
5
  "license": "MIT",
6
6
  "author": "VibeRaven",