@verirun/cli 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -495,17 +495,25 @@ workflows, recent runs.
495
495
  ```bash
496
496
  verirun agent > .verirun/AGENT.md # save it as context for your agent
497
497
  verirun agent --json # machine-readable form
498
- verirun agent --skill --install # .claude/skills/verirun/SKILL.md
498
+ verirun agent --skill --install # .claude/skills/verirun/SKILL.md
499
+ verirun agent --skill --install cursor # .cursor/rules/verirun.mdc
500
+ verirun agent --skill --install all # both
499
501
  ```
500
502
 
501
- `--skill` emits the same knowledge as a **Claude Code skill** — YAML frontmatter
502
- with a `description` that tells Claude when to load it, then a shorter body
503
- aimed at deciding *which* command to reach for. With `--install` it writes
504
- `.claude/skills/verirun/SKILL.md` in the repo, and Claude Code loads it on its
505
- own whenever a task looks like app testing. Re-run it after upgrading verirun;
506
- the file is generated, not hand-maintained.
503
+ `--skill` emits the same knowledge as an agent skill — frontmatter with a
504
+ `description` that tells the agent when to load it, then a shorter body aimed at
505
+ deciding *which* command to reach for. `--install` writes it where the agent
506
+ looks:
507
507
 
508
- Paste the output into `CLAUDE.md`, `.cursorrules`, an `AGENTS.md`, or pipe it
508
+ | Target | File | Loaded |
509
+ |---|---|---|
510
+ | `claude` (default) | `.claude/skills/verirun/SKILL.md` | automatically, when a task looks like app testing |
511
+ | `cursor` | `.cursor/rules/verirun.mdc` | when the task matches its description (an agent-requested rule, not always-on) |
512
+ | `all` | both | |
513
+
514
+ Re-run it after upgrading verirun; the file is generated, not hand-maintained.
515
+
516
+ For any other agent, paste the output into `CLAUDE.md`, an `AGENTS.md`, or pipe it
509
517
  straight into a prompt. No account needed. The agent then knows to run
510
518
  `verirun run <name>`, read exit code + `.verirun/runs/<name>-<newest>/logs.json`,
511
519
  and act on `status` / `error` / `entries` without you explaining the tool.
@@ -655,6 +663,30 @@ run this often.
655
663
 
656
664
  ## Changelog
657
665
 
666
+ ### 0.2.4
667
+
668
+ - **`verirun map` reads the import aliases your project actually declares.**
669
+ Only `"@/*": ["./src/*"]` was understood before; a `paths` entry resolved
670
+ against `baseUrl` (`"@/*": ["*"]`) or inherited through `extends` — the two
671
+ shapes `create-next-app` and most monorepos emit — silently produced no
672
+ aliases at all. Every `@/…` import then resolved to nothing, so the child
673
+ components a page renders were never analysed and each page was reported as
674
+ empty: pages listed, zero elements, zero effects, zero edges, no warning.
675
+ - **An unresolvable import alias now says so, and says what to do.** `map`
676
+ prints the exact `--alias` flag to re-run with, instead of quietly reporting
677
+ an app it could not read as an app with nothing in it. A scoped npm package
678
+ is not mistaken for a broken alias.
679
+ - **`verirun agent --skill --install` now installs for Cursor too.** `--install
680
+ cursor` writes `.cursor/rules/verirun.mdc` as an agent-requested rule, `--install
681
+ all` writes that and the Claude Code skill; a bare `--install` still means Claude
682
+ Code.
683
+ - **`verirun record --url` checks the URL is up before opening a browser.** A
684
+ dev server that is not running produced a raw Node stack trace from
685
+ Playwright's child process, followed by a message blaming the `jsonl` codegen
686
+ target — pointing at the wrong thing entirely. It now stops with
687
+ `Nothing is listening at http://localhost:3000`. The message for a codegen
688
+ exit that genuinely recorded nothing no longer leads with the `jsonl` theory.
689
+
658
690
  ### 0.2.3
659
691
 
660
692
  - **`verirun whoami` shows this machine's fingerprint**, in the same 24-character
package/dist/cli.js CHANGED
@@ -1,40 +1,42 @@
1
1
  #!/usr/bin/env node
2
2
  import{createRequire as __cr}from'node:module';const require=__cr(import.meta.url);
3
- import{createPublicKey as Gn,verify as Hn}from"node:crypto";import{readFileSync as Kn}from"node:fs";import Er from"node:path";import{fileURLToPath as Jn}from"node:url";import{Command as Yn}from"commander";import se from"node:os";import{setTimeout as xe}from"node:timers/promises";var Ce=!1,Ar=["https_proxy","HTTPS_PROXY","http_proxy","HTTP_PROXY"];function B(){for(let e of Ar){let r=process.env[e]?.trim();if(r)return r}}function Nr(e,r=process.env.NO_PROXY??process.env.no_proxy){let o=r?.trim();if(!o)return!1;if(o==="*")return!0;let t=e.toLowerCase();return o.split(",").map(i=>i.trim().toLowerCase().replace(/^\./,"").split(":")[0]??"").filter(Boolean).some(i=>t===i||t.endsWith(`.${i}`))}async function Lr(e){if(Ce)return;Ce=!0;let r=B();if(!r)return;let o;try{o=(typeof e=="string"?new URL(e):e).hostname}catch{return}if(!Nr(o))try{let{ProxyAgent:t,setGlobalDispatcher:i}=await import("undici");i(new t(r))}catch{}}async function E(e,r){return await Lr(e),fetch(e,r)}function je(e){let r=Tr(e);if(r)switch(r){case"ENOTFOUND":case"EAI_AGAIN":return`${r} \u2014 the address could not be resolved. A DNS filter or a captive portal will do this.`;case"ECONNREFUSED":case"ECONNRESET":case"EHOSTUNREACH":case"ENETUNREACH":return`${r} \u2014 the connection was blocked. ${Ie()}`;case"UND_ERR_CONNECT_TIMEOUT":case"ETIMEDOUT":return`${r} \u2014 the connection timed out. ${Ie()}`;case"UNABLE_TO_GET_ISSUER_CERT_LOCALLY":case"SELF_SIGNED_CERT_IN_CHAIN":case"DEPTH_ZERO_SELF_SIGNED_CERT":case"CERT_HAS_EXPIRED":return`${r} \u2014 the TLS certificate was not trusted. A proxy that inspects traffic causes this; point NODE_EXTRA_CA_CERTS at your organisation's CA file.`;default:return r}}function Ie(){let e=B();return e?`Reached through the proxy ${e}, so check that the proxy is correct and running.`:"If this network needs a proxy, set HTTPS_PROXY."}function Tr(e){for(let r=e,o=0;r&&o<4;o++){if(typeof r=="object"&&"code"in r&&typeof r.code=="string")return r.code;r=typeof r=="object"&&"cause"in r?r.cause:void 0}}import{spawn as Pr}from"node:child_process";function L(e){let r=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",o=process.platform==="win32"?["/c","start","",e]:[e];try{let t=Pr(r,o,{stdio:"ignore",detached:!0});t.on("error",()=>{}),t.unref()}catch{}}var _r=!!process.stdout.isTTY&&!process.env.NO_COLOR,P=(e,r)=>_r?`\x1B[${e}m${r}\x1B[0m`:r,n={info:e=>console.log(e),step:e=>console.log(`${P("90","\xB7")} ${e}`),success:e=>console.log(`${P("32","\u2713")} ${e}`),warn:e=>console.warn(`${P("33","!")} ${e}`),error:e=>console.error(`${P("31","\u2717")} ${e}`),dim:e=>P("90",e),bold:e=>P("1",e)};var T="0.2.3";var Or=1440*60*1e3;function ae(){return import("./gate.mjs")}async function Ae(e){let{getMachineId:r,saveGlobalConfig:o,clearLicenseState:t,loadGlobalConfig:i,resolveServer:s,persistLease:a}=await ae(),c=await i(),l=e.server?e.server.replace(/\/+$/,""):s(c.licenseServer);if(c.token&&!e.force){n.info("This machine is already connected. Run `verirun whoami`, or"),n.info("`verirun login --force` to connect it to a different account.");return}let d=await r(),p;try{p=await E(`${l}/api/cli/link`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fingerprint:d,hostname:se.hostname(),os:`${se.platform()} ${se.release()}`,cliVersion:T})})}catch(h){let u=je(h);throw new Error(`Could not reach ${l}.${u?`
4
- ${u}`:" Check your connection."}`)}if(!p.ok)throw new Error(p.status===429?`${l} is rate limiting this machine (429). Wait a few minutes and try again.`:`${l} could not start the login (HTTP ${p.status}). This is a server-side problem, not your connection.`);let f=await p.json(),g=`${f.verifyUrl}?code=${encodeURIComponent(f.userCode)}`;n.info(""),n.info("To connect this machine to your Verirun account:"),n.info(""),n.info(` 1. Open ${n.bold(f.verifyUrl)}`),n.info(` 2. Enter ${n.bold(f.userCode)}`),n.info(""),n.info(n.dim(`(trying to open ${g} for you)`)),L(g),n.info(""),n.step("Waiting for approval in the browser..."),e.server&&await o({licenseServer:l});let m=Date.now()+f.expiresIn*1e3,w=Math.max(2,f.interval)*1e3;for(;Date.now()<m;){await xe(w);let h=await E(`${l}/api/cli/link/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:f.deviceCode,fingerprint:d})}).catch(()=>{});if(!h)continue;if(h.status===429){await xe(w);continue}let u=await h.json().catch(()=>({status:"server_error"}));if(u.status==="ok"&&u.token){await o({token:u.token,licenseKey:void 0}),await t();let v={kind:"token",value:u.token,server:l},S=u.license?.lease;if(S){await a(v,S);let $=u.license,x=$?.planName??$?.plan??"trial",A=typeof $?.seats=="number"&&$.seats>1?`, ${$.seats} machine seats`:"";n.success(`Connected. Plan: ${x} (${$?.status??"ok"})${A}.`)}else u.license&&u.license.valid===!1?(n.success("Connected."),u.license.reason==="trial_device_limit"?n.warn("This machine has already been used for the free trial on two other accounts, so record and run are blocked. Email support to request another trial, or subscribe from your account."):n.warn(`The account is connected but not active (${u.license.reason??u.license.status??"unknown"}). Check your subscription at your account page.`)):n.success("Connected.");return}if(u.status!=="pending"){if(u.status==="expired")throw new Error("The code expired. Run `verirun login` again.");if(u.status==="denied")throw new Error("The request was denied in the browser.");if(u.status==="no_license")throw new Error("That account has no license. Contact support.");if(u.status==="fingerprint_mismatch")throw new Error("This machine does not match the one that started the login.")}}throw new Error("Timed out waiting for approval. Run `verirun login` again.")}async function Ne(){let{loadGlobalConfig:e,resolveServer:r,saveGlobalConfig:o,clearLicenseState:t}=await ae(),i=await e(),s=r(i.licenseServer);i.token&&await E(`${s}/api/cli/logout`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:i.token})}).catch(()=>{}),await o({token:void 0,licenseKey:void 0}),await t(),n.success("Disconnected this machine. Run `verirun login` to reconnect.")}async function Le(e){let{resolveCredential:r,checkWithServer:o,persistLease:t,readStoredLease:i,getMachineId:s}=await ae(),a=await r();if(n.info(""),!a){n.info(n.bold("Verirun: not connected")),n.info(""),n.info(`Run ${n.bold("verirun login")} to connect this machine.`),n.info("");return}let c=e.server?e.server.replace(/\/+$/,""):a.server,l={...a,server:c};n.info(n.bold("Verirun")),n.info(` credential ${a.kind==="token"?"device token":"license key"}`+(process.env.VERIRUN_LICENSE_KEY?n.dim(" (from $VERIRUN_LICENSE_KEY)"):"")),n.info(` server ${c}`),n.info(` machine ${(await s()).slice(0,24)}\u2026`);let d=await o(l);if(d.reachable&&d.lease){await t(l,d.lease);let m=(await i(l))?.payload;if(n.info(` status ${n.bold(m?.status??"valid")}`),m?.planName||m?.plan){let w=m.planName&&m.plan&&m.planName!==m.plan?n.dim(` (${m.plan})`):"";n.info(` plan ${m.planName??m.plan}${w}`)}typeof m?.seats=="number"&&n.info(` seats ${m.seats>1e3?"unlimited":`${m.seats} machine${m.seats===1?"":"s"}`}`),m?.exp&&n.info(` lease until ${new Date(m.exp*1e3).toISOString()}`),n.info(""),n.info(n.dim("Checked just now, lease signature verified.")),n.info("");return}if(d.reachable&&d.result&&!d.result.valid){n.info(` status ${d.result.status??"invalid"} (${d.result.reason??"\u2014"})`),n.info(""),n.info("record and run will not proceed."),n.info("");return}n.warn(" the license server is not reachable right now."),d.detail&&n.info(` reason ${d.detail}`);let p=B();p&&!d.detail?.includes(p)&&n.info(` network using proxy ${p}`);let f=await i(l);if(f){let g=Math.floor((Date.now()-f.payload.iat*1e3)/Or);n.info(` lease valid, issued ${g} day${g===1?"":"s"} ago`),n.info(n.dim(" Nags after 15 days offline, stops after 30."))}else n.info(n.dim(" No valid lease stored. Connect to the internet and run this again."));n.info("")}import{existsSync as Ve}from"node:fs";import{mkdir as Jr,readdir as Me,writeFile as Yr}from"node:fs/promises";import{join as Fe}from"node:path";import{existsSync as le}from"node:fs";import{mkdir as Br,readFile as Te,writeFile as Gr}from"node:fs/promises";import Hr from"node:path";import{execFile as Dr}from"node:child_process";import{chmod as Ur}from"node:fs/promises";import Vr from"node:os";import{promisify as Fr}from"node:util";var Mr=Fr(Dr);async function ce(e,r){if(process.platform!=="win32")try{return await Ur(e,r==="dir"?448:384),!0}catch{return!1}let o=Wr();if(!o)return!1;let t=r==="dir"?`${o}:(OI)(CI)F`:`${o}:F`;try{return await Mr("icacls",[e,"/inheritance:r","/grant:r",t],{timeout:1e4,windowsHide:!0}),!0}catch{return!1}}function Wr(){let e=process.env.USERNAME;if(!e)try{e=Vr.userInfo().username}catch{return}if(!e)return;let r=process.env.USERDOMAIN;return r&&r!==e?`${r}\\${e}`:e}var Pe="data-testid";async function N(e){let r={};if(le(e)){let a=await Te(e,"utf8");try{r=JSON.parse(a)}catch(c){throw new Error(`Config file is not valid JSON: ${e}`,{cause:c})}}let o=process.env.VERIRUN_SUPABASE_ACCESS_TOKEN;o&&(r.supabase={...r.supabase,accessToken:o});let t=process.env.VERIRUN_RAILWAY_TOKEN;t&&(r.railway={...r.railway,token:t});let i=process.env.VERIRUN_VERCEL_DRAIN_SECRET;i&&(r.vercel={...r.vercel,drainSecret:i});let s=process.env.VERIRUN_VERCEL_TOKEN?.trim();return s&&(r.vercel={...r.vercel,token:s}),r}async function _e(e,r){let o={};if(le(e))try{o=JSON.parse(await Te(e,"utf8"))}catch(a){throw new Error(`Config file is not valid JSON: ${e}`,{cause:a})}let t={...o,...r,supabase:r.supabase?{...o.supabase,...r.supabase}:o.supabase,vercel:r.vercel?{...o.vercel,...r.vercel}:o.vercel,railway:r.railway?{...o.railway,...r.railway}:o.railway},i=Hr.dirname(e),s=le(i);return await Br(i,{recursive:!0,mode:448}),s||await ce(i,"dir"),await Gr(e,`${JSON.stringify(t,null,2)}
5
- `,{mode:384}),ce(e,"file")}import{existsSync as Oe}from"node:fs";import C from"node:path";var G=".verirun";function Kr(e=process.cwd()){let r=C.resolve(e),o;for(;;){if(Oe(C.join(r,".git")))return r;!o&&Oe(C.join(r,"package.json"))&&(o=r);let t=C.dirname(r);if(t===r)break;r=t}return o??C.resolve(e)}function y(e){let r=Kr(e),o=C.join(r,G);return{repoRoot:r,dataDir:o,workflowsDir:C.join(o,"workflows"),runsDir:C.join(o,"runs"),configPath:C.join(o,"config.json")}}function _(e,r){return C.join(e.workflowsDir,`${r}.json`)}function De(e=new Date){return e.toISOString().replace(/[:.]/g,"-")}function Ue(e,r,o){return C.join(e.runsDir,`${r}-${o}`)}var H=1;function qr(e){return e.commands.filter(r=>r.name()!=="help").map(r=>{let o=r.registeredArguments.map(t=>t.required?`<${t.name()}>`:`[${t.name()}]`).join(" ");return{name:r.name(),usage:`verirun ${r.name()}${o?` ${o}`:""}${r.options.length?" [options]":""}`,description:r.description(),options:r.options.map(t=>({flags:t.flags,description:t.description}))}})}async function Xr(e){try{return(await Me(e)).filter(r=>r.endsWith(".json")).map(r=>r.slice(0,-5)).sort()}catch{return[]}}async function zr(e,r){try{return(await Me(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort().slice(-r).reverse()}catch{return[]}}async function Qr(){let e=y(),r={};try{r=await N(e.configPath)}catch{}let o=["supabase","vercel","railway"].filter(t=>r[t]);return{repoRoot:e.repoRoot,dataDir:e.dataDir,dataDirExists:Ve(e.dataDir),configPath:e.configPath,configExists:Ve(e.configPath),logSources:[...o],userFilter:typeof r.userFilter=="string"?r.userFilter:null,workflows:await Xr(e.workflowsDir),recentRuns:await zr(e.runsDir,5)}}var de="verirun records a browser workflow once, replays those exact steps headless on demand, and captures the backend logs produced during the replay. Deterministic: the same recording gives the same run and the same answer. `verirun map` is the static half: it reads a React/TypeScript repo and emits the interaction graph \u2014 every page, the interactive elements on it, where they navigate, and the backend calls they make \u2014 without running anything.",ue=["```jsonc","{",' "schemaVersion": 1,',' "name": "<same as the filename>",',' "createdAt": "<ISO>",',' "startUrl": "https://app.example.com/login", // optional',' "browser": "chromium", // chromium | firefox | webkit',' "channel": "chrome", // optional: installed browser',' "steps": [',' { "index": 0, "action": "navigate", "params": { "url": "https://app.example.com/login" }, "signals": [] },',' { "index": 1, "action": "fill", "selector": "role=textbox[name=\\"Email\\"i]", "params": { "text": "ada@example.com" }, "signals": [] },',' { "index": 2, "action": "click", "selector": "role=button[name=\\"Log in\\"i]", "params": {}, "signals": [] }'," ]","}","```","","**Click your way through the app; do not walk it by URL.** Use `navigate` for the","first step, and after that reach a page by clicking the thing that goes there \u2014 a","workflow that jumps between URLs proves nothing about the UI, and a dead link or a","button that stopped submitting still passes. `verirun map --bfs <route> --depth 2`","prints each reachable page with the element that gets you there, and every element","in `map --json` carries the `selector` to click. Navigate mid-workflow only for a","page with no path to it, or to deliberately deep-link into a state.","","Actions and their required `params`: `navigate` (`url`, absolute), `click` /","`dblclick`, `fill` (`text`), `press` (`key`), `check` / `uncheck`, `select`","(`values`), `setInputFiles` (`files`). Everything except `navigate` needs a","`selector`. An unknown action stops the run; `assert*` is skipped with a warning.","`selector` goes straight to `page.locator()`, so it must be Playwright selector",'syntax \u2014 `role=button[name="Log in"i]`, `[data-testid="x"]`, or CSS.'],fe=["Anything behind a login needs a browser profile that is already signed in.","Pass the profile to `record` and `run`:","","```bash","# macOS / Linux \u2014 the shell expands ~ before verirun sees it","verirun run <name> --channel chrome --user-data-dir ~/.verirun-profile","verirun record <name> --channel chrome --user-data-dir ~/.verirun-profile","```","","```powershell","# Windows \u2014 cmd and PowerShell do NOT expand ~ inside this argument, so pass an",'# absolute path. A literal ~ creates a directory named "~" and the run silently',"# starts logged out.",'verirun run <name> --channel chrome --user-data-dir "$env:USERPROFILE\\.verirun-profile"',"```","","verirun never expands `~` itself \u2014 the path goes straight through to Playwright.","","The profile has to be created once **by a human**, because identity providers","refuse to authenticate an automation-launched browser:","","```bash","# macOS / Linux",'google-chrome --user-data-dir="$HOME/.verirun-profile" --password-store=basic',"```","","```powershell","# Windows (PowerShell)",'& "$env:ProgramFiles\\Google\\Chrome\\Application\\chrome.exe" `',' --user-data-dir="$env:USERPROFILE\\.verirun-profile"',"```","","Sign in to the app in that window, then close it.","","`--password-store=basic` (and `--use-mock-keychain` on macOS) matter on Unix:","Playwright passes both on every platform, and cookies written under the OS keyring","cannot be decrypted without them \u2014 the run would silently start logged out.","Both switches are Unix-only, so on Windows they are ignored and the profile just","has to be created by the same Windows user that runs verirun. The Windows path is","untested \u2014 if a run there starts logged out despite a signed-in profile, report","that rather than guessing.","","On every platform, do not point `--user-data-dir` at the human's everyday Chrome","profile.","","If you are asked to test a signed-in flow and no such profile exists, say so and","give the command above rather than trying to script the login."],pe=["A human records the workflow once: `verirun record <name> --url <app-url>` (needs a display).","After a code change, run it: `verirun run <name>`. Add `--user <email>` to keep only that user's log lines.","Exit code 0 = every step replayed. Exit code 1 = a step failed, or a licensing / setup error.","Read `.verirun/runs/<name>-<newest>/logs.json`: check `status`; on `failed` read `error` and `steps.failedAt`; then scan `entries` for the backend's side \u2014 a 200 that hid an exception, a write that never landed, a job that threw after the screen said done.","`verirun run` writes logs.json even when replay fails, so partial logs survive.","Do not edit files under `.verirun/workflows/` by hand unless you understand the selector format; re-record instead.","`verirun map` needs no recording and no run: use it to find what a page can do before writing a workflow, `--json` for the whole graph, `--bfs <route> --depth N` for what is reachable from one page."];function Zr(e,r){let o=[],t=(i="")=>{o.push(i)};t("# verirun \u2014 agent reference"),t(),t(de),t(),t(`Version ${T}. Full docs: https://get-verirun.duely.in and the bundled README.md / \`man verirun\`.`),t(),t("## This checkout"),t(),t(`- repo root: ${e.repoRoot}`),t(`- data dir: ${e.dataDir} ${e.dataDirExists?"(exists)":"(not created yet)"}`),t(`- config: ${e.configPath} ${e.configExists?"(present)":"(absent)"}`),t(`- log sources: ${e.logSources.length?e.logSources.join(", "):"none configured \u2014 `verirun run` still replays, just with no backend logs"}`),t(`- user filter: ${e.userFilter??"none"}`),t(`- workflows: ${e.workflows.length?e.workflows.join(", "):"none recorded yet"}`),t(`- recent runs: ${e.recentRuns.length?e.recentRuns.join(", "):"none yet"}`),t(),t("Account: `record`, `run` and `map` need a connected account (`verirun login`, or `$VERIRUN_LICENSE_KEY` in CI). `verirun whoami` shows status. `--help`, `--version`, `verirun log`, and `verirun agent` do not need one."),t(),t("## Commands");for(let i of r){t(),t(`### ${i.usage}`),i.description&&t(i.description);for(let s of i.options)t(`- \`${s.flags}\` \u2014 ${s.description}`)}t(),t("## `.verirun/` layout (at the repo root shown above)"),t(),t("```"),t(".verirun/"),t(" config.json log sources, userFilter, testIdAttribute"),t(" workflows/<name>.json one recorded workflow each"),t(" runs/<name>-<timestamp>/logs.json captured logs, one directory per run"),t("```"),t(),t("Per-user, not per-project: `~/.verirun/config.json` (device token), `~/.verirun/state.json` (signed license lease)."),t(),t(`## logs.json (schemaVersion ${H})`),t(),t("```jsonc"),t("{"),t(` "schemaVersion": ${H},`),t(' "workflow": "<name>",'),t(' "status": "ok" | "failed", // "failed" => process exit code 1'),t(' "window": { "startedAt": "<ISO>", "endedAt": "<ISO>" },'),t(' "steps": { "total": N, "replayed": N, "failedAt"?: N },'),t(' "error"?: "<message>", // present only when status is "failed"'),t(' "filter"?: { "user": "<needle>" }, // present when --user / config.userFilter narrowed entries'),t(' "sources": [ { "id": "supabase"|"vercel"|"railway", "name": "...", "entries": N } ],'),t(' "entries": ['),t(" {"),t(' "source": "supabase"|"vercel"|"railway",'),t(' "stream": "<sub-stream, e.g. edge_logs / lambda>",'),t(' "timestamp": "<ISO>",'),t(' "level": "<info|warn|error|...>",'),t(' "message": "<rendered log line>",'),t(' "raw": { /* provider payload, untouched */ }'),t(" }"),t(" ]"),t("}"),t("```"),t(),t("`entries` is every source merged and sorted by `timestamp`. When a `--user` filter is active, `entries` and every `sources[].entries` count are post-filter."),t(),t("## Writing a workflow yourself"),t(),t("`verirun map --json` gives every page element a `selector`, a `selectorConfidence` (`high` / `medium` / `low`) and a suggested `action`. That is enough to author `.verirun/workflows/<name>.json` without recording:"),t();for(let i of ue)t(i);t(),t("Then `verirun workflow check <name>` (add `--json` for machine-readable findings) validates shape, actions, selectors and params without opening a browser. It cannot tell you a selector matches the live page \u2014 only `verirun run <name>` can. Prefer `high`-confidence selectors; a `low` one is a guess. A recorded workflow is still more faithful, so do not overwrite one with a generated file: pick a different name."),t(),t("## Signed-in runs"),t();for(let i of fe)t(i);return t(),t("## Recommended agent loop"),t(),pe.forEach((i,s)=>t(`${s+1}. ${i}`)),t(),t("Save this into your agent context: `verirun agent > .verirun/AGENT.md`, or paste it into `CLAUDE.md` / `.cursorrules` / an AGENTS.md. `verirun agent --json` emits the same information as JSON."),t(),o.join(`
6
- `)}function et(e,r){let o=[],t=(i="")=>{o.push(i)};t("---"),t("name: verirun"),t("description: >-"),t(" Test this app end to end with verirun: map the interaction graph to find what a"),t(" page does, replay a recorded browser workflow, and read the backend logs that the"),t(" replay produced. Use when asked to test a user flow, verify a change end to end,"),t(" reproduce a bug, or find out what a page can do and which API calls it makes."),t("---"),t(),t("# verirun"),t(),t(de),t(),t("## Decide which command you need"),t(),t("| You want to | Command | Needs a recording? |"),t("|---|---|---|"),t("| Know what a page does / which endpoints it calls | `verirun map` | no |"),t("| Know what is reachable from a page | `verirun map --bfs /route --depth 2` | no |"),t("| Re-run a user flow after a change | `verirun run <name>` | yes |"),t("| Write a test for a flow yourself | `verirun map --json` then author the workflow | no |"),t("| Validate what you wrote | `verirun workflow check <name>` | no |"),t("| Capture a flow faithfully (incl. auth) | ask the human to run `verirun record <name>` | \u2014 |"),t(),t("## Static analysis first \u2014 `verirun map`"),t(),t("`map` reads the source and needs no browser, so reach for it before anything else."),t("It reports every page, the interactive elements on it, where they navigate, and the"),t("backend calls each one makes. `--json` gives the whole graph for programmatic use."),t("Limits to keep in mind: a target computed at runtime shows as `unresolved`, an"),t("endpoint passed through a variable as `?`, and Supabase `.auth.*` calls are not"),t("classified yet. `verirun map --reach` shows how much of each page it actually"),t("attached, so check it before trusting a page that looks empty."),t(),t("## Replay \u2014 `verirun run <name>`"),t(),t("A workflow is either recorded by a human (ground truth) or written by you from the"),t("map (a guess until `run` confirms it). Do not edit a recorded one by hand. Recording"),t("needs a display and a human, so ask for it rather than attempting it. For anything"),t("behind a login, see **Signed-in runs** below."),t(),pe.slice(1).forEach((i,s)=>t(`${s+1}. ${i}`)),t(),t("## Writing a workflow from the map"),t(),t("`verirun map --json` gives each element a `selector`, a `selectorConfidence`"),t("(`high`/`medium`/`low`) and a suggested `action`, so you can author"),t("`.verirun/workflows/<name>.json` yourself instead of asking for a recording:"),t();for(let i of ue)t(i);t(),t("Loop: write the file \u2192 `verirun workflow check <name>` (static: shape, actions,"),t("params, selectors \u2014 no browser) \u2192 fix \u2192 `verirun run <name>` to find out whether"),t("the selectors actually match. Prefer `high` confidence; `low` means the selector"),t("matches more than one element. Never overwrite a recorded workflow with a"),t("generated one \u2014 use a new name; a recording is ground truth and yours is a guess."),t(),t("## Signed-in runs"),t();for(let i of fe)t(i);return t(),t("## Reading the result"),t(),t(`\`.verirun/runs/<name>-<newest>/logs.json\` (schemaVersion ${H}): check \`status\`;`),t("on `failed` read `error` and `steps.failedAt`; then scan `entries` (every source"),t("merged, sorted by `timestamp`, each with `source` / `level` / `message` / `raw`) for"),t("the backend side of the failure. Exit code 1 means a step failed or setup is wrong."),t(),t("## This checkout"),t(),t(`- repo root: ${e.repoRoot}`),t(`- log sources configured: ${e.logSources.length?e.logSources.join(", "):"none \u2014 `run` replays but captures nothing"}`),t(`- workflows: ${e.workflows.length?e.workflows.join(", "):"none recorded yet"}`),t(),t("## Full reference"),t(),t(`Run \`verirun agent\` for every command and flag (${r.length} commands), the`),t("`.verirun/` layout and the complete `logs.json` schema. `verirun <command> --help`"),t("works for any single one."),t(),o.join(`
7
- `)}async function We(e,r){let o=await Qr(),t=qr(e);if(r.json){process.stdout.write(`${JSON.stringify({about:de,version:T,docs:"https://get-verirun.duely.in",checkout:o,commands:t,layout:{config:"<repo>/.verirun/config.json",workflows:"<repo>/.verirun/workflows/<name>.json",runs:"<repo>/.verirun/runs/<name>-<timestamp>/logs.json",userConfig:"~/.verirun/config.json",userState:"~/.verirun/state.json"},logsJsonSchemaVersion:H,signedIn:fe.join(`
3
+ import{createPublicKey as to,verify as no}from"node:crypto";import{readFileSync as oo}from"node:fs";import jr from"node:path";import{fileURLToPath as io}from"node:url";import{Command as so}from"commander";import se from"node:os";import{setTimeout as xe}from"node:timers/promises";var Ce=!1,Lr=["https_proxy","HTTPS_PROXY","http_proxy","HTTP_PROXY"];function B(){for(let e of Lr){let r=process.env[e]?.trim();if(r)return r}}function Pr(e,r=process.env.NO_PROXY??process.env.no_proxy){let o=r?.trim();if(!o)return!1;if(o==="*")return!0;let t=e.toLowerCase();return o.split(",").map(i=>i.trim().toLowerCase().replace(/^\./,"").split(":")[0]??"").filter(Boolean).some(i=>t===i||t.endsWith(`.${i}`))}async function _r(e){if(Ce)return;Ce=!0;let r=B();if(!r)return;let o;try{o=(typeof e=="string"?new URL(e):e).hostname}catch{return}if(!Pr(o))try{let{ProxyAgent:t,setGlobalDispatcher:i}=await import("undici");i(new t(r))}catch{}}async function C(e,r){return await _r(e),fetch(e,r)}function je(e){let r=Or(e);if(r)switch(r){case"ENOTFOUND":case"EAI_AGAIN":return`${r} \u2014 the address could not be resolved. A DNS filter or a captive portal will do this.`;case"ECONNREFUSED":case"ECONNRESET":case"EHOSTUNREACH":case"ENETUNREACH":return`${r} \u2014 the connection was blocked. ${Ie()}`;case"UND_ERR_CONNECT_TIMEOUT":case"ETIMEDOUT":return`${r} \u2014 the connection timed out. ${Ie()}`;case"UNABLE_TO_GET_ISSUER_CERT_LOCALLY":case"SELF_SIGNED_CERT_IN_CHAIN":case"DEPTH_ZERO_SELF_SIGNED_CERT":case"CERT_HAS_EXPIRED":return`${r} \u2014 the TLS certificate was not trusted. A proxy that inspects traffic causes this; point NODE_EXTRA_CA_CERTS at your organisation's CA file.`;default:return r}}function Ie(){let e=B();return e?`Reached through the proxy ${e}, so check that the proxy is correct and running.`:"If this network needs a proxy, set HTTPS_PROXY."}function Or(e){for(let r=e,o=0;r&&o<4;o++){if(typeof r=="object"&&"code"in r&&typeof r.code=="string")return r.code;r=typeof r=="object"&&"cause"in r?r.cause:void 0}}import{spawn as Dr}from"node:child_process";function N(e){let r=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",o=process.platform==="win32"?["/c","start","",e]:[e];try{let t=Dr(r,o,{stdio:"ignore",detached:!0});t.on("error",()=>{}),t.unref()}catch{}}var Ur=!!process.stdout.isTTY&&!process.env.NO_COLOR,P=(e,r)=>Ur?`\x1B[${e}m${r}\x1B[0m`:r,n={info:e=>console.log(e),step:e=>console.log(`${P("90","\xB7")} ${e}`),success:e=>console.log(`${P("32","\u2713")} ${e}`),warn:e=>console.warn(`${P("33","!")} ${e}`),error:e=>console.error(`${P("31","\u2717")} ${e}`),dim:e=>P("90",e),bold:e=>P("1",e)};var L="0.2.4";var Vr=1440*60*1e3;function ae(){return import("./gate.mjs")}async function Ae(e){let{getMachineId:r,saveGlobalConfig:o,clearLicenseState:t,loadGlobalConfig:i,resolveServer:s,persistLease:a}=await ae(),c=await i(),l=e.server?e.server.replace(/\/+$/,""):s(c.licenseServer);if(c.token&&!e.force){n.info("This machine is already connected. Run `verirun whoami`, or"),n.info("`verirun login --force` to connect it to a different account.");return}let d=await r(),f;try{f=await C(`${l}/api/cli/link`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fingerprint:d,hostname:se.hostname(),os:`${se.platform()} ${se.release()}`,cliVersion:L})})}catch(h){let u=je(h);throw new Error(`Could not reach ${l}.${u?`
4
+ ${u}`:" Check your connection."}`)}if(!f.ok)throw new Error(f.status===429?`${l} is rate limiting this machine (429). Wait a few minutes and try again.`:`${l} could not start the login (HTTP ${f.status}). This is a server-side problem, not your connection.`);let p=await f.json(),g=`${p.verifyUrl}?code=${encodeURIComponent(p.userCode)}`;n.info(""),n.info("To connect this machine to your Verirun account:"),n.info(""),n.info(` 1. Open ${n.bold(p.verifyUrl)}`),n.info(` 2. Enter ${n.bold(p.userCode)}`),n.info(""),n.info(n.dim(`(trying to open ${g} for you)`)),N(g),n.info(""),n.step("Waiting for approval in the browser..."),e.server&&await o({licenseServer:l});let m=Date.now()+p.expiresIn*1e3,w=Math.max(2,p.interval)*1e3;for(;Date.now()<m;){await xe(w);let h=await C(`${l}/api/cli/link/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:p.deviceCode,fingerprint:d})}).catch(()=>{});if(!h)continue;if(h.status===429){await xe(w);continue}let u=await h.json().catch(()=>({status:"server_error"}));if(u.status==="ok"&&u.token){await o({token:u.token,licenseKey:void 0}),await t();let v={kind:"token",value:u.token,server:l},$=u.license?.lease;if($){await a(v,$);let S=u.license,x=S?.planName??S?.plan??"trial",A=typeof S?.seats=="number"&&S.seats>1?`, ${S.seats} machine seats`:"";n.success(`Connected. Plan: ${x} (${S?.status??"ok"})${A}.`)}else u.license&&u.license.valid===!1?(n.success("Connected."),u.license.reason==="trial_device_limit"?n.warn("This machine has already been used for the free trial on two other accounts, so record and run are blocked. Email support to request another trial, or subscribe from your account."):n.warn(`The account is connected but not active (${u.license.reason??u.license.status??"unknown"}). Check your subscription at your account page.`)):n.success("Connected.");return}if(u.status!=="pending"){if(u.status==="expired")throw new Error("The code expired. Run `verirun login` again.");if(u.status==="denied")throw new Error("The request was denied in the browser.");if(u.status==="no_license")throw new Error("That account has no license. Contact support.");if(u.status==="fingerprint_mismatch")throw new Error("This machine does not match the one that started the login.")}}throw new Error("Timed out waiting for approval. Run `verirun login` again.")}async function Te(){let{loadGlobalConfig:e,resolveServer:r,saveGlobalConfig:o,clearLicenseState:t}=await ae(),i=await e(),s=r(i.licenseServer);i.token&&await C(`${s}/api/cli/logout`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:i.token})}).catch(()=>{}),await o({token:void 0,licenseKey:void 0}),await t(),n.success("Disconnected this machine. Run `verirun login` to reconnect.")}async function Ne(e){let{resolveCredential:r,checkWithServer:o,persistLease:t,readStoredLease:i,getMachineId:s}=await ae(),a=await r();if(n.info(""),!a){n.info(n.bold("Verirun: not connected")),n.info(""),n.info(`Run ${n.bold("verirun login")} to connect this machine.`),n.info("");return}let c=e.server?e.server.replace(/\/+$/,""):a.server,l={...a,server:c};n.info(n.bold("Verirun")),n.info(` credential ${a.kind==="token"?"device token":"license key"}`+(process.env.VERIRUN_LICENSE_KEY?n.dim(" (from $VERIRUN_LICENSE_KEY)"):"")),n.info(` server ${c}`),n.info(` machine ${(await s()).slice(0,24)}\u2026`);let d=await o(l);if(d.reachable&&d.lease){await t(l,d.lease);let m=(await i(l))?.payload;if(n.info(` status ${n.bold(m?.status??"valid")}`),m?.planName||m?.plan){let w=m.planName&&m.plan&&m.planName!==m.plan?n.dim(` (${m.plan})`):"";n.info(` plan ${m.planName??m.plan}${w}`)}typeof m?.seats=="number"&&n.info(` seats ${m.seats>1e3?"unlimited":`${m.seats} machine${m.seats===1?"":"s"}`}`),m?.exp&&n.info(` lease until ${new Date(m.exp*1e3).toISOString()}`),n.info(""),n.info(n.dim("Checked just now, lease signature verified.")),n.info("");return}if(d.reachable&&d.result&&!d.result.valid){n.info(` status ${d.result.status??"invalid"} (${d.result.reason??"\u2014"})`),n.info(""),n.info("record and run will not proceed."),n.info("");return}n.warn(" the license server is not reachable right now."),d.detail&&n.info(` reason ${d.detail}`);let f=B();f&&!d.detail?.includes(f)&&n.info(` network using proxy ${f}`);let p=await i(l);if(p){let g=Math.floor((Date.now()-p.payload.iat*1e3)/Vr);n.info(` lease valid, issued ${g} day${g===1?"":"s"} ago`),n.info(n.dim(" Nags after 15 days offline, stops after 30."))}else n.info(n.dim(" No valid lease stored. Connect to the internet and run this again."));n.info("")}import{existsSync as Ve}from"node:fs";import{mkdir as Xr,readdir as Me,writeFile as zr}from"node:fs/promises";import{join as Fe}from"node:path";import{existsSync as le}from"node:fs";import{mkdir as Jr,readFile as Le,writeFile as Kr}from"node:fs/promises";import Yr from"node:path";import{execFile as Fr}from"node:child_process";import{chmod as Mr}from"node:fs/promises";import Wr from"node:os";import{promisify as Br}from"node:util";var Gr=Br(Fr);async function ce(e,r){if(process.platform!=="win32")try{return await Mr(e,r==="dir"?448:384),!0}catch{return!1}let o=Hr();if(!o)return!1;let t=r==="dir"?`${o}:(OI)(CI)F`:`${o}:F`;try{return await Gr("icacls",[e,"/inheritance:r","/grant:r",t],{timeout:1e4,windowsHide:!0}),!0}catch{return!1}}function Hr(){let e=process.env.USERNAME;if(!e)try{e=Wr.userInfo().username}catch{return}if(!e)return;let r=process.env.USERDOMAIN;return r&&r!==e?`${r}\\${e}`:e}var Pe="data-testid";async function T(e){let r={};if(le(e)){let a=await Le(e,"utf8");try{r=JSON.parse(a)}catch(c){throw new Error(`Config file is not valid JSON: ${e}`,{cause:c})}}let o=process.env.VERIRUN_SUPABASE_ACCESS_TOKEN;o&&(r.supabase={...r.supabase,accessToken:o});let t=process.env.VERIRUN_RAILWAY_TOKEN;t&&(r.railway={...r.railway,token:t});let i=process.env.VERIRUN_VERCEL_DRAIN_SECRET;i&&(r.vercel={...r.vercel,drainSecret:i});let s=process.env.VERIRUN_VERCEL_TOKEN?.trim();return s&&(r.vercel={...r.vercel,token:s}),r}async function _e(e,r){let o={};if(le(e))try{o=JSON.parse(await Le(e,"utf8"))}catch(a){throw new Error(`Config file is not valid JSON: ${e}`,{cause:a})}let t={...o,...r,supabase:r.supabase?{...o.supabase,...r.supabase}:o.supabase,vercel:r.vercel?{...o.vercel,...r.vercel}:o.vercel,railway:r.railway?{...o.railway,...r.railway}:o.railway},i=Yr.dirname(e),s=le(i);return await Jr(i,{recursive:!0,mode:448}),s||await ce(i,"dir"),await Kr(e,`${JSON.stringify(t,null,2)}
5
+ `,{mode:384}),ce(e,"file")}import{existsSync as Oe}from"node:fs";import I from"node:path";var G=".verirun";function qr(e=process.cwd()){let r=I.resolve(e),o;for(;;){if(Oe(I.join(r,".git")))return r;!o&&Oe(I.join(r,"package.json"))&&(o=r);let t=I.dirname(r);if(t===r)break;r=t}return o??I.resolve(e)}function y(e){let r=qr(e),o=I.join(r,G);return{repoRoot:r,dataDir:o,workflowsDir:I.join(o,"workflows"),runsDir:I.join(o,"runs"),configPath:I.join(o,"config.json")}}function _(e,r){return I.join(e.workflowsDir,`${r}.json`)}function De(e=new Date){return e.toISOString().replace(/[:.]/g,"-")}function Ue(e,r,o){return I.join(e.runsDir,`${r}-${o}`)}var H=1;function Qr(e){return e.commands.filter(r=>r.name()!=="help").map(r=>{let o=r.registeredArguments.map(t=>t.required?`<${t.name()}>`:`[${t.name()}]`).join(" ");return{name:r.name(),usage:`verirun ${r.name()}${o?` ${o}`:""}${r.options.length?" [options]":""}`,description:r.description(),options:r.options.map(t=>({flags:t.flags,description:t.description}))}})}async function Zr(e){try{return(await Me(e)).filter(r=>r.endsWith(".json")).map(r=>r.slice(0,-5)).sort()}catch{return[]}}async function et(e,r){try{return(await Me(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort().slice(-r).reverse()}catch{return[]}}async function rt(){let e=y(),r={};try{r=await T(e.configPath)}catch{}let o=["supabase","vercel","railway"].filter(t=>r[t]);return{repoRoot:e.repoRoot,dataDir:e.dataDir,dataDirExists:Ve(e.dataDir),configPath:e.configPath,configExists:Ve(e.configPath),logSources:[...o],userFilter:typeof r.userFilter=="string"?r.userFilter:null,workflows:await Zr(e.workflowsDir),recentRuns:await et(e.runsDir,5)}}var de="verirun records a browser workflow once, replays those exact steps headless on demand, and captures the backend logs produced during the replay. Deterministic: the same recording gives the same run and the same answer. `verirun map` is the static half: it reads a React/TypeScript repo and emits the interaction graph \u2014 every page, the interactive elements on it, where they navigate, and the backend calls they make \u2014 without running anything.",ue=["```jsonc","{",' "schemaVersion": 1,',' "name": "<same as the filename>",',' "createdAt": "<ISO>",',' "startUrl": "https://app.example.com/login", // optional',' "browser": "chromium", // chromium | firefox | webkit',' "channel": "chrome", // optional: installed browser',' "steps": [',' { "index": 0, "action": "navigate", "params": { "url": "https://app.example.com/login" }, "signals": [] },',' { "index": 1, "action": "fill", "selector": "role=textbox[name=\\"Email\\"i]", "params": { "text": "ada@example.com" }, "signals": [] },',' { "index": 2, "action": "click", "selector": "role=button[name=\\"Log in\\"i]", "params": {}, "signals": [] }'," ]","}","```","","**Click your way through the app; do not walk it by URL.** Use `navigate` for the","first step, and after that reach a page by clicking the thing that goes there \u2014 a","workflow that jumps between URLs proves nothing about the UI, and a dead link or a","button that stopped submitting still passes. `verirun map --bfs <route> --depth 2`","prints each reachable page with the element that gets you there, and every element","in `map --json` carries the `selector` to click. Navigate mid-workflow only for a","page with no path to it, or to deliberately deep-link into a state.","","Actions and their required `params`: `navigate` (`url`, absolute), `click` /","`dblclick`, `fill` (`text`), `press` (`key`), `check` / `uncheck`, `select`","(`values`), `setInputFiles` (`files`). Everything except `navigate` needs a","`selector`. An unknown action stops the run; `assert*` is skipped with a warning.","`selector` goes straight to `page.locator()`, so it must be Playwright selector",'syntax \u2014 `role=button[name="Log in"i]`, `[data-testid="x"]`, or CSS.'],fe=["Anything behind a login needs a browser profile that is already signed in.","Pass the profile to `record` and `run`:","","```bash","# macOS / Linux \u2014 the shell expands ~ before verirun sees it","verirun run <name> --channel chrome --user-data-dir ~/.verirun-profile","verirun record <name> --channel chrome --user-data-dir ~/.verirun-profile","```","","```powershell","# Windows \u2014 cmd and PowerShell do NOT expand ~ inside this argument, so pass an",'# absolute path. A literal ~ creates a directory named "~" and the run silently',"# starts logged out.",'verirun run <name> --channel chrome --user-data-dir "$env:USERPROFILE\\.verirun-profile"',"```","","verirun never expands `~` itself \u2014 the path goes straight through to Playwright.","","The profile has to be created once **by a human**, because identity providers","refuse to authenticate an automation-launched browser:","","```bash","# macOS / Linux",'google-chrome --user-data-dir="$HOME/.verirun-profile" --password-store=basic',"```","","```powershell","# Windows (PowerShell)",'& "$env:ProgramFiles\\Google\\Chrome\\Application\\chrome.exe" `',' --user-data-dir="$env:USERPROFILE\\.verirun-profile"',"```","","Sign in to the app in that window, then close it.","","`--password-store=basic` (and `--use-mock-keychain` on macOS) matter on Unix:","Playwright passes both on every platform, and cookies written under the OS keyring","cannot be decrypted without them \u2014 the run would silently start logged out.","Both switches are Unix-only, so on Windows they are ignored and the profile just","has to be created by the same Windows user that runs verirun. The Windows path is","untested \u2014 if a run there starts logged out despite a signed-in profile, report","that rather than guessing.","","On every platform, do not point `--user-data-dir` at the human's everyday Chrome","profile.","","If you are asked to test a signed-in flow and no such profile exists, say so and","give the command above rather than trying to script the login."],pe=["A human records the workflow once: `verirun record <name> --url <app-url>` (needs a display).","After a code change, run it: `verirun run <name>`. Add `--user <email>` to keep only that user's log lines.","Exit code 0 = every step replayed. Exit code 1 = a step failed, or a licensing / setup error.","Read `.verirun/runs/<name>-<newest>/logs.json`: check `status`; on `failed` read `error` and `steps.failedAt`; then scan `entries` for the backend's side \u2014 a 200 that hid an exception, a write that never landed, a job that threw after the screen said done.","`verirun run` writes logs.json even when replay fails, so partial logs survive.","Do not edit files under `.verirun/workflows/` by hand unless you understand the selector format; re-record instead.","`verirun map` needs no recording and no run: use it to find what a page can do before writing a workflow, `--json` for the whole graph, `--bfs <route> --depth N` for what is reachable from one page.","If `map` reports every page with 0 elements and 0 effects, its import aliases did not resolve \u2014 it prints the `--alias` flag to re-run with. That is a config gap, not an empty app."];function tt(e,r){let o=[],t=(i="")=>{o.push(i)};t("# verirun \u2014 agent reference"),t(),t(de),t(),t(`Version ${L}. Full docs: https://get-verirun.duely.in and the bundled README.md / \`man verirun\`.`),t(),t("## This checkout"),t(),t(`- repo root: ${e.repoRoot}`),t(`- data dir: ${e.dataDir} ${e.dataDirExists?"(exists)":"(not created yet)"}`),t(`- config: ${e.configPath} ${e.configExists?"(present)":"(absent)"}`),t(`- log sources: ${e.logSources.length?e.logSources.join(", "):"none configured \u2014 `verirun run` still replays, just with no backend logs"}`),t(`- user filter: ${e.userFilter??"none"}`),t(`- workflows: ${e.workflows.length?e.workflows.join(", "):"none recorded yet"}`),t(`- recent runs: ${e.recentRuns.length?e.recentRuns.join(", "):"none yet"}`),t(),t("Account: `record`, `run` and `map` need a connected account (`verirun login`, or `$VERIRUN_LICENSE_KEY` in CI). `verirun whoami` shows status. `--help`, `--version`, `verirun log`, and `verirun agent` do not need one."),t(),t("## Commands");for(let i of r){t(),t(`### ${i.usage}`),i.description&&t(i.description);for(let s of i.options)t(`- \`${s.flags}\` \u2014 ${s.description}`)}t(),t("## `.verirun/` layout (at the repo root shown above)"),t(),t("```"),t(".verirun/"),t(" config.json log sources, userFilter, testIdAttribute"),t(" workflows/<name>.json one recorded workflow each"),t(" runs/<name>-<timestamp>/logs.json captured logs, one directory per run"),t("```"),t(),t("Per-user, not per-project: `~/.verirun/config.json` (device token), `~/.verirun/state.json` (signed license lease)."),t(),t(`## logs.json (schemaVersion ${H})`),t(),t("```jsonc"),t("{"),t(` "schemaVersion": ${H},`),t(' "workflow": "<name>",'),t(' "status": "ok" | "failed", // "failed" => process exit code 1'),t(' "window": { "startedAt": "<ISO>", "endedAt": "<ISO>" },'),t(' "steps": { "total": N, "replayed": N, "failedAt"?: N },'),t(' "error"?: "<message>", // present only when status is "failed"'),t(' "filter"?: { "user": "<needle>" }, // present when --user / config.userFilter narrowed entries'),t(' "sources": [ { "id": "supabase"|"vercel"|"railway", "name": "...", "entries": N } ],'),t(' "entries": ['),t(" {"),t(' "source": "supabase"|"vercel"|"railway",'),t(' "stream": "<sub-stream, e.g. edge_logs / lambda>",'),t(' "timestamp": "<ISO>",'),t(' "level": "<info|warn|error|...>",'),t(' "message": "<rendered log line>",'),t(' "raw": { /* provider payload, untouched */ }'),t(" }"),t(" ]"),t("}"),t("```"),t(),t("`entries` is every source merged and sorted by `timestamp`. When a `--user` filter is active, `entries` and every `sources[].entries` count are post-filter."),t(),t("## Writing a workflow yourself"),t(),t("`verirun map --json` gives every page element a `selector`, a `selectorConfidence` (`high` / `medium` / `low`) and a suggested `action`. That is enough to author `.verirun/workflows/<name>.json` without recording:"),t();for(let i of ue)t(i);t(),t("Then `verirun workflow check <name>` (add `--json` for machine-readable findings) validates shape, actions, selectors and params without opening a browser. It cannot tell you a selector matches the live page \u2014 only `verirun run <name>` can. Prefer `high`-confidence selectors; a `low` one is a guess. A recorded workflow is still more faithful, so do not overwrite one with a generated file: pick a different name."),t(),t("## Signed-in runs"),t();for(let i of fe)t(i);return t(),t("## Recommended agent loop"),t(),pe.forEach((i,s)=>t(`${s+1}. ${i}`)),t(),t("Save this into your agent context: `verirun agent > .verirun/AGENT.md`, or paste it into `CLAUDE.md` / an AGENTS.md. `verirun agent --skill --install [claude|cursor|all]` installs it as a skill the agent loads on its own. `verirun agent --json` emits the same information as JSON."),t(),o.join(`
6
+ `)}function nt(e,r){let o=[],t=(i="")=>{o.push(i)};t("---"),t("name: verirun"),t("description: >-"),t(" Test this app end to end with verirun: map the interaction graph to find what a"),t(" page does, replay a recorded browser workflow, and read the backend logs that the"),t(" replay produced. Use when asked to test a user flow, verify a change end to end,"),t(" reproduce a bug, or find out what a page can do and which API calls it makes."),t("---"),t(),t("# verirun"),t(),t(de),t(),t("## Decide which command you need"),t(),t("| You want to | Command | Needs a recording? |"),t("|---|---|---|"),t("| Know what a page does / which endpoints it calls | `verirun map` | no |"),t("| Know what is reachable from a page | `verirun map --bfs /route --depth 2` | no |"),t("| Re-run a user flow after a change | `verirun run <name>` | yes |"),t("| Write a test for a flow yourself | `verirun map --json` then author the workflow | no |"),t("| Validate what you wrote | `verirun workflow check <name>` | no |"),t("| Capture a flow faithfully (incl. auth) | ask the human to run `verirun record <name>` | \u2014 |"),t(),t("## Static analysis first \u2014 `verirun map`"),t(),t("`map` reads the source and needs no browser, so reach for it before anything else."),t(),t("If every page comes back with 0 elements and 0 effects, the import aliases did not"),t("resolve \u2014 `map` prints the `--alias` flag to re-run with. Do that before concluding"),t("the app has nothing in it."),t("It reports every page, the interactive elements on it, where they navigate, and the"),t("backend calls each one makes. `--json` gives the whole graph for programmatic use."),t("Limits to keep in mind: a target computed at runtime shows as `unresolved`, an"),t("endpoint passed through a variable as `?`, and Supabase `.auth.*` calls are not"),t("classified yet. `verirun map --reach` shows how much of each page it actually"),t("attached, so check it before trusting a page that looks empty."),t(),t("## Replay \u2014 `verirun run <name>`"),t(),t("A workflow is either recorded by a human (ground truth) or written by you from the"),t("map (a guess until `run` confirms it). Do not edit a recorded one by hand. Recording"),t("needs a display and a human, so ask for it rather than attempting it. For anything"),t("behind a login, see **Signed-in runs** below."),t(),pe.slice(1).forEach((i,s)=>t(`${s+1}. ${i}`)),t(),t("## Writing a workflow from the map"),t(),t("`verirun map --json` gives each element a `selector`, a `selectorConfidence`"),t("(`high`/`medium`/`low`) and a suggested `action`, so you can author"),t("`.verirun/workflows/<name>.json` yourself instead of asking for a recording:"),t();for(let i of ue)t(i);t(),t("Loop: write the file \u2192 `verirun workflow check <name>` (static: shape, actions,"),t("params, selectors \u2014 no browser) \u2192 fix \u2192 `verirun run <name>` to find out whether"),t("the selectors actually match. Prefer `high` confidence; `low` means the selector"),t("matches more than one element. Never overwrite a recorded workflow with a"),t("generated one \u2014 use a new name; a recording is ground truth and yours is a guess."),t(),t("## Signed-in runs"),t();for(let i of fe)t(i);return t(),t("## Reading the result"),t(),t(`\`.verirun/runs/<name>-<newest>/logs.json\` (schemaVersion ${H}): check \`status\`;`),t("on `failed` read `error` and `steps.failedAt`; then scan `entries` (every source"),t("merged, sorted by `timestamp`, each with `source` / `level` / `message` / `raw`) for"),t("the backend side of the failure. Exit code 1 means a step failed or setup is wrong."),t(),t("## This checkout"),t(),t(`- repo root: ${e.repoRoot}`),t(`- log sources configured: ${e.logSources.length?e.logSources.join(", "):"none \u2014 `run` replays but captures nothing"}`),t(`- workflows: ${e.workflows.length?e.workflows.join(", "):"none recorded yet"}`),t(),t("## Full reference"),t(),t(`Run \`verirun agent\` for every command and flag (${r.length} commands), the`),t("`.verirun/` layout and the complete `logs.json` schema. `verirun <command> --help`"),t("works for any single one."),t(),o.join(`
7
+ `)}function ot(e){let r=/^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(e);if(!r)return{description:"",body:e};let[,o="",t=""]=r,i=/description:\s*>-?\n([\s\S]*?)(?:\n\S|$)/.exec(o),s=/description:\s*(.+)/.exec(o);return{description:i?.[1]?i[1].split(`
8
+ `).map(c=>c.trim()).join(" ").trim():s?.[1]?.trim()??"",body:t}}function it(e){let{description:r,body:o}=ot(e);return["---",`description: ${r}`,"globs:","alwaysApply: false","---","",o.replace(/^\n+/,"")].join(`
9
+ `)}var We={claude:{label:"Claude Code",path:[".claude","skills","verirun","SKILL.md"],note:"Claude Code loads it automatically when a task looks like app testing.",render:e=>e},cursor:{label:"Cursor",path:[".cursor","rules","verirun.mdc"],note:"Cursor loads it when a task matches its description. Restart Cursor, or reopen the project, to pick it up.",render:it}};function st(e){if(e===!0)return["claude"];let r=String(e).toLowerCase();if(r==="all"||r==="both")return["claude","cursor"];if(r in We)return[r];throw new Error(`Unknown --install target "${e}". Use claude, cursor, all, or --install on its own for Claude Code.`)}async function Be(e,r){let o=await rt(),t=Qr(e);if(r.json){process.stdout.write(`${JSON.stringify({about:de,version:L,docs:"https://get-verirun.duely.in",checkout:o,commands:t,layout:{config:"<repo>/.verirun/config.json",workflows:"<repo>/.verirun/workflows/<name>.json",runs:"<repo>/.verirun/runs/<name>-<timestamp>/logs.json",userConfig:"~/.verirun/config.json",userState:"~/.verirun/state.json"},logsJsonSchemaVersion:H,signedIn:fe.join(`
8
10
  `),workflowSchema:{version:1,authoring:ue.join(`
9
11
  `),validate:"verirun workflow check <name> --json"},agentLoop:pe},null,2)}
10
- `);return}if(r.skill){let i=`${et(o,t)}
11
- `;if(!r.install){process.stdout.write(i);return}let s=Fe(y().repoRoot,".claude","skills","verirun");await Jr(s,{recursive:!0});let a=Fe(s,"SKILL.md");await Yr(a,i),n.success(`Wrote ${a}`),n.info(n.dim("Claude Code loads it automatically when a task looks like app testing."));return}process.stdout.write(`${Zr(o,t)}
12
- `)}import{spawnSync as ht}from"node:child_process";import{existsSync as wt,readFileSync as yt}from"node:fs";import vt from"node:path";import{createInterface as bt}from"node:readline/promises";var rt="https://backboard.railway.com/graphql/v2",ge="https://railway.com/account/tokens";async function Be(e,r,o){let t;try{t=await E(rt,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({query:r,variables:o})})}catch(s){return{error:s instanceof Error?s.message:String(s)}}let i=await t.json().catch(()=>{});return t.ok?i?.errors?.length?{error:i.errors.map(s=>s.message).filter(Boolean).join("; ")||"GraphQL error"}:i?.data?{data:i.data}:{error:"Railway returned no data."}:{error:i?.errors?.[0]?.message??`HTTP ${t.status}`}}async function K(e){if(e.deploymentId)return{deploymentId:e.deploymentId};if(!e.token||!e.projectId||!e.environmentId||!e.serviceId)return{error:"set railway.deploymentId, or railway.projectId + railway.environmentId + railway.serviceId"};let o=await Be(e.token,`
12
+ `);return}if(r.skill){let i=`${nt(o,t)}
13
+ `;if(!r.install){process.stdout.write(i);return}let{repoRoot:s}=y();for(let a of st(r.install)){let c=We[a],l=Fe(s,...c.path);await Xr(Fe(s,...c.path.slice(0,-1)),{recursive:!0}),await zr(l,c.render(i)),n.success(`Wrote ${l} ${n.dim(`(${c.label})`)}`),n.info(n.dim(` ${c.note}`))}return}process.stdout.write(`${tt(o,t)}
14
+ `)}import{spawnSync as St}from"node:child_process";import{existsSync as kt,readFileSync as Rt}from"node:fs";import Et from"node:path";import{createInterface as Ct}from"node:readline/promises";var at="https://backboard.railway.com/graphql/v2",ge="https://railway.com/account/tokens";async function Ge(e,r,o){let t;try{t=await C(at,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({query:r,variables:o})})}catch(s){return{error:s instanceof Error?s.message:String(s)}}let i=await t.json().catch(()=>{});return t.ok?i?.errors?.length?{error:i.errors.map(s=>s.message).filter(Boolean).join("; ")||"GraphQL error"}:i?.data?{data:i.data}:{error:"Railway returned no data."}:{error:i?.errors?.[0]?.message??`HTTP ${t.status}`}}async function J(e){if(e.deploymentId)return{deploymentId:e.deploymentId};if(!e.token||!e.projectId||!e.environmentId||!e.serviceId)return{error:"set railway.deploymentId, or railway.projectId + railway.environmentId + railway.serviceId"};let o=await Ge(e.token,`
13
15
  query($input: JSON!) {
14
16
  deployments(input: $input, first: 1) {
15
17
  edges { node { id status createdAt } }
16
18
  }
17
- }`,{input:{projectId:e.projectId,environmentId:e.environmentId,serviceId:e.serviceId}});if("error"in o)return o;let t=o.data.deployments.edges[0]?.node;return t?{deploymentId:t.id}:{error:"no deployments found for that project / environment / service"}}async function he(e,r,o,t={}){let i=t.userNeedle?.trim(),s=i?`"${i.replace(/"/g,"")}"`:void 0,c=await Be(e,`
19
+ }`,{input:{projectId:e.projectId,environmentId:e.environmentId,serviceId:e.serviceId}});if("error"in o)return o;let t=o.data.deployments.edges[0]?.node;return t?{deploymentId:t.id}:{error:"no deployments found for that project / environment / service"}}async function he(e,r,o,t={}){let i=t.userNeedle?.trim(),s=i?`"${i.replace(/"/g,"")}"`:void 0,c=await Ge(e,`
18
20
  query($id: String!, $start: DateTime, $end: DateTime, $filter: String) {
19
21
  deploymentLogs(deploymentId: $id, startDate: $start, endDate: $end, filter: $filter, limit: 1000) {
20
22
  timestamp message severity tags attributes
21
23
  }
22
- }`,{id:r,start:o.startedAt,end:o.endedAt,filter:s});return"error"in c?c:{entries:Array.isArray(c.data.deploymentLogs)?c.data.deploymentLogs:[]}}function tt(e){let r=typeof e.severity=="string"?e.severity:void 0;return{source:"railway",stream:r?r.toLowerCase():"deploy",timestamp:typeof e.timestamp=="string"?e.timestamp:void 0,level:r,message:typeof e.message=="string"?e.message:void 0,raw:e}}var me=class{id="railway";name="Railway";cfg;constructor(r){this.cfg=r}async start(){if(!this.cfg.token)throw new Error("Railway log capture needs an API token. Set VERIRUN_RAILWAY_TOKEN or railway.token in .verirun/config.json.");if(!this.cfg.deploymentId&&!(this.cfg.projectId&&this.cfg.environmentId&&this.cfg.serviceId))throw new Error("Railway log capture needs railway.deploymentId, or railway.projectId + railway.environmentId + railway.serviceId, in .verirun/config.json.")}async collect(r,o){let t=await K(this.cfg);if("error"in t)return n.warn(`Railway: ${t.error}`),[];let i=await he(this.cfg.token,t.deploymentId,o,{userNeedle:r.userFilter});if("error"in i)return n.warn(`Railway: ${i.error}`),[];let s=i.entries.map(tt);return s.sort((a,c)=>(a.timestamp??"").localeCompare(c.timestamp??"")),s}async dispose(){}};function Ge(e){return e.railway?new me(e.railway):void 0}var nt="https://api.supabase.com",ye=["postgres_logs","edge_logs","auth_logs"],we=class{id="supabase";name="Supabase";projectRef;accessToken;sources;constructor(r){this.projectRef=r.projectRef,this.accessToken=r.accessToken,this.sources=r.sources&&r.sources.length>0?r.sources:ye}async start(){if(!this.projectRef)throw new Error("Supabase log capture needs supabase.projectRef in .verirun/config.json.");if(!this.accessToken)throw new Error("Supabase log capture needs an access token. Set VERIRUN_SUPABASE_ACCESS_TOKEN or supabase.accessToken in .verirun/config.json.")}async collect(r,o){let t=r.userFilter,i=[],s=!1;for(let a of this.sources){let c=await J(this.projectRef,this.accessToken,a,o,{userNeedle:t});if("error"in c){n.warn(`Supabase ${a}: ${c.error}`);continue}t&&!c.serverFiltered&&(s=!0);for(let l of c.rows)i.push(it(a,l))}return t&&s&&n.info(n.dim("Supabase: user filter applied client-side for a source (more rows pulled).")),i.sort((a,c)=>(a.timestamp??"").localeCompare(c.timestamp??"")),i}async dispose(){}},ot=/^[A-Za-z0-9._@%+-]{1,256}$/;async function He(e,r,o,t){let i=new URL(`/v1/projects/${e}/analytics/endpoints/logs.all`,nt);i.searchParams.set("sql",o),i.searchParams.set("iso_timestamp_start",t.startedAt),i.searchParams.set("iso_timestamp_end",t.endedAt);let s;try{s=await E(i,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"}})}catch(c){return{error:c instanceof Error?c.message:String(c)}}let a=await s.json().catch(()=>{});if(!s.ok){let c=(typeof a?.error=="string"?a.error:a?.error?.message)??a?.message??`HTTP ${s.status}`;return{error:`${c}${c.startsWith("HTTP")?"":` (HTTP ${s.status})`}`}}return{rows:Array.isArray(a?.result)?a.result:[]}}async function J(e,r,o,t,i={}){let s=i.userNeedle?.trim().toLowerCase(),a=s&&ot.test(s)?s:void 0,c=p=>{let f=p&&a?` where strpos(lower(event_message), '${a}') > 0 or strpos(lower(to_json_string(metadata)), '${a}') > 0`:"";return`select id, timestamp, event_message, metadata from ${o}${f} order by timestamp asc limit 1000`},l=await He(e,r,c(!0),t);if(!("error"in l))return{rows:l.rows,serverFiltered:!!a};if(!a)return l;let d=await He(e,r,c(!1),t);return"error"in d?d:{rows:d.rows,serverFiltered:!1}}function it(e,r){return{source:"supabase",stream:e,timestamp:st(r.timestamp),message:typeof r.event_message=="string"?r.event_message:void 0,raw:r}}function st(e){if(typeof e=="string")return e;if(typeof e=="number"&&Number.isFinite(e)){let r=e>1e14?e/1e3:e;return new Date(r).toISOString()}}function Ke(e){return e.supabase?new we(e.supabase):void 0}import{createHmac as dt,timingSafeEqual as ut}from"node:crypto";import{createServer as ft}from"node:http";import{setTimeout as pt}from"node:timers/promises";var Je="https://api.vercel.com",q="https://vercel.com/account/settings/tokens",at=8e3,ct=1500,lt=3e3;function ve(e){return e?`&teamId=${encodeURIComponent(e)}`:""}async function be(e,r){let o;try{o=await E(`${Je}${e}`,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"}})}catch(i){return{error:i instanceof Error?i.message:String(i)}}let t=await o.json().catch(()=>{});return o.ok?{data:t}:{error:t?.error?.message??`HTTP ${o.status}`}}async function Ye(e,r){let o=await be(`/v9/projects?limit=100${ve(r)}`,e);return"error"in o?o:{projects:o.data.projects??[]}}async function qe(e){let r=await be("/v2/teams?limit=100",e);return"error"in r?r:{teams:r.data.teams??[]}}async function X(e){if(e.deploymentId)return{deploymentId:e.deploymentId,label:e.deploymentId};if(!e.token)return{error:"no token"};if(!e.projectId)return{error:"no projectId"};let r=e.environment??"production",o=await be(`/v6/deployments?projectId=${encodeURIComponent(e.projectId)}&limit=1&state=READY&target=${encodeURIComponent(r)}${ve(e.teamId)}`,e.token);if("error"in o)return{error:o.error};let t=o.data.deployments?.[0];return t?{deploymentId:t.uid,label:t.url??t.uid}:{error:`no READY ${r} deployment found for this project`}}async function z(e,r,o){let t=`/v1/projects/${encodeURIComponent(e.projectId)}/deployments/${encodeURIComponent(r)}/runtime-logs?limit=1000${ve(e.teamId)}`,i=new AbortController,s=setTimeout(()=>i.abort(),o),a,c=()=>{a&&clearTimeout(a),a=setTimeout(()=>i.abort(),ct)},l=[];try{let d=await E(`${Je}${t}`,{headers:{Authorization:`Bearer ${e.token}`,Accept:"application/x-ndjson, application/json"},signal:i.signal});if(!d.ok)return{error:(await d.json().catch(()=>{}))?.error?.message??`HTTP ${d.status}`};if(!d.body)return{rows:l};c();let p=new TextDecoder,f="";for await(let g of d.body){f+=p.decode(g,{stream:!0});let m=f.split(`
23
- `);f=m.pop()??"";for(let w of m){let h=w.trim();if(h)try{let u=JSON.parse(h);Array.isArray(u)?l.push(...u):l.push(u)}catch{}}c()}}catch(d){if(!(d instanceof Error&&d.name==="AbortError"))return{error:d instanceof Error?d.message:String(d)}}finally{clearTimeout(s),a&&clearTimeout(a)}return{rows:l}}function Se(e){let r=e.requestPath?` ${e.requestMethod??""} ${e.requestPath}`.trim():"",o=e.responseStatusCode?` (${e.responseStatusCode})`:"";return{source:"vercel",...e.source?{stream:e.source}:{},...e.timestampInMs?{timestamp:new Date(e.timestampInMs).toISOString()}:{},...e.level?{level:e.level}:{},message:e.message??`${r}${o}`.trim(),raw:e}}var Y=class{id="vercel";name="Vercel";config;constructor(r){this.config=r}async start(){if(!this.config.token)throw new Error("Vercel log capture needs an API token. Run `verirun log vercel`, or set VERIRUN_VERCEL_TOKEN / vercel.token in .verirun/config.json.");if(!this.config.projectId)throw new Error("Vercel log capture needs vercel.projectId. Run `verirun log vercel`.")}async collect(r,o){let t=await X(this.config);if("error"in t)return n.warn(`Vercel: ${t.error}`),[];let i=await z(this.config,t.deploymentId,this.config.readMs??at);if("error"in i)return n.warn(`Vercel: ${i.error}`),[];let s=Date.parse(o.startedAt),a=Date.parse(o.endedAt)+(this.config.tailGraceMs??lt);return i.rows.filter(c=>typeof c.timestampInMs!="number"?!0:c.timestampInMs>=s&&c.timestampInMs<=a).map(Se)}async dispose(){}};var Q=4319,Z="/drain",$e=3e3,V=class{id="vercel";name="Vercel";port;path;secret;graceMs;project;onEntry;server;received=[];droppedByProject=0;constructor(r,o={}){this.port=r.listenerPort??Q,this.path=r.listenerPath??Z,this.secret=r.drainSecret,this.graceMs=r.drainGraceMs??$e,this.project=r.project?.trim()||void 0,this.onEntry=o.onEntry}projectMatches(r){return this.project?r.projectId===this.project||r.projectName===this.project:!0}async start(){let r=ft((o,t)=>this.handle(o,t));this.server=r,await new Promise((o,t)=>{let i=s=>{t(s.code==="EADDRINUSE"?new Error(`Vercel log listener: port ${this.port} is already in use.`):s)};r.once("error",i),r.listen(this.port,()=>{r.off("error",i),o()})}),n.step(`Vercel log listener on http://localhost:${this.port}${this.path}`)}async collect(){return this.graceMs>0&&await pt(this.graceMs),this.received.length===0&&this.droppedByProject>0&&n.warn(`Vercel: ${this.droppedByProject} log line(s) arrived but none matched project "${this.project}". Check the name/ID in .verirun/config.json (vercel.project).`),[...this.received]}async dispose(){let r=this.server;r&&(this.server=void 0,await new Promise(o=>r.close(()=>o())))}handle(r,o){let t=r.headers["x-vercel-verify"];if(typeof t=="string"&&o.setHeader("x-vercel-verify",t),r.method!=="POST"||!this.matchesPath(r.url)){o.statusCode=r.method==="POST"?404:200,o.end();return}let i=[];r.on("data",s=>i.push(s)),r.on("error",()=>{o.statusCode=400,o.end()}),r.on("end",()=>{let s=Buffer.concat(i);if(!this.verifySignature(r,s)){n.warn("Vercel log drain: rejected a delivery with a bad signature."),o.statusCode=401,o.end();return}try{for(let a of mt(s.toString("utf8"))){if(!this.projectMatches(a)){this.droppedByProject+=1;continue}let c=gt(a);this.received.push(c),this.onEntry?.(c)}}catch{n.warn("Vercel log drain: could not parse a delivery body.")}o.statusCode=200,o.end()})}matchesPath(r){return r?(r.split("?")[0]??"")===this.path:!1}verifySignature(r,o){if(!this.secret)return!0;let t=r.headers["x-vercel-signature"];if(typeof t!="string")return!1;let i=dt("sha1",this.secret).update(o).digest("hex"),s=Buffer.from(i),a=Buffer.from(t);return s.length===a.length&&ut(s,a)}};function mt(e){let r=e.trim();if(!r)return[];if(r.startsWith("[")){let o=JSON.parse(r);return Array.isArray(o)?o:[]}return r.split(`
24
- `).map(o=>o.trim()).filter(Boolean).map(o=>JSON.parse(o))}function gt(e){return{source:"vercel",stream:typeof e.source=="string"?e.source:void 0,timestamp:typeof e.timestamp=="number"?new Date(e.timestamp).toISOString():void 0,level:typeof e.level=="string"?e.level:void 0,message:typeof e.message=="string"?e.message:void 0,raw:e}}function Xe(e){if(e.vercel)return e.vercel.token?new Y(e.vercel):new V(e.vercel)}var ze=["vercel","supabase","railway"];async function Qe(e,r){if(e!==void 0&&!ze.includes(e))throw new Error(`Unknown log source "${e}". Use one of: ${ze.join(", ")}.`);let o=y(),t=await N(o.configPath);if(e===void 0){St(t);return}if(e==="vercel"){await Ct(t,r);return}if(e==="railway"){await _t(t,r);return}await Lt(t,r)}function St(e){let r=e.vercel,o=e.supabase,t=e.railway;n.info(""),n.info(n.bold("Log sources")),n.info(""),n.info(` ${"vercel".padEnd(10)} ${r?.token&&r.projectId?`configured project ${r.projectId}`:r?`drain mode listener :${r.listenerPort??Q}${r.listenerPath??Z}`:n.dim("not configured")}`),n.info(` ${"supabase".padEnd(10)} ${o?`configured project ${o.projectRef??n.dim("(no projectRef)")}`:n.dim("not configured")}`),n.info(` ${"railway".padEnd(10)} ${t?`configured ${t.deploymentId?`deployment ${t.deploymentId}`:`service ${t.serviceId??n.dim("(none)")}`}`:n.dim("not configured")}`),n.info(""),n.info(`Run ${n.bold("verirun log vercel")}, ${n.bold("verirun log supabase")} or ${n.bold("verirun log railway")} to connect one.`)}var $t="https://vercel.com/d?to=%2F%5Bteam%5D%2F~%2Fsettings%2Flog-drains&title=Log%20Drains";function kt(e){let r=vt.join(e,".vercel","project.json");if(wt(r))try{let o=JSON.parse(yt(r,"utf8"));return o.projectId?{projectId:o.projectId,...o.orgId?.startsWith("team_")?{teamId:o.orgId}:{}}:void 0}catch{return}}async function Rt(e){let r=await qe(e),o;if("error"in r)n.warn(` Could not list teams: ${r.error}`);else if(r.teams.length===1)o=r.teams[0].id,n.info(` team ${r.teams[0].name??o}`);else if(r.teams.length>1){n.info(" Which team?"),n.info(` 1. ${n.dim("(personal account)")}`),r.teams.forEach((c,l)=>n.info(` ${l+2}. ${c.name??c.slug??c.id}`));let a=Number.parseInt(await b(" Number: "),10)-2;r.teams[a]&&(o=r.teams[a].id)}let t=await Ye(e,o);if("error"in t){n.error(` Could not list projects: ${t.error}`);return}if(t.projects.length===0){n.warn(" That token can see no projects.");return}if(t.projects.length===1){let a=t.projects[0];return n.info(` project ${a.name} (${a.id})`),{projectId:a.id,...o?{teamId:o}:{}}}n.info(" Which project?"),t.projects.forEach((a,c)=>n.info(` ${c+1}. ${a.name}`));let i=Number.parseInt(await b(" Number: "),10)-1,s=t.projects[i];if(!s){n.warn(" Not one of the choices.");return}return{projectId:s.id,...o?{teamId:o}:{}}}async function Et(e){if(!e.token||!e.projectId)throw new Error("--test needs a connected project. Run `verirun log vercel` first.");let r=await X(e);if("error"in r){n.error(` ${r.error}`),process.exitCode=1;return}n.info(""),n.info(`Reading runtime logs for ${n.bold(r.label)}\u2026`);let o=await z(e,r.deploymentId,e.readMs??8e3);if("error"in o){n.error(` ${o.error}`),process.exitCode=1;return}let t=Date.now()-5*6e4,i=o.rows.filter(s=>typeof s.timestampInMs!="number"||s.timestampInMs>=t);n.success(` ${o.rows.length} line(s) on the stream, ${i.length} from the last 5 minutes.`);for(let s of i.slice(-5)){let a=Se(s);n.info(` ${n.dim(a.timestamp??"")} ${a.message??""}`)}o.rows.length===0&&n.info(n.dim(" No lines yet \u2014 hit the deployed app once, then re-run with --test."))}async function Ct(e,r){let{configPath:o,repoRoot:t}=y(),i=e.vercel??{},s=process.env.VERIRUN_VERCEL_TOKEN;if(r.drain||r.listen){await It(e,r);return}if(r.test){await Et(i);return}if(i.token&&i.projectId&&!r.reconnect){n.info(""),n.info(n.bold("Vercel logs \u2014 connected")),n.info(` project ${i.projectId}`),i.teamId&&n.info(` team ${i.teamId}`),n.info(` token ${s?"from $VERIRUN_VERCEL_TOKEN":"from config.json"}`),n.info(` deployment ${i.deploymentId??n.dim(`newest ready ${i.environment??"production"}`)}`),n.info(""),n.info(n.dim("--reconnect to replace it \xB7 --test to read the last 5 minutes"));return}n.info(""),n.info(n.bold("Connect Vercel logs"));let a=s??i.token;if(!a||r.reconnect){if(!process.stdin.isTTY){n.info(""),n.info("Not an interactive shell. Set these and re-run:"),n.info(` export VERIRUN_VERCEL_TOKEN=... ${n.dim(`(create at ${q})`)}`),n.info(` ${n.dim("and vercel.projectId (+ vercel.teamId) in .verirun/config.json")}`);return}n.info(` Opening ${n.bold(q)}`),n.info(" Create a token, copy it, come back here."),L(q),n.info("");let m=await b(" Paste the token: ");if(!m){n.warn(" Nothing pasted. No changes made.");return}a=m}let c=r.reconnect?void 0:kt(t);c&&n.info(` project ${c.projectId} ${n.dim("\u2014 from .vercel/project.json")}`);let l=c??await Rt(a);if(!l){n.warn(" No project chosen. No changes made.");return}let d={projectId:l.projectId,...l.teamId?{teamId:l.teamId}:{}};s||(d.token=a),await ee(o,{vercel:d}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let p={...i,...d,token:a},f=await X(p);if("error"in f){n.error(` ${f.error}`),n.info(n.dim(" Token or project looks wrong. Re-run `verirun log vercel --reconnect`.")),process.exitCode=1;return}let g=await z(p,f.deploymentId,4e3);if("error"in g){n.error(` Reading logs failed: ${g.error}`),n.info(n.dim(" The token may lack access to this project. Re-run with --reconnect.")),process.exitCode=1;return}n.success(` Connected to ${f.label}. \`verirun run\` now includes Vercel logs.`),g.rows.length===0&&n.info(n.dim(" (No log lines in the stream right now \u2014 that is normal for an idle app.)"))}async function It(e,r){let{configPath:o}=y(),t=e.vercel??{},i=t.listenerPort??Q,s=t.listenerPath??Z,a=t.drainGraceMs??$e;if(r.listen){await jt({...t,listenerPort:i,listenerPath:s});return}let c=process.env.VERIRUN_VERCEL_DRAIN_SECRET;if((t.drainSecret||c)&&!r.reconnect){n.info(""),n.info(n.bold("Vercel logs \u2014 drain mode")),n.info(` endpoint http://localhost:${i}${s}`),n.info(` drain secret ${c?"from $VERIRUN_VERCEL_DRAIN_SECRET":"from config.json"}`),n.info(` grace ${a}ms`),n.info(` project ${t.project??n.dim("all projects on the drain")}`),n.info(""),n.info(n.dim("--reconnect to change it \xB7 --listen to run the verification listener")),n.info(n.dim("`verirun log vercel` (no --drain) switches to the simpler API mode"));return}if(n.info(""),n.info(n.bold("Connect Vercel logs the old way (drain) \u2014 do these in order:")),n.info(n.dim(" You probably want `verirun log vercel` instead: a token, no tunnel.")),n.info(""),n.info(" 1. New terminal. Start a tunnel to port "+i+" and copy the https URL it prints:"),n.info(` ${n.bold(`ngrok http ${i}`)}`),n.info(n.dim(` (or: cloudflared tunnel --url http://localhost:${i})`)),n.info(""),n.info(" 2. Another new terminal. Start the listener and leave it running:"),n.info(` ${n.bold("verirun log vercel --listen")}`),n.info(""),n.info(" 3. Vercel page opening now (your team \u2192 Settings \u2192 Log Drains) \u2192 Add a drain:"),n.info(" Sources ......... check "+n.bold("Edge")+" and "+n.bold("Serverless")+", uncheck the rest"),n.info(" Delivery format . "+n.bold("JSON")),n.info(` Endpoint ........ ${n.bold(`<https URL from step 1>${s}`)}`),n.info(" then Save."),n.info(""),n.info(" 4. Vercel shows a Signing Secret. Copy it, paste it below."),!process.stdin.isTTY){n.info(""),n.info(n.dim(" Then: VERIRUN_VERCEL_DRAIN_SECRET=<secret> (or vercel.drainSecret in .verirun/config.json)"));return}L($t),n.info("");let l=await b(" Signing secret: ");if(!l){n.warn(" No secret. Deliveries would NOT be verified \u2014 anyone who finds the tunnel URL"),n.warn(" could feed fake logs into your runs.");let f=(await b(" Save without a secret anyway? [y/N]: ")).toLowerCase();if(f!=="y"&&f!=="yes"){n.info(" Nothing saved. Re-run `verirun log vercel --drain` once you have the secret.");return}l=""}let d=await b(" Only one project's logs? Paste its name or prj_\u2026 ID, or press Enter for all: "),p={};l&&(p.drainSecret=l),d&&(p.project=d),await ee(o,{vercel:p}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.success(" Done. `verirun run` starts its own listener \u2014 you only need --listen for tailing.")}async function jt(e){let r=new V(e,{onEntry:o=>{let t=o.timestamp??new Date().toISOString(),i=(o.level??"log").padEnd(5),s=o.stream?`${o.stream} `:"";n.info(`${n.dim(t)} ${i} ${n.dim(s)}${o.message??""}`)}});await r.start(),e.project&&n.info(n.dim(`Filtering to project "${e.project}".`)),n.info(n.dim("Waiting for deliveries. Press Ctrl+C to stop.")),n.info(""),await new Promise(o=>{let t=()=>{process.off("SIGINT",t),process.off("SIGTERM",t),n.info(""),r.dispose().then(o)};process.on("SIGINT",t),process.on("SIGTERM",t)}),n.step("Listener stopped.")}var ke="https://supabase.com/dashboard/account/tokens";async function b(e){if(!process.stdin.isTTY)return"";let r=bt({input:process.stdin,output:process.stdout});try{return(await r.question(e)).trim()}finally{r.close()}}async function ee(e,r){await _e(e,r)||n.warn(`Could not restrict ${e} to your account. It holds an API token \u2014 check its permissions.`)}function xt(){let e=ht("supabase",["projects","list","--output","json"],{encoding:"utf8",shell:process.platform==="win32"});if(!(e.error||e.status!==0))try{let o=JSON.parse(e.stdout).map(t=>({ref:String(t.id??t.ref??t.reference_id??""),name:String(t.name??"")})).filter(t=>t.ref!=="");return o.length>0?o:void 0}catch{return}}async function At(e){if(e)return e;let r=xt();if(r&&r.length===1){let t=r[0];return n.info(` project ${t.name} (${t.ref}) ${n.dim("\u2014 from the supabase CLI")}`),t.ref}if(r&&r.length>1){n.info(" Which project?"),r.forEach((i,s)=>n.info(` ${s+1}. ${i.name} (${i.ref})`));let t=Number.parseInt(await b(" Number: "),10)-1;if(r[t])return r[t].ref;n.warn(" Not one of the choices.")}return await b(" Project ref (the <ref> in dashboard/project/<ref>): ")||void 0}async function Nt(e,r,o){if(!e.projectRef)throw new Error("--test needs a connected project. Run `verirun log supabase` first.");if(!o)throw new Error("--test needs an access token. Run `verirun log supabase`, or set $VERIRUN_SUPABASE_ACCESS_TOKEN.");let t=new Date,i={startedAt:new Date(t.getTime()-5*6e4).toISOString(),endedAt:t.toISOString()};n.info(""),n.info(`Querying ${r.length} source${r.length===1?"":"s"} for the last 5 minutes\u2026`),n.info("");let s=!1;for(let a of r){let c=await J(e.projectRef,o,a,i);"error"in c?(s=!0,n.error(`${a.padEnd(16)} ${c.error}`)):n.success(`${a.padEnd(16)} ${c.rows.length} row${c.rows.length===1?"":"s"}`)}s&&(process.exitCode=1)}async function Lt(e,r){let{configPath:o}=y(),t=e.supabase??{},i=t.sources&&t.sources.length>0?t.sources:ye,s=process.env.VERIRUN_SUPABASE_ACCESS_TOKEN,a=s??t.accessToken;if(r.test){await Nt(t,i,a);return}if(t.projectRef&&a&&!r.reconnect){n.info(""),n.info(n.bold("Supabase logs \u2014 connected")),n.info(` project ${t.projectRef}`),n.info(` token ${s?"from $VERIRUN_SUPABASE_ACCESS_TOKEN":"from config.json"}`),n.info(` sources ${i.join(", ")}`),n.info(""),n.info(n.dim("--reconnect to replace the token \xB7 --test to query the last 5 minutes"));return}if(n.info(""),n.info(n.bold("Connect Supabase logs")),!a||r.reconnect){if(!process.stdin.isTTY){n.info(""),n.info("Not an interactive shell. Set these and re-run:"),n.info(` export VERIRUN_SUPABASE_ACCESS_TOKEN=sbp_... ${n.dim(`(create at ${ke})`)}`),n.info(` ${n.dim("and supabase.projectRef in .verirun/config.json")}`);return}n.info(` Opening ${n.bold(ke)}`),n.info(' Click "Generate new token", copy it, come back here.'),L(ke),n.info("");let g=await b(" Paste the token: ");if(!g){n.warn(" Nothing pasted. No changes made.");return}g.startsWith("sbp_")||n.warn(" That does not look like a Supabase token (expected sbp_\u2026). Saving it anyway."),a=g}let c=await At(r.reconnect?void 0:t.projectRef);if(!c){n.warn(" No project ref given. No changes made.");return}let l={projectRef:c};s||(l.accessToken=a),await ee(o,{supabase:l}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let d=new Date,p={startedAt:new Date(d.getTime()-5*6e4).toISOString(),endedAt:d.toISOString()},f=await J(c,a,i[0],p);if("error"in f){n.error(` ${i[0]} query failed: ${f.error}`),n.info(n.dim(" Token or project ref looks wrong. Re-run `verirun log supabase --reconnect`.")),process.exitCode=1;return}n.success(` Connected. \`verirun run\` now includes Supabase logs (${i.join(", ")}).`)}function Ze(e){return!!(e.deploymentId||e.projectId&&e.environmentId&&e.serviceId)}function Tt(e){try{let r=new URL(e.trim());if(!/(^|\.)railway\.(com|app)$/.test(r.hostname))return;let o=r.pathname.match(/\/project\/([^/]+)\/service\/([^/?#]+)/),t=r.searchParams.get("environmentId");return!o||!o[1]||!o[2]||!t?void 0:{projectId:o[1],environmentId:t,serviceId:o[2]}}catch{return}}async function Pt(e,r){if(!r)throw new Error("--test needs a token. Run `verirun log railway`, or set $VERIRUN_RAILWAY_TOKEN.");if(!Ze(e))throw new Error("--test needs a connected deployment. Run `verirun log railway` first.");let o=await K({...e,token:r});if("error"in o)throw new Error(`Railway: ${o.error}`);let t=new Date,i={startedAt:new Date(t.getTime()-5*6e4).toISOString(),endedAt:t.toISOString()};n.info(""),n.info(`Querying deployment ${o.deploymentId} for the last 5 minutes\u2026`);let s=await he(r,o.deploymentId,i);if("error"in s){n.error(`railway ${s.error}`),process.exitCode=1;return}n.success(`railway ${s.entries.length} row${s.entries.length===1?"":"s"}`)}async function _t(e,r){let{configPath:o}=y(),t=e.railway??{},i=process.env.VERIRUN_RAILWAY_TOKEN,s=i??t.token;if(r.test){await Pt(t,s);return}if(s&&Ze(t)&&!r.reconnect){n.info(""),n.info(n.bold("Railway logs \u2014 connected")),n.info(` token ${i?"from $VERIRUN_RAILWAY_TOKEN":"from config.json"}`),t.deploymentId?n.info(` deployment ${t.deploymentId} ${n.dim("(pinned)")}`):(n.info(` project ${t.projectId}`),n.info(` environment ${t.environmentId}`),n.info(` service ${t.serviceId} ${n.dim("(latest deployment resolved per run)")}`)),n.info(""),n.info(n.dim("--reconnect to change it \xB7 --test to query the last 5 minutes"));return}if(n.info(""),n.info(n.bold("Connect Railway logs \u2014 2 things:")),n.info(""),n.info(` 1. On the page opening now (${ge}):`),n.info(' "Create Token" \u2192 name it \u2192 pick your team \u2192 Create \u2192 copy the value.'),n.info(" 2. In Railway, open the service you want logs from. Copy its URL from the"),n.info(" address bar \u2014 looks like:"),n.info(" https://railway.com/project/PROJECT/service/SERVICE?environmentId=ENV"),!process.stdin.isTTY){n.info(""),n.info(n.dim("Then: VERIRUN_RAILWAY_TOKEN=<token>, and railway.projectId / environmentId / serviceId (from that URL) in .verirun/config.json."));return}if(!s||r.reconnect){L(ge),n.info("");let d=await b(" Railway token: ");if(!d){n.warn(" Nothing pasted. No changes made.");return}s=d}let a={};i||(a.token=s);let c=Tt(await b(" Service URL (paste the whole thing): "));if(c)a.projectId=c.projectId,a.environmentId=c.environmentId,a.serviceId=c.serviceId;else{n.warn(" Couldn't read that URL. Enter the three IDs from it by hand:");let d=await b(" Project ID: "),p=await b(" Environment ID: "),f=await b(" Service ID: ");if(!d||!p||!f){n.warn(" Need all three. No changes made.");return}a.projectId=d,a.environmentId=p,a.serviceId=f}await ee(o,{railway:a}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let l=await K({...t,...a,token:s});if("error"in l){n.error(` ${l.error}`),n.info(n.dim(" Re-run `verirun log railway --reconnect` with the right token / IDs.")),process.exitCode=1;return}n.success(` Connected. Deployment ${l.deploymentId}. \`verirun run\` now includes Railway logs.`)}import{existsSync as rr,readFileSync as tr}from"node:fs";import{mkdir as Ot,readdir as Dt,writeFile as er}from"node:fs/promises";import I from"node:path";var Ut=new Set(["node_modules",".git",".next",".verirun","dist","build","out","coverage",".turbo",".vercel"]);async function Vt(e){let r=[],o=async t=>{for(let i of await Dt(t,{withFileTypes:!0})){if(i.name.startsWith(".")&&i.name!==".")continue;let s=I.join(t,i.name);if(i.isDirectory()){if(Ut.has(i.name))continue;await o(s)}else/\.tsx?$/.test(i.name)&&!i.name.endsWith(".d.ts")&&r.push({file:I.relative(e,s).split(I.sep).join("/"),source:tr(s,"utf8")})}};return await o(e),r}function Ft(e){let r=I.join(e,"tsconfig.json");if(!rr(r))return{};try{let o=tr(r,"utf8").replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1").replace(/,(\s*[}\]])/g,"$1"),t=JSON.parse(o),i={};for(let[s,a]of Object.entries(t.compilerOptions?.paths??{})){let c=a[0];!s.endsWith("/*")||!c?.endsWith("/*")||(i[s.slice(0,-1)]=c.slice(0,-2).replace(/^\.\//,""))}return i}catch{return{}}}function Mt(e,r){let o={...r};for(let t of e??[]){let[i,s]=t.split("=");i&&(o[i]=s??"")}return o}function Wt(e,r){let o=e.nodes.pages.filter(i=>!i.inferred);n.info(`${n.bold(String(o.length))} pages \xB7 ${n.bold(String(e.nodes.leaves.length))} backend effects \xB7 ${n.bold(String(e.edges.length))} edges ${n.dim(`(${r.length} files)`)}`),n.info("");for(let i of e.nodes.pages){let s=e.edges.filter(d=>d.from===i.id),a=s.filter(d=>d.kind==="nav").length,c=s.filter(d=>d.kind==="effect").length,l=i.inferred?n.dim(" (inferred)"):"";n.info(` ${i.path}${l} ${n.dim(`\u2014 ${i.component}, ${i.elements.length} element(s), ${a} nav, ${c} effect`)}`)}let t=e.diagnostics;t.parseErrors.length>0&&n.warn(`${t.parseErrors.length} file(s) failed to parse`),t.unresolvedTargets.length>0&&(n.info(""),n.info(n.dim(`${t.unresolvedTargets.length} nav target(s) could not be resolved to a page`)))}async function nr(e){let{assertLicensed:r}=await import("./gate.mjs"),{assembleTree:o,bfs:t,buildCoverage:i,measureReach:s,renderBfs:a,renderMarkdown:c,renderReachTable:l}=await import("./graph.mjs"),d=await r();d.note&&n.warn(d.note);let p=y(),f=e.dir?I.resolve(e.dir):p.repoRoot;if(!rr(f))throw new Error(`no such directory: ${f}`);let g=await Vt(f);if(g.length===0)throw new Error(`no .ts/.tsx files found under ${f}`);let w={aliases:Mt(e.alias,Ft(f)),...e.followChildren===!1?{followChildren:!1}:{},...e.appFile?{appFile:e.appFile}:{}};if(e.bfs){let u=o(g,w),v=e.kind==="nav"||e.kind==="effect"?[e.kind]:void 0,S=t(u,e.bfs,{depth:e.depth?Number(e.depth):2,...v?{kinds:v}:{}});n.info(n.dim(`${S.order.length-1} node(s) within ${S.maxDepth} step(s) of ${S.from}`)),n.info(a(S));return}if(e.reach){let u=s(g,w);n.info(l(u));for(let v of u.unreachedFiles)n.info(n.dim(`unreached: ${v.file} (${v.elements} elements)`));return}let h=o(g,w);if(e.json){process.stdout.write(`${JSON.stringify(h,null,2)}
25
- `);return}if(e.report){let u=e.out?I.resolve(e.out):I.join(p.dataDir,"map");await Ot(u,{recursive:!0});let v=i(g,h);await er(I.join(u,"interaction-tree.json"),`${JSON.stringify(h,null,2)}
26
- `),await er(I.join(u,"coverage.md"),`${c(v,h)}
27
- `);let S=I.relative(process.cwd(),u),$=S.startsWith("..")?u:S;n.success(`wrote ${$}/interaction-tree.json + coverage.md`);let x=v.bar.filter(A=>A.pass===!1).length;n.info(n.dim(`${v.bar.length-x}/${v.bar.length} coverage checks pass`));return}Wt(h,g)}import{existsSync as yn}from"node:fs";import{mkdir as vn}from"node:fs/promises";import ur from"node:path";import{spawnSync as Bt}from"node:child_process";var Gt={browser:"chromium",channel:"chrome",label:"Chrome",approximated:!1},Ht={browser:"chromium",channel:"msedge",label:"Edge",approximated:!1},Kt={browser:"firefox",label:"Firefox",approximated:!1},Jt={browser:"chromium",label:"Chromium",approximated:!1};function Re(e,r){let o=e.toLowerCase(),t=i=>r?{...i,label:r}:i;if(o.includes("firefox")||o.includes("mozilla"))return t(Kt);if(o.includes("msedge")||o.includes("microsoft-edge")||o.includes("edgemac")||o.includes("microsoftedge"))return t(Ht);if(o.includes("google-chrome")||o.includes("com.google.chrome")||o==="chromehtml"||o.includes("chrome"))return t(Gt);if(o.includes("chromium"))return t(Jt);if(o.includes("safari"))return{browser:"webkit",label:"Safari",approximated:!0};if(o.includes("brave"))return{browser:"chromium",label:"Brave",approximated:!0};if(o.includes("thebrowser")||o.includes("arc"))return{browser:"chromium",label:"Arc",approximated:!0};if(o.includes("vivaldi"))return{browser:"chromium",label:"Vivaldi",approximated:!0};if(o.includes("opera")||o.includes("opr"))return{browser:"chromium",label:"Opera",approximated:!0}}function re(e,r){let o=Bt(e,r,{encoding:"utf8",timeout:4e3});if(!(o.error||o.status!==0))return(o.stdout||"").trim()||void 0}function Yt(){let e=re("xdg-settings",["get","default-web-browser"])??re("xdg-mime",["query","default","x-scheme-handler/https"]);return e?Re(e):void 0}function qt(){let e=re("plutil",["-convert","json","-o","-",`${process.env.HOME}/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`]);if(e)try{let o=(JSON.parse(e).LSHandlers??[]).find(i=>i.LSHandlerURLScheme==="https"),t=typeof o?.LSHandlerRoleAll=="string"?o.LSHandlerRoleAll:void 0;return t?Re(t):void 0}catch{return}}function Xt(){let r=re("reg",["query","HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\https\\UserChoice","/v","ProgId"])?.match(/ProgId\s+REG_SZ\s+(\S+)/i)?.[1];return r?Re(r):void 0}function or(){try{if(process.platform==="darwin")return qt();if(process.platform==="linux")return Yt();if(process.platform==="win32")return Xt()}catch{}}import{spawn as zt}from"node:child_process";import{mkdtemp as Qt,readFile as Zt,rm as en}from"node:fs/promises";import{createRequire as rn}from"node:module";import tn from"node:os";import te from"node:path";var nn=new Set(["name","selector","locator","signals","pageGuid","ariaSnapshot"]);function ir(e){let r={};for(let[o,t]of Object.entries(e))!nn.has(o)&&t!==void 0&&(r[o]=t);return r}function on(){let e=rn(import.meta.url),r=e.resolve("playwright/package.json"),o=e("playwright/package.json"),t=typeof o.bin=="string"?o.bin:o.bin?.playwright;if(!t)throw new Error("Could not locate the Playwright CLI entrypoint in playwright/package.json.");return te.join(te.dirname(r),t)}async function sr(e){let r=on(),o=await Qt(te.join(tn.tmpdir(),"verirun-record-")),t=te.join(o,"recording.jsonl"),i=[r,"codegen","--target=jsonl",`--output=${t}`];e.browser&&i.push(`--browser=${e.browser}`),e.channel&&i.push(`--channel=${e.channel}`),e.userDataDir&&i.push(`--user-data-dir=${e.userDataDir}`),e.testIdAttribute&&i.push(`--test-id-attribute=${e.testIdAttribute}`),e.url&&i.push(e.url);try{let s=await new Promise((c,l)=>{let d=zt(process.execPath,i,{stdio:["ignore","inherit","inherit"]});d.on("error",l),d.on("close",p=>c(p))}),a=await Zt(t,"utf8").catch(()=>"");return{...sn(a),exitCode:s}}finally{await en(o,{recursive:!0,force:!0})}}function sn(e){let r=e.split(`
28
- `).filter(i=>i.trim().length>0),o={},t=[];for(let[i,s]of r.entries()){let a;try{a=JSON.parse(s)}catch{continue}if(i===0&&a&&typeof a=="object"&&!("name"in a)){o=a;continue}a&&typeof a=="object"&&"name"in a&&t.push(a)}return{header:o,actions:t}}import{existsSync as an}from"node:fs";import{appendFile as cn,readFile as ln}from"node:fs/promises";import dn from"node:path";function un(e){return e.split(`
29
- `).map(r=>r.trim()).filter(r=>r&&!r.startsWith("#")).some(r=>r.replace(/^\//,"").replace(/\/$/,"")===G)}async function ar(e){let r=dn.join(e,".gitignore");if(!an(r))return"no-gitignore";let o=await ln(r,"utf8");if(un(o))return"already-present";let t=o.length===0||o.endsWith(`
24
+ }`,{id:r,start:o.startedAt,end:o.endedAt,filter:s});return"error"in c?c:{entries:Array.isArray(c.data.deploymentLogs)?c.data.deploymentLogs:[]}}function ct(e){let r=typeof e.severity=="string"?e.severity:void 0;return{source:"railway",stream:r?r.toLowerCase():"deploy",timestamp:typeof e.timestamp=="string"?e.timestamp:void 0,level:r,message:typeof e.message=="string"?e.message:void 0,raw:e}}var me=class{id="railway";name="Railway";cfg;constructor(r){this.cfg=r}async start(){if(!this.cfg.token)throw new Error("Railway log capture needs an API token. Set VERIRUN_RAILWAY_TOKEN or railway.token in .verirun/config.json.");if(!this.cfg.deploymentId&&!(this.cfg.projectId&&this.cfg.environmentId&&this.cfg.serviceId))throw new Error("Railway log capture needs railway.deploymentId, or railway.projectId + railway.environmentId + railway.serviceId, in .verirun/config.json.")}async collect(r,o){let t=await J(this.cfg);if("error"in t)return n.warn(`Railway: ${t.error}`),[];let i=await he(this.cfg.token,t.deploymentId,o,{userNeedle:r.userFilter});if("error"in i)return n.warn(`Railway: ${i.error}`),[];let s=i.entries.map(ct);return s.sort((a,c)=>(a.timestamp??"").localeCompare(c.timestamp??"")),s}async dispose(){}};function He(e){return e.railway?new me(e.railway):void 0}var lt="https://api.supabase.com",ye=["postgres_logs","edge_logs","auth_logs"],we=class{id="supabase";name="Supabase";projectRef;accessToken;sources;constructor(r){this.projectRef=r.projectRef,this.accessToken=r.accessToken,this.sources=r.sources&&r.sources.length>0?r.sources:ye}async start(){if(!this.projectRef)throw new Error("Supabase log capture needs supabase.projectRef in .verirun/config.json.");if(!this.accessToken)throw new Error("Supabase log capture needs an access token. Set VERIRUN_SUPABASE_ACCESS_TOKEN or supabase.accessToken in .verirun/config.json.")}async collect(r,o){let t=r.userFilter,i=[],s=!1;for(let a of this.sources){let c=await K(this.projectRef,this.accessToken,a,o,{userNeedle:t});if("error"in c){n.warn(`Supabase ${a}: ${c.error}`);continue}t&&!c.serverFiltered&&(s=!0);for(let l of c.rows)i.push(ut(a,l))}return t&&s&&n.info(n.dim("Supabase: user filter applied client-side for a source (more rows pulled).")),i.sort((a,c)=>(a.timestamp??"").localeCompare(c.timestamp??"")),i}async dispose(){}},dt=/^[A-Za-z0-9._@%+-]{1,256}$/;async function Je(e,r,o,t){let i=new URL(`/v1/projects/${e}/analytics/endpoints/logs.all`,lt);i.searchParams.set("sql",o),i.searchParams.set("iso_timestamp_start",t.startedAt),i.searchParams.set("iso_timestamp_end",t.endedAt);let s;try{s=await C(i,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"}})}catch(c){return{error:c instanceof Error?c.message:String(c)}}let a=await s.json().catch(()=>{});if(!s.ok){let c=(typeof a?.error=="string"?a.error:a?.error?.message)??a?.message??`HTTP ${s.status}`;return{error:`${c}${c.startsWith("HTTP")?"":` (HTTP ${s.status})`}`}}return{rows:Array.isArray(a?.result)?a.result:[]}}async function K(e,r,o,t,i={}){let s=i.userNeedle?.trim().toLowerCase(),a=s&&dt.test(s)?s:void 0,c=f=>{let p=f&&a?` where strpos(lower(event_message), '${a}') > 0 or strpos(lower(to_json_string(metadata)), '${a}') > 0`:"";return`select id, timestamp, event_message, metadata from ${o}${p} order by timestamp asc limit 1000`},l=await Je(e,r,c(!0),t);if(!("error"in l))return{rows:l.rows,serverFiltered:!!a};if(!a)return l;let d=await Je(e,r,c(!1),t);return"error"in d?d:{rows:d.rows,serverFiltered:!1}}function ut(e,r){return{source:"supabase",stream:e,timestamp:ft(r.timestamp),message:typeof r.event_message=="string"?r.event_message:void 0,raw:r}}function ft(e){if(typeof e=="string")return e;if(typeof e=="number"&&Number.isFinite(e)){let r=e>1e14?e/1e3:e;return new Date(r).toISOString()}}function Ke(e){return e.supabase?new we(e.supabase):void 0}import{createHmac as ht,timingSafeEqual as wt}from"node:crypto";import{createServer as yt}from"node:http";import{setTimeout as vt}from"node:timers/promises";var Ye="https://api.vercel.com",q="https://vercel.com/account/settings/tokens",pt=8e3,mt=1500,gt=3e3;function ve(e){return e?`&teamId=${encodeURIComponent(e)}`:""}async function be(e,r){let o;try{o=await C(`${Ye}${e}`,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"}})}catch(i){return{error:i instanceof Error?i.message:String(i)}}let t=await o.json().catch(()=>{});return o.ok?{data:t}:{error:t?.error?.message??`HTTP ${o.status}`}}async function qe(e,r){let o=await be(`/v9/projects?limit=100${ve(r)}`,e);return"error"in o?o:{projects:o.data.projects??[]}}async function Xe(e){let r=await be("/v2/teams?limit=100",e);return"error"in r?r:{teams:r.data.teams??[]}}async function X(e){if(e.deploymentId)return{deploymentId:e.deploymentId,label:e.deploymentId};if(!e.token)return{error:"no token"};if(!e.projectId)return{error:"no projectId"};let r=e.environment??"production",o=await be(`/v6/deployments?projectId=${encodeURIComponent(e.projectId)}&limit=1&state=READY&target=${encodeURIComponent(r)}${ve(e.teamId)}`,e.token);if("error"in o)return{error:o.error};let t=o.data.deployments?.[0];return t?{deploymentId:t.uid,label:t.url??t.uid}:{error:`no READY ${r} deployment found for this project`}}async function z(e,r,o){let t=`/v1/projects/${encodeURIComponent(e.projectId)}/deployments/${encodeURIComponent(r)}/runtime-logs?limit=1000${ve(e.teamId)}`,i=new AbortController,s=setTimeout(()=>i.abort(),o),a,c=()=>{a&&clearTimeout(a),a=setTimeout(()=>i.abort(),mt)},l=[];try{let d=await C(`${Ye}${t}`,{headers:{Authorization:`Bearer ${e.token}`,Accept:"application/x-ndjson, application/json"},signal:i.signal});if(!d.ok)return{error:(await d.json().catch(()=>{}))?.error?.message??`HTTP ${d.status}`};if(!d.body)return{rows:l};c();let f=new TextDecoder,p="";for await(let g of d.body){p+=f.decode(g,{stream:!0});let m=p.split(`
25
+ `);p=m.pop()??"";for(let w of m){let h=w.trim();if(h)try{let u=JSON.parse(h);Array.isArray(u)?l.push(...u):l.push(u)}catch{}}c()}}catch(d){if(!(d instanceof Error&&d.name==="AbortError"))return{error:d instanceof Error?d.message:String(d)}}finally{clearTimeout(s),a&&clearTimeout(a)}return{rows:l}}function $e(e){let r=e.requestPath?` ${e.requestMethod??""} ${e.requestPath}`.trim():"",o=e.responseStatusCode?` (${e.responseStatusCode})`:"";return{source:"vercel",...e.source?{stream:e.source}:{},...e.timestampInMs?{timestamp:new Date(e.timestampInMs).toISOString()}:{},...e.level?{level:e.level}:{},message:e.message??`${r}${o}`.trim(),raw:e}}var Y=class{id="vercel";name="Vercel";config;constructor(r){this.config=r}async start(){if(!this.config.token)throw new Error("Vercel log capture needs an API token. Run `verirun log vercel`, or set VERIRUN_VERCEL_TOKEN / vercel.token in .verirun/config.json.");if(!this.config.projectId)throw new Error("Vercel log capture needs vercel.projectId. Run `verirun log vercel`.")}async collect(r,o){let t=await X(this.config);if("error"in t)return n.warn(`Vercel: ${t.error}`),[];let i=await z(this.config,t.deploymentId,this.config.readMs??pt);if("error"in i)return n.warn(`Vercel: ${i.error}`),[];let s=Date.parse(o.startedAt),a=Date.parse(o.endedAt)+(this.config.tailGraceMs??gt);return i.rows.filter(c=>typeof c.timestampInMs!="number"?!0:c.timestampInMs>=s&&c.timestampInMs<=a).map($e)}async dispose(){}};var Q=4319,Z="/drain",Se=3e3,V=class{id="vercel";name="Vercel";port;path;secret;graceMs;project;onEntry;server;received=[];droppedByProject=0;constructor(r,o={}){this.port=r.listenerPort??Q,this.path=r.listenerPath??Z,this.secret=r.drainSecret,this.graceMs=r.drainGraceMs??Se,this.project=r.project?.trim()||void 0,this.onEntry=o.onEntry}projectMatches(r){return this.project?r.projectId===this.project||r.projectName===this.project:!0}async start(){let r=yt((o,t)=>this.handle(o,t));this.server=r,await new Promise((o,t)=>{let i=s=>{t(s.code==="EADDRINUSE"?new Error(`Vercel log listener: port ${this.port} is already in use.`):s)};r.once("error",i),r.listen(this.port,()=>{r.off("error",i),o()})}),n.step(`Vercel log listener on http://localhost:${this.port}${this.path}`)}async collect(){return this.graceMs>0&&await vt(this.graceMs),this.received.length===0&&this.droppedByProject>0&&n.warn(`Vercel: ${this.droppedByProject} log line(s) arrived but none matched project "${this.project}". Check the name/ID in .verirun/config.json (vercel.project).`),[...this.received]}async dispose(){let r=this.server;r&&(this.server=void 0,await new Promise(o=>r.close(()=>o())))}handle(r,o){let t=r.headers["x-vercel-verify"];if(typeof t=="string"&&o.setHeader("x-vercel-verify",t),r.method!=="POST"||!this.matchesPath(r.url)){o.statusCode=r.method==="POST"?404:200,o.end();return}let i=[];r.on("data",s=>i.push(s)),r.on("error",()=>{o.statusCode=400,o.end()}),r.on("end",()=>{let s=Buffer.concat(i);if(!this.verifySignature(r,s)){n.warn("Vercel log drain: rejected a delivery with a bad signature."),o.statusCode=401,o.end();return}try{for(let a of bt(s.toString("utf8"))){if(!this.projectMatches(a)){this.droppedByProject+=1;continue}let c=$t(a);this.received.push(c),this.onEntry?.(c)}}catch{n.warn("Vercel log drain: could not parse a delivery body.")}o.statusCode=200,o.end()})}matchesPath(r){return r?(r.split("?")[0]??"")===this.path:!1}verifySignature(r,o){if(!this.secret)return!0;let t=r.headers["x-vercel-signature"];if(typeof t!="string")return!1;let i=ht("sha1",this.secret).update(o).digest("hex"),s=Buffer.from(i),a=Buffer.from(t);return s.length===a.length&&wt(s,a)}};function bt(e){let r=e.trim();if(!r)return[];if(r.startsWith("[")){let o=JSON.parse(r);return Array.isArray(o)?o:[]}return r.split(`
26
+ `).map(o=>o.trim()).filter(Boolean).map(o=>JSON.parse(o))}function $t(e){return{source:"vercel",stream:typeof e.source=="string"?e.source:void 0,timestamp:typeof e.timestamp=="number"?new Date(e.timestamp).toISOString():void 0,level:typeof e.level=="string"?e.level:void 0,message:typeof e.message=="string"?e.message:void 0,raw:e}}function ze(e){if(e.vercel)return e.vercel.token?new Y(e.vercel):new V(e.vercel)}var Qe=["vercel","supabase","railway"];async function Ze(e,r){if(e!==void 0&&!Qe.includes(e))throw new Error(`Unknown log source "${e}". Use one of: ${Qe.join(", ")}.`);let o=y(),t=await T(o.configPath);if(e===void 0){It(t);return}if(e==="vercel"){await Nt(t,r);return}if(e==="railway"){await Mt(t,r);return}await Ut(t,r)}function It(e){let r=e.vercel,o=e.supabase,t=e.railway;n.info(""),n.info(n.bold("Log sources")),n.info(""),n.info(` ${"vercel".padEnd(10)} ${r?.token&&r.projectId?`configured project ${r.projectId}`:r?`drain mode listener :${r.listenerPort??Q}${r.listenerPath??Z}`:n.dim("not configured")}`),n.info(` ${"supabase".padEnd(10)} ${o?`configured project ${o.projectRef??n.dim("(no projectRef)")}`:n.dim("not configured")}`),n.info(` ${"railway".padEnd(10)} ${t?`configured ${t.deploymentId?`deployment ${t.deploymentId}`:`service ${t.serviceId??n.dim("(none)")}`}`:n.dim("not configured")}`),n.info(""),n.info(`Run ${n.bold("verirun log vercel")}, ${n.bold("verirun log supabase")} or ${n.bold("verirun log railway")} to connect one.`)}var jt="https://vercel.com/d?to=%2F%5Bteam%5D%2F~%2Fsettings%2Flog-drains&title=Log%20Drains";function xt(e){let r=Et.join(e,".vercel","project.json");if(kt(r))try{let o=JSON.parse(Rt(r,"utf8"));return o.projectId?{projectId:o.projectId,...o.orgId?.startsWith("team_")?{teamId:o.orgId}:{}}:void 0}catch{return}}async function At(e){let r=await Xe(e),o;if("error"in r)n.warn(` Could not list teams: ${r.error}`);else if(r.teams.length===1)o=r.teams[0].id,n.info(` team ${r.teams[0].name??o}`);else if(r.teams.length>1){n.info(" Which team?"),n.info(` 1. ${n.dim("(personal account)")}`),r.teams.forEach((c,l)=>n.info(` ${l+2}. ${c.name??c.slug??c.id}`));let a=Number.parseInt(await b(" Number: "),10)-2;r.teams[a]&&(o=r.teams[a].id)}let t=await qe(e,o);if("error"in t){n.error(` Could not list projects: ${t.error}`);return}if(t.projects.length===0){n.warn(" That token can see no projects.");return}if(t.projects.length===1){let a=t.projects[0];return n.info(` project ${a.name} (${a.id})`),{projectId:a.id,...o?{teamId:o}:{}}}n.info(" Which project?"),t.projects.forEach((a,c)=>n.info(` ${c+1}. ${a.name}`));let i=Number.parseInt(await b(" Number: "),10)-1,s=t.projects[i];if(!s){n.warn(" Not one of the choices.");return}return{projectId:s.id,...o?{teamId:o}:{}}}async function Tt(e){if(!e.token||!e.projectId)throw new Error("--test needs a connected project. Run `verirun log vercel` first.");let r=await X(e);if("error"in r){n.error(` ${r.error}`),process.exitCode=1;return}n.info(""),n.info(`Reading runtime logs for ${n.bold(r.label)}\u2026`);let o=await z(e,r.deploymentId,e.readMs??8e3);if("error"in o){n.error(` ${o.error}`),process.exitCode=1;return}let t=Date.now()-5*6e4,i=o.rows.filter(s=>typeof s.timestampInMs!="number"||s.timestampInMs>=t);n.success(` ${o.rows.length} line(s) on the stream, ${i.length} from the last 5 minutes.`);for(let s of i.slice(-5)){let a=$e(s);n.info(` ${n.dim(a.timestamp??"")} ${a.message??""}`)}o.rows.length===0&&n.info(n.dim(" No lines yet \u2014 hit the deployed app once, then re-run with --test."))}async function Nt(e,r){let{configPath:o,repoRoot:t}=y(),i=e.vercel??{},s=process.env.VERIRUN_VERCEL_TOKEN;if(r.drain||r.listen){await Lt(e,r);return}if(r.test){await Tt(i);return}if(i.token&&i.projectId&&!r.reconnect){n.info(""),n.info(n.bold("Vercel logs \u2014 connected")),n.info(` project ${i.projectId}`),i.teamId&&n.info(` team ${i.teamId}`),n.info(` token ${s?"from $VERIRUN_VERCEL_TOKEN":"from config.json"}`),n.info(` deployment ${i.deploymentId??n.dim(`newest ready ${i.environment??"production"}`)}`),n.info(""),n.info(n.dim("--reconnect to replace it \xB7 --test to read the last 5 minutes"));return}n.info(""),n.info(n.bold("Connect Vercel logs"));let a=s??i.token;if(!a||r.reconnect){if(!process.stdin.isTTY){n.info(""),n.info("Not an interactive shell. Set these and re-run:"),n.info(` export VERIRUN_VERCEL_TOKEN=... ${n.dim(`(create at ${q})`)}`),n.info(` ${n.dim("and vercel.projectId (+ vercel.teamId) in .verirun/config.json")}`);return}n.info(` Opening ${n.bold(q)}`),n.info(" Create a token, copy it, come back here."),N(q),n.info("");let m=await b(" Paste the token: ");if(!m){n.warn(" Nothing pasted. No changes made.");return}a=m}let c=r.reconnect?void 0:xt(t);c&&n.info(` project ${c.projectId} ${n.dim("\u2014 from .vercel/project.json")}`);let l=c??await At(a);if(!l){n.warn(" No project chosen. No changes made.");return}let d={projectId:l.projectId,...l.teamId?{teamId:l.teamId}:{}};s||(d.token=a),await ee(o,{vercel:d}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let f={...i,...d,token:a},p=await X(f);if("error"in p){n.error(` ${p.error}`),n.info(n.dim(" Token or project looks wrong. Re-run `verirun log vercel --reconnect`.")),process.exitCode=1;return}let g=await z(f,p.deploymentId,4e3);if("error"in g){n.error(` Reading logs failed: ${g.error}`),n.info(n.dim(" The token may lack access to this project. Re-run with --reconnect.")),process.exitCode=1;return}n.success(` Connected to ${p.label}. \`verirun run\` now includes Vercel logs.`),g.rows.length===0&&n.info(n.dim(" (No log lines in the stream right now \u2014 that is normal for an idle app.)"))}async function Lt(e,r){let{configPath:o}=y(),t=e.vercel??{},i=t.listenerPort??Q,s=t.listenerPath??Z,a=t.drainGraceMs??Se;if(r.listen){await Pt({...t,listenerPort:i,listenerPath:s});return}let c=process.env.VERIRUN_VERCEL_DRAIN_SECRET;if((t.drainSecret||c)&&!r.reconnect){n.info(""),n.info(n.bold("Vercel logs \u2014 drain mode")),n.info(` endpoint http://localhost:${i}${s}`),n.info(` drain secret ${c?"from $VERIRUN_VERCEL_DRAIN_SECRET":"from config.json"}`),n.info(` grace ${a}ms`),n.info(` project ${t.project??n.dim("all projects on the drain")}`),n.info(""),n.info(n.dim("--reconnect to change it \xB7 --listen to run the verification listener")),n.info(n.dim("`verirun log vercel` (no --drain) switches to the simpler API mode"));return}if(n.info(""),n.info(n.bold("Connect Vercel logs the old way (drain) \u2014 do these in order:")),n.info(n.dim(" You probably want `verirun log vercel` instead: a token, no tunnel.")),n.info(""),n.info(" 1. New terminal. Start a tunnel to port "+i+" and copy the https URL it prints:"),n.info(` ${n.bold(`ngrok http ${i}`)}`),n.info(n.dim(` (or: cloudflared tunnel --url http://localhost:${i})`)),n.info(""),n.info(" 2. Another new terminal. Start the listener and leave it running:"),n.info(` ${n.bold("verirun log vercel --listen")}`),n.info(""),n.info(" 3. Vercel page opening now (your team \u2192 Settings \u2192 Log Drains) \u2192 Add a drain:"),n.info(" Sources ......... check "+n.bold("Edge")+" and "+n.bold("Serverless")+", uncheck the rest"),n.info(" Delivery format . "+n.bold("JSON")),n.info(` Endpoint ........ ${n.bold(`<https URL from step 1>${s}`)}`),n.info(" then Save."),n.info(""),n.info(" 4. Vercel shows a Signing Secret. Copy it, paste it below."),!process.stdin.isTTY){n.info(""),n.info(n.dim(" Then: VERIRUN_VERCEL_DRAIN_SECRET=<secret> (or vercel.drainSecret in .verirun/config.json)"));return}N(jt),n.info("");let l=await b(" Signing secret: ");if(!l){n.warn(" No secret. Deliveries would NOT be verified \u2014 anyone who finds the tunnel URL"),n.warn(" could feed fake logs into your runs.");let p=(await b(" Save without a secret anyway? [y/N]: ")).toLowerCase();if(p!=="y"&&p!=="yes"){n.info(" Nothing saved. Re-run `verirun log vercel --drain` once you have the secret.");return}l=""}let d=await b(" Only one project's logs? Paste its name or prj_\u2026 ID, or press Enter for all: "),f={};l&&(f.drainSecret=l),d&&(f.project=d),await ee(o,{vercel:f}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.success(" Done. `verirun run` starts its own listener \u2014 you only need --listen for tailing.")}async function Pt(e){let r=new V(e,{onEntry:o=>{let t=o.timestamp??new Date().toISOString(),i=(o.level??"log").padEnd(5),s=o.stream?`${o.stream} `:"";n.info(`${n.dim(t)} ${i} ${n.dim(s)}${o.message??""}`)}});await r.start(),e.project&&n.info(n.dim(`Filtering to project "${e.project}".`)),n.info(n.dim("Waiting for deliveries. Press Ctrl+C to stop.")),n.info(""),await new Promise(o=>{let t=()=>{process.off("SIGINT",t),process.off("SIGTERM",t),n.info(""),r.dispose().then(o)};process.on("SIGINT",t),process.on("SIGTERM",t)}),n.step("Listener stopped.")}var ke="https://supabase.com/dashboard/account/tokens";async function b(e){if(!process.stdin.isTTY)return"";let r=Ct({input:process.stdin,output:process.stdout});try{return(await r.question(e)).trim()}finally{r.close()}}async function ee(e,r){await _e(e,r)||n.warn(`Could not restrict ${e} to your account. It holds an API token \u2014 check its permissions.`)}function _t(){let e=St("supabase",["projects","list","--output","json"],{encoding:"utf8",shell:process.platform==="win32"});if(!(e.error||e.status!==0))try{let o=JSON.parse(e.stdout).map(t=>({ref:String(t.id??t.ref??t.reference_id??""),name:String(t.name??"")})).filter(t=>t.ref!=="");return o.length>0?o:void 0}catch{return}}async function Ot(e){if(e)return e;let r=_t();if(r&&r.length===1){let t=r[0];return n.info(` project ${t.name} (${t.ref}) ${n.dim("\u2014 from the supabase CLI")}`),t.ref}if(r&&r.length>1){n.info(" Which project?"),r.forEach((i,s)=>n.info(` ${s+1}. ${i.name} (${i.ref})`));let t=Number.parseInt(await b(" Number: "),10)-1;if(r[t])return r[t].ref;n.warn(" Not one of the choices.")}return await b(" Project ref (the <ref> in dashboard/project/<ref>): ")||void 0}async function Dt(e,r,o){if(!e.projectRef)throw new Error("--test needs a connected project. Run `verirun log supabase` first.");if(!o)throw new Error("--test needs an access token. Run `verirun log supabase`, or set $VERIRUN_SUPABASE_ACCESS_TOKEN.");let t=new Date,i={startedAt:new Date(t.getTime()-5*6e4).toISOString(),endedAt:t.toISOString()};n.info(""),n.info(`Querying ${r.length} source${r.length===1?"":"s"} for the last 5 minutes\u2026`),n.info("");let s=!1;for(let a of r){let c=await K(e.projectRef,o,a,i);"error"in c?(s=!0,n.error(`${a.padEnd(16)} ${c.error}`)):n.success(`${a.padEnd(16)} ${c.rows.length} row${c.rows.length===1?"":"s"}`)}s&&(process.exitCode=1)}async function Ut(e,r){let{configPath:o}=y(),t=e.supabase??{},i=t.sources&&t.sources.length>0?t.sources:ye,s=process.env.VERIRUN_SUPABASE_ACCESS_TOKEN,a=s??t.accessToken;if(r.test){await Dt(t,i,a);return}if(t.projectRef&&a&&!r.reconnect){n.info(""),n.info(n.bold("Supabase logs \u2014 connected")),n.info(` project ${t.projectRef}`),n.info(` token ${s?"from $VERIRUN_SUPABASE_ACCESS_TOKEN":"from config.json"}`),n.info(` sources ${i.join(", ")}`),n.info(""),n.info(n.dim("--reconnect to replace the token \xB7 --test to query the last 5 minutes"));return}if(n.info(""),n.info(n.bold("Connect Supabase logs")),!a||r.reconnect){if(!process.stdin.isTTY){n.info(""),n.info("Not an interactive shell. Set these and re-run:"),n.info(` export VERIRUN_SUPABASE_ACCESS_TOKEN=sbp_... ${n.dim(`(create at ${ke})`)}`),n.info(` ${n.dim("and supabase.projectRef in .verirun/config.json")}`);return}n.info(` Opening ${n.bold(ke)}`),n.info(' Click "Generate new token", copy it, come back here.'),N(ke),n.info("");let g=await b(" Paste the token: ");if(!g){n.warn(" Nothing pasted. No changes made.");return}g.startsWith("sbp_")||n.warn(" That does not look like a Supabase token (expected sbp_\u2026). Saving it anyway."),a=g}let c=await Ot(r.reconnect?void 0:t.projectRef);if(!c){n.warn(" No project ref given. No changes made.");return}let l={projectRef:c};s||(l.accessToken=a),await ee(o,{supabase:l}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let d=new Date,f={startedAt:new Date(d.getTime()-5*6e4).toISOString(),endedAt:d.toISOString()},p=await K(c,a,i[0],f);if("error"in p){n.error(` ${i[0]} query failed: ${p.error}`),n.info(n.dim(" Token or project ref looks wrong. Re-run `verirun log supabase --reconnect`.")),process.exitCode=1;return}n.success(` Connected. \`verirun run\` now includes Supabase logs (${i.join(", ")}).`)}function er(e){return!!(e.deploymentId||e.projectId&&e.environmentId&&e.serviceId)}function Vt(e){try{let r=new URL(e.trim());if(!/(^|\.)railway\.(com|app)$/.test(r.hostname))return;let o=r.pathname.match(/\/project\/([^/]+)\/service\/([^/?#]+)/),t=r.searchParams.get("environmentId");return!o||!o[1]||!o[2]||!t?void 0:{projectId:o[1],environmentId:t,serviceId:o[2]}}catch{return}}async function Ft(e,r){if(!r)throw new Error("--test needs a token. Run `verirun log railway`, or set $VERIRUN_RAILWAY_TOKEN.");if(!er(e))throw new Error("--test needs a connected deployment. Run `verirun log railway` first.");let o=await J({...e,token:r});if("error"in o)throw new Error(`Railway: ${o.error}`);let t=new Date,i={startedAt:new Date(t.getTime()-5*6e4).toISOString(),endedAt:t.toISOString()};n.info(""),n.info(`Querying deployment ${o.deploymentId} for the last 5 minutes\u2026`);let s=await he(r,o.deploymentId,i);if("error"in s){n.error(`railway ${s.error}`),process.exitCode=1;return}n.success(`railway ${s.entries.length} row${s.entries.length===1?"":"s"}`)}async function Mt(e,r){let{configPath:o}=y(),t=e.railway??{},i=process.env.VERIRUN_RAILWAY_TOKEN,s=i??t.token;if(r.test){await Ft(t,s);return}if(s&&er(t)&&!r.reconnect){n.info(""),n.info(n.bold("Railway logs \u2014 connected")),n.info(` token ${i?"from $VERIRUN_RAILWAY_TOKEN":"from config.json"}`),t.deploymentId?n.info(` deployment ${t.deploymentId} ${n.dim("(pinned)")}`):(n.info(` project ${t.projectId}`),n.info(` environment ${t.environmentId}`),n.info(` service ${t.serviceId} ${n.dim("(latest deployment resolved per run)")}`)),n.info(""),n.info(n.dim("--reconnect to change it \xB7 --test to query the last 5 minutes"));return}if(n.info(""),n.info(n.bold("Connect Railway logs \u2014 2 things:")),n.info(""),n.info(` 1. On the page opening now (${ge}):`),n.info(' "Create Token" \u2192 name it \u2192 pick your team \u2192 Create \u2192 copy the value.'),n.info(" 2. In Railway, open the service you want logs from. Copy its URL from the"),n.info(" address bar \u2014 looks like:"),n.info(" https://railway.com/project/PROJECT/service/SERVICE?environmentId=ENV"),!process.stdin.isTTY){n.info(""),n.info(n.dim("Then: VERIRUN_RAILWAY_TOKEN=<token>, and railway.projectId / environmentId / serviceId (from that URL) in .verirun/config.json."));return}if(!s||r.reconnect){N(ge),n.info("");let d=await b(" Railway token: ");if(!d){n.warn(" Nothing pasted. No changes made.");return}s=d}let a={};i||(a.token=s);let c=Vt(await b(" Service URL (paste the whole thing): "));if(c)a.projectId=c.projectId,a.environmentId=c.environmentId,a.serviceId=c.serviceId;else{n.warn(" Couldn't read that URL. Enter the three IDs from it by hand:");let d=await b(" Project ID: "),f=await b(" Environment ID: "),p=await b(" Service ID: ");if(!d||!f||!p){n.warn(" Need all three. No changes made.");return}a.projectId=d,a.environmentId=f,a.serviceId=p}await ee(o,{railway:a}),n.info(""),n.info(` Saved to ${n.dim(o)}`),n.info(" Checking it works\u2026");let l=await J({...t,...a,token:s});if("error"in l){n.error(` ${l.error}`),n.info(n.dim(" Re-run `verirun log railway --reconnect` with the right token / IDs.")),process.exitCode=1;return}n.success(` Connected. Deployment ${l.deploymentId}. \`verirun run\` now includes Railway logs.`)}import{existsSync as tr,readFileSync as nr}from"node:fs";import{mkdir as Wt,readdir as Bt,writeFile as rr}from"node:fs/promises";import R from"node:path";var Gt=new Set(["node_modules",".git",".next",".verirun","dist","build","out","coverage",".turbo",".vercel"]);async function Ht(e){let r=[],o=async t=>{for(let i of await Bt(t,{withFileTypes:!0})){if(i.name.startsWith(".")&&i.name!==".")continue;let s=R.join(t,i.name);if(i.isDirectory()){if(Gt.has(i.name))continue;await o(s)}else/\.tsx?$/.test(i.name)&&!i.name.endsWith(".d.ts")&&r.push({file:R.relative(e,s).split(R.sep).join("/"),source:nr(s,"utf8")})}};return await o(e),r}function Jt(e){if(tr(e))try{let r=nr(e,"utf8").replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1").replace(/,(\s*[}\]])/g,"$1");return JSON.parse(r)}catch{return}}function or(e,r=0){if(r>5)return{};let o=Jt(e);if(!o)return{};let t=o.compilerOptions??{},i=o.extends;if(typeof i!="string"||!i.startsWith("."))return t;let s=R.resolve(R.dirname(e),i),a=or(/\.json$/.test(s)?s:`${s}.json`,r+1);return{...a,...t,paths:t.paths??a.paths}}function Kt(e){let{baseUrl:r,paths:o}=or(R.join(e,"tsconfig.json")),t=(r??"").replace(/^\.\/?/,"").replace(/\/$/,""),i={};for(let[s,a]of Object.entries(o??{})){let c=a[0];if(!s.endsWith("/*")||!c?.endsWith("*"))continue;let l=c.slice(0,-1).replace(/\/$/,"").replace(/^\.\//,"");i[s.slice(0,-1)]=[t,l].filter(Boolean).join("/")}return i}function Yt(e,r){let o={...r};for(let t of e??[]){let[i,s]=t.split("=");i&&(o[i]=s??"")}return o}var qt=/(?:from|import)\s*\(?\s*['"]([^'"]+)['"]/g;function Xt(e,r){let o=new Set(e.map(i=>i.file)),t=new Map;for(let i of e)for(let[,s]of i.source.matchAll(qt)){if(!s||s.startsWith(".")||Object.keys(r).some(d=>s.startsWith(d)))continue;let a=s.indexOf("/");if(a<=0)continue;let c=`${s.slice(0,a)}/`;if(t.has(c))continue;let l=s.slice(a+1);for(let d of o){let f=d.replace(/\.tsx?$/,"").replace(/\/index$/,"");if(f===l||!f.endsWith(`/${l}`)){if(f===l)t.set(c,"");else continue;break}t.set(c,f.slice(0,f.length-l.length-1));break}}return[...t].map(([i,s])=>`--alias ${i}=${s}`)}function zt(e,r,o){let t=e.nodes.pages.filter(s=>!s.inferred);n.info(`${n.bold(String(t.length))} pages \xB7 ${n.bold(String(e.nodes.leaves.length))} backend effects \xB7 ${n.bold(String(e.edges.length))} edges ${n.dim(`(${r.length} files)`)}`),n.info("");for(let s of e.nodes.pages){let a=e.edges.filter(f=>f.from===s.id),c=a.filter(f=>f.kind==="nav").length,l=a.filter(f=>f.kind==="effect").length,d=s.inferred?n.dim(" (inferred)"):"";n.info(` ${s.path}${d} ${n.dim(`\u2014 ${s.component}, ${s.elements.length} element(s), ${c} nav, ${l} effect`)}`)}let i=e.diagnostics;i.parseErrors.length>0&&n.warn(`${i.parseErrors.length} file(s) failed to parse`);for(let s of o)n.info(""),n.warn(`Imports like ${n.bold(s.split(" ")[1]?.split("=")[0]??"")} could not be resolved, so components they point at were not analysed. Re-run with:`),n.info(` verirun map ${s}`);i.unresolvedTargets.length>0&&(n.info(""),n.info(n.dim(`${i.unresolvedTargets.length} nav target(s) could not be resolved to a page`)))}async function ir(e){let{assertLicensed:r}=await import("./gate.mjs"),{assembleTree:o,bfs:t,buildCoverage:i,measureReach:s,renderBfs:a,renderMarkdown:c,renderReachTable:l}=await import("./graph.mjs"),d=await r();d.note&&n.warn(d.note);let f=y(),p=e.dir?R.resolve(e.dir):f.repoRoot;if(!tr(p))throw new Error(`no such directory: ${p}`);let g=await Ht(p);if(g.length===0)throw new Error(`no .ts/.tsx files found under ${p}`);let m=Yt(e.alias,Kt(p)),w={aliases:m,...e.followChildren===!1?{followChildren:!1}:{},...e.appFile?{appFile:e.appFile}:{}};if(e.bfs){let u=o(g,w),v=e.kind==="nav"||e.kind==="effect"?[e.kind]:void 0,$=t(u,e.bfs,{depth:e.depth?Number(e.depth):2,...v?{kinds:v}:{}});n.info(n.dim(`${$.order.length-1} node(s) within ${$.maxDepth} step(s) of ${$.from}`)),n.info(a($));return}if(e.reach){let u=s(g,w);n.info(l(u));for(let v of u.unreachedFiles)n.info(n.dim(`unreached: ${v.file} (${v.elements} elements)`));return}let h=o(g,w);if(e.json){process.stdout.write(`${JSON.stringify(h,null,2)}
27
+ `);return}if(e.report){let u=e.out?R.resolve(e.out):R.join(f.dataDir,"map");await Wt(u,{recursive:!0});let v=i(g,h);await rr(R.join(u,"interaction-tree.json"),`${JSON.stringify(h,null,2)}
28
+ `),await rr(R.join(u,"coverage.md"),`${c(v,h)}
29
+ `);let $=R.relative(process.cwd(),u),S=$.startsWith("..")?u:$;n.success(`wrote ${S}/interaction-tree.json + coverage.md`);let x=v.bar.filter(A=>A.pass===!1).length;n.info(n.dim(`${v.bar.length-x}/${v.bar.length} coverage checks pass`));return}zt(h,g,Xt(g,m))}import{existsSync as An}from"node:fs";import{mkdir as Tn}from"node:fs/promises";import mr from"node:path";import{spawnSync as Qt}from"node:child_process";var Zt={browser:"chromium",channel:"chrome",label:"Chrome",approximated:!1},en={browser:"chromium",channel:"msedge",label:"Edge",approximated:!1},rn={browser:"firefox",label:"Firefox",approximated:!1},tn={browser:"chromium",label:"Chromium",approximated:!1};function Re(e,r){let o=e.toLowerCase(),t=i=>r?{...i,label:r}:i;if(o.includes("firefox")||o.includes("mozilla"))return t(rn);if(o.includes("msedge")||o.includes("microsoft-edge")||o.includes("edgemac")||o.includes("microsoftedge"))return t(en);if(o.includes("google-chrome")||o.includes("com.google.chrome")||o==="chromehtml"||o.includes("chrome"))return t(Zt);if(o.includes("chromium"))return t(tn);if(o.includes("safari"))return{browser:"webkit",label:"Safari",approximated:!0};if(o.includes("brave"))return{browser:"chromium",label:"Brave",approximated:!0};if(o.includes("thebrowser")||o.includes("arc"))return{browser:"chromium",label:"Arc",approximated:!0};if(o.includes("vivaldi"))return{browser:"chromium",label:"Vivaldi",approximated:!0};if(o.includes("opera")||o.includes("opr"))return{browser:"chromium",label:"Opera",approximated:!0}}function re(e,r){let o=Qt(e,r,{encoding:"utf8",timeout:4e3});if(!(o.error||o.status!==0))return(o.stdout||"").trim()||void 0}function nn(){let e=re("xdg-settings",["get","default-web-browser"])??re("xdg-mime",["query","default","x-scheme-handler/https"]);return e?Re(e):void 0}function on(){let e=re("plutil",["-convert","json","-o","-",`${process.env.HOME}/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`]);if(e)try{let o=(JSON.parse(e).LSHandlers??[]).find(i=>i.LSHandlerURLScheme==="https"),t=typeof o?.LSHandlerRoleAll=="string"?o.LSHandlerRoleAll:void 0;return t?Re(t):void 0}catch{return}}function sn(){let r=re("reg",["query","HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\https\\UserChoice","/v","ProgId"])?.match(/ProgId\s+REG_SZ\s+(\S+)/i)?.[1];return r?Re(r):void 0}function sr(){try{if(process.platform==="darwin")return on();if(process.platform==="linux")return nn();if(process.platform==="win32")return sn()}catch{}}import{spawn as an}from"node:child_process";import{mkdtemp as cn,readFile as ln,rm as dn}from"node:fs/promises";import{createRequire as un}from"node:module";import fn from"node:os";import te from"node:path";var pn=new Set(["name","selector","locator","signals","pageGuid","ariaSnapshot"]);function ar(e){let r={};for(let[o,t]of Object.entries(e))!pn.has(o)&&t!==void 0&&(r[o]=t);return r}function mn(){let e=un(import.meta.url),r=e.resolve("playwright/package.json"),o=e("playwright/package.json"),t=typeof o.bin=="string"?o.bin:o.bin?.playwright;if(!t)throw new Error("Could not locate the Playwright CLI entrypoint in playwright/package.json.");return te.join(te.dirname(r),t)}async function cr(e){let r=mn(),o=await cn(te.join(fn.tmpdir(),"verirun-record-")),t=te.join(o,"recording.jsonl"),i=[r,"codegen","--target=jsonl",`--output=${t}`];e.browser&&i.push(`--browser=${e.browser}`),e.channel&&i.push(`--channel=${e.channel}`),e.userDataDir&&i.push(`--user-data-dir=${e.userDataDir}`),e.testIdAttribute&&i.push(`--test-id-attribute=${e.testIdAttribute}`),e.url&&i.push(e.url);try{let s=await new Promise((c,l)=>{let d=an(process.execPath,i,{stdio:["ignore","inherit","inherit"]});d.on("error",l),d.on("close",f=>c(f))}),a=await ln(t,"utf8").catch(()=>"");return{...gn(a),exitCode:s}}finally{await dn(o,{recursive:!0,force:!0})}}function gn(e){let r=e.split(`
30
+ `).filter(i=>i.trim().length>0),o={},t=[];for(let[i,s]of r.entries()){let a;try{a=JSON.parse(s)}catch{continue}if(i===0&&a&&typeof a=="object"&&!("name"in a)){o=a;continue}a&&typeof a=="object"&&"name"in a&&t.push(a)}return{header:o,actions:t}}import{existsSync as hn}from"node:fs";import{appendFile as wn,readFile as yn}from"node:fs/promises";import vn from"node:path";function bn(e){return e.split(`
31
+ `).map(r=>r.trim()).filter(r=>r&&!r.startsWith("#")).some(r=>r.replace(/^\//,"").replace(/\/$/,"")===G)}async function lr(e){let r=vn.join(e,".gitignore");if(!hn(r))return"no-gitignore";let o=await yn(r,"utf8");if(bn(o))return"already-present";let t=o.length===0||o.endsWith(`
30
32
  `)?"":`
31
- `;return await cn(r,`${t}
33
+ `;return await wn(r,`${t}
32
34
  # verirun: recorded workflows and captured run logs (may contain secrets)
33
35
  ${G}/
34
- `,"utf8"),"added"}function O(e){return`'${e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n")}'`}function F(e){if(e&&typeof e=="object"&&"source"in e){let r=e;return`/${r.source??""}/${r.flags??""}`}return O(String(e))}function fn(e){let r=e.options??{},o=e.body;switch(e.kind){case"role":{let t=[];r.name!==void 0&&t.push(`name: ${F(r.name)}`),r.exact===!0&&t.push("exact: true");for(let i of r.attrs??[])t.push(`${i.name}: ${JSON.stringify(i.value)}`);return t.length?`getByRole(${O(o)}, { ${t.join(", ")} })`:`getByRole(${O(o)})`}case"test-id":return`getByTestId(${O(o)})`;case"text":case"label":case"placeholder":case"alt":case"title":{let t={text:"getByText",label:"getByLabel",placeholder:"getByPlaceholder",alt:"getByAltText",title:"getByTitle"}[e.kind];return r.exact===!0?`${t}(${F(o)}, { exact: true })`:`${t}(${F(o)})`}case"nth":return`nth(${o})`;case"first":return"first()";case"last":return"last()";case"visible":return`filter({ visible: ${o==="true"} })`;case"frame":return"contentFrame()";case"frame-locator":return`frameLocator(${O(o)})`;case"has-text":return`filter({ hasText: ${F(o)} })`;case"has-not-text":return`filter({ hasNotText: ${F(o)} })`;default:return`locator(${O(o)})`}}function cr(e){if(!e)return;let r=[],o=e;for(;o;)r.push(fn(o)),o=o.next;return r.join(".")}var pn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;var mn=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function D(e){if(!e)throw new Error("Workflow name is required.");if(e.length>64)throw new Error("Workflow name must be 64 characters or fewer.");if(!pn.test(e))throw new Error(`Invalid workflow name "${e}". Use letters, digits, dot, dash or underscore, starting with a letter or digit.`);if(e==="."||e==="..")throw new Error(`Invalid workflow name "${e}".`);if(e.endsWith("."))throw new Error(`Invalid workflow name "${e}". A trailing dot is dropped on Windows, so "${e}" and "${e.replace(/\.+$/,"")}" would be the same file.`);let r=e.split(".")[0]??"";if(mn.test(r))throw new Error(`Invalid workflow name "${e}". "${r}" is a reserved device name on Windows and cannot be used as a filename.`)}import{mkdir as gn,readFile as hn,writeFile as wn}from"node:fs/promises";import lr from"node:path";var U=1;async function dr(e,r){await gn(lr.dirname(e),{recursive:!0}),await wn(e,`${JSON.stringify(r,null,2)}
35
- `,"utf8")}async function ne(e){let r=await hn(e,"utf8"),o;try{o=JSON.parse(r)}catch(i){throw new Error(`Workflow file is not valid JSON: ${e}`,{cause:i})}let t=o;if(!t||typeof t!="object"||!Array.isArray(t.steps))throw new Error(`Workflow file is malformed (no steps array): ${e}`);if(t.schemaVersion!==U)throw new Error(`Workflow "${t.name??lr.basename(e)}" uses schema version ${t.schemaVersion}, but this build expects ${U}. Re-record it.`);return t}function bn(e){return!(e.name==="openPage"&&e.url==="about:blank")}function Sn(e){let r=e.length;for(;r>0&&e[r-1]?.name==="closePage";)r-=1;return e.slice(0,r)}function $n(e,r){let o={index:r,action:e.name,params:ir(e),signals:Array.isArray(e.signals)?e.signals:[]};e.selector&&(o.selector=e.selector),e.locator&&(o.locator=e.locator);let t=cr(e.locator);return t&&(o.description=t),e.pageGuid&&(o.pageGuid=e.pageGuid),o}function kn(e){let r=e.description??e.selector??"";switch(e.action){case"navigate":return`navigate ${String(e.params.url??"")}`;case"fill":return`fill ${r} ${n.dim(`= ${JSON.stringify(e.params.text??"")}`)}`;case"press":return`press ${r} ${n.dim(String(e.params.key??""))}`;default:return`${e.action.padEnd(9)} ${r}`.trimEnd()}}async function fr(e,r){let{assertLicensed:o}=await import("./gate.mjs"),t=await o();t.note&&n.warn(t.note),D(e);let i=y(),s=await N(i.configPath),a=_(i,e);if(yn(a)&&!r.force)throw new Error(`Workflow "${e}" already exists at ${ur.relative(i.repoRoot,a)}. Re-run with --force to overwrite it.`);await vn(i.workflowsDir,{recursive:!0});let c=await ar(i.repoRoot);c==="added"?n.step("Added .verirun/ to .gitignore"):c==="no-gitignore"&&n.warn("No .gitignore at the repo root, so .verirun/ is not ignored. Recorded values and run logs may contain secrets.");let l=r.testIdAttribute??s.testIdAttribute??Pe,d=r.browser,p=r.channel;if(r.defaultBrowser){(r.browser||r.channel)&&n.warn("--default-browser overrides -b / --channel.");let u=or();u?(d=u.browser,p=u.channel,u.approximated?n.warn(`Your default browser is ${u.label}, which Playwright can't drive directly \u2014 recording in ${p??d}.`):n.info(n.dim(`Recording in your default browser: ${u.label}`))):(n.warn("Couldn't detect your default browser; recording in bundled Chromium."),d="chromium",p=void 0)}n.info(""),n.info(`Recording ${n.bold(e)}. A browser window will open.`),n.info(n.dim("Perform the workflow, then close the browser to save.")),n.info("");let f=await sr({url:r.url,browser:d,channel:p,userDataDir:r.userDataDir,testIdAttribute:l}),g=Sn(f.actions.filter(bn));if(g.length===0){if(f.exitCode!==0)throw new Error(`Playwright codegen exited with code ${f.exitCode} and recorded nothing. If this persists, the installed Playwright may no longer support the \`jsonl\` codegen target that recording depends on.`);n.warn("No actions were recorded, so nothing was saved.");return}let m=g.map($n),w=m.find(u=>u.action==="navigate"),h={schemaVersion:U,name:e,createdAt:new Date().toISOString(),startUrl:r.url??w?.params.url,browser:f.header.browserName??d??"chromium",channel:p,testIdAttribute:l,steps:m};await dr(a,h),n.info("");for(let u of m)n.info(` ${n.dim(String(u.index).padStart(2))} ${kn(u)}`);n.info(""),n.success(`Saved ${m.length} step${m.length===1?"":"s"} to ${ur.relative(i.repoRoot,a)}`),m.some(u=>u.action==="fill"&&u.params.text)&&n.warn("Recorded steps include text you typed. Check the workflow file before sharing it.")}import{existsSync as An}from"node:fs";import{mkdir as Nn,writeFile as Ln}from"node:fs/promises";import Sr from"node:path";import{chromium as M,firefox as Rn,selectors as En,webkit as Cn}from"playwright";var In={chromium:M,firefox:Rn,webkit:Cn};async function jn(e,r){let o=!r.headed,t=r.slowMoMs&&r.slowMoMs>0?r.slowMoMs:void 0;if(r.cdpEndpoint){let c=await M.connectOverCDP(r.cdpEndpoint,{slowMo:t}),l=c.contexts()[0]??await c.newContext(),d=l.pages()[0]??await l.newPage();return{context:l,page:d,close:()=>c.close()}}if(r.userDataDir){let c=await M.launchPersistentContext(r.userDataDir,{headless:o,channel:r.channel,slowMo:t}),l=c.pages()[0]??await c.newPage();return{context:c,page:l,close:()=>c.close()}}if(r.channel){let c=await M.launch({headless:o,channel:r.channel,slowMo:t}),l=await c.newContext();return{context:l,page:await l.newPage(),close:()=>c.close()}}let s=await(In[e.browser]??M).launch({headless:o,slowMo:t}),a=await s.newContext();return{context:a,page:await a.newPage(),close:()=>s.close()}}function pr(e){let r=typeof e=="number"?e:0,o=[];return r&1&&o.push("Alt"),r&2&&o.push("Control"),r&4&&o.push("Meta"),r&8&&o.push("Shift"),o}function oe(e){return typeof e=="string"?e:void 0}function mr(e){return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}async function xn(e,r){let o=()=>{if(!r.selector)throw new Error(`Step ${r.index} (${r.action}) has no selector to act on.`);return e.locator(r.selector)};switch(r.action){case"navigate":{let t=oe(r.params.url);if(!t)throw new Error(`Step ${r.index} (navigate) has no url.`);await e.goto(t);return}case"openPage":return;case"closePage":await e.close();return;case"click":case"dblclick":{await o().click({button:oe(r.params.button)??"left",clickCount:typeof r.params.clickCount=="number"?r.params.clickCount:r.action==="dblclick"?2:1,modifiers:pr(r.params.modifiers)});return}case"fill":await o().fill(oe(r.params.text)??"");return;case"press":{let t=oe(r.params.key);if(!t)throw new Error(`Step ${r.index} (press) has no key.`);await o().press([...pr(r.params.modifiers),t].join("+"));return}case"check":await o().check();return;case"uncheck":await o().uncheck();return;case"select":await o().selectOption(mr(r.params.options));return;case"setInputFiles":await o().setInputFiles(mr(r.params.files));return;default:if(r.action.startsWith("assert")){n.warn(`Step ${r.index}: skipping ${r.action} (assertions are not replayed).`);return}throw new Error(`Step ${r.index}: don't know how to replay a "${r.action}" action.`)}}async function gr(e,r={}){e.testIdAttribute&&En.setTestIdAttribute(e.testIdAttribute);let o={...r,channel:r.channel??e.channel},t=await jn(e,o),i=0;try{let{context:s}=t;r.timeoutMs!==void 0&&s.setDefaultTimeout(r.timeoutMs);let a=t.page;s.on("page",c=>{a=c});for(let c of e.steps){n.step(`${String(c.index).padStart(2)} ${c.action}`+(c.description?` ${n.dim(c.description)}`:""));try{await xn(a,c)}catch(l){return{stepsTotal:e.steps.length,stepsReplayed:i,error:l instanceof Error?l:new Error(String(l)),failedStepIndex:c.index}}if(i+=1,a.isClosed()){let l=s.pages().at(-1);l&&(a=l)}}return{stepsTotal:e.steps.length,stepsReplayed:i}}finally{await t.close()}}function hr(e,r){let o=r.toLowerCase();if(!o||typeof e.message=="string"&&e.message.toLowerCase().includes(o))return!0;if(e.raw!==void 0)try{return JSON.stringify(e.raw).toLowerCase().includes(o)}catch{return!1}return!1}var wr=[];function ie(e){wr.push(e)}function yr(e){return wr.map(r=>r(e)).filter(r=>!!r)}var vr=!1;function br(){vr||(vr=!0,ie(Ke),ie(Xe),ie(Ge))}var Tn=1,Pn=500;function _n(e){if(e.slowMo!==void 0){let r=Number(e.slowMo);if(!Number.isFinite(r)||r<0)throw new Error(`--slow-mo needs a number of milliseconds, got "${e.slowMo}".`);return r}return e.headed?Pn:0}function W(e){return e instanceof Error?e.message:String(e)}function On(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}async function $r(e){for(let r of[...e].reverse())try{await r.dispose()}catch(o){n.warn(`${r.name}: dispose failed: ${W(o)}`)}}async function kr(e,r){let{assertLicensed:o}=await import("./gate.mjs"),t=await o();t.note&&n.warn(t.note),D(e);let i=y(),s=await N(i.configPath),a=_(i,e);if(!An(a))throw new Error(`No workflow named "${e}". Record it first with: verirun record ${e}`);let c=await ne(a),l;if(r.timeout!==void 0&&(l=Number(r.timeout),!Number.isFinite(l)||l<0))throw new Error(`--timeout must be a non-negative number of milliseconds, got "${r.timeout}".`);let d=(r.user??s.userFilter)?.trim()||void 0;br();let p=yr(s),f=De(),g=Ue(i,e,f);await Nn(g,{recursive:!0});let m={config:s,runDir:g,workflowName:e,userFilter:d};n.info(""),n.info(`Running ${n.bold(e)} ${n.dim(`${c.steps.length} steps \xB7 ${c.browser}`)}`),p.length===0?n.warn("No log sources configured. Add a supabase or vercel block to .verirun/config.json."):n.info(n.dim(`Log sources: ${p.map(h=>h.name).join(", ")}`)),d&&n.info(n.dim(`User filter: entries mentioning "${d}"`)),n.info("");let w=[];try{for(let h of p)await h.start(m),w.push(h)}catch(h){let u=p[w.length];throw await $r(w),new Error(`Log source "${u?.name??"?"}" failed to start: ${W(h)}`)}try{let h=new Date().toISOString(),u=await gr(c,{headed:r.headed,slowMoMs:_n(r),timeoutMs:l,channel:r.channel,userDataDir:r.userDataDir,cdpEndpoint:r.cdp}),v=new Date().toISOString(),S={startedAt:h,endedAt:v};u.error?n.error(`Replay failed at step ${u.failedStepIndex}: ${W(u.error)}`):n.success(`Replayed ${u.stepsReplayed} step${u.stepsReplayed===1?"":"s"}`);let $=[],x=[],A=0;for(let k of w)try{let j=await k.collect(m,S);A+=j.length,d&&(j=j.filter(xr=>hr(xr,d))),x.push(...j),$.push({id:k.id,name:k.name,entries:j.length})}catch(j){n.warn(`${k.name}: log collection failed: ${W(j)}`),$.push({id:k.id,name:k.name,entries:0})}d&&x.length===0&&A>0&&n.warn(`${A} log entr${A===1?"y":"ies"} collected, none mention "${d}".`),x.sort((k,j)=>(k.timestamp??"").localeCompare(j.timestamp??""));let jr={schemaVersion:Tn,workflow:e,status:u.error?"failed":"ok",window:S,steps:{total:u.stepsTotal,replayed:u.stepsReplayed,...u.failedStepIndex!==void 0?{failedAt:u.failedStepIndex}:{}},...u.error?{error:On(W(u.error))}:{},...d?{filter:{user:d}}:{},sources:$,entries:x},Ee=Sr.join(g,"logs.json");await Ln(Ee,`${JSON.stringify(jr,null,2)}
36
- `,"utf8"),n.info("");for(let k of $)n.info(` ${k.name.padEnd(10)} ${k.entries} entr${k.entries===1?"y":"ies"}`);n.info(""),n.success(`Logs written to ${Sr.relative(i.repoRoot,Ee)}`),u.error&&(process.exitCode=1)}finally{await $r(w)}}import{existsSync as Dn}from"node:fs";import Un from"node:path";var Vn=new Set(["navigate","click","dblclick","fill","press","check","uncheck","select","setInputFiles","openPage","closePage"]),Fn=/^assert/,Mn=new Set(["click","dblclick","fill","press","check","uncheck","select","setInputFiles"]),Wn={navigate:["url"],fill:["text"],press:["key"],select:["values"],setInputFiles:["files"]};function Bn(e){let r=[],o=(i,s,a)=>{r.push({step:i,level:s,message:a})};e.length===0&&r.push({step:0,level:"error",message:"no steps"}),e.forEach((i,s)=>{let a=s+1;if(typeof i.action!="string"||i.action===""){o(a,"error",'missing "action"');return}if(Fn.test(i.action)){o(a,"warning",`"${i.action}" is skipped at replay \u2014 it asserts nothing`);return}if(!Vn.has(i.action)){o(a,"error",`unknown action "${i.action}" \u2014 a run stops here`);return}Mn.has(i.action)&&!i.selector&&o(a,"error",`"${i.action}" needs a "selector"`);for(let c of Wn[i.action]??[])i.params?.[c]===void 0&&o(a,"error",`"${i.action}" needs params.${c}`);if(i.action==="navigate"){let c=i.params?.url;typeof c=="string"&&!/^https?:\/\//.test(c)&&o(a,"error",`params.url must be absolute, got "${c}"`)}i.selector?.startsWith("role=")&&!/\[name=/.test(i.selector)&&o(a,"warning",`"${i.selector}" matches every such element on the page`),typeof i.index!="number"&&o(a,"warning",`missing "index" \u2014 set it to the step's position`)}),e.length>0&&e[0]?.action!=="navigate"&&r.push({step:1,level:"warning",message:'first step is not "navigate" \u2014 replay opens a blank page, so start with one'});let t=e.map((i,s)=>({step:i,n:s+1})).filter(({step:i,n:s})=>s>1&&i.action==="navigate");for(let{n:i}of t)r.push({step:i,level:"warning",message:"navigating by URL skips the UI \u2014 click the link or button that goes there instead (`verirun map --bfs <route>` names it). Fine only for a deep link with no path to it."});return r}async function Rr(e,r,o){if(e!=="check")throw new Error(`Unknown workflow action "${e}". Only "check" exists.`);if(!r)throw new Error("workflow check needs a workflow name or a path to a .json file.");let t=y(),i;if(r.endsWith(".json")?i=Un.resolve(r):(D(r),i=_(t,r)),!Dn(i))throw new Error(`No such workflow file: ${i}`);let s=await ne(i),a=Bn(s.steps),c=a.filter(l=>l.level==="error");if(o.json){process.stdout.write(`${JSON.stringify({file:i,name:s.name,steps:s.steps.length,ok:c.length===0,findings:a},null,2)}
37
- `),c.length>0&&(process.exitCode=1);return}n.info(""),n.info(`${n.bold(s.name)} ${n.dim(`\u2014 ${s.steps.length} step(s), schemaVersion ${s.schemaVersion}`)}`),n.info(n.dim(` ${i}`)),n.info("");for(let l of a){let d=`step ${l.step}`.padEnd(8);l.level==="error"?n.error(`${d} ${l.message}`):n.warn(`${d} ${l.message}`)}a.length===0?n.success(` Looks runnable. Try it: verirun run ${s.name}`):c.length===0?(n.info(""),n.success(` No errors. Try it: verirun run ${s.name}`)):(n.info(""),n.error(` ${c.length} error(s) \u2014 a run would fail. Fix them and check again.`),process.exitCode=1),n.info(""),n.info(n.dim(` Static checks only: selectors are not resolved against a page. Schema version ${U}.`))}var Cr="GU2O8XlPF/Dj/CHE1sX1sCZNwAZ7IIAukLAQhBlByTFpEMrkUeZkRXEmx8raivcfc+IV9SkiBs7VlgSxGOxKDQ==",Ir="MCowBQYDK2VwAyEATFTl78zmb+BITZuy9mdPMtujnz1tAeVidJT3dccuhLg=";function qn(){if(Cr.startsWith("@@")||Ir.startsWith("@@"))return!0;try{let e=Er.dirname(Jn(import.meta.url)),r=Kn(Er.join(e,"gate.mjs")),o=Gn({key:Buffer.from(Ir,"base64"),format:"der",type:"spki"});return Hn(null,r,o,Buffer.from(Cr,"base64"))}catch{return!1}}var R=new Yn;R.name("verirun").description("Record and replay app workflows, and capture backend logs for each run.").version(T);R.command("record").argument("<name>","name for the workflow").description("Record a workflow in a headed browser and save it to .verirun/workflows").option("-u, --url <url>","URL to open the browser at").option("-b, --browser <browser>","browser to record in: chromium, firefox or webkit").option("--channel <channel>","use an installed browser: chrome, msedge, chrome-beta, ...").option("--default-browser","record in your OS default browser (falls back to bundled Chromium)").option("--user-data-dir <dir>","record in a persistent profile directory (keeps you logged in)").option("--test-id-attribute <attribute>","attribute to prefer for getByTestId selectors").option("-f, --force","overwrite an existing workflow with this name").action(async(e,r)=>{await fr(e,r)});R.command("run").argument("<name>","name of the workflow to replay").description("Replay a recorded workflow and capture Supabase / Vercel / Railway logs for the run window").option("--headed","run with a visible browser window instead of headless (paced so you can watch)").option("--slow-mo <ms>","pause before each action; default 500 when --headed, 0 otherwise").option("--timeout <ms>","per-action timeout in milliseconds (default: Playwright 30000)").option("--channel <channel>","replay in an installed browser: chrome, msedge, ...").option("--user-data-dir <dir>","replay in a persistent profile directory (keeps you logged in)").option("--cdp <url>","attach to a browser already running with --remote-debugging-port, e.g. http://localhost:9222").option("--user <id>","keep only log entries mentioning this string, e.g. an email (overrides config.userFilter)").action(async(e,r)=>{await kr(e,r)});R.command("login").description("Connect this machine to your Verirun account").option("-f, --force","connect even if this machine is already linked").option("--server <url>","account server base URL (default: https://get-verirun.duely.in)").action(async e=>{await Ae(e)});R.command("logout").description("Disconnect this machine from your Verirun account").action(async()=>{await Ne()});R.command("whoami").description("Show the connected account and subscription status").option("--server <url>","account server base URL").action(async e=>{await Le(e)});R.command("map").description("Build an interaction graph of this repo: pages, the elements on them, and the backend calls they make").option("-d, --dir <dir>","directory to analyze (default: the repo root)").option("--json","print the full interaction graph as JSON").option("--report","write interaction-tree.json + coverage.md (default: .verirun/map)").option("--out <dir>","output directory for --report").option("--reach","per-route table of reachable vs attached elements").option("--bfs <node>","walk the graph from a node: a route path, page id or component name").option("--depth <n>","steps to follow for --bfs (default: 2)").option("--kind <kind>","--bfs: follow only nav or only effect edges").option("--alias <prefix=dir...>","extra import alias, e.g. @/=src (tsconfig paths are read automatically)").option("--no-follow-children","do not follow child components out of a page file").option("--app-file <file>","file declaring <Routes> (react-router apps; auto-detected by default)").action(async e=>{await nr(e)});R.command("workflow").argument("<action>","what to do: check").argument("[name]","workflow name, or a path to a .json file").description("Check a workflow file without running it (shape, actions, selectors, params)").option("--json","emit the findings as JSON").action(async(e,r,o)=>{await Rr(e,r,o)});R.command("agent").description("Print a compact reference (commands, .verirun/ layout, logs.json schema) for an AI coding agent").option("--json","emit JSON instead of Markdown").option("--skill","emit a Claude Code skill file instead of the plain reference").option("--install","with --skill: write it to .claude/skills/verirun/SKILL.md").action(async e=>{await We(R,e)});R.command("log").argument("[source]","log source to connect: vercel, supabase or railway (omit for an overview)").description("Connect a log source and check its configuration").option("--test","query the last 5 minutes and report what comes back").option("--drain","vercel: set up the old push-based log drain instead of the API").option("--listen","vercel: run the drain listener until Ctrl+C (drain mode only)").option("--reconnect","re-run the connect step and replace what was saved").action(async(e,r)=>{await Qe(e,r)});async function Xn(){qn()||(process.stderr.write(`verirun: this installation looks modified. Reinstall it:
36
+ `,"utf8"),"added"}function O(e){return`'${e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n")}'`}function F(e){if(e&&typeof e=="object"&&"source"in e){let r=e;return`/${r.source??""}/${r.flags??""}`}return O(String(e))}function $n(e){let r=e.options??{},o=e.body;switch(e.kind){case"role":{let t=[];r.name!==void 0&&t.push(`name: ${F(r.name)}`),r.exact===!0&&t.push("exact: true");for(let i of r.attrs??[])t.push(`${i.name}: ${JSON.stringify(i.value)}`);return t.length?`getByRole(${O(o)}, { ${t.join(", ")} })`:`getByRole(${O(o)})`}case"test-id":return`getByTestId(${O(o)})`;case"text":case"label":case"placeholder":case"alt":case"title":{let t={text:"getByText",label:"getByLabel",placeholder:"getByPlaceholder",alt:"getByAltText",title:"getByTitle"}[e.kind];return r.exact===!0?`${t}(${F(o)}, { exact: true })`:`${t}(${F(o)})`}case"nth":return`nth(${o})`;case"first":return"first()";case"last":return"last()";case"visible":return`filter({ visible: ${o==="true"} })`;case"frame":return"contentFrame()";case"frame-locator":return`frameLocator(${O(o)})`;case"has-text":return`filter({ hasText: ${F(o)} })`;case"has-not-text":return`filter({ hasNotText: ${F(o)} })`;default:return`locator(${O(o)})`}}function dr(e){if(!e)return;let r=[],o=e;for(;o;)r.push($n(o)),o=o.next;return r.join(".")}var Sn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;var kn=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function D(e){if(!e)throw new Error("Workflow name is required.");if(e.length>64)throw new Error("Workflow name must be 64 characters or fewer.");if(!Sn.test(e))throw new Error(`Invalid workflow name "${e}". Use letters, digits, dot, dash or underscore, starting with a letter or digit.`);if(e==="."||e==="..")throw new Error(`Invalid workflow name "${e}".`);if(e.endsWith("."))throw new Error(`Invalid workflow name "${e}". A trailing dot is dropped on Windows, so "${e}" and "${e.replace(/\.+$/,"")}" would be the same file.`);let r=e.split(".")[0]??"";if(kn.test(r))throw new Error(`Invalid workflow name "${e}". "${r}" is a reserved device name on Windows and cannot be used as a filename.`)}import Rn from"node:net";var En=2e3,Cn={"http:":80,"https:":443};async function ur(e){let r;try{r=new URL(e)}catch{return{reachable:"unknown"}}let o=Cn[r.protocol];if(o===void 0)return{reachable:"unknown"};let t=r.hostname.replace(/^\[|\]$/g,""),i=r.port?Number(r.port):o;return new Promise(s=>{let a=!1,c=d=>{a||(a=!0,l.destroy(),s(d))},l=Rn.connect({host:t,port:i,autoSelectFamily:!0});l.setTimeout(En),l.on("connect",()=>c({reachable:!0})),l.on("timeout",()=>c({reachable:"unknown"})),l.on("error",d=>{c(d.code==="ECONNREFUSED"?{reachable:!1,host:t,port:i}:{reachable:"unknown"})})})}import{mkdir as In,readFile as jn,writeFile as xn}from"node:fs/promises";import fr from"node:path";var U=1;async function pr(e,r){await In(fr.dirname(e),{recursive:!0}),await xn(e,`${JSON.stringify(r,null,2)}
37
+ `,"utf8")}async function ne(e){let r=await jn(e,"utf8"),o;try{o=JSON.parse(r)}catch(i){throw new Error(`Workflow file is not valid JSON: ${e}`,{cause:i})}let t=o;if(!t||typeof t!="object"||!Array.isArray(t.steps))throw new Error(`Workflow file is malformed (no steps array): ${e}`);if(t.schemaVersion!==U)throw new Error(`Workflow "${t.name??fr.basename(e)}" uses schema version ${t.schemaVersion}, but this build expects ${U}. Re-record it.`);return t}function Nn(e){return!(e.name==="openPage"&&e.url==="about:blank")}function Ln(e){let r=e.length;for(;r>0&&e[r-1]?.name==="closePage";)r-=1;return e.slice(0,r)}function Pn(e,r){let o={index:r,action:e.name,params:ar(e),signals:Array.isArray(e.signals)?e.signals:[]};e.selector&&(o.selector=e.selector),e.locator&&(o.locator=e.locator);let t=dr(e.locator);return t&&(o.description=t),e.pageGuid&&(o.pageGuid=e.pageGuid),o}function _n(e){let r=e.description??e.selector??"";switch(e.action){case"navigate":return`navigate ${String(e.params.url??"")}`;case"fill":return`fill ${r} ${n.dim(`= ${JSON.stringify(e.params.text??"")}`)}`;case"press":return`press ${r} ${n.dim(String(e.params.key??""))}`;default:return`${e.action.padEnd(9)} ${r}`.trimEnd()}}async function gr(e,r){let{assertLicensed:o}=await import("./gate.mjs"),t=await o();t.note&&n.warn(t.note),D(e);let i=y(),s=await T(i.configPath),a=_(i,e);if(An(a)&&!r.force)throw new Error(`Workflow "${e}" already exists at ${mr.relative(i.repoRoot,a)}. Re-run with --force to overwrite it.`);await Tn(i.workflowsDir,{recursive:!0});let c=await lr(i.repoRoot);c==="added"?n.step("Added .verirun/ to .gitignore"):c==="no-gitignore"&&n.warn("No .gitignore at the repo root, so .verirun/ is not ignored. Recorded values and run logs may contain secrets.");let l=r.testIdAttribute??s.testIdAttribute??Pe,d=r.browser,f=r.channel;if(r.defaultBrowser){(r.browser||r.channel)&&n.warn("--default-browser overrides -b / --channel.");let u=sr();u?(d=u.browser,f=u.channel,u.approximated?n.warn(`Your default browser is ${u.label}, which Playwright can't drive directly \u2014 recording in ${f??d}.`):n.info(n.dim(`Recording in your default browser: ${u.label}`))):(n.warn("Couldn't detect your default browser; recording in bundled Chromium."),d="chromium",f=void 0)}if(r.url){let u=await ur(r.url);if(u.reachable===!1)throw new Error(`Nothing is listening at ${r.url} (connection refused on ${u.host}:${u.port}). Start the app you want to record, then run this again.`)}n.info(""),n.info(`Recording ${n.bold(e)}. A browser window will open.`),n.info(n.dim("Perform the workflow, then close the browser to save.")),n.info("");let p=await cr({url:r.url,browser:d,channel:f,userDataDir:r.userDataDir,testIdAttribute:l}),g=Ln(p.actions.filter(Nn));if(g.length===0){if(p.exitCode!==0)throw new Error(`Playwright codegen exited with code ${p.exitCode} before anything was recorded. Its output is above \u2014 commonly the browser failed to open, or a page the recording needed was unreachable. If it persists against a page that loads fine, the installed Playwright may no longer support the \`jsonl\` codegen target that recording depends on.`);n.warn("No actions were recorded, so nothing was saved.");return}let m=g.map(Pn),w=m.find(u=>u.action==="navigate"),h={schemaVersion:U,name:e,createdAt:new Date().toISOString(),startUrl:r.url??w?.params.url,browser:p.header.browserName??d??"chromium",channel:f,testIdAttribute:l,steps:m};await pr(a,h),n.info("");for(let u of m)n.info(` ${n.dim(String(u.index).padStart(2))} ${_n(u)}`);n.info(""),n.success(`Saved ${m.length} step${m.length===1?"":"s"} to ${mr.relative(i.repoRoot,a)}`),m.some(u=>u.action==="fill"&&u.params.text)&&n.warn("Recorded steps include text you typed. Check the workflow file before sharing it.")}import{existsSync as Wn}from"node:fs";import{mkdir as Bn,writeFile as Gn}from"node:fs/promises";import Rr from"node:path";import{chromium as M,firefox as On,selectors as Dn,webkit as Un}from"playwright";var Vn={chromium:M,firefox:On,webkit:Un};async function Fn(e,r){let o=!r.headed,t=r.slowMoMs&&r.slowMoMs>0?r.slowMoMs:void 0;if(r.cdpEndpoint){let c=await M.connectOverCDP(r.cdpEndpoint,{slowMo:t}),l=c.contexts()[0]??await c.newContext(),d=l.pages()[0]??await l.newPage();return{context:l,page:d,close:()=>c.close()}}if(r.userDataDir){let c=await M.launchPersistentContext(r.userDataDir,{headless:o,channel:r.channel,slowMo:t}),l=c.pages()[0]??await c.newPage();return{context:c,page:l,close:()=>c.close()}}if(r.channel){let c=await M.launch({headless:o,channel:r.channel,slowMo:t}),l=await c.newContext();return{context:l,page:await l.newPage(),close:()=>c.close()}}let s=await(Vn[e.browser]??M).launch({headless:o,slowMo:t}),a=await s.newContext();return{context:a,page:await a.newPage(),close:()=>s.close()}}function hr(e){let r=typeof e=="number"?e:0,o=[];return r&1&&o.push("Alt"),r&2&&o.push("Control"),r&4&&o.push("Meta"),r&8&&o.push("Shift"),o}function oe(e){return typeof e=="string"?e:void 0}function wr(e){return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}async function Mn(e,r){let o=()=>{if(!r.selector)throw new Error(`Step ${r.index} (${r.action}) has no selector to act on.`);return e.locator(r.selector)};switch(r.action){case"navigate":{let t=oe(r.params.url);if(!t)throw new Error(`Step ${r.index} (navigate) has no url.`);await e.goto(t);return}case"openPage":return;case"closePage":await e.close();return;case"click":case"dblclick":{await o().click({button:oe(r.params.button)??"left",clickCount:typeof r.params.clickCount=="number"?r.params.clickCount:r.action==="dblclick"?2:1,modifiers:hr(r.params.modifiers)});return}case"fill":await o().fill(oe(r.params.text)??"");return;case"press":{let t=oe(r.params.key);if(!t)throw new Error(`Step ${r.index} (press) has no key.`);await o().press([...hr(r.params.modifiers),t].join("+"));return}case"check":await o().check();return;case"uncheck":await o().uncheck();return;case"select":await o().selectOption(wr(r.params.options));return;case"setInputFiles":await o().setInputFiles(wr(r.params.files));return;default:if(r.action.startsWith("assert")){n.warn(`Step ${r.index}: skipping ${r.action} (assertions are not replayed).`);return}throw new Error(`Step ${r.index}: don't know how to replay a "${r.action}" action.`)}}async function yr(e,r={}){e.testIdAttribute&&Dn.setTestIdAttribute(e.testIdAttribute);let o={...r,channel:r.channel??e.channel},t=await Fn(e,o),i=0;try{let{context:s}=t;r.timeoutMs!==void 0&&s.setDefaultTimeout(r.timeoutMs);let a=t.page;s.on("page",c=>{a=c});for(let c of e.steps){n.step(`${String(c.index).padStart(2)} ${c.action}`+(c.description?` ${n.dim(c.description)}`:""));try{await Mn(a,c)}catch(l){return{stepsTotal:e.steps.length,stepsReplayed:i,error:l instanceof Error?l:new Error(String(l)),failedStepIndex:c.index}}if(i+=1,a.isClosed()){let l=s.pages().at(-1);l&&(a=l)}}return{stepsTotal:e.steps.length,stepsReplayed:i}}finally{await t.close()}}function vr(e,r){let o=r.toLowerCase();if(!o||typeof e.message=="string"&&e.message.toLowerCase().includes(o))return!0;if(e.raw!==void 0)try{return JSON.stringify(e.raw).toLowerCase().includes(o)}catch{return!1}return!1}var br=[];function ie(e){br.push(e)}function $r(e){return br.map(r=>r(e)).filter(r=>!!r)}var Sr=!1;function kr(){Sr||(Sr=!0,ie(Ke),ie(ze),ie(He))}var Hn=1,Jn=500;function Kn(e){if(e.slowMo!==void 0){let r=Number(e.slowMo);if(!Number.isFinite(r)||r<0)throw new Error(`--slow-mo needs a number of milliseconds, got "${e.slowMo}".`);return r}return e.headed?Jn:0}function W(e){return e instanceof Error?e.message:String(e)}function Yn(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}async function Er(e){for(let r of[...e].reverse())try{await r.dispose()}catch(o){n.warn(`${r.name}: dispose failed: ${W(o)}`)}}async function Cr(e,r){let{assertLicensed:o}=await import("./gate.mjs"),t=await o();t.note&&n.warn(t.note),D(e);let i=y(),s=await T(i.configPath),a=_(i,e);if(!Wn(a))throw new Error(`No workflow named "${e}". Record it first with: verirun record ${e}`);let c=await ne(a),l;if(r.timeout!==void 0&&(l=Number(r.timeout),!Number.isFinite(l)||l<0))throw new Error(`--timeout must be a non-negative number of milliseconds, got "${r.timeout}".`);let d=(r.user??s.userFilter)?.trim()||void 0;kr();let f=$r(s),p=De(),g=Ue(i,e,p);await Bn(g,{recursive:!0});let m={config:s,runDir:g,workflowName:e,userFilter:d};n.info(""),n.info(`Running ${n.bold(e)} ${n.dim(`${c.steps.length} steps \xB7 ${c.browser}`)}`),f.length===0?n.warn("No log sources configured. Add a supabase or vercel block to .verirun/config.json."):n.info(n.dim(`Log sources: ${f.map(h=>h.name).join(", ")}`)),d&&n.info(n.dim(`User filter: entries mentioning "${d}"`)),n.info("");let w=[];try{for(let h of f)await h.start(m),w.push(h)}catch(h){let u=f[w.length];throw await Er(w),new Error(`Log source "${u?.name??"?"}" failed to start: ${W(h)}`)}try{let h=new Date().toISOString(),u=await yr(c,{headed:r.headed,slowMoMs:Kn(r),timeoutMs:l,channel:r.channel,userDataDir:r.userDataDir,cdpEndpoint:r.cdp}),v=new Date().toISOString(),$={startedAt:h,endedAt:v};u.error?n.error(`Replay failed at step ${u.failedStepIndex}: ${W(u.error)}`):n.success(`Replayed ${u.stepsReplayed} step${u.stepsReplayed===1?"":"s"}`);let S=[],x=[],A=0;for(let k of w)try{let j=await k.collect(m,$);A+=j.length,d&&(j=j.filter(Nr=>vr(Nr,d))),x.push(...j),S.push({id:k.id,name:k.name,entries:j.length})}catch(j){n.warn(`${k.name}: log collection failed: ${W(j)}`),S.push({id:k.id,name:k.name,entries:0})}d&&x.length===0&&A>0&&n.warn(`${A} log entr${A===1?"y":"ies"} collected, none mention "${d}".`),x.sort((k,j)=>(k.timestamp??"").localeCompare(j.timestamp??""));let Tr={schemaVersion:Hn,workflow:e,status:u.error?"failed":"ok",window:$,steps:{total:u.stepsTotal,replayed:u.stepsReplayed,...u.failedStepIndex!==void 0?{failedAt:u.failedStepIndex}:{}},...u.error?{error:Yn(W(u.error))}:{},...d?{filter:{user:d}}:{},sources:S,entries:x},Ee=Rr.join(g,"logs.json");await Gn(Ee,`${JSON.stringify(Tr,null,2)}
38
+ `,"utf8"),n.info("");for(let k of S)n.info(` ${k.name.padEnd(10)} ${k.entries} entr${k.entries===1?"y":"ies"}`);n.info(""),n.success(`Logs written to ${Rr.relative(i.repoRoot,Ee)}`),u.error&&(process.exitCode=1)}finally{await Er(w)}}import{existsSync as qn}from"node:fs";import Xn from"node:path";var zn=new Set(["navigate","click","dblclick","fill","press","check","uncheck","select","setInputFiles","openPage","closePage"]),Qn=/^assert/,Zn=new Set(["click","dblclick","fill","press","check","uncheck","select","setInputFiles"]),eo={navigate:["url"],fill:["text"],press:["key"],select:["values"],setInputFiles:["files"]};function ro(e){let r=[],o=(i,s,a)=>{r.push({step:i,level:s,message:a})};e.length===0&&r.push({step:0,level:"error",message:"no steps"}),e.forEach((i,s)=>{let a=s+1;if(typeof i.action!="string"||i.action===""){o(a,"error",'missing "action"');return}if(Qn.test(i.action)){o(a,"warning",`"${i.action}" is skipped at replay \u2014 it asserts nothing`);return}if(!zn.has(i.action)){o(a,"error",`unknown action "${i.action}" \u2014 a run stops here`);return}Zn.has(i.action)&&!i.selector&&o(a,"error",`"${i.action}" needs a "selector"`);for(let c of eo[i.action]??[])i.params?.[c]===void 0&&o(a,"error",`"${i.action}" needs params.${c}`);if(i.action==="navigate"){let c=i.params?.url;typeof c=="string"&&!/^https?:\/\//.test(c)&&o(a,"error",`params.url must be absolute, got "${c}"`)}i.selector?.startsWith("role=")&&!/\[name=/.test(i.selector)&&o(a,"warning",`"${i.selector}" matches every such element on the page`),typeof i.index!="number"&&o(a,"warning",`missing "index" \u2014 set it to the step's position`)}),e.length>0&&e[0]?.action!=="navigate"&&r.push({step:1,level:"warning",message:'first step is not "navigate" \u2014 replay opens a blank page, so start with one'});let t=e.map((i,s)=>({step:i,n:s+1})).filter(({step:i,n:s})=>s>1&&i.action==="navigate");for(let{n:i}of t)r.push({step:i,level:"warning",message:"navigating by URL skips the UI \u2014 click the link or button that goes there instead (`verirun map --bfs <route>` names it). Fine only for a deep link with no path to it."});return r}async function Ir(e,r,o){if(e!=="check")throw new Error(`Unknown workflow action "${e}". Only "check" exists.`);if(!r)throw new Error("workflow check needs a workflow name or a path to a .json file.");let t=y(),i;if(r.endsWith(".json")?i=Xn.resolve(r):(D(r),i=_(t,r)),!qn(i))throw new Error(`No such workflow file: ${i}`);let s=await ne(i),a=ro(s.steps),c=a.filter(l=>l.level==="error");if(o.json){process.stdout.write(`${JSON.stringify({file:i,name:s.name,steps:s.steps.length,ok:c.length===0,findings:a},null,2)}
39
+ `),c.length>0&&(process.exitCode=1);return}n.info(""),n.info(`${n.bold(s.name)} ${n.dim(`\u2014 ${s.steps.length} step(s), schemaVersion ${s.schemaVersion}`)}`),n.info(n.dim(` ${i}`)),n.info("");for(let l of a){let d=`step ${l.step}`.padEnd(8);l.level==="error"?n.error(`${d} ${l.message}`):n.warn(`${d} ${l.message}`)}a.length===0?n.success(` Looks runnable. Try it: verirun run ${s.name}`):c.length===0?(n.info(""),n.success(` No errors. Try it: verirun run ${s.name}`)):(n.info(""),n.error(` ${c.length} error(s) \u2014 a run would fail. Fix them and check again.`),process.exitCode=1),n.info(""),n.info(n.dim(` Static checks only: selectors are not resolved against a page. Schema version ${U}.`))}var xr="a9zglrV4HjD4mtG96GnT/VoUfjD7fciQX76suBEw114AnDKGO9o7n8L4nq44bxxasgcZnW5kM8mkoE9WCik6AA==",Ar="MCowBQYDK2VwAyEATFTl78zmb+BITZuy9mdPMtujnz1tAeVidJT3dccuhLg=";function ao(){if(xr.startsWith("@@")||Ar.startsWith("@@"))return!0;try{let e=jr.dirname(io(import.meta.url)),r=oo(jr.join(e,"gate.mjs")),o=to({key:Buffer.from(Ar,"base64"),format:"der",type:"spki"});return no(null,r,o,Buffer.from(xr,"base64"))}catch{return!1}}var E=new so;E.name("verirun").description("Record and replay app workflows, and capture backend logs for each run.").version(L);E.command("record").argument("<name>","name for the workflow").description("Record a workflow in a headed browser and save it to .verirun/workflows").option("-u, --url <url>","URL to open the browser at").option("-b, --browser <browser>","browser to record in: chromium, firefox or webkit").option("--channel <channel>","use an installed browser: chrome, msedge, chrome-beta, ...").option("--default-browser","record in your OS default browser (falls back to bundled Chromium)").option("--user-data-dir <dir>","record in a persistent profile directory (keeps you logged in)").option("--test-id-attribute <attribute>","attribute to prefer for getByTestId selectors").option("-f, --force","overwrite an existing workflow with this name").action(async(e,r)=>{await gr(e,r)});E.command("run").argument("<name>","name of the workflow to replay").description("Replay a recorded workflow and capture Supabase / Vercel / Railway logs for the run window").option("--headed","run with a visible browser window instead of headless (paced so you can watch)").option("--slow-mo <ms>","pause before each action; default 500 when --headed, 0 otherwise").option("--timeout <ms>","per-action timeout in milliseconds (default: Playwright 30000)").option("--channel <channel>","replay in an installed browser: chrome, msedge, ...").option("--user-data-dir <dir>","replay in a persistent profile directory (keeps you logged in)").option("--cdp <url>","attach to a browser already running with --remote-debugging-port, e.g. http://localhost:9222").option("--user <id>","keep only log entries mentioning this string, e.g. an email (overrides config.userFilter)").action(async(e,r)=>{await Cr(e,r)});E.command("login").description("Connect this machine to your Verirun account").option("-f, --force","connect even if this machine is already linked").option("--server <url>","account server base URL (default: https://get-verirun.duely.in)").action(async e=>{await Ae(e)});E.command("logout").description("Disconnect this machine from your Verirun account").action(async()=>{await Te()});E.command("whoami").description("Show the connected account and subscription status").option("--server <url>","account server base URL").action(async e=>{await Ne(e)});E.command("map").description("Build an interaction graph of this repo: pages, the elements on them, and the backend calls they make").option("-d, --dir <dir>","directory to analyze (default: the repo root)").option("--json","print the full interaction graph as JSON").option("--report","write interaction-tree.json + coverage.md (default: .verirun/map)").option("--out <dir>","output directory for --report").option("--reach","per-route table of reachable vs attached elements").option("--bfs <node>","walk the graph from a node: a route path, page id or component name").option("--depth <n>","steps to follow for --bfs (default: 2)").option("--kind <kind>","--bfs: follow only nav or only effect edges").option("--alias <prefix=dir...>","extra import alias, e.g. @/=src (tsconfig paths are read automatically)").option("--no-follow-children","do not follow child components out of a page file").option("--app-file <file>","file declaring <Routes> (react-router apps; auto-detected by default)").action(async e=>{await ir(e)});E.command("workflow").argument("<action>","what to do: check").argument("[name]","workflow name, or a path to a .json file").description("Check a workflow file without running it (shape, actions, selectors, params)").option("--json","emit the findings as JSON").action(async(e,r,o)=>{await Ir(e,r,o)});E.command("agent").description("Print a compact reference (commands, .verirun/ layout, logs.json schema) for an AI coding agent").option("--json","emit JSON instead of Markdown").option("--skill","emit an agent skill file (Claude Code, Cursor) instead of the plain reference").option("--install [agent]","with --skill: write it where the agent looks \u2014 claude (default), cursor, or all").action(async e=>{await Be(E,e)});E.command("log").argument("[source]","log source to connect: vercel, supabase or railway (omit for an overview)").description("Connect a log source and check its configuration").option("--test","query the last 5 minutes and report what comes back").option("--drain","vercel: set up the old push-based log drain instead of the API").option("--listen","vercel: run the drain listener until Ctrl+C (drain mode only)").option("--reconnect","re-run the connect step and replace what was saved").action(async(e,r)=>{await Ze(e,r)});async function co(){ao()||(process.stderr.write(`verirun: this installation looks modified. Reinstall it:
38
40
 
39
41
  npm install -g @verirun/cli
40
- `),process.exit(1));try{await R.parseAsync(process.argv)}catch(e){n.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}Xn();
42
+ `),process.exit(1));try{await E.parseAsync(process.argv)}catch(e){n.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}co();
package/dist/gate.mjs CHANGED
@@ -1 +1 @@
1
- function i(a,b){a=a-(-0x1*-0x289+-0x12ac+0x429*0x4);const c=e();let d=c[a];if(i['ZgMjCX']===undefined){var f=function(j){const l='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let m='',n='',o=m+f,p=(''+function(){return-0x32*-0x54+0x5*0x731+0xa79*-0x5;})['indexOf']('\x0a')!==-(0x6c*0x59+0x95c+-0x2ee7);for(let q=-0x1316+0xaee+0x48*0x1d,r,s,t=-0x769+-0x1*-0x9f1+-0x9*0x48;s=j['charAt'](t++);~s&&(r=q%(0x1ffc+0xd73+0x7*-0x67d)?r*(0xa84+-0x21bf+0x1*0x177b)+s:s,q++%(0x1*-0x61d+-0x6b*-0x4a+-0x18cd))?m+=p||o['charCodeAt'](t+(-0x207d+0x2a4*0xe+0x1*-0x471))-(-0x5ba*0x1+0x5a+0x56a)!==-0x1*-0x2311+0x1d7d+-0x408e?String['fromCharCode'](-0xacf*0x1+0x3ce*0x1+0x40*0x20&r>>(-(0x24e1*-0x1+-0x1*0x50b+0x6fd*0x6)*q&0x72a+0x59*-0x59+0x1*0x17cd)):q:0x1114*-0x2+0x4*-0x3d2+0x3170){s=l['indexOf'](s);}for(let u=-0x3*0x5d1+0xb29+0x64a,v=m['length'];u<v;u++){n+='%'+('00'+m['charCodeAt'](u)['toString'](-0x2522+0x1263+0x12cf))['slice'](-(0x11f9*0x1+0x1748*0x1+-0x293f));}return decodeURIComponent(n);};i['tPydgb']=f,i['aMysPD']={},i['ZgMjCX']=!![];}const g=c[-0x1c1e+0x37a+0xa6*0x26];i['icBAgP']!==g&&(i['aMysPD']={},i['icBAgP']=g);const h=i['aMysPD'][a];if(h===undefined){const j=function(k){this['QTiBmz']=k,this['XhRYDw']=[-0x7b4*0x4+0x263*0xf+-0x4fc,-0x1*0x23f+0x1dd9+-0x1b9a,0x1*0x5f7+-0xf9a+0x9a3],this['zSdAAm']=function(){return'newState';},this['AgNtes']='\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a',this['jDqZEt']='\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d';};j['prototype']['EPdTGW']=function(){const k=new RegExp(this['AgNtes']+this['jDqZEt']),l=k['test'](this['zSdAAm']['toString']())?--this['XhRYDw'][-0xd57+0x16c3*-0x1+-0xc09*-0x3]:--this['XhRYDw'][0xa37+0x23cf+-0x2e06];return this['FiMHQu'](l);},j['prototype']['FiMHQu']=function(k){if(!Boolean(~k))return k;return this['qIOXUq'](this['QTiBmz']);},j['prototype']['qIOXUq']=function(k){for(let l=0x2211+-0xab6*0x3+-0xb*0x2d,m=this['XhRYDw']['length'];l<m;l++){this['XhRYDw']['push'](Math['round'](Math['random']())),m=this['XhRYDw']['length'];}return k(this['XhRYDw'][-0x6d7+0x1bb*0xb+0x1be*-0x7]);},(''+function(){return 0x1308+-0xcdb+-0x62d;})['indexOf']('\x0a')===-(-0x10d*-0x11+0x7*-0x33c+0x264*0x2)&&new j(i)['EPdTGW'](),d=i['tPydgb'](d),i['aMysPD'][a]=d;}else d=h;return d;}const aN=i;(function(n,o){const aK=i,r=n();while(!![]){try{const s=parseInt(aK(0x155))/(-0x3*-0x8fe+0xd12+-0x280b)*(-parseInt(aK(0xdb))/(-0xe1b+0x26f8+0x18db*-0x1))+-parseInt(aK(0x20d))/(-0x183c+-0x511*-0x1+0x132e)*(parseInt(aK(0x8d))/(0x1852+-0x3d*0x3f+-0x94b))+parseInt(aK(0x2c8))/(-0x39f+0x2376+0xfe9*-0x2)+parseInt(aK(0xb5))/(0xf1*-0x23+0x1a62+0x697)*(parseInt(aK(0x1f3))/(-0x1*0x1cb8+0x2*0xc15+0x17*0x33))+parseInt(aK(0x293))/(0x16ec+0x2028+0x1*-0x370c)+-parseInt(aK(0xa0))/(-0x2b*-0xa5+-0x1*0x24ee+0x940)*(parseInt(aK(0x1c6))/(0x9df+-0x1c1*0x12+0x15bd))+parseInt(aK(0x2c9))/(0x24cf+-0x3*0xc9c+0x110*0x1)*(parseInt(aK(0x166))/(0x13a6+0x1d2c+-0x30c6));if(s===o)break;else r['push'](r['shift']());}catch(t){r['push'](r['shift']());}}}(e,-0x59*0x3873+-0xfb6*-0x77+0x175180*0x1));const c=(function(){let n=!![];return function(o,r){const s=n?function(){const aL=i;if(r){const t=r[aL(0x200)](o,arguments);return r=null,t;}}:function(){};return n=![],s;};}()),a=c(this,function(){const aM=i,n={'ZQLdG':function(o,r){return o!==r;},'MqPND':aM(0xca)+aM(0x130)};if(n[aM(0x2cb)](a[aM(0x204)]()[aM(0x1d7)]()[aM(0x203)]('\x0a'),-(-0xe0b*0x2+0x146e+0x7a9)))return;return a[aM(0x1d7)]()[aM(0x233)](n[aM(0x273)])[aM(0x1d7)]()[aM(0x251)+aM(0x115)](a)[aM(0x233)](aM(0xca)+aM(0x130));});a();import{randomBytes as aq}from'node:crypto';import ar from'node:os';function e(){const br=['mJqYnJeXogrHDMjxyW','BYb0AguGAw4','AwTQreC','AM9PBG','zxaGCNvUBMK','yNnJCMLIzsa','ChjVyMXLBq','qw5Krvq','C2XPy2u','ywjVCNrLza','D2LUmZi','uuzpDuW','zgXJAgO','BMv0D29YAYa','C2vYDMvY','ig9MzMXPBMu','vfjbx0nbx0m','zgvY','z2v0lxzLCMK','DLnTCe0','AwrHDguGEw8','ywWGAgfZigu','C2nYAxb0Aw8','zxqGsfruufm','yw5PC2f0Aw8','DNbHEw4','zMLUz2vYChi','CgfYC2vjBNq','zMLuwKS','vfDbuKvCtwK','BwfW','zePum2rJy3u','B2jQzwn0','zxnWB25Zzs4','Agj2D3y','DgHYB3vNAca','Df9KDwu','BYb2ywXPzca','C2vHCMnO','ue9tva','BNrZlIbfBwe','y3rmu08','C3rYAw5NAwy','y2fWDgL2zsa','B2XK','AxjLza','uMvHy2HLzca','BMrLza','twfJAgLUzuC','AgLUzsbPCYa','BwfJoG','D3LKqMe','CNvZDgvKlIa','CMvN','BgLUDxG','AYbPDcbWB2K','y2HPBMuTAwq','BIbPCYbUB3q','yxbOEq','y2SGzMfPBgu','vNL4B1K','ieLMihLVDsa','zfjxt3G','cLrOAxmGBwe','Ahr0Chm6lY8','EurVyxq','y2SGDgHHDca','CMvHy2HHyMW','y29UC3rYDwm','yITcsvrADxK','CNnPB24','uMvZDwjZy3i','CNvUlMr1zwW','CvjnEfe','q0jps28','q2Dkv0C','idmWigrHExm','BwXqB1O','uvv3AK4','AuHwq3i','revqveHFwKu','Dg8GC2LNBIa','C3rHDhvZ','quni','AguGCMvHBca','wfftzxm','CgTuv1G','BNnLihnLCNy','uNPJwe4','tfLOzwy','C3rYAw5N','BgvUz3rO','AuD3wvq','vKf0CeK','BMrLzc4Gu3u','AeXNpq','q0n2s3a','rufdsa','lNzLCMLYDw4','C2vYDMvYlG','B25Uzwn0ihq','rMnVEe0','txfqtKq','DguGysbUzxC','DxiGC3vIC2m','zgf5igzYzwu','C2vHDf9SAw0','BhL6Bey','CgXHDgzVCM0','DgHHDcbPBNm','uLvox0Xjq0u','C2HHmJu2','C2v0ifzfuKK','y3jLzgvUDgK','qxrXBK4','vNfls2m','Dw5RBM93BG','zxiGB3iGysa','zwqGzM9Yihq','ihjLDhvYBIa','zxj2zxi','yw5JztPY','zsbVBMuGyxq','zNjVBq','Dg9mB3DLCKm','BIbSB2DPBG','rvju','CMvJDcbHBMq','Dw5KAwnP','EuToy3O','u0LbsxC','q0vsvf9iqvm','zxjPCNvUige','BgqGDg8GA2u','nJu4mJe2mhHyqKHxEa','Dw50lIbsDw4','Bg5nzgi','zMLSDgvY','zgvK','u0vmrL9tsuC','Axj1BIb0CMK','DgvZDa','CMvSzwfZzq','l2rIDxmVBwe','vgHPCYb2zxi','Ahr0ChnFChi','wNzLBLm','yxnL','Ehr3A1K','ienOzwnRihK','BgvHC2uGDg8','vezuBdC4EM0','zMXVB3i','y2f1C2u','ihr3BYbVDgG','zgLY','EsbPCYbJB3i','zw5Zzsb3yxm','vgHPCYbTywm','DcbHzNrLCIa','sKj4tgm','DgLTzwqGB3u','uK9Fu0vmrL8','ihjLDM9Rzwq','t2zOv24','y29UzMLNlMO','yurVy1O','Awf0','AgLUzs1Pza','sw5gtvq','AhDF','CgvJDhmGDhi','vMvYAxj1BIa','CMvWBgfJzq','AgLUzsbOyxm','zMLJyxrLihC','runptK5sruy','BIb3yxmGy2e','yMXgzMS','ywjVCNq','seTmtvXtt0y','igrHExmUiem','BI9JBgLaBge','tNDysMi','DhjPywXFzw4','BwjbsNi','Es5PBG','mZyZmtqXmgjeufPcuW','nJe0ovnKzLfQqq','BNOXDefLvMK','wLfmzeC','u0LhtKvex0m','wefMs1q','y2HLy2TWB2K','te5mr1G','lIbhzw5LCMe','x0Lox0niquK','z1nWsuW','DgHLifzLCMK','t21yAuO','CNvUigfJy28','igzHBgWGyMe','zgfYD2LU','y2SGB24Uiem','B25uuuC','AwjLigf0ia','C2LNBMfS','l3vZCI9ZyMK','C2LNBMvKihi','zxjPCNvUigW','tfztEMe','EgLTDw0GBNu','DhjPywWGB24','ngLku2TNyW','C3vIC2nYAxa','DhjPBq','yxHfB3u','igLUDgvYBMu','DgLVBL9LEha','zwTYvg4','lGPszwXLyxm','q2DHr2q','qu11t3K','DfjzD2e','yMzgEMK','mc4YlJm','tKvex0nfuLq','DgvKihrVihK','DgfYDhmGyxu','yxqGB3bLBNm','tfmGy2vYDgK','ufPWtui','mtm5nvDMqu1nuW','Dg9Rzw4','mNHmmhbsnge','B3vSzcbUB3q','wvjNuM8','CMvHC29U','A2v5x3jLDM8','zxjYB3i','yMfZzty0','igjLzw4GDxm','ve50Bg0','Agv4','DxnLCM5HBwu','Dw4GBg9NAw4','A2v5','igXVz2LU','B3H5','BNrLCMzHy2u','BhzLzc4Gqsa','ieb2zxjPCNu','u1nNwhe','odq0ntu0A3jYrwH1','AwXSigrVihq','q3zvwuu','C2LN','vgHPCYbHy2m','igrHEq','CMrPCNO','BwfJ','BLDWwxe','Ag9TzwrPCG','Dcb0BYb0Agu','Ag9ZDg5HBwu','y2f0y2G','wLjvzNe','Dw5RBM93BL8','wgjStfK','shrgs04','ig9UzsbMCM8','BhrXzvu','ksbHBMqGDgG','BgvHC2u','kcGOlISPkYK','zxiGka','Aw50','BNvVELi','C2LNBMf0Dxi','zwn0zwqGDg8','zxiGyxqG','zxjLigLZig4','qKzLzMy','zxn0igfUB3q','igLZig5VDca','B3jRAw5NigK','BgLJzw5ZzuS','ihrVihjLCxu','zxHW','sfruufnFufi','DguGAxq6cGO','nZz4CNPqB1G','qvLdvui','B2DPBGOkvgG','vezprgW','DwLK','BM9Uy2u','ihrYAwfSihm','AguGzNjLzsa','DxbKyxrL','B3vUDcbPCYa','y3jVC29MDfW','wNfUtwG','C2HHCgu','AxmGDg9Vig8','DNi5x3m3uwu','z2jYyxu','A2LUza','CNra','runptK5srvm','yMvLBIbHyMW','t19hrvrFsvm','Aw50zxjUywW','Cg9YDgfSihC','mda6mda6mda','DgvYBMv0ige','BM8TBwfJ','DM5WAwe','vgHLigXPy2u','yNnJCMLIztO','ru5fvfvouKu','BMvLzhmGysa','BMv0D29YA0K','Dg8GA2vLCca','DK9js0e','ENPntvO','igfJDgL2zs4','zw50CMLLCW','BxjsrfC','wJfTsZHKvZm','ANjZBfi','q09otKvdvf8','AxnbCNjHEq','ywrK','BM93','r29zDKS','vgHHDcbSAwm','lcb0AgvUihi','DcbYzwfJAca','B25Uzwn0Aw8','uKX5y2G','zxiGywnJB3u','y2nVDw50lG','zMLSzq','v3P6vfy','swffCwC','CxvLCNK','C3rHDguUANm','C29Tzq','Dg9Y','DcbHBMqGCNu','CNvUihDOB2e','CM91BMq','A2LK','l2DYyw50oNi','igfSCMvHzhK','iokaLcb0AguGyq','C29U','zvzyD08','BKi2DfK1AeO','Bwf0y2G','vgHPCYbSAwm','ihzHBgLKicG','BYbYzxzHBgK','CMvHy2HLzca','zfzpEhO','rgv2AwnL','vwvZuwi','A1rOu00','C29YDa','ELvRCxm','B3vYigjPBgW','tMjgwfm','ruHpu1rvtLi','BMr4CLK','BM90ignVBM4','kYKRja','BwfJAgLUzuK','B3v0lIa','vf9mt0nbteW','Aw4UieeGnYa','CgvYAw9Kx2u','Aw9Ul2PZB24','y2XPx3rVB18','zw5Zzs92ywW','yxbWBgLJyxq','B2nRzwqUia','DMLJzv9SAw0','BI9PB3jLzW','x0vyueLsruq','lIbdB25Uzwm','ow1Kue10DwO','CMvJB2DUAxm','C3bSAxq','zxiGAw4G','rfbhDuG','BwfJAgLUzxm','tLnfx1nfuLy','oIaGDMvYAxi','zffjt1K','A1H0t28','BJOGihzLCMK','y291BNqUifi','ywDHAw4U','zw5ZzsbRzxK','DgLVBL9Jyw4','BMnLBgvKlIa','Cgf5Bg9Hza','DxnLCKLUzM8','x1bst1HzlG','wuz3B0G','zgrYzxnZigm','DxrMoa','mtaYmdrTy1bpCuq','BIb0AguGBwe','BIDZienbigy','C3rKB3v0','AxrFzxHJzwu','CNvUigXPy2u','zxiGBgLUAYa','tgTNANa','y2vSzwq','Be5RBhO','l2fWAs9SAwm','BgvHC2vFAw4','vvnfra','sZjwD0f5rue','Ahr0Cf9WCM8','zvbREMG','DxnLCG','mtu1nJr2whHbCwK','rwLOzvq','igrPzcbUB3q','tunVD0jrwuq','ChjVEhKSihm','iokaLcb0AguGva','B3uGyxjLig4','DgLVBL9Wyxm','t0vmB08','zsb0BYb2ywW','zg1jvxi','DMfSDwu','ihzLCMLYDw4','BgX5igLMihK','CMvZDwX0','ywXYzwfKEsa','v2PNCMu','AgfZig5VDca','ANbStei','veLnru9vva','l2LUAgvYAxq','vu5bqKXfx1q','qsbWCM94Esa','lYnWCMLJAw4','igjLihjLC28','z1niruq','wLPHsgW','DMfSAwq','u1vfuL9drvi','l3zHCI9SAwi','icb2zxjPCNu','txL0y1O','BwjLCIbVzIa','uunmq0C','l2fJy291BNq','EMHXtMO','oIHpssKOq0K','Axz2suW','yLr2y2K','tg9yuvm','yxmGBM90ihq','BwvZC2fNzq','ie5prevFrvG','vfLeruq','twrdwLa','Aw5Nigf0ia','B3vKEhm','x0LorKLosvq','Awq6','vu5ex0vsuL8','C3bRAq','rgvzrfO','Dw46cGOGihy','zgf0zs4Gsxq','swyGDgHPCYa','Axj1BIbZDwi','lxjKmq','ihj1BM5PBMC','BIb0Aw1Lzca','y2vPBa','CgfYC2u','t1Hz','re5tigzPBhq','CMLYDw4Gywm','yM9VBgvHBG','ywzMAwmGy2e','C2L6zq','BgvKqMfJAW','EenbuMC','uwnoB1q','CwjIEe4','AvrWzxG','q3j5ChrVz3i','ru5pvezpvu4','zvLwqNu','ywn0AxzLig8','DgvYBMv0ihq','zgPuvhy','CfzWr2K','EevuC04','CgrbC0i','tfPzz0K','y2XVy2TsB2W','ysb2ywXPzca','zM9Yig92zxi','zw5KC1DPDgG','ANnVBG','vLfvDwu','sfLhAwu','AwnHy2XZ','BNrZigf0ihq','wurVCue','zxCU','BwLUq2XPvMu','oJaWoJaWoJa','z2rQqMW','mZiXmtbNB0H6EKS','BM90zq','t3vcC1a','igeGyNjVD3m','zgLNzxn0','BNvTyMvY','ww91CIbwzxi','q291BgqGBM8','AhnQDK0','DgHLihbYB3G','lcbZBYbJAgu','DhjPywXFzgu','rviSignOzwm','Dg9TyxrPy2e','y2HPBMuGAxm','yvvNqwS','A2v5CW','Dg9tDhjPBMC','BcWGB3iGC3u','vwvrAK4','BMCUifvWzge','ihn0B3bZihC','BMqGCNvUoIa','vM11q2i','CIbJB25Uzwm','BM8GBg9Uz2u','rvrjtuvet1u','DxnLCYb0AgK','sfruuf9quK8','zwqUifj1BJO','AgLZlG','DxnPBMCGAxq','swjUtva','B3vYifzLCMK','A2vK','rvjuuYbHDca','l2v0yY9Tywm','rufjx0fhquK','Dw4GDgHPCYa','wvLHBMS','AwXLlG','C2LVBIbVzIa','DgLVBIbJAgu','BgLJzw5Zzvm','icbUCg0GAw4','n09xD0jYyq','z2LkD1m','Auncs1u','CMLWDgLVBIa','y29Kzq','AgvYihrYAwe','DgHLigXPy2u','ihLVDxiGvMu','Bwf4','CZSGCg9PBNq','CM1fEhbLCNq','su9qBgf0zM8','Bsb5B3vYify','yxbWBhK','Ew91CIbVCMC','yxjJAa','Aw5KzxHpzG','yMLUza','r01Mz3q','AwrHDgu','BIb3yxmGyMW','AwWGC3vWCg8','iokaLcb0AguGyW','ue9tsvrjvKu','C3rHBgWGlwC','vM5sBKm'];e=function(){return br;};return e();}var T=!(-0x198a+0x1ea0+0x1*-0x515),ne=[aN(0x29e)+aN(0xb0),aN(0xd9)+aN(0x1a3),aN(0x163)+'xy',aN(0x1e2)+'XY'];function I(){const aO=aN;for(let n of ne){let o=process.env[n]?.[aO(0x8f)]();if(o)return o;}}function re(r,s=process.env.NO_PROXY??process.env.no_proxy){const aP=aN;let a0=s?.[aP(0x8f)]();if(!a0)return!(-0x143f+0x144b+0xb*-0x1);if(a0==='*')return!(0x1d07*0x1+-0x1948+-0x3bf);let a1=r[aP(0x289)+aP(0x2a0)]();return a0[aP(0x141)](',')[aP(0x22b)](a2=>a2[aP(0x8f)]()[aP(0x289)+aP(0x2a0)]()[aP(0x2ba)](/^\./,'')[aP(0x141)](':')[-0x2510+-0x1f*-0x11+0xbab*0x3]??'')[aP(0x296)](Boolean)[aP(0x114)](a2=>a1===a2||a1[aP(0x1bb)]('.'+a2));}async function ie(s){const aQ=aN,a0={'XAfKT':aQ(0x267),'onTQG':function(a3,a4){return a3(a4);},'LYhef':aQ(0x28d)};if(T)return;T=!(-0x1f*0xb8+-0x347*-0xb+0xf*-0xeb);let a1=I();if(!a1)return;let a2;try{a2=(typeof s==a0[aQ(0x2cd)]?new URL(s):s)[aQ(0xc0)];}catch{return;}if(!a0[aQ(0x84)](re,a2))try{let {ProxyAgent:a3,setGlobalDispatcher:a4}=await import(a0[aQ(0x266)]);a4(new a3(a1));}catch{}}async function A(n,o){const aR=aN,r={'SIAIw':function(s,a0){return s(a0);},'dmIUr':function(s,a0,a1){return s(a0,a1);}};return await r[aR(0x28f)](ie,n),r[aR(0x170)](fetch,n,o);}function N(n){const aS=aN,o={'VmuCb':function(s,a0){return s(a0);},'zhqNj':aS(0x1af)+'D','DeYDZ':aS(0x1eb)+'N','eVXwO':aS(0x2bd)+aS(0x161),'dRWOx':aS(0xf8)+aS(0x260),'MdCZP':function(s){return s();},'jplLB':aS(0x1e0)+'T','HYGie':aS(0x17b)+aS(0xef)+aS(0x182)+aS(0x133)+'Y','CCvKp':aS(0x25d)+aS(0x2af)+aS(0x2cc)+aS(0x28b),'OmXiJ':aS(0x290)+aS(0x13d)};let r=o[aS(0x1dd)](oe,n);if(r)switch(r){case o[aS(0x189)]:case o[aS(0x199)]:return r+(aS(0x11c)+aS(0x153)+aS(0xa3)+aS(0x17e)+aS(0xb2)+aS(0x1a4)+aS(0x282)+aS(0x238)+aS(0xf1)+aS(0xb6)+aS(0x1e4));case o[aS(0x11e)]:case aS(0xed)+'ET':case aS(0x12d)+aS(0x26e):case o[aS(0x24b)]:return r+(aS(0x209)+aS(0x10b)+aS(0x207)+aS(0x13a))+o[aS(0x192)](C);case aS(0x197)+aS(0x103)+aS(0x179):case o[aS(0x178)]:return r+(aS(0x209)+aS(0x10b)+aS(0x1a0)+aS(0x132))+C();case o[aS(0x1be)]:case aS(0x298)+aS(0x9a)+aS(0x2d1)+'N':case o[aS(0x26d)]:case o[aS(0x2d4)]:return r+(aS(0x16b)+aS(0x9e)+aS(0x2bc)+aS(0x18e)+aS(0x241)+aS(0x17c)+aS(0x27a)+aS(0x2b8)+aS(0x1a7)+aS(0x1e1)+aS(0x1fc)+aS(0x190)+aS(0x21d)+aS(0x1e9)+aS(0x201)+aS(0x225)+aS(0x157)+aS(0x1ee));default:return r;}}function C(){const aT=aN,n={'SSgXq':function(r){return r();}};let o=n[aT(0xb4)](I);return o?aT(0x23b)+aT(0x230)+aT(0x1cf)+'y\x20'+o+(aT(0x1d0)+aT(0x24f)+aT(0x1cf)+aT(0x2a9)+aT(0x28c)+aT(0x19f)+'.'):aT(0x19c)+aT(0x21a)+aT(0xf9)+aT(0x16a)+aT(0x224)+aT(0x151);}function oe(o){const aU=aN,r={'FcoxM':function(s,a0){return s<a0;},'kThSM':function(s,a0){return s==a0;},'dVOxz':aU(0x22d),'IaEqg':function(s,a0){return s in a0;},'pkTWX':aU(0x1f7),'jrslR':aU(0x267)};for(let s=o,a0=-0x26b+-0x5c1*-0x1+-0x356;s&&r[aU(0x272)](a0,0x19a*0x1+-0x12*-0x83+-0xacc);a0++){if(r[aU(0x128)](typeof s,r[aU(0x125)])&&r[aU(0x111)](r[aU(0x263)],s)&&r[aU(0x128)](typeof s[aU(0x1f7)],r[aU(0x102)]))return s[aU(0x1f7)];s=typeof s==aU(0x22d)&&r[aU(0x111)](aU(0x2a6),s)?s[aU(0x2a6)]:void(0x18d*0x13+0xd7+-0x1e4e);}}import{createHmac as as}from'node:crypto';import{existsSync as at}from'node:fs';import{mkdir as au,readFile as av,rm as aw,writeFile as ax}from'node:fs/promises';import ay from'node:os';import az from'node:path';import{execFile as aA}from'node:child_process';import{chmod as aB}from'node:fs/promises';import aC from'node:os';import{promisify as aD}from'node:util';var le=aD(aA);async function g(r,s){const aV=aN,a0={'HtFKN':function(a3,a4){return a3!==a4;},'QCLCG':aV(0x217),'djTTv':function(a3,a4){return a3===a4;},'iTpex':aV(0x2a8),'aUgAk':function(a3,a4,a5,a6){return a3(a4,a5,a6);},'GoYvK':aV(0x1bf),'iCBKU':aV(0x17a)+aV(0x286)};if(a0[aV(0xc5)](process[aV(0x279)],a0[aV(0x187)]))try{return await aB(r,a0[aV(0x1b3)](s,aV(0x2a8))?-0x19b1*0x1+-0x6a6*-0x5+-0x5cd:0x2025+-0x980*0x4+-0x1*-0x75b),!(0x55d+-0x1*-0x1b+0x1*-0x578);}catch{return!(-0x16be+-0x2*0x1079+-0x10d*-0x35);}let a1=fe();if(!a1)return!(-0x2*-0xca6+-0x1eab+0x560);let a2=a0[aV(0x1b3)](s,a0[aV(0x1ad)])?a1+(aV(0x18a)+')F'):a1+':F';try{return await a0[aV(0x1d5)](le,a0[aV(0x107)],[r,a0[aV(0x1f5)],aV(0x11a),a2],{'timeout':0x2710,'windowsHide':!(-0x1*-0x382+-0x3*-0xb57+-0x2587)}),!(-0x911+0x24b1+0x88*-0x34);}catch{return!(-0x1*-0x6a1+-0x6*-0x2d6+-0xb2*0x22);}}function fe(){const aW=aN;let n=process.env.USERNAME;if(!n)try{n=aC[aW(0x150)]()[aW(0xac)];}catch{return;}if(!n)return;let o=process.env.USERDOMAIN;return o&&o!==n?o+'\x5c'+n:n;}import{spawnSync as aE}from'node:child_process';import{createHash as aF}from'node:crypto';import{readFileSync as aG}from'node:fs';import aH from'node:os';var ge=/^(lo|docker|veth|br-|virbr|vmnet|vboxnet|vnic|tun|tap|utun|llw|awdl|ap\d|zt|wg|nordlynx|tailscale|ham|anpi|bridge)/i,he=/(vethernet|hyper-v|virtualbox|vmware|vmnet|loopback|bluetooth|wi-fi direct|local area connection\*|tap-windows|openvpn|wireguard|nordlynx|tailscale|zerotier|wintun|npcap|teredo|isatap|docker)/i;function ye(n){const aX=aN,o={'BFeff':function(r,s){return r===s;},'iGwYT':aX(0x217)};return ge[aX(0x29a)](n)?!(-0xffe+-0x982+0x4*0x660):o[aX(0xd2)](process[aX(0x279)],o[aX(0x269)])&&he[aX(0x29a)](n);}function we(){const aY=aN,s={'lyzlF':aY(0xf2)+aY(0x1c4)+'0'};let a0=new Set(),a1=new Set();for(let [a2,a3]of Object[aY(0xff)](aH[aY(0xfa)+aY(0xb1)+'s']()))for(let a4 of a3??[]){if(a4[aY(0xf0)]||!a4[aY(0xbc)]||a4[aY(0xbc)]===s[aY(0x278)])continue;let a5=a4[aY(0xbc)][aY(0x289)+aY(0x2a0)]();a1[aY(0x105)](a5),ye(a2)||a0[aY(0x105)](a5);}return[...a0[aY(0x1a8)]>0x213d+-0xfe7*0x2+-0x16f?a0:a1][aY(0x129)]();}function O(){const aZ=aN,n={'ivvIL':function(o,r){return o!==r;},'ZZaHl':aZ(0xb7),'WzzTV':aZ(0x165)};try{return aH[aZ(0x150)]()[aZ(0xac)];}catch{return n[aZ(0x18b)](aZ(0xb7),n[aZ(0x180)])?o[aZ(0x150)]()[aZ(0xac)]:process.env.USER??process.env.USERNAME??n[aZ(0x110)];}}function P(o,r){const b0=aN,s={'MytcZ':function(a0,a1,a2,a3){return a0(a1,a2,a3);},'VQUue':b0(0x154),'VqKKc':function(a0,a1){return a0!==a1;}};try{let a0=s[b0(0x185)](aE,o,r,{'encoding':s[b0(0x1bd)],'timeout':0xfa0,'windowsHide':!(-0x181*0xb+-0x2aa+0x1335)});return a0[b0(0xa7)]||s[b0(0x280)](a0[b0(0x25f)],-0x25e2+0x3c*0x7+-0x121f*-0x2)?void(-0x33*-0x43+0x13c+0xe95*-0x1):a0[b0(0x158)];}catch{return;}}function be(){const b1=aN,n={'IbnMP':function(o,r){return o!==r;},'zUkqs':function(o,r){return o||r;}};return n[b1(0x1e6)](h,void(0x888+-0x13c9+0xb41*0x1))||(h=Ee()??''),n[b1(0x12a)](h,void(-0x3*-0xa5d+0x7ea*-0x1+0x15d*-0x11));}var h;function Ee(){const b2=aN,n={'NbFXS':b2(0x243),'hbvwv':b2(0x1ea)+b2(0x2b5),'CgJWG':b2(0x183)+b2(0x29c)+b2(0x245),'axEou':function(o,r,s){return o(r,s);},'lnMdb':b2(0x154),'xtwkY':b2(0x82),'OuBsP':b2(0x87)+b2(0x13c),'blFfk':b2(0x19e),'GMfgt':b2(0x217),'EiheT':b2(0x242)};if(process[b2(0x279)]===n[b2(0x12c)]){for(let o of[n[b2(0x22f)],n[b2(0x258)]])try{let r=n[b2(0x90)](aG,o,n[b2(0x295)])[b2(0x8f)]();if(r)return r;}catch{}return;}if(process[b2(0x279)]===n[b2(0x2a1)])return P(n[b2(0x1c8)],[n[b2(0x2bf)],'-c',b2(0x1fe)+b2(0x1fd)+b2(0x126)])?.[b2(0x120)](/"IOPlatformUUID"\s*=\s*"([^"]+)"/)?.[-0x79b+0x1b42+-0x13a6];if(process[b2(0x279)]===n[b2(0x205)])return P(n[b2(0x167)],[b2(0x112),b2(0x2c1)+b2(0x22a)+b2(0xe5)+b2(0x1ae)+b2(0x247),'/v',b2(0x23d)+b2(0xdf)])?.[b2(0x120)](/MachineGuid\s+REG_SZ\s+(\S+)/i)?.[-0x262e+-0x8e3*-0x4+0x2a3];}function _e(n=be()){const b3=aN,o={'LNLGX':function(r){return r();}};return n?[b3(0x196)+n,aH[b3(0x279)](),aH[b3(0x202)](),o[b3(0x2cf)](O)]:[b3(0x23f)+(o[b3(0x2cf)](we)[b3(0x210)](',')||b3(0xf4)),aH[b3(0xc0)](),aH[b3(0x279)](),aH[b3(0x202)](),O()];}function b(){const b4=aN,n={'gSpIL':function(o,r){return o(r);}};return b4(0x2b7)+n[b4(0x2d2)](aF,b4(0x27c))[b4(0xe3)](_e()[b4(0x210)]('|'))[b4(0x1ca)](b4(0xab))[b4(0x215)](-0x1125+0x1ea8+-0xd83,0x5ff+0x1*0x8aa+-0xe81);}var f=az[aN(0x210)](ay[aN(0xbe)](),aN(0x26f)),E=az[aN(0x210)](f,aN(0x2b2)+aN(0x11d)),y=az[aN(0x210)](f,aN(0x113)+'on'),U=aN(0xe9)+aN(0xa2)+aN(0x101)+aN(0x11f);async function D(){const b5=aN,n={'tRYwa':function(r,s){return r(s);},'OfhWn':b5(0x2a8)};let o=n[b5(0x97)](at,f);await au(f,{'recursive':!(-0x1*0x2029+-0x1b8d*-0x1+0x49c*0x1),'mode':0x1c0}),o||await g(f,n[b5(0x2b1)]);}async function F(n){const b6=aN,o={'AtqnN':function(r,s){return r(s);},'RLych':b6(0xaa)};if(o[b6(0x27f)](at,n))try{return JSON[b6(0x1a2)](await av(n,b6(0x154)));}catch{if(b6(0xaa)!==o[b6(0x10c)])for(let s of t){let t=a1.env[s]?.[b6(0x8f)]();if(t)return t;}else return;}}async function d(){return await F(E)??{};}async function G(n){const b7=aN,o={'UeQjN':function(s){return s();},'gbrau':function(s,a0,a1){return s(a0,a1);},'giJwS':b7(0x10f)};await D();let r={...await o[b7(0x1d9)](d),...n};return await ax(E,JSON[b7(0x237)+'y'](r,null,0x19dc+-0x75d+-0x127d)+'\x0a',{'mode':0x180}),await o[b7(0xea)](g,E,o[b7(0x1f4)]),r;}async function l(){const b8=aN,n={'dQIOY':function(r){return r();},'AYCUB':function(r,s){return r(s);}};let o=n[b8(0x147)](b);return(await d())[b8(0x131)+'d']!==o&&await n[b8(0xdc)](G,{'machineId':o}),o;}function k(n){const b9=aN,o={'JBxLc':b9(0x27c)};return as(o[b9(0x2ad)],U)[b9(0xe3)](n)[b9(0x1ca)](b9(0xab))[b9(0x215)](-0xe52+0x3c9+-0x1d*-0x5d,0x1260+0x1a63+-0x1*0x2cb3);}function _(n){const ba=aN,o={'Lkgjp':ba(0x22d)};return n===null||typeof n!=o[ba(0x15c)]?JSON[ba(0x237)+'y'](n):Array[ba(0x104)](n)?'['+n[ba(0x22b)](_)[ba(0x210)](',')+']':'{'+Object[ba(0x1d6)](n)[ba(0x129)]()[ba(0x22b)](r=>JSON[ba(0x237)+'y'](r)+':'+_(n[r]))[ba(0x210)](',')+'}';}function B(n){const bb=aN,o={'mrRDW':function(r,s,t){return r(s,t);},'oudxs':bb(0x27c),'TYDED':function(r){return r();}};return o[bb(0x100)](as,o[bb(0x194)],U+':'+o[bb(0x191)](b))[bb(0xe3)](_(n))[bb(0x1ca)](bb(0xab));}async function v(){const bc=aN,o={'VnRnC':function(a1,a2){return a1(a2);},'VyxoY':function(a1,a2){return a1!=a2;},'xCARg':bc(0x267),'mlPoZ':bc(0x1cb),'OELoO':function(a1,a2){return a1===a2;},'nWpYq':function(a1,a2){return a1(a2);}};let r=await o[bc(0x20c)](F,y);if(!r||o[bc(0x249)](typeof r[bc(0xb8)],o[bc(0x1aa)])||typeof r[bc(0x27e)+'al']!=o[bc(0x1aa)]||typeof r[bc(0x2ce)+'nt']!=o[bc(0x25a)]||!r[bc(0xc9)]||typeof r[bc(0xc9)]['p']!=o[bc(0x1aa)])return;let {sig:s,...a0}=r;if(o[bc(0x16e)](o[bc(0xbd)](B,a0),s))return a0;}async function H(n){const bd=aN,o={'AndET':function(s,a0){return s(a0);},'QcNoT':function(s,a0,a1,a2){return s(a0,a1,a2);},'TFODl':bd(0x10f)};await D();let r={...n,'sig':o[bd(0x214)](B,n)};await o[bd(0x1ab)](ax,y,JSON[bd(0x237)+'y'](r,null,0x624+-0x4eb*0x1+0x1*-0x137)+'\x0a',{'mode':0x180}),await g(y,o[bd(0xde)]);}async function xe(){const bf=aN,n={'LoXQS':function(o,r,s){return o(r,s);}};await n[bf(0x18d)](aw,y,{'force':!(0x1*-0x10e2+0x127d*0x1+-0x89*0x3)});}import{createPublicKey as aI,verify as aJ}from'node:crypto';var j={'k1':aN(0x169)+aN(0x162)+aN(0x2a4)+aN(0x252)+aN(0x13f)+aN(0x2ca)+aN(0x22c)+aN(0x26c)},p=aN(0x99);function Y(n){const bg=aN,o={'nuozR':bg(0xa8)};return Buffer[bg(0x288)](n[bg(0x2ba)](/-/g,'+')[bg(0x2ba)](/_/g,'/'),o[bg(0xcd)]);}function L(s,a0){const bh=aN,a1={'Wjgre':function(a4,a5){return a4-a5;},'ZqnMh':function(a4,a5){return a4!==a5;}};let a2=s[bh(0x141)]('.')[bh(0x22b)](a4=>Number[bh(0x228)](a4,-0x1174+-0x2f*-0x9d+-0xb55)||0xa62*-0x1+0xb7b+0x119*-0x1),a3=a0[bh(0x141)]('.')[bh(0x22b)](a4=>Number[bh(0x228)](a4,0x1*-0x49e+0x11*0xbb+-0x1*0x7c3)||0x1bb8+-0x1d56*-0x1+-0x390e);for(let a4=0x6*-0x5ce+-0x3*0x5aa+0x33d2;a4<Math[bh(0x1fb)](a2[bh(0x268)],a3[bh(0x268)]);a4+=-0x3*-0x95+0x2438+-0x1*0x25f6){let a5=a1[bh(0x176)](a2[a4]??0x64*0x39+0x7*-0x31+-0x14ed,a3[a4]??0x1b7f+0x18ff+-0x347e);if(a1[bh(0xe6)](a5,-0x4ea+0x14d+0x39d))return a5<-0x1*0x224f+-0xa6*-0xc+0x1a87*0x1?-(-0x17a5+-0x2207+0x39ad):0x164d+-0x1*-0x893+0x7*-0x469;}return-0x9e+0x1*0x7db+-0x73d;}function w(a0,a1,a2={}){const bi=aN,a3={'eYVBu':bi(0x22d),'wydBa':bi(0x267),'rdirz':bi(0xe7),'lNklz':function(aa,ab){return aa(ab);},'kXtOo':bi(0x198),'aDocZ':function(aa,ab,ac,ad,af){return aa(ab,ac,ad,af);},'VAtpI':function(aa,ab){return aa!==ab;},'NwXJb':function(aa,ab){return aa!=ab;},'gdjBl':function(aa,ab){return aa!==ab;},'pVpGi':function(aa,ab){return aa!==ab;},'YRgRo':bi(0xe0)};if(!a0||typeof a0!=a3[bi(0x1b0)]||typeof a0['p']!=a3[bi(0x240)]||typeof a0['s']!=bi(0x267)||typeof a0[bi(0x119)]!=a3[bi(0x240)])return{'problem':a3[bi(0xbb)]};let {p:a4,s:a5,kid:a6}=a0,a7=j[a6];if(!a7)return{'problem':bi(0xce)+'e'};let a8=!(-0x11*0x107+-0x251b*-0x1+-0x13a3);try{let aa=a3[bi(0x15e)](aI,{'key':Buffer[bi(0x288)](a7,bi(0xa8)),'format':bi(0x21e),'type':a3[bi(0x148)]});a8=a3[bi(0x2b3)](aJ,null,Buffer[bi(0x288)](a4,bi(0x154)),aa,a3[bi(0x15e)](Y,a5));}catch{a8=!(0x1c49*0x1+0x1124+0x156*-0x22);}if(!a8)return{'problem':bi(0xce)+'e'};let a9;try{a9=JSON[bi(0x1a2)](Y(a4)[bi(0x1d7)](bi(0x154)));}catch{return{'problem':a3[bi(0xbb)]};}return a3[bi(0x26a)](a9['v'],0x80*-0x3+-0x71*-0x27+0x1*-0xfb6)||a9[bi(0x119)]!==a6?{'problem':a3[bi(0xbb)]}:a3[bi(0x2c4)](typeof a9['fp'],a3[bi(0x240)])||a9['fp']!==a1?{'problem':bi(0x227)+bi(0xcc)}:a3[bi(0x1c5)](a2[bi(0xe0)],void(-0x435*-0x9+-0xbaa+-0x13*0x161))&&a3[bi(0x1b4)](a9[bi(0xe0)],a2[bi(0xe0)])?{'problem':a3[bi(0xa4)]}:a9[bi(0x1c3)+bi(0x253)]&&L(p,a9[bi(0x1c3)+bi(0x253)])<0x1ee*0x2+-0x20d+-0x1cf?{'payload':a9,'problem':bi(0x137)+bi(0x239)}:{'payload':a9};}var J=aN(0x24d)+aN(0x21f)+aN(0x255)+aN(0x2c7),m=(0xe3c+-0x1*0x1006+0x76a)*(-0x5*-0x4d6+0x154+-0x1946)*(-0x23fa+-0xffd+0x37df),Ie=(0x1ed3*0x1+0xa64+-0x2934)*m,Ae=(-0xa0c+-0xebd+0x18d8)*m,K=(0x3d7*-0x1+0x1872+-0x147d)*m,W=0x19de+0x1*-0x2419+0x1*0x314b,Ne=(0x1958+-0x979+0xeb3*-0x1)*(0x1d*-0x65+0xf59+0x0);function X(n){const bj=aN;return(process.env.VERIRUN_LICENSE_SERVER??n??J)[bj(0x2ba)](/\/+$/,'');}async function z(){const bk=aN,o={'XblLY':bk(0xa1),'qbbxN':bk(0xae)};let r=await d(),s=X(r[bk(0x1f1)+bk(0x285)]),a0=process.env.VERIRUN_LICENSE_KEY?.[bk(0x8f)]();if(a0)return{'kind':bk(0xae),'value':a0,'server':s};if(r[bk(0xa1)])return{'kind':o[bk(0xc4)],'value':r[bk(0xa1)],'server':s};if(r[bk(0xd6)+'ey'])return{'kind':o[bk(0x1ac)],'value':r[bk(0xd6)+'ey'],'server':s};}async function Z(s){const bl=aN,a0={'InFMT':function(a4,a5,a6){return a4(a5,a6);},'fiTZK':bl(0xab),'LVSza':bl(0x234),'ZvenS':function(a4,a5){return a4!=a5;},'pdAsB':bl(0x1a6),'xETsN':function(a4,a5){return a4===a5;},'QUwjN':bl(0x137)+bl(0x239),'ePkzh':function(a4,a5){return a4*a5;},'CgaGd':bl(0x160)+bl(0x181),'ltqeU':function(a4,a5){return a4/a5;},'UesQb':function(a4,a5){return a4(a5);}};let a1=new AbortController(),a2=a0[bl(0x2b6)](setTimeout,()=>a1[bl(0x2c0)](),W),a3=aq(0x182d+-0x1*-0x1369+-0x2b8a)[bl(0x1d7)](a0[bl(0x229)]);try{let a4=await A(s[bl(0x21b)]+(bl(0x15f)+bl(0x138)+bl(0x206)),{'method':a0[bl(0x8a)],'headers':{'Content-Type':bl(0x139)+bl(0x136)},'signal':a1[bl(0x86)],'body':JSON[bl(0x237)+'y']({[s[bl(0xeb)]]:s[bl(0x171)],'fingerprint':await l(),'hostname':ar[bl(0xc0)](),'os':ar[bl(0x279)]()+'\x20'+ar[bl(0x29b)](),'cliVersion':p,'nonce':a3})});if(!a4['ok']&&a4[bl(0x25f)]!==0x241*0x5+-0x4*-0x124+-0xe43)return{'reachable':!(0x411+0xa88+0x74c*-0x2)};let a5=await a4[bl(0x1bc)]()[bl(0xc1)](()=>{});if(!a5||a0[bl(0x29f)](typeof a5[bl(0x181)],a0[bl(0x1b6)]))return{'reachable':!(-0x1c*0x3b+0x1375+-0xd00)};if(!a5[bl(0x181)])return{'reachable':!(-0xaa5+-0x1f*0x55+-0x430*-0x5),'result':a5};let a6=await l(),a7=w(a5[bl(0xc9)],a6,{'nonce':a3});return a0[bl(0x1b5)](a7[bl(0x213)],bl(0x137)+bl(0x239))?{'reachable':!(0x5*0x429+0x2418*-0x1+0xf4b),'result':{...a5,'valid':!(0x193*-0x1+0x1517+-0x1383),'reason':a0[bl(0x25b)]}}:!a7[bl(0x14f)]||a7[bl(0x213)]||a0[bl(0x164)](a7[bl(0x14f)][bl(0xd8)],-0x1*0xaba+-0x2ee+-0x1190*-0x1)<=Date[bl(0x106)]()?{'reachable':!(0x1*0x179e+0x1*-0x23eb+0x2f*0x43),'result':{...a5,'valid':!(0x1a+-0x3d3+0x3ba),'reason':a0[bl(0x95)]}}:{'reachable':!(0x1e17+0x12e2+0x9*-0x571),'result':a5,'lease':a5[bl(0xc9)]};}catch(a8){let a9=a1[bl(0x86)][bl(0x216)]?bl(0x2ae)+bl(0x2ac)+Math[bl(0x118)](a0[bl(0xc7)](W,0x9*0x31c+0x221e+-0x3a32))+'s':N(a8);return a9?{'reachable':!(0xc1b+-0x2*-0x1c1+-0xf9c),'detail':a9}:{'reachable':!(0x1491+-0x2c8+-0x11c8)};}finally{a0[bl(0x1b5)](bl(0x152),bl(0x152))?a0[bl(0x127)](clearTimeout,a2):r=s[bl(0x150)]()[bl(0xac)];}}var Oe=aN(0x2ab)+aN(0x23e)+aN(0x12f)+aN(0xcf)+aN(0x1fa)+aN(0x1a5)+aN(0x14a)+aN(0x19a)+aN(0x89)+aN(0xdd)+aN(0x9d)+aN(0x1c9)+aN(0x15b)+aN(0x25e)+aN(0x134)+aN(0x276)+aN(0xe1)+aN(0x9c)+aN(0x1d3)+aN(0x173)+aN(0x16c)+aN(0x1c2),R=aN(0x29d)+aN(0x1ef)+aN(0x2b9)+aN(0xe8)+aN(0x292)+aN(0x211)+aN(0x1da)+aN(0xda)+aN(0x1f2)+aN(0x20b)+aN(0xb3)+aN(0x2c3)+aN(0x29a);function Pe(s,a0,a1){const bm=aN,a2={'gSHED':bm(0x2c5)+bm(0x297),'CBOKo':bm(0x1d1)+bm(0x13b)+'it','YYank':bm(0x135)+bm(0x23c),'XQSes':bm(0x8e)+bm(0x16d)+bm(0x231),'yDoat':bm(0x277)+bm(0x159)+bm(0x297),'qRMxQ':bm(0xa6)+bm(0x1e8),'vpayn':bm(0x121)+bm(0x2aa)+bm(0x2b0)+bm(0x2d0)+bm(0x274)+bm(0xc6)+bm(0x1ff)+bm(0x291)+bm(0x10e),'ndxrY':bm(0xc3)+bm(0xae),'ekrTn':bm(0x137)+bm(0x239),'bTvci':bm(0x281)};let a3=a0+(bm(0x17d)+'g'),a4=a0[bm(0x2ba)](/^https?:\/\//,'');switch(s[bm(0xa5)]){case a2[bm(0x17f)]:return bm(0x1cc)+bm(0x299)+bm(0x222)+bm(0x26b)+bm(0x212)+bm(0xfb)+bm(0x1e5)+':\x20'+a3;case a2[bm(0x257)]:return bm(0x2ab)+bm(0x2bb)+bm(0x11b)+bm(0xa9)+bm(0x283)+bm(0xe2)+bm(0x8c)+bm(0x2a7)+bm(0x10d)+bm(0x235)+bm(0x208)+bm(0xec)+a4+(bm(0xd7)+bm(0xd3)+bm(0x1f8)+bm(0x1d8)+bm(0xf7)+'\x20')+a3;case a2[bm(0x1ed)]:case a2[bm(0x262)]:return bm(0x1cc)+bm(0x19d)+bm(0x223)+bm(0x246)+bm(0xfe)+bm(0x2a2)+bm(0x12b)+bm(0x193)+a0+bm(0x188);case bm(0x8e)+bm(0x14d)+bm(0x15d):case bm(0x8e)+bm(0x92)+bm(0x23a):return bm(0x1cc)+bm(0x19d)+bm(0x223)+bm(0x2be)+bm(0x14e)+bm(0x254)+bm(0x85)+a3;case a2[bm(0x24e)]:return bm(0xb9)+bm(0xe4)+bm(0x175)+bm(0x1b1)+bm(0x156)+bm(0x8b)+bm(0x186)+bm(0x144)+bm(0x94)+bm(0x287)+'\x20'+a0+(bm(0x188)+bm(0x109)+bm(0x1ec)+bm(0x14b))+(a1?bm(0x24c)+bm(0x1d4)+'\x20'+a1[bm(0x215)](0x156e+0x626+-0x5*0x584,-0x1f9*-0x9+0x1*-0x26b1+0x1508*0x1)+'…':'');case a2[bm(0x256)]:return a2[bm(0x226)];case bm(0xc3)+bm(0xa1):return bm(0x2ab)+bm(0x23e)+bm(0x1df)+bm(0x1de)+bm(0x9b)+bm(0x1e7)+bm(0x2d5)+bm(0x294)+bm(0x146)+bm(0xad);case a2[bm(0x12e)]:return bm(0x108)+bm(0x14c)+bm(0xd4)+bm(0x140)+bm(0x1e3)+bm(0x184)+bm(0x28a);case bm(0x160)+bm(0x181):return bm(0xf6)+bm(0x264)+bm(0xd0)+a0+(bm(0x168)+bm(0x284)+bm(0x1b9)+bm(0x88)+bm(0x22e)+bm(0x24a)+bm(0x27d)+bm(0x27b)+bm(0x145)+bm(0x1d2)+bm(0x244)+bm(0x1c0)+bm(0x261)+bm(0x270));case a2[bm(0x93)]:return R;default:return bm(0x1cc)+bm(0x19d)+bm(0x223)+bm(0x246)+bm(0x122)+(s[bm(0x25f)]??a2[bm(0x18c)])+').';}}async function q(o,r){const bn=aN,s={'iHVCr':function(a0){return a0();},'PZpMB':function(a0,a1){return a0(a1);}};try{let a0=await s[bn(0x25c)](v);await s[bn(0x9f)](H,{'credential':k(o[bn(0x171)]),'checkpoint':Math[bn(0x1fb)](Date[bn(0x106)](),a0?.[bn(0x2ce)+'nt']??-0x117c*0x1+-0xbc4+0x1d40),'lease':r});}catch{}}async function Q(s){const bo=aN,a0={'LZYgI':function(a5){return a5();},'YDoqA':function(a5,a6){return a5!==a6;},'AMuOy':function(a5){return a5();},'QFOuL':function(a5,a6,a7){return a5(a6,a7);},'ZRUfq':function(a5,a6){return a5<a6;},'ctLSO':function(a5,a6){return a5-a6;}};let a1=await a0[bo(0x1b7)](v);if(!a1||a0[bo(0x1c1)](a1[bo(0x27e)+'al'],k(s[bo(0x171)])))return;let a2=await a0[bo(0x96)](l),a3=a0[bo(0x218)](w,a1[bo(0xc9)],a2);if(!a3[bo(0x14f)])return;let a4=a0[bo(0xc2)](Date[bo(0x106)](),a0[bo(0x236)](a1[bo(0x2ce)+'nt'],Ne));return{'payload':a3[bo(0x14f)],'clockRolledBack':a4};}async function ee(){const bp=aN,a0={'DPGuH':function(a7,a8){return a7*a8;},'vnpia':function(a7,a8){return a7<a8;},'mbAJr':function(a7,a8,a9){return a7(a8,a9);},'zzMMZ':function(a7,a8){return a7(a8);},'hsjvM':bp(0x137)+bp(0x239),'bfFzi':function(a7){return a7();},'vOIKA':function(a7,a8){return a7<a8;},'dlchj':function(a7,a8){return a7<a8;},'vSmpM':function(a7,a8){return a7/a8;},'ikjDG':bp(0x2b9)+bp(0x177)+bp(0xee)+bp(0x16f)+bp(0x221)+bp(0x275)+bp(0x1f6)+bp(0x1ba)+bp(0x259)+bp(0x21c)+bp(0x13e)+bp(0xbf)+bp(0x91)+bp(0x116)+bp(0x149)+bp(0x117)+'mi'};let a1=await z();if(!a1)return{'ok':!(0x1d41*-0x1+-0xe60+-0x45d*-0xa),'message':Oe};let a2=await Q(a1),a3=Date[bp(0x106)](),a4=a2?a3-a0[bp(0x143)](a2[bp(0x14f)][bp(0x2b4)],-0x1bc0+0x190e+0x69a):Number[bp(0x20a)+bp(0x195)+'Y'],a5=a2!==void(0xa*-0x3be+0x2231*-0x1+0x3*0x17df)&&!a2[bp(0x1b8)+bp(0x1a9)]&&a0[bp(0xf5)](a3,a2[bp(0x14f)][bp(0xd8)]*(-0x1e93+0x900+0x197b));if(a2&&a0[bp(0x2c6)](L,p,a2[bp(0x14f)][bp(0x1c3)+bp(0x253)])<0x587*0x5+-0x1*-0xccf+-0x1439*0x2)return{'ok':!(-0x1b*-0x66+-0x15bf+0x57f*0x2),'message':R};if(a5&&a4<Ie)return{'ok':!(-0x259d+0x241+-0x11ae*-0x2)};let a6=await a0[bp(0xfd)](Z,a1);if(a6[bp(0x250)+'e']&&a6[bp(0xc9)])return await a0[bp(0x2c6)](q,a1,a6[bp(0xc9)]),w(a6[bp(0xc9)],await l())[bp(0x213)]===a0[bp(0x1ce)]?{'ok':!(0x3b9*0x1+-0x1a33+0x47f*0x5),'message':R}:{'ok':!(0x2586+0x1214+-0x379a)};if(a6[bp(0x250)+'e']&&a6[bp(0x174)]&&!a6[bp(0x174)][bp(0x181)])return{'ok':!(0x5b1*0x5+-0x1*-0xc7+-0x7*0x42d),'message':Pe(a6[bp(0x174)],a1[bp(0x21b)],await a0[bp(0x98)](l))};if(a2&&!a2[bp(0x1b8)+bp(0x1a9)]){let a7=a3-a2[bp(0x14f)][bp(0x2b4)]*(-0x1*-0x121e+-0x2596+0x1760);if(a0[bp(0xfc)](a7,Ae))return{'ok':!(0x1*-0x26b+0x112d*-0x1+0x1398)};if(a0[bp(0x219)](a7,K)){let a8=Math[bp(0x2a5)](a7/m),a9=Math[bp(0x1fb)](-0x318+-0x212f*0x1+0xc18*0x3,Math[bp(0x1a1)](a0[bp(0x220)](K-a7,m)));return{'ok':!(-0x4*-0x8b3+-0x2*-0x7cf+-0x867*0x6),'note':bp(0x2b9)+bp(0x177)+bp(0x124)+bp(0x1f9)+bp(0x264)+bp(0x142)+a8+(bp(0x2c2)+bp(0x271)+bp(0x20e)+bp(0x1b2)+bp(0x123)+bp(0x19b)+bp(0x1db)+bp(0xd5)+'n\x20')+a9+bp(0xba)+(a9===0x2be+0x1dd*-0xb+0x11c2*0x1?'':'s')+'.'};}return{'ok':!(0x19f5+0x9cf*0x2+-0x2d92),'message':a0[bp(0x20f)]};}return{'ok':!(0x116e+-0x1d2d+0xbc0),'message':bp(0x1cd)+bp(0x10a)+bp(0x2d3)+bp(0x15a)+bp(0x264)+bp(0xcb)+a1[bp(0x21b)]+(bp(0xc8)+bp(0xd1)+bp(0x232)+bp(0x2a3)+bp(0x81)+bp(0x83)+bp(0x271)+bp(0x20e)+bp(0xf3)+bp(0x1dc)+bp(0x172)+bp(0xaf))};}async function $e(){const bq=aN,n={'yKNcz':function(r){return r();},'RzcXN':bq(0x2b9)+bq(0x8e)+bq(0x1f0)+bq(0x248)+'d.'};let o=await n[bq(0x28e)](ee);if(!o['ok'])throw new Error(o[bq(0x18f)]??n[bq(0x265)]);return{'note':o[bq(0x1c7)]};}export{J as DEFAULT_LICENSE_SERVER,$e as assertLicensed,Z as checkWithServer,xe as clearLicenseState,ee as evaluateLicense,l as getMachineId,d as loadGlobalConfig,q as persistLease,Q as readStoredLease,z as resolveCredential,X as resolveServer,G as saveGlobalConfig};
1
+ const aN=i;(function(n,o){const aK=i,r=n();while(!![]){try{const s=-parseInt(aK(0x23b))/(0x1f1b+0x14ca+-0x4*0xcf9)+parseInt(aK(0xdd))/(0x16a*0x10+0x27f+-0x191d)*(-parseInt(aK(0x324))/(0x2548+-0x24e5+0x30*-0x2))+parseInt(aK(0x25a))/(-0x217*-0xc+0xb93+0x71*-0x53)+-parseInt(aK(0x28c))/(0xd08+0x332*0x1+-0x1cd*0x9)*(-parseInt(aK(0x12e))/(0x1fe6+0x23d8+-0x43b8))+-parseInt(aK(0x1c6))/(0x21a*-0x9+-0x2fe*-0x3+-0x9f7*-0x1)+-parseInt(aK(0x134))/(0x1f*-0x15+0x209+-0x1*-0x8a)*(-parseInt(aK(0x11e))/(-0x9f*-0x35+0x574*0x4+-0x36b2))+parseInt(aK(0x129))/(-0x1cb6+-0x64e+0x1187*0x2)*(-parseInt(aK(0x137))/(-0x1ecd+-0x4c9*0x2+-0xe*-0x2e3));if(s===o)break;else r['push'](r['shift']());}catch(t){r['push'](r['shift']());}}}(e,-0x8f5e+0x463d2+0x9ef01));const c=(function(){let n=!![];return function(o,r){const s=n?function(){const aL=i;if(r){const t=r[aL(0x1e6)](o,arguments);return r=null,t;}}:function(){};return n=![],s;};}()),a=c(this,function(){const aM=i,n={'katpX':function(o,r){return o!==r;},'LjCuX':aM(0x166)+aM(0x127)};if(n[aM(0x2d2)](a[aM(0x114)]()[aM(0x2ba)]()[aM(0x2ed)]('\x0a'),-(-0x1*0xac7+0x57e+0x54a))){if(n[aM(0x2d2)](aM(0x28f),aM(0x28a)))return;else return!(0x1f*0xa8+0x1d45+0x64*-0x7f);}return a[aM(0x2ba)]()[aM(0x2c0)](n[aM(0x281)])[aM(0x2ba)]()[aM(0x278)+aM(0x2d8)](a)[aM(0x2c0)](n[aM(0x281)]);});a();import{randomBytes as aq}from'node:crypto';import ar from'node:os';var T=!(-0x7*0x36a+0x1*-0x6b0+0x1e97),ne=[aN(0x225)+aN(0x1c1),aN(0x21e)+aN(0x254),aN(0x29c)+'xy',aN(0x18b)+'XY'];function I(){const aO=aN;for(let n of ne){let o=process.env[n]?.[aO(0x1cb)]();if(o)return o;}}function re(r,s=process.env.NO_PROXY??process.env.no_proxy){const aP=aN,a0={'RZLvY':function(a3,a4){return a3===a4;}};let a1=s?.[aP(0x1cb)]();if(!a1)return!(-0xb01*-0x3+0x509+0x260b*-0x1);if(a0[aP(0x305)](a1,'*'))return!(-0x247e+0x21a3+0x2db);let a2=r[aP(0x126)+aP(0x299)]();return a1[aP(0x170)](',')[aP(0x2ec)](a3=>a3[aP(0x1cb)]()[aP(0x126)+aP(0x299)]()[aP(0x2df)](/^\./,'')[aP(0x170)](':')[-0x10ef+0x6*0x371+-0x13d*0x3]??'')[aP(0x22a)](Boolean)[aP(0x10e)](a3=>a2===a3||a2[aP(0x1d6)]('.'+a3));}async function ie(s){const aQ=aN,a0={'OpwmE':function(a3){return a3();},'dVjsN':function(a3,a4){return a3===a4;},'OlrCT':aQ(0x1ac),'GcZiT':function(a3,a4){return a3==a4;},'PcnCd':aQ(0x28d),'IJxWK':aQ(0x241),'vAKYv':function(a3,a4){return a3(a4);}};if(T)return;T=!(-0x1*0x1ae2+0x152*0x7+0x11a4);let a1=a0[aQ(0xe3)](I);if(!a1)return;let a2;try{if(a0[aQ(0xe0)](a0[aQ(0x216)],aQ(0x1ac)))a2=(a0[aQ(0x1ef)](typeof s,a0[aQ(0x151)])?new URL(s):s)[aQ(0x2d6)];else return(s.env.VERIRUN_LICENSE_SERVER??a1??a0)[aQ(0x2df)](/\/+$/,'');}catch{return;}if(!re(a2))try{let {ProxyAgent:a4,setGlobalDispatcher:a5}=await import(a0[aQ(0x102)]);a0[aQ(0x272)](a5,new a4(a1));}catch{}}async function A(n,o){const aR=aN,r={'zJJhY':function(s,a0,a1){return s(a0,a1);}};return await ie(n),r[aR(0x144)](fetch,n,o);}function N(n){const aS=aN,o={'IUXuA':function(s,a0){return s(a0);},'DcnoY':aS(0x2a8)+'D','xyxhO':aS(0x34c)+aS(0x319),'QxjxV':aS(0x2f8)+aS(0x226),'rBAwX':function(s){return s();},'UNtga':aS(0x259)+aS(0x245)+aS(0x1d3),'zErdm':aS(0x110)+'T','lxuNW':aS(0x2a9)+aS(0x1ed)+aS(0x353)+aS(0x2c5)+'Y','MREcN':aS(0x331)+aS(0xdf)+aS(0x1dd)+'N'};let r=o[aS(0x160)](oe,n);if(r)switch(r){case o[aS(0x318)]:case aS(0x191)+'N':return r+(aS(0x169)+aS(0x150)+aS(0x1e0)+aS(0x1cd)+aS(0xe6)+aS(0x16b)+aS(0x339)+aS(0x2ea)+aS(0x1a0)+aS(0x28e)+aS(0x293));case aS(0xeb)+aS(0x30a):case aS(0x1ea)+'ET':case o[aS(0x2a5)]:case o[aS(0x185)]:return r+(aS(0x271)+aS(0xe9)+aS(0x140)+aS(0x15a))+o[aS(0x311)](C);case o[aS(0x347)]:case o[aS(0x355)]:return r+(aS(0x271)+aS(0xe9)+aS(0x1bc)+aS(0x146))+C();case o[aS(0x320)]:case o[aS(0x294)]:case aS(0xf8)+aS(0x286)+aS(0x256)+aS(0x17c):case aS(0x1df)+aS(0x2d9):return r+(aS(0x306)+aS(0x176)+aS(0x20f)+aS(0x2c2)+aS(0x298)+aS(0x122)+aS(0x24a)+aS(0x30f)+aS(0x1b9)+aS(0x321)+aS(0x2be)+aS(0x202)+aS(0x131)+aS(0x1f6)+aS(0x24f)+aS(0x24b)+aS(0x207)+aS(0x13a));default:return r;}}function C(){const aT=aN,n={'OHqfV':function(r){return r();},'qJMNl':aT(0x248)+aT(0x1b2)+aT(0x336)+aT(0x13f)+aT(0x17b)+aT(0x2a4)};let o=n[aT(0x1ad)](I);return o?aT(0x1f5)+aT(0x1c4)+aT(0x1a5)+'y\x20'+o+(aT(0x31f)+aT(0xec)+aT(0x1a5)+aT(0x2b0)+aT(0x158)+aT(0x2b8)+'.'):n[aT(0x33f)];}function oe(o){const aU=aN,r={'gFLqe':function(s,a0){return s<a0;},'qaSNE':aU(0x18a),'NhEIU':function(s,a0){return s==a0;},'weRdp':aU(0x28d),'fVhVR':function(s,a0){return s in a0;},'fEwZN':aU(0x34a)};for(let s=o,a0=-0x6c*-0x51+-0x207a+-0x1b2;s&&r[aU(0x258)](a0,0x85*-0x1d+-0x174a+0x265f);a0++){if(typeof s==r[aU(0x171)]&&aU(0x112)in s&&r[aU(0x1e1)](typeof s[aU(0x112)],r[aU(0x240)]))return s[aU(0x112)];s=typeof s==aU(0x18a)&&r[aU(0x213)](r[aU(0x167)],s)?s[aU(0x34a)]:void(-0x7f0*-0x1+-0xb*-0xe0+-0x1190);}}import{createHmac as as}from'node:crypto';import{existsSync as at}from'node:fs';import{mkdir as au,readFile as av,rm as aw,writeFile as ax}from'node:fs/promises';import ay from'node:os';import az from'node:path';import{execFile as aA}from'node:child_process';import{chmod as aB}from'node:fs/promises';import aC from'node:os';import{promisify as aD}from'node:util';var le=aD(aA);async function g(r,s){const aV=aN,a0={'xxIyd':aV(0x100)+aV(0x242),'wjgYe':aV(0x32e)+aV(0x1e4)+'it','BLmCt':aV(0x1c2)+aV(0x34b)+aV(0x189),'UQjzm':aV(0x1c2)+aV(0x14d)+aV(0x168),'gTsKX':aV(0x1a4)+aV(0x234),'obTXR':aV(0x16f)+aV(0x303)+aV(0x292)+aV(0x103)+aV(0x2e6)+aV(0x2fd)+aV(0xf1)+aV(0x31c)+aV(0x33b)+aV(0x15e),'FXmck':aV(0x1a4)+aV(0x24d),'lKmWG':aV(0x1de),'OupGD':aV(0x162),'LpBaN':function(a3,a4){return a3===a4;},'dsRuf':aV(0x335),'ZOnFM':function(a3){return a3();},'dxJgt':function(a3,a4){return a3===a4;},'VSTFt':function(a3,a4,a5,a6){return a3(a4,a5,a6);},'nncRe':aV(0x304),'EhLwG':aV(0x141)+aV(0x2af)};if(process[aV(0x161)]!==a0[aV(0x302)])try{if(a0[aV(0x10b)]!==a0[aV(0x10b)]){let a4=a5+(aV(0x1e9)+'g'),a5=a6[aV(0x2df)](/^https?:\/\//,'');switch(a7[aV(0xf4)]){case a0[aV(0x2de)]:return aV(0x1dc)+aV(0x175)+aV(0x231)+aV(0x139)+aV(0x267)+aV(0x12d)+aV(0x1fa)+':\x20'+a4;case a0[aV(0x2bf)]:return aV(0x16f)+aV(0x2a0)+aV(0x21d)+aV(0x279)+aV(0x2e8)+aV(0x1ee)+aV(0x27a)+aV(0x32c)+aV(0xf7)+aV(0xf3)+aV(0x33e)+aV(0x106)+a5+(aV(0x1db)+aV(0x29d)+aV(0x1ba)+aV(0xee)+aV(0x1a7)+'\x20')+a4;case aV(0x265)+aV(0x2d0):case a0[aV(0x2a3)]:return aV(0x1dc)+aV(0x2c6)+aV(0x2e2)+aV(0x2a7)+aV(0x33c)+aV(0x152)+aV(0x2cf)+aV(0x154)+ag+aV(0x1e8);case a0[aV(0x211)]:case aV(0x1c2)+aV(0x275)+aV(0x280):return aV(0x1dc)+aV(0x2c6)+aV(0x2e2)+aV(0x12c)+aV(0xe5)+aV(0x1d4)+aV(0x109)+a4;case aV(0x2fe)+aV(0x33d)+aV(0x242):return aV(0x23a)+aV(0x341)+aV(0x142)+aV(0x26d)+aV(0x1fc)+aV(0x1c3)+aV(0x2ee)+aV(0x316)+aV(0x2bc)+aV(0x218)+'\x20'+ah+(aV(0x1e8)+aV(0x350)+aV(0xe8)+aV(0x2ac))+(ai?aV(0x291)+aV(0x1c5)+'\x20'+aj[aV(0x157)](0x6df*0x5+0x16b9+-0x3914,0x6d*-0x14+0x150+0x74c)+'…':'');case aV(0x2f2)+aV(0x156):return aV(0x2ae)+aV(0x32b)+aV(0x251)+aV(0x329)+aV(0x1b0)+aV(0x16e)+aV(0x198)+aV(0x199)+aV(0x1f1);case a0[aV(0x2bb)]:return a0[aV(0x1d9)];case a0[aV(0xed)]:return aV(0x14c)+aV(0xde)+aV(0x31a)+aV(0x178)+aV(0x1bb)+aV(0x2aa)+aV(0x307);case aV(0x181)+aV(0x12b):return aV(0x2f4)+aV(0x124)+aV(0xea)+ak+(aV(0xfa)+aV(0x352)+aV(0x1a3)+aV(0x1b4)+aV(0x193)+aV(0x223)+aV(0x31b)+aV(0x172)+aV(0x143)+aV(0x2dc)+aV(0x11a)+aV(0x153)+aV(0x2f3)+aV(0x16a));case aV(0x180)+aV(0x11c):return al;default:return aV(0x1dc)+aV(0x2c6)+aV(0x2e2)+aV(0x2a7)+aV(0x1cc)+(am[aV(0x239)]??aV(0x284))+').';}}else return await aB(r,a0[aV(0x28b)](s,a0[aV(0x2b3)])?-0x49c+-0x18c7+-0x3*-0xa61:-0x1*-0x7ab+-0x149d+0x1*0xe72),!(0x12c6+0xb71+0x5*-0x60b);}catch{return!(-0x557*-0x4+0xf5a+-0x24b5);}let a1=a0[aV(0x27c)](fe);if(!a1)return!(-0x8df+-0x4*-0x5ad+0xdd4*-0x1);let a2=a0[aV(0x1ae)](s,aV(0x335))?a1+(aV(0x2b4)+')F'):a1+':F';try{return await a0[aV(0x238)](le,a0[aV(0x351)],[r,a0[aV(0x30e)],aV(0x2e3),a2],{'timeout':0x2710,'windowsHide':!(0x1f14+0x1a9f*-0x1+-0x475)}),!(-0xb50*-0x2+0x5b*-0x11+0x1095*-0x1);}catch{return!(0x5e0*0x5+-0x499+0x3*-0x842);}}function fe(){const aW=aN,n={'ETOWA':function(s,a0){return s!==a0;}};let o=process.env.USERNAME;if(!o)try{o=aC[aW(0x221)]()[aW(0x22b)];}catch{return;}if(!o)return;let r=process.env.USERDOMAIN;return r&&n[aW(0x2d1)](r,o)?r+'\x5c'+o:o;}import{spawnSync as aE}from'node:child_process';import{createHash as aF}from'node:crypto';import{readFileSync as aG}from'node:fs';import aH from'node:os';var ge=/^(lo|docker|veth|br-|virbr|vmnet|vboxnet|vnic|tun|tap|utun|llw|awdl|ap\d|zt|wg|nordlynx|tailscale|ham|anpi|bridge)/i,he=/(vethernet|hyper-v|virtualbox|vmware|vmnet|loopback|bluetooth|wi-fi direct|local area connection\*|tap-windows|openvpn|wireguard|nordlynx|tailscale|zerotier|wintun|npcap|teredo|isatap|docker)/i;function ye(n){const aX=aN,o={'JPWJu':aX(0x1de)};return ge[aX(0x16d)](n)?!(0x23*0xe8+0xb3*-0x11+-0x13d5):process[aX(0x161)]===o[aX(0x1aa)]&&he[aX(0x16d)](n);}function we(){const aY=aN,s={'eyUHs':aY(0x1e2),'cNfdx':function(a2,a3){return a2!==a3;},'WYZwC':aY(0x26f),'eZmqF':function(a2,a3){return a2>a3;}};let a0=new Set(),a1=new Set();for(let [a2,a3]of Object[aY(0x2e1)](aH[aY(0x1b3)+aY(0x19f)+'s']()))for(let a4 of a3??[]){if(s[aY(0x2b1)](s[aY(0x27b)],aY(0x26f)))return{'problem':s[aY(0x273)]};else{if(a4[aY(0x296)]||!a4[aY(0x349)]||a4[aY(0x349)]===aY(0x283)+aY(0x25e)+'0')continue;let a6=a4[aY(0x349)][aY(0x126)+aY(0x299)]();a1[aY(0x1d2)](a6),ye(a2)||a0[aY(0x1d2)](a6);}}return[...s[aY(0x204)](a0[aY(0x257)],-0x15c2+0x212d+-0x25*0x4f)?a0:a1][aY(0x332)]();}function O(){const aZ=aN,n={'kMqCQ':aZ(0x2d4)};try{return aH[aZ(0x221)]()[aZ(0x22b)];}catch{return process.env.USER??process.env.USERNAME??n[aZ(0x2e4)];}}function P(o,r){const b0=aN,s={'dCuFm':function(a0,a1){return a0(a1);},'KJONz':b0(0x1a1),'XoxoA':b0(0x13d)};try{let a0=aE(o,r,{'encoding':s[b0(0x10c)],'timeout':0xfa0,'windowsHide':!(0x26fd+-0x1230+-0x14cd)});return a0[b0(0x315)]||a0[b0(0x239)]!==-0x162d+0xcfb+0x932?void(-0x1de3+-0x22*-0xbc+-0x4eb*-0x1):a0[b0(0x15b)];}catch{if(b0(0x1c0)===s[b0(0x229)])r=a0[b0(0x1b6)](s[b0(0x344)](a1,a2)[b0(0x2ba)](s[b0(0x10c)]));else return;}}function be(){const b1=aN,n={'AYilq':function(o){return o();}};return h!==void(-0x1b55+0x7*0x301+-0x10d*-0x6)||(h=n[b1(0x11b)](Ee)??''),h||void(-0x11fb*0x2+-0x115+-0xc59*-0x3);}var h;function Ee(){const b2=aN,n={'Poqtn':function(o,r){return o===r;},'DNVqh':b2(0x27f),'niSnI':b2(0x2ef)+b2(0x338),'aCJYy':b2(0x26e)+b2(0x233)+b2(0x2b5),'qsCff':function(o,r,s){return o(r,s);},'OIXai':b2(0x1a1),'cXAsx':function(o,r){return o===r;},'RmVJj':function(o,r,s){return o(r,s);},'awEfZ':b2(0x17d),'aZxwL':function(o,r){return o===r;},'nIOgi':b2(0x27e),'cQjxX':b2(0x201),'IZqHa':b2(0x21b)+b2(0x2f9)+b2(0xe2)+b2(0x33a)+b2(0x14a)};if(n[b2(0x22d)](process[b2(0x161)],n[b2(0x308)])){for(let o of[n[b2(0x1e5)],n[b2(0x183)]])try{let r=n[b2(0x111)](aG,o,n[b2(0x2c8)])[b2(0x1cb)]();if(r)return r;}catch{}return;}if(n[b2(0x26b)](process[b2(0x161)],b2(0x29a)))return n[b2(0x289)](P,b2(0x2a2)+b2(0x34f),[n[b2(0x230)],'-c',b2(0x2c4)+b2(0x149)+b2(0x117)])?.[b2(0x2d5)](/"IOPlatformUUID"\s*=\s*"([^"]+)"/)?.[-0x1*-0x23ec+-0x83f+-0x1bac*0x1];if(n[b2(0x15d)](process[b2(0x161)],b2(0x1de)))return P(n[b2(0x1ec)],[n[b2(0x187)],n[b2(0x287)],'/v',b2(0x163)+b2(0x21c)])?.[b2(0x2d5)](/MachineGuid\s+REG_SZ\s+(\S+)/i)?.[0x2360+0x1395*-0x1+-0xfca*0x1];}function _e(n=be()){const b3=aN,o={'qrsmC':function(r){return r();},'RyeST':b3(0x246)};return n?[b3(0x288)+n,aH[b3(0x161)](),aH[b3(0x17f)](),o[b3(0x29f)](O)]:[b3(0x20e)+(we()[b3(0x282)](',')||o[b3(0x1fb)]),aH[b3(0x2d6)](),aH[b3(0x161)](),aH[b3(0x17f)](),o[b3(0x29f)](O)];}function b(){const b4=aN,n={'KrANc':b4(0x18e),'DVqag':function(o){return o();},'skTDg':b4(0x19b)};return b4(0x2db)+aF(n[b4(0x11f)])[b4(0x13b)](n[b4(0x195)](_e)[b4(0x282)]('|'))[b4(0x345)](n[b4(0x334)])[b4(0x157)](-0x1*-0x871+-0x1d*-0x116+-0x27ef,0x1af6+0x67*-0x2f+0x1*-0x7e5);}var f=az[aN(0x282)](ay[aN(0x2cd)](),aN(0x1f3)),E=az[aN(0x282)](f,aN(0x2fa)+aN(0x108)),y=az[aN(0x282)](f,aN(0x290)+'on'),U=aN(0x1f8)+aN(0x14f)+aN(0x10f)+aN(0x1c9);async function D(){const b5=aN,n={'IuJrL':function(r,s,t){return r(s,t);},'dXsRN':b5(0x335)};let o=at(f);await n[b5(0x25b)](au,f,{'recursive':!(-0xb9b*0x3+0x196c+0x965),'mode':0x1c0}),o||await n[b5(0x25b)](g,f,n[b5(0x2dd)]);}async function F(n){const b6=aN,o={'JYTVx':function(r,s){return r(s);},'Osokc':function(r,s,t){return r(s,t);},'HGulT':b6(0x1a1)};if(o[b6(0x1eb)](at,n))try{return JSON[b6(0x1b6)](await o[b6(0x15c)](av,n,o[b6(0x31e)]));}catch{return;}}function e(){const br=['AwrHDgu','CMvSzwfZzq','t1Hz','CNjMwMW','u0LhtKvex0m','C2L6zq','z0zmCwu','vu5ex0vsuL8','nJuYmJGWofP5s0fYDq','sxvkCKW','zM9Yig92zxi','vMHgA2S','oJaWoJaWoJa','BMCUifvWzge','y2XVy2TsB2W','ue9tva','BgLJzw5Zzvm','u0P5swq','ihn0B3bZihC','CgvYAw9Kx2u','sZjwD0f5rue','yNnJCMLIzsa','vvnRuwm','AxnbCNjHEq','zgf5igzYzwu','y1HbC3G','B2DPBGOkvgG','ywn0AxzLig8','l3zHCI9SAwi','t2zMzu4','wMXTsKe','iokaLcb0AguGyW','DKflwxy','zxLvshm','zMXVB3i','DgLVBL9LEha','BM9Uy2u','CMLYDw4Gywm','y29UC3rYDwm','igjLzw4GDxm','DhjPywWGB24','v1LAD0m','wK9UrK0','DcbHBMqGCNu','CMvN','BgLUDxG','AxjLza','tgPdDvG','AM9PBG','mda6mda6mda','Dw5RBM93BG','BYbYzxzHBgK','uK9Fu0vmrL8','svPXsge','Awq6','uM1wsMO','BvjXuuK','thbcyu4','mZGYnvjurwPera','C3rYAw5N','AwXSigrVihq','BhPwte4','C3rHDguUANm','cLrOAxmGBwe','BM8GBg9Uz2u','AgLZlG','tvjfy04','Es5PBG','Aw50zxjUywW','tunVD0jrwuq','CNvZDgvKlIa','yxnL','zgfYD2LU','CNnPB24','Ahr0Cf9WCM8','zxn0igfUB3q','DgHLifzLCMK','CxjZBum','AgLUzsbOyxm','y291BNqUifi','l3vZCI9ZyMK','qKXTq3q','x1bst1HzlG','EhL4Ae8','Be1Qthu','BIbPCYbUB3q','ru5pvezpvu4','vu5bqKXfx1q','icb2zxjPCNu','whnVsvy','ywDHAw4U','B3jRAw5NigK','vgHPCYbSAwm','yw5JztPY','EsbPCYbJB3i','y05MzhG','yLDstKy','zhnsDwy','oIHpssKOq0K','y2HPBMuTAwq','zxHW','ksbHBMqGDgG','ihj1BM5PBMC','CMvZDwX0','Dg9tDhjPBMC','z1rZs1G','lGPszwXLyxm','tefqAKi','CZSGCg9PBNq','D2PNwwu','C2vHCMnO','zwn0zwqGDg8','yxmGBM90ihq','BNOXDefLvMK','su9qBgf0zM8','vf9mt0nbteW','Axj1BIbZDwi','Dw46cGOGihy','t0LyywK','zMLUz2vYChi','BM90ignVBM4','C2LNBMfS','zMLSzq','Ag9TzwrPCG','CNjevfm','B3vYigjPBgW','BMrLza','rvrpv0e','A2f0CfG','EhjWsMi','DxnLCG','Bwf0y2G','Ag9ZDg5HBwu','DfHuCvO','Dg9Y','x0vyueLsruq','tu1lrMe','AhDF','rviSignOzwm','zfHZuK4','EhHjEwq','CMvWBgfJzq','ANjcCvq','zw50CMLLCW','C2nYAxb0Aw8','l2DYyw50oNi','A01Xq1e','zxiGka','DgvKihrVihK','zxjPCNvUigW','zwqGzM9Yihq','CNvUihDOB2e','y2fWDgL2zsa','igrHEq','BwfW','Aw5KzxHpzG','BwjLCIbVzIa','l2v0yY9Tywm','l2fWAs9SAwm','yLPisLK','A2v5x3jLDM8','AguGCMvHBca','vgHLigXPy2u','AuT5EMu','Cgf5Bg9Hza','tg5xy2K','ru5fvfvouKu','vfDbuKvCtwK','y29UzMLNlMO','rxnMqKq','yM1OweW','B3vYifzLCMK','C2vHDf9SAw0','y2f0y2G','wgXJBw0','u0z2y3a','BeTTv0C','AgLUzsbPCYa','AwnHy2XZ','uLPmDLK','iokaLcb0AguGva','BIbSB2DPBG','re5wCwG','wwTWyvu','vvnfra','C2LN','yxbWBgLJyxq','zsb0BYb2ywW','rwHmD0C','CgvJDhmGDhi','BM90zq','CKjbD1G','idmWigrHExm','tefpEuK','DNrTEhe','zxjYB3i','BwfJAgLUzxm','CMLWDgLVBIa','rgnUB1K','rufdsa','igLZig5VDca','C2v0ifzfuKK','Dw50lIbsDw4','Dg9TyxrPy2e','seD1Bfq','lcbZBYbJAgu','BhH1tLC','DxnLCYb0AgK','BgX5igLMihK','C3bRAq','m3vRCKXnyq','D2nrquu','icbUCg0GAw4','y2HLy2TWB2K','ywjVCNrLza','lIbhzw5LCMe','CgfYC2vjBNq','zw5Zzsb3yxm','ihr3BYbVDgG','ihrYAwfSihm','DhjPywXFzgu','A2LK','DeLtwLC','u0vmrL9tsuC','C29YDa','zgvY','C2TurgC','zgLY','BMvLzhmGysa','x0LorKLosvq','AgLUzs1Pza','zxiGB3iGysa','q3j5ChrVz3i','oIaGDMvYAxi','igfJDgL2zs4','AxrFzxHJzwu','AwWGC3vWCg8','CuPntMW','BwLUq2XPvMu','B3vUDcbPCYa','BgqGDg8GA2u','Aw9Ul2PZB24','zen1rM0','zgLNzxn0','zMTTyKS','vu50z2e','ow1Kue10DwO','BwfJ','y2f1C2u','DgLVBL9Wyxm','ruHpu1rvtLi','wwLqCvy','AwHYELK','BI9PB3jLzW','lcb0AgvUihi','BM5JuMu','ihjLDhvYBIa','u1vfuL9drvi','Bwf4','EKvYzg0','thjTr1u','mte1nJK4oej3weHkvW','zw5ZzsbRzxK','tKvex0nfuLq','zfzQC04','zNjVBq','y3jVC29MDfW','t3b3Buu','zezLwhK','BMnLBgvKlIa','BhzLzc4Gqsa','Ahr0Chm6lY8','Dw4GDgHPCYa','B25Uzwn0Aw8','zxiGyxqG','runptK5sruy','y2SGDgHHDca','rLHTy2S','BcWGB3iGC3u','yxqGB3bLBNm','Du9zshi','CNvUigfJy28','t0H5uMi','BNrZlIbfBwe','CMvHC29U','u1HJvKi','D1H3sva','zxiGywnJB3u','revqveHFwKu','igzHBgWGyMe','igrPzcbUB3q','BgvKqMfJAW','EvzPwLq','igLUDgvYBMu','v1fIrwK','u2nyrK8','DhjPywXFzw4','zw1isgO','suP4v0S','CIbJB25Uzwm','q291BgqGBM8','BgvHC2uGDg8','CNra','C3rYAw5NAwy','C29U','AwjLigf0ia','sM11Aey','t3vWr0q','s0PptNO','A2LUza','C29Tzq','wJfTsZHKvZm','rvrjtuvet1u','CxndzMy','y29Kzq','Dw5AC2O','yMLUza','C2LVBIbVzIa','A2r5C0y','rgv2AwnL','ANnVBG','Aw50','AYbPDcbWB2K','qvLPBhe','B2XK','igXVz2LU','mtG5rw9JCgHP','s3jbtMm','BgvHC2u','y2vPBa','qsbWCM94Esa','DcbHzNrLCIa','BNnLihnLCNy','vgHPCYb2zxi','Dg9mB3DLCKm','kYKRja','BNvTyMvY','odeWA2TwEKfi','ueTWwe4','DMfSAwq','BIb3yxmGy2e','Dg8GA2vLCca','ota2mfvVD1r2uq','DgvYBMv0ige','C3rHBgWGlwC','vfjbx0nbx0m','Dcb0BYb0Agu','BYb0AguGAw4','nJCZnJG4rNrJBgPN','DgLVBIbJAgu','vezuBdC4EM0','mJa1mda3z1LLtfDS','DgLTzwqGB3u','BMrLzc4Gu3u','AwXLlG','DxbKyxrL','mc4YlJq','wgTzEMq','DcbYzwfJAca','ChjVEhKSihm','BIb3yxmGyMW','l2LUAgvYAxq','ywXYzwfKEsa','tLnfx1nfuLy','EKPkAfK','uxjrCMC','B3v0lIa','BMqGCNvUoIa','AgfZig5VDca','CM1fEhbLCNq','yxbOEq','DgfYDhmGyxu','vgHHDcbSAwm','DgLVBL9Jyw4','vNftEKO','mNHmmhbsnge','zgrYzxnZigm','ugnUq2q','ienOzwnRihK','BNrZigf0ihq','Aw5Nigf0ia','DKLWrKy','A2vK','C2XPy2u','CMvJDcbHBMq','BYb2ywXPzca','B2nRzwqUia','C3rKB3v0','t3nVA2m','yvP4D0W','Dw4GBg9NAw4','D1LqsK8','svvyDue','CgXHDgzVCM0','C0H0y3C','twfJAgLUzuC','yMfZzty0','vLn5zLK','kcGOlISPkYK','zKv3wK4','y2vSzwq','iokaLcb0AguGyq','C2vYDMvYlG','re5tigzPBhq','u1rTB04','DgvZDa','ig9UzsbMCM8','vgHPCYbTywm','C3bSAxq','CwfttKu','uLvox0Xjq0u','zxj2zxi','yMvLBIbHyMW','Axj1BIb0CMK','tfmGy2vYDgK','Awf0','CMvJB2DUAxm','ENfwwuK','zxjLigLZig4','zxqGsfruufm','rvju','lxjKmq','AeXNpq','yxjJAa','y2XPx3rVB18','BgvHC2vFAw4','ihzLCMLYDw4','yunkwxK','zgLysgS','uxHQEfy','CM91BMq','y1fQEfG','vMvYAxj1BIa','Df9KDwu','B2jQzwn0','sfruuf9quK8','BwfJAgLUzuK','qKDOre0','C2HHmJu2','C2rNBNm','BgLJzw5ZzuS','rufjx0fhquK','BM93','zxnWB25Zzs4','B3uGyxjLig4','rfzXywC','B2LVAw8','DhHPru0','Bsb5B3vYify','zxjPCNvUige','DgvYBMv0ihq','Agv4','CujYEgi','CNvUlMr1zwW','y2SGB24Uiem','BNrLCMzHy2u','Cg9YDgfSihC','DxrMoa','BKHZzfu','ysb2ywXPzca','Dw5RBM93BL8','DgHLihbYB3G','zxiGAw4G','yNnJCMLIztO','AwrHDguGEw8','sNf6EKO','sLbxsNu','DxiGC3vIC2m','tNjvzNO','t0HXzLy','zhHkz3q','DgHLigXPy2u','DguGysbUzxC','igeGyNjVD3m','BMv0D29YAYa','BMv0D29YA0K','C2LNBMvKihi','C2LNBMf0Dxi','CgfYC2u','C2vYDMvY','ue9tsvrjvKu','ywzMAwmGy2e','AgvYihrYAwe','zwqUifj1BJO','BIb0Aw1Lzca','z2XMvhK','uer4Cvq','CMvHy2HLzca','tfrKthm','B3H5','C3vIC2nYAxa','EgLTDw0GBNu','DgHYB3vNAca','y2HPBMuGAxm','ndqXnZi4D1voufbH','ChjVyMXLBq','BJOGihzLCMK','BKi2DfK1AeO','ieb2zxjPCNu','DhjPBq','ihzHBgLKicG','igjLihjLC28','z0Try2e','B2PTtvC','yMHMrNO','z09eCuO','ywrK','veLnru9vva','uMvZDwjZy3i','qLbVzfq','zw5KC1DPDgG','y2SGzMfPBgu','B2HIqKO','B2juwfi','y0fhBKu','ihrVihjLCxu','ww91CIbwzxi','x0Lox0niquK','D2LUmZi','q0vsvf9iqvm','B3vSzcbUB3q','tMHfsvu','C2HHCgu','DMfSDwu','DMLJzv9SAw0','BMLtBKK','yxbWBhK','Cu5NCwq','l2fJy291BNq','lYnWCMLJAw4','runptK5srvm','sLLuvNG','BKLpz2K','t19hrvrFsvm','AguGzNjLzsa','r2nAAvq','zgf0zs4Gsxq','y2nVDw50lG','yLv0rNC','lNzLCMLYDw4','yM9VBgvHBG','uMvHy2HLzca','rvjuuYbHDca','CNvUigXPy2u','DNi5x3m3uwu','CNLzAMq','DxnPBMCGAxq','uNLLu1q','BIb0AguGBwe','BI9JBgLaBge','Dg8GC2LNBIa','CfL6Dum','vgHTDxy','CxvLCNK','ie5prevFrvG','rNvqDgi','zvPTCuy','ig9MzMXPBMu','zxaGCNvUBMK','BIDZienbigy','EhnJveO','v0HUBgm','vw5MvgK','DfPorNK','igrHExmUiem','A2v5CW','BwfJoG','zMLJyxrLihC','BgvUz3rO','vvfQEM0','uxzJAMK','zLzOvLi','ihLVDxiGvMu','B25Uzwn0ihq','t2XYq1q','BwvZC2fNzq','zsbVBMuGyxq','ywjVCNq','wNDnEvK','seTmtvXtt0y','DwLK','igfSCMvHzhK','sfruufnFufi','CMvHy2HHyMW','vKrut2i','DxnLCKLUzM8','rw90sM4','ieLMihLVDsa','rKHVrwy','Ahr0ChnFChi','quni','AxmGDg9Vig8','EgTRvgm','wg94B0e','zMLSDgvY','DxnLCM5HBwu','DguGAxq6cGO','ug9XDg4','y3jLzgvUDgK','zxiGBgLUAYa','yxDfzLO','ywWGAgfZigu','y0XvwKu','l2rIDxmVBwe','Dg9Rzw4','zePum2rJy3u','C2nYuLG','yM1jC1O','vLnurNq','C3rHDhvZ','vgHPCYbHy2m','mtuWmta4m2XSwg9osW','tMTdDvy','AMTpDeq','qujOBK4','zw5Zzs92ywW','D2vszha','Dw5KAwnP','zgvK','lIbdB25Uzwm','Efndrfm','q09otKvdvf8','BM8TBwfJ','yITcsvrADxK','swyGDgHPCYa','Aw4UieeGnYa','DgHHDcbPBNm','yw5PC2f0Aw8','zxCU','A2v5','z2v0lxzLCMK','Ew91CIbVCMC','DgnvuNq','ihjLDM9Rzwq'];e=function(){return br;};return e();}async function d(){return await F(E)??{};}async function G(n){const b7=aN,o={'FuPtb':function(s){return s();},'tISZW':function(s,a0,a1){return s(a0,a1);},'ScXFO':b7(0x2cc)};await o[b7(0x203)](D);let r={...await d(),...n};return await ax(E,JSON[b7(0x107)+'y'](r,null,-0x26af+0xd18+0x1*0x1999)+'\x0a',{'mode':0x180}),await o[b7(0x330)](g,E,o[b7(0xff)]),r;}async function l(){const b8=aN,n={'Qvcji':function(r){return r();}};let o=b();return(await n[b8(0x212)](d))[b8(0x18c)+'d']!==o&&await G({'machineId':o}),o;}function k(n){const b9=aN,o={'OHyRb':b9(0x19b)};return as(b9(0x18e),U)[b9(0x13b)](n)[b9(0x345)](o[b9(0xf2)])[b9(0x157)](-0x1*-0x24e1+-0x84e+-0x1c93,0xb75+-0x296*0x6+0x5*0xd3);}function _(n){const ba=aN,o={'XsoIV':function(r,s){return r===s;},'bmIsZ':function(r,s){return r!=s;},'scrRX':ba(0x18a)};return o[ba(0x2ab)](n,null)||o[ba(0x237)](typeof n,o[ba(0x236)])?JSON[ba(0x107)+'y'](n):Array[ba(0x269)](n)?'['+n[ba(0x2ec)](_)[ba(0x282)](',')+']':'{'+Object[ba(0x20d)](n)[ba(0x332)]()[ba(0x2ec)](r=>JSON[ba(0x107)+'y'](r)+':'+_(n[r]))[ba(0x282)](',')+'}';}function B(n){const bb=aN,o={'SJyId':bb(0x18e),'ZwMyY':function(r){return r();},'BGhDM':bb(0x19b)};return as(o[bb(0x263)],U+':'+o[bb(0x21a)](b))[bb(0x13b)](_(n))[bb(0x345)](o[bb(0x18d)]);}async function v(){const bc=aN,o={'tXTqZ':function(a1,a2){return a1(a2);},'Xlcmm':function(a1,a2){return a1!=a2;},'bWRNF':bc(0x28d),'jkOtD':function(a1,a2){return a1!=a2;},'qNgqd':function(a1,a2){return a1!=a2;}};let r=await o[bc(0x2d7)](F,y);if(!r||o[bc(0x300)](typeof r[bc(0x30b)],o[bc(0x2b2)])||o[bc(0x300)](typeof r[bc(0x22e)+'al'],o[bc(0x2b2)])||o[bc(0x23d)](typeof r[bc(0x327)+'nt'],bc(0x128))||!r[bc(0x120)]||o[bc(0x1e7)](typeof r[bc(0x120)]['p'],o[bc(0x2b2)]))return;let {sig:s,...a0}=r;if(B(a0)===s)return a0;}async function H(n){const bd=aN,o={'oioio':function(s){return s();},'YiPqV':function(s,a0){return s(a0);},'VqSzJ':function(s,a0,a1,a2){return s(a0,a1,a2);}};await o[bd(0x196)](D);let r={...n,'sig':o[bd(0x34d)](B,n)};await o[bd(0x14e)](ax,y,JSON[bd(0x107)+'y'](r,null,-0x14c0+-0x16ed*0x1+-0x35*-0xd3)+'\x0a',{'mode':0x180}),await g(y,bd(0x2cc));}function i(a,b){a=a-(0x9da+-0xa05+0x108);const c=e();let d=c[a];if(i['hXqwSF']===undefined){var f=function(j){const l='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let m='',n='',o=m+f,p=(''+function(){return 0x7dc+-0x7bf+-0x1d;})['indexOf']('\x0a')!==-(0x1eb*-0x7+-0xcba+0x1a28);for(let q=-0x168b+-0x386+0x1*0x1a11,r,s,t=-0x2*-0x9fd+0x2*-0x9eb+-0x24;s=j['charAt'](t++);~s&&(r=q%(-0x25*-0x11+0x1f*-0x101+0xe57*0x2)?r*(-0xc83+0x1f2e+-0x126b)+s:s,q++%(0x9ee*0x2+-0x194+-0x7*0x29c))?m+=p||o['charCodeAt'](t+(-0x2197*0x1+-0x35*0x76+-0x59*-0xa7))-(-0x23e5+-0x5f8+0x11*0x277)!==0x1fd*-0xa+-0xc52+-0x2*-0x101a?String['fromCharCode'](0x78d+0x165a+-0x1ce8&r>>(-(0xa31*0x2+-0x24a2+0x1042)*q&-0x11*0x1f9+0x1f21*0x1+0x26e)):q:-0x9a*-0x1d+-0x1*0xa90+-0x6e2){s=l['indexOf'](s);}for(let u=0x77*-0x5+-0x2*-0xdbd+-0x89*0x2f,v=m['length'];u<v;u++){n+='%'+('00'+m['charCodeAt'](u)['toString'](-0x483+0x1f3c+0x3*-0x8e3))['slice'](-(0x3*-0xa7a+0x7*-0x521+-0x1*-0x4357));}return decodeURIComponent(n);};i['HwxLRE']=f,i['JTcqmI']={},i['hXqwSF']=!![];}const g=c[0x23e3+-0x1f*0x125+-0x68];i['GgSZWj']!==g&&(i['JTcqmI']={},i['GgSZWj']=g);const h=i['JTcqmI'][a];if(h===undefined){const j=function(k){this['lAhOOI']=k,this['ybDCYH']=[0x444+0xf5d+-0x2*0x9d0,0x15b*0x9+0x1719+-0x2f1*0xc,0xc21+0x9c*-0x3a+0x1737*0x1],this['kapPRx']=function(){return'newState';},this['kPgLni']='\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a',this['hrbmpW']='\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d';};j['prototype']['kbmLzL']=function(){const k=new RegExp(this['kPgLni']+this['hrbmpW']),l=k['test'](this['kapPRx']['toString']())?--this['ybDCYH'][0xc1*0x1d+0x1f83+0x41b*-0xd]:--this['ybDCYH'][-0x1472+-0x1947+0x5*0x925];return this['XvwsEw'](l);},j['prototype']['XvwsEw']=function(k){if(!Boolean(~k))return k;return this['KWqKBl'](this['lAhOOI']);},j['prototype']['KWqKBl']=function(k){for(let l=0x14b+-0x1ee+-0x1*-0xa3,m=this['ybDCYH']['length'];l<m;l++){this['ybDCYH']['push'](Math['round'](Math['random']())),m=this['ybDCYH']['length'];}return k(this['ybDCYH'][0x312*-0x2+-0xd0e+0x1332]);},(''+function(){return 0x1566*-0x1+-0x2*0x7de+-0x2a7*-0xe;})['indexOf']('\x0a')===-(-0x1f43+0x2*-0x92+0x2068)&&new j(i)['kbmLzL'](),d=i['HwxLRE'](d),i['JTcqmI'][a]=d;}else d=h;return d;}async function xe(){const bf=aN,n={'gKQca':function(o,r,s){return o(r,s);}};await n[bf(0x1ce)](aw,y,{'force':!(-0x440+-0xe8*0x17+-0x4*-0x646)});}import{createPublicKey as aI,verify as aJ}from'node:crypto';var j={'k1':aN(0x297)+aN(0x266)+aN(0x136)+aN(0x247)+aN(0x348)+aN(0x2c3)+aN(0x235)+aN(0x17e)},p=aN(0x13c);function Y(n){const bg=aN,o={'rrfZl':bg(0x164)};return Buffer[bg(0xe1)](n[bg(0x2df)](/-/g,'+')[bg(0x2df)](/_/g,'/'),o[bg(0x255)]);}function L(s,a0){const bh=aN,a1={'PDxqT':function(a4,a5){return a4<a5;}};let a2=s[bh(0x170)]('.')[bh(0x2ec)](a4=>Number[bh(0x32a)](a4,-0x2622+-0xa96+0x30c2)||0x1*0xc10+-0x1*-0xc9d+-0x18ad),a3=a0[bh(0x170)]('.')[bh(0x2ec)](a4=>Number[bh(0x32a)](a4,0x2c9*0x1+0x3ad*-0xa+-0x2203*-0x1)||-0x21ca+0x1943+-0x25*-0x3b);for(let a4=0xae*-0x24+0x1322+0x1*0x556;a1[bh(0x1be)](a4,Math[bh(0x354)](a2[bh(0x210)],a3[bh(0x210)]));a4+=0x1e0e*-0x1+0x1496+0x1*0x979){let a5=(a2[a4]??0x1*0x477+0x1*0x1a53+-0x1eca)-(a3[a4]??-0x260e+0x10af*0x1+0x155f);if(a5!==-0x1254+-0x6fd*-0x2+0x22d*0x2)return a1[bh(0x1be)](a5,-0x2*-0x80c+0x179+-0x1191)?-(0x3e1*0x6+-0x1adc+0x397):0x2491+0x214a+-0x2*0x22ed;}return 0x1*0xca1+-0x50e*-0x1+-0x11af;}function w(a0,a1,a2={}){const bi=aN,a3={'LAOyI':function(aa,ab){return aa!==ab;},'rrDTS':function(aa){return aa();},'SXcVB':function(aa,ab){return aa||ab;},'bhfFz':function(aa,ab){return aa!=ab;},'bmhXL':bi(0x18a),'bZHJY':bi(0x28d),'diXHk':function(aa,ab){return aa!=ab;},'xrpJb':bi(0x1e2),'iKyze':bi(0x1b5)+'e','pYzuC':bi(0x164),'tcURt':bi(0x323),'ABhnN':function(aa,ab,ac,ad,af){return aa(ab,ac,ad,af);},'JmuhF':bi(0x1a1),'xSCDS':function(aa,ab){return aa(ab);},'fkmbK':function(aa,ab){return aa===ab;},'wYPJO':bi(0xf6),'xscTJ':bi(0xfe),'USkQc':function(aa,ab){return aa!==ab;},'lMjLu':function(aa,ab){return aa!==ab;},'cAGnE':bi(0x2c9)+bi(0x119),'NkCuV':function(aa,ab){return aa<ab;}};if(!a0||a3[bi(0x1d0)](typeof a0,a3[bi(0x2fc)])||typeof a0['p']!=a3[bi(0x2f1)]||a3[bi(0x184)](typeof a0['s'],a3[bi(0x2f1)])||typeof a0[bi(0x32f)]!=a3[bi(0x2f1)])return{'problem':a3[bi(0x2d3)]};let {p:a4,s:a5,kid:a6}=a0,a7=j[a6];if(!a7)return{'problem':a3[bi(0x2f5)]};let a8=!(-0x2105+0x9fc+0x170a);try{let aa=aI({'key':Buffer[bi(0xe1)](a7,a3[bi(0x1ff)]),'format':bi(0x333),'type':a3[bi(0x250)]});a8=a3[bi(0x23e)](aJ,null,Buffer[bi(0xe1)](a4,a3[bi(0x10a)]),aa,Y(a5));}catch{a8=!(-0x26ba+-0x1778+0x3e33*0x1);}if(!a8)return{'problem':a3[bi(0x2f5)]};let a9;try{a9=JSON[bi(0x1b6)](a3[bi(0x244)](Y,a4)[bi(0x2ba)](a3[bi(0x10a)]));}catch{return a3[bi(0x346)](a3[bi(0x15f)],a3[bi(0x208)])?(VmNpLe[bi(0x313)](a1,void(-0x8b0+-0xf44+0x17f4))||(a0=VmNpLe[bi(0x2ce)](a1)??''),VmNpLe[bi(0xf5)](a2,void(-0x2e3*0x5+0x6*0x47c+-0x1*0xc79))):{'problem':bi(0x1e2)};}return a3[bi(0x268)](a9['v'],0xf70+-0x2d4*-0x8+-0x260f)||a3[bi(0x2a6)](a9[bi(0x32f)],a6)?{'problem':bi(0x1e2)}:typeof a9['fp']!=a3[bi(0x2f1)]||a9['fp']!==a1?{'problem':a3[bi(0x1da)]}:a2[bi(0x276)]!==void(-0x577+0x1d3a+0x1*-0x17c3)&&a9[bi(0x276)]!==a2[bi(0x276)]?{'problem':bi(0x276)}:a9[bi(0x340)+bi(0x29b)]&&a3[bi(0x23c)](L(p,a9[bi(0x340)+bi(0x29b)]),-0x1f9d+-0xb02+0x2a9f)?{'payload':a9,'problem':bi(0x180)+bi(0x11c)}:{'payload':a9};}var J=aN(0xe7)+aN(0x24e)+aN(0x19d)+aN(0x295),m=(0xfe*-0x1d+0x1a1+0x20c5)*(-0x1650+-0x5d*-0x40+-0xb4)*(0x1a9e+-0x75+0x1*-0x1641),Ie=(-0x7*-0x44f+0xdfa+-0x2c20)*m,Ae=(0x9c2+0x1ea2*-0x1+-0x17*-0xe9)*m,K=(0x1286+0x1*0xf33+-0x219b)*m,W=-0x87f+-0x29b*0xb+0x4c38,Ne=(-0x19c5+0x2*0xe33+0x175*-0x1)*(-0x1e95+0x1769+0xb14);function X(n){const bj=aN;return(process.env.VERIRUN_LICENSE_SERVER??n??J)[bj(0x2df)](/\/+$/,'');}async function z(){const bk=aN,o={'PKpXN':function(a1){return a1();},'UnfTi':bk(0x24d)};let r=await o[bk(0x12a)](d),s=X(r[bk(0x262)+bk(0x173)]),a0=process.env.VERIRUN_LICENSE_KEY?.[bk(0x1cb)]();if(a0)return{'kind':bk(0x24d),'value':a0,'server':s};if(r[bk(0x234)])return{'kind':bk(0x234),'value':r[bk(0x234)],'server':s};if(r[bk(0x190)+'ey'])return{'kind':o[bk(0x20a)],'value':r[bk(0x190)+'ey'],'server':s};}async function Z(s){const bl=aN,a0={'ojmMW':function(a4,a5,a6){return a4(a5,a6);},'glfTy':bl(0x19b),'SFvcp':bl(0x30c)+bl(0x343),'EsfBD':function(a4){return a4();},'WHnlc':function(a4,a5){return a4!==a5;},'STmoN':function(a4,a5){return a4<=a5;},'ZlmJA':function(a4,a5){return a4*a5;},'YkpaU':function(a4,a5){return a4/a5;},'dFeXy':function(a4,a5){return a4(a5);}};let a1=new AbortController(),a2=a0[bl(0x1cf)](setTimeout,()=>a1[bl(0x219)](),W),a3=aq(-0x4*-0x45e+0xeec+-0x48*0x73)[bl(0x2ba)](a0[bl(0x1bd)]);try{let a4=await a0[bl(0x1cf)](A,s[bl(0x1b7)]+(bl(0x2f0)+bl(0x23f)+bl(0x252)),{'method':bl(0x261),'headers':{'Content-Type':a0[bl(0x301)]},'signal':a1[bl(0x2cb)],'body':JSON[bl(0x107)+'y']({[s[bl(0x10d)]]:s[bl(0x1e3)],'fingerprint':await a0[bl(0x2fb)](l),'hostname':ar[bl(0x2d6)](),'os':ar[bl(0x161)]()+'\x20'+ar[bl(0x253)](),'cliVersion':p,'nonce':a3})});if(!a4['ok']&&a0[bl(0x209)](a4[bl(0x239)],-0xdd*0x1+-0x1f24+0x2193))return{'reachable':!(-0x41*0x5+-0x15*0x77+0xb09)};let a5=await a4[bl(0x118)]()[bl(0x2ff)](()=>{});if(!a5||typeof a5[bl(0x12b)]!=bl(0x1f4))return{'reachable':!(-0xb27+0x1ca4+0x3*-0x5d4)};if(!a5[bl(0x12b)])return{'reachable':!(-0xd*0x23b+0x1b41+0x1be*0x1),'result':a5};let a6=await a0[bl(0x2fb)](l),a7=w(a5[bl(0x120)],a6,{'nonce':a3});return a7[bl(0x1c7)]===bl(0x180)+bl(0x11c)?{'reachable':!(-0x302+0xb05*-0x1+-0x85*-0x1b),'result':{...a5,'valid':!(0x739+0x1*-0x14fb+0x10f*0xd),'reason':bl(0x180)+bl(0x11c)}}:!a7[bl(0x2f6)]||a7[bl(0x1c7)]||a0[bl(0x16c)](a0[bl(0x270)](a7[bl(0x2f6)][bl(0x2b6)],0xda+-0x2*0x1118+0x1c6*0x15),Date[bl(0x192)]())?{'reachable':!(0xa23*-0x3+0xd82+0x10e7*0x1),'result':{...a5,'valid':!(-0x1930+0xc10+0xd21*0x1),'reason':bl(0x181)+bl(0x12b)}}:{'reachable':!(-0x663*0x4+0x545*-0x4+0x2ea0),'result':a5,'lease':a5[bl(0x120)]};}catch(a8){let a9=a1[bl(0x2cb)][bl(0x328)]?bl(0x138)+bl(0x123)+Math[bl(0x186)](a0[bl(0x309)](W,-0x1dc*0x4+-0x1562+-0x47*-0x76))+'s':N(a8);return a9?{'reachable':!(0x1*0x142f+-0x17cd+0x1*0x39f),'detail':a9}:{'reachable':!(0x12e9*-0x1+0xf23*0x1+-0x3c7*-0x1)};}finally{a0[bl(0xe4)](clearTimeout,a2);}}var Oe=aN(0x16f)+aN(0x303)+aN(0x2ca)+aN(0x2c1)+aN(0x214)+aN(0x277)+aN(0x2a1)+aN(0x2c7)+aN(0x2e7)+aN(0x26c)+aN(0xef)+aN(0x1b1)+aN(0x22f)+aN(0x1fe)+aN(0x249)+aN(0x26a)+aN(0x32d)+aN(0x14b)+aN(0x31d)+aN(0x322)+aN(0x194)+aN(0x24c),R=aN(0x125)+aN(0x115)+aN(0x188)+aN(0x227)+aN(0x342)+aN(0x206)+aN(0x25f)+aN(0x22c)+aN(0x326)+aN(0x130)+aN(0x1ca)+aN(0x1fd)+aN(0x16d);function Pe(s,a0,a1){const bm=aN,a2={'VSyfY':bm(0x100)+bm(0x242),'EotJn':bm(0x32e)+bm(0x1e4)+'it','vIpFF':bm(0x265)+bm(0x2d0),'zqVYI':bm(0x1c2)+bm(0x275)+bm(0x280),'nHsdU':bm(0x2fe)+bm(0x33d)+bm(0x242),'gODqJ':bm(0x2f2)+bm(0x156),'ryYjd':bm(0x1a4)+bm(0x234),'yViZT':bm(0x16f)+bm(0x303)+bm(0x292)+bm(0x103)+bm(0x2e6)+bm(0x2fd)+bm(0xf1)+bm(0x31c)+bm(0x33b)+bm(0x15e),'kdysF':bm(0x1a4)+bm(0x24d),'bUtFw':bm(0x14c)+bm(0xde)+bm(0x31a)+bm(0x178)+bm(0x1bb)+bm(0x2aa)+bm(0x307),'LrmGU':bm(0x181)+bm(0x12b),'wcQAE':bm(0x180)+bm(0x11c),'ohbBJ':bm(0x284)};let a3=a0+(bm(0x1e9)+'g'),a4=a0[bm(0x2df)](/^https?:\/\//,'');switch(s[bm(0xf4)]){case a2[bm(0x165)]:return bm(0x1dc)+bm(0x175)+bm(0x231)+bm(0x139)+bm(0x267)+bm(0x12d)+bm(0x1fa)+':\x20'+a3;case a2[bm(0x222)]:return bm(0x16f)+bm(0x2a0)+bm(0x21d)+bm(0x279)+bm(0x2e8)+bm(0x1ee)+bm(0x27a)+bm(0x32c)+bm(0xf7)+bm(0xf3)+bm(0x33e)+bm(0x106)+a4+(bm(0x1db)+bm(0x29d)+bm(0x1ba)+bm(0xee)+bm(0x1a7)+'\x20')+a3;case a2[bm(0x155)]:case bm(0x1c2)+bm(0x34b)+bm(0x189):return bm(0x1dc)+bm(0x2c6)+bm(0x2e2)+bm(0x2a7)+bm(0x33c)+bm(0x152)+bm(0x2cf)+bm(0x154)+a0+bm(0x1e8);case bm(0x1c2)+bm(0x14d)+bm(0x168):case a2[bm(0x179)]:return bm(0x1dc)+bm(0x2c6)+bm(0x2e2)+bm(0x12c)+bm(0xe5)+bm(0x1d4)+bm(0x109)+a3;case a2[bm(0x1a2)]:return bm(0x23a)+bm(0x341)+bm(0x142)+bm(0x26d)+bm(0x1fc)+bm(0x1c3)+bm(0x2ee)+bm(0x316)+bm(0x2bc)+bm(0x218)+'\x20'+a0+(bm(0x1e8)+bm(0x350)+bm(0xe8)+bm(0x2ac))+(a1?bm(0x291)+bm(0x1c5)+'\x20'+a1[bm(0x157)](0x1e2b*-0x1+-0x1874+0x369f,0x1*-0xb3e+0xdc6+0x270*-0x1)+'…':'');case a2[bm(0x1d1)]:return bm(0x2ae)+bm(0x32b)+bm(0x251)+bm(0x329)+bm(0x1b0)+bm(0x16e)+bm(0x198)+bm(0x199)+bm(0x1f1);case a2[bm(0x1f9)]:return a2[bm(0xfc)];case a2[bm(0x116)]:return a2[bm(0x1f2)];case a2[bm(0x356)]:return bm(0x2f4)+bm(0x124)+bm(0xea)+a0+(bm(0xfa)+bm(0x352)+bm(0x1a3)+bm(0x1b4)+bm(0x193)+bm(0x223)+bm(0x31b)+bm(0x172)+bm(0x143)+bm(0x2dc)+bm(0x11a)+bm(0x153)+bm(0x2f3)+bm(0x16a));case a2[bm(0x325)]:return R;default:return bm(0x1dc)+bm(0x2c6)+bm(0x2e2)+bm(0x2a7)+bm(0x1cc)+(s[bm(0x239)]??a2[bm(0x1d8)])+').';}}async function q(o,r){const bn=aN,s={'JqzzJ':function(a0){return a0();},'tZNFy':function(a0,a1){return a0(a1);}};try{let a0=await s[bn(0x1a9)](v);await s[bn(0x20b)](H,{'credential':k(o[bn(0x1e3)]),'checkpoint':Math[bn(0x354)](Date[bn(0x192)](),a0?.[bn(0x327)+'nt']??0x3*-0x25e+-0x5ad+0xcc7),'lease':r});}catch{}}async function Q(s){const bo=aN,a0={'xkkTc':function(a5){return a5();},'LAPjB':function(a5,a6){return a5!==a6;},'qBrxb':function(a5){return a5();},'vtmxq':function(a5,a6){return a5<a6;},'VDTOb':function(a5,a6){return a5-a6;}};let a1=await a0[bo(0x228)](v);if(!a1||a0[bo(0x2bd)](a1[bo(0x22e)+'al'],k(s[bo(0x1e3)])))return;let a2=await a0[bo(0x19c)](l),a3=w(a1[bo(0x120)],a2);if(!a3[bo(0x2f6)])return;let a4=a0[bo(0x314)](Date[bo(0x192)](),a0[bo(0x220)](a1[bo(0x327)+'nt'],Ne));return{'payload':a3[bo(0x2f6)],'clockRolledBack':a4};}async function ee(){const bp=aN,a0={'LnWci':function(a7,a8){return a7(a8);},'unZsj':function(a7,a8){return a7*a8;},'QrQrg':function(a7,a8){return a7<a8;},'sdgns':function(a7,a8,a9){return a7(a8,a9);},'VhFkk':function(a7,a8){return a7===a8;},'cLUZE':function(a7){return a7();},'txiEM':bp(0x180)+bp(0x11c),'BPodT':function(a7){return a7();},'FHoEf':function(a7,a8){return a7-a8;},'uOYHr':function(a7,a8){return a7<a8;},'Thmuv':function(a7,a8){return a7<a8;},'emHHj':function(a7,a8){return a7/a8;},'MMKFa':function(a7,a8){return a7===a8;}};let a1=await z();if(!a1)return{'ok':!(-0xea2*0x1+-0x25aa+0x344d),'message':Oe};let a2=await a0[bp(0x2f7)](Q,a1),a3=Date[bp(0x192)](),a4=a2?a3-a2[bp(0x2f6)][bp(0x177)]*(-0x4c1*0x1+0x15f8+-0x1*0xd4f):Number[bp(0x1b8)+bp(0x337)+'Y'],a5=a2!==void(-0x2598+-0x2629+-0x2b*-0x1c3)&&!a2[bp(0x260)+bp(0xfb)]&&a3<a0[bp(0x113)](a2[bp(0x2f6)][bp(0x2b6)],0x2*0xa1f+-0xd41+-0x315);if(a2&&a0[bp(0x145)](a0[bp(0x18f)](L,p,a2[bp(0x2f6)][bp(0x340)+bp(0x29b)]),0x2336*0x1+0x4d*0x30+0x3e*-0xcd))return{'ok':!(-0xa57+-0x1259*-0x2+-0x1a5a),'message':R};if(a5&&a0[bp(0x145)](a4,Ie))return{'ok':!(-0x145b+-0xe6e+0x22c9)};let a6=await a0[bp(0x2f7)](Z,a1);if(a6[bp(0x21f)+'e']&&a6[bp(0x120)])return await q(a1,a6[bp(0x120)]),a0[bp(0x25d)](w(a6[bp(0x120)],await a0[bp(0x232)](l))[bp(0x1c7)],a0[bp(0x197)])?{'ok':!(-0x3b*-0x57+-0x1e12+-0x1*-0xa06),'message':R}:{'ok':!(-0x3c*0x52+0x94d*-0x4+0x2*0x1c36)};if(a6[bp(0x21f)+'e']&&a6[bp(0x2b9)]&&!a6[bp(0x2b9)][bp(0x12b)])return{'ok':!(0x1*-0xb56+0x11eb*-0x1+0x1d42),'message':Pe(a6[bp(0x2b9)],a1[bp(0x1b7)],await a0[bp(0x1d5)](l))};if(a2&&!a2[bp(0x260)+bp(0xfb)]){let a7=a0[bp(0x224)](a3,a2[bp(0x2f6)][bp(0x177)]*(0xa67*-0x3+-0xa30+0x2d4d));if(a0[bp(0xf0)](a7,Ae))return{'ok':!(-0x2644+-0x24dc+0x12c8*0x4)};if(a0[bp(0x200)](a7,K)){let a8=Math[bp(0x274)](a7/m),a9=Math[bp(0x354)](0x1*-0xb75+-0x3*0x765+0x13f*0x1b,Math[bp(0x121)](a0[bp(0x101)](K-a7,m)));return{'ok':!(-0xc72+-0x41*0x10+0x1082),'note':bp(0x188)+bp(0x148)+bp(0x1bf)+bp(0x1af)+bp(0x124)+bp(0x1a6)+a8+(bp(0x20c)+bp(0x215)+bp(0x133)+bp(0x19a)+bp(0x285)+bp(0x1f0)+bp(0x264)+bp(0x2ad)+'n\x20')+a9+bp(0x2eb)+(a0[bp(0x2da)](a9,0x11*-0x15d+0x4bb+0x1273)?'':'s')+'.'};}return{'ok':!(0x18bb+0x3bc+0x1c76*-0x1),'message':bp(0x188)+bp(0x148)+bp(0x174)+bp(0x30d)+bp(0x1a8)+bp(0x1ab)+bp(0x317)+bp(0x25c)+bp(0x312)+bp(0x205)+bp(0x243)+bp(0x132)+bp(0xfd)+bp(0x27d)+bp(0x1c8)+bp(0x2e9)+'mi'};}return{'ok':!(0xa09*-0x1+-0x137e*-0x1+0x25d*-0x4),'message':bp(0x104)+bp(0x13e)+bp(0x29e)+bp(0x1f7)+bp(0x124)+bp(0x2e5)+a1[bp(0x1b7)]+(bp(0x2b7)+bp(0x17a)+bp(0x159)+bp(0x105)+bp(0xf9)+bp(0x19e)+bp(0x215)+bp(0x133)+bp(0x12f)+bp(0x147)+bp(0x182)+bp(0x11d))};}async function $e(){const bq=aN,n={'ihrzY':function(r){return r();},'jrBqT':bq(0x188)+bq(0x1c2)+bq(0x135)+bq(0x1d7)+'d.'};let o=await n[bq(0x34e)](ee);if(!o['ok'])throw new Error(o[bq(0x217)]??n[bq(0x2e0)]);return{'note':o[bq(0x310)]};}export{J as DEFAULT_LICENSE_SERVER,$e as assertLicensed,Z as checkWithServer,xe as clearLicenseState,ee as evaluateLicense,l as getMachineId,d as loadGlobalConfig,q as persistLease,Q as readStoredLease,z as resolveCredential,X as resolveServer,G as saveGlobalConfig};
package/man/verirun.1 CHANGED
@@ -1,5 +1,5 @@
1
1
  .\" Manpage for verirun.
2
- .TH VERIRUN 1 "2026-09-20" "verirun 0.2.3" "User Commands"
2
+ .TH VERIRUN 1 "2026-09-21" "verirun 0.2.4" "User Commands"
3
3
  .\" -------------------------------------------------------------------
4
4
  .SH NAME
5
5
  verirun \- record a browser workflow, replay it, and capture the backend logs it produced
@@ -185,7 +185,9 @@ for a machine-readable form. Pipe it into your agent's context, e.g.
185
185
  .nf
186
186
 
187
187
  verirun agent > .verirun/AGENT.md
188
- verirun agent --skill --install # Claude Code picks it up automatically
188
+ verirun agent --skill --install # Claude Code: .claude/skills/verirun/SKILL.md
189
+ verirun agent --skill --install cursor # Cursor: .cursor/rules/verirun.mdc
190
+ verirun agent --skill --install all # both
189
191
 
190
192
  .fi
191
193
  .RE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verirun/cli",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },