diff --git a/coverage/base.css b/coverage/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js new file mode 100644 index 0000000..530d1ed --- /dev/null +++ b/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/browser.ts.html b/coverage/browser.ts.html new file mode 100644 index 0000000..dd2f915 --- /dev/null +++ b/coverage/browser.ts.html @@ -0,0 +1,691 @@ + + + + + + Code coverage report for browser.ts + + + + + + + + + +
+
+

All files browser.ts

+
+ +
+ 58.42% + Statements + 52/89 +
+ + +
+ 75.67% + Branches + 28/37 +
+ + +
+ 80.95% + Functions + 17/21 +
+ + +
+ 58.42% + Lines + 52/89 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203  +  +  +  +  +6x +6x +6x +  +  +  +6x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +12x +12x +  +  +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +14x +14x +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +1x +  +  +1x +  +  +  +  +  +  +  +  +13x +  +  +  + 
import { resolve } from 'node:path';
+import { type Browser, type BrowserContext, type Page, webkit } from 'playwright';
+import type { BrowserCommand, BrowserOptions, CommandResponse, ElementInfo } from './types.js';
+ 
+export class ClaudeBrowser {
+  private browser: Browser | null = null;
+  private context: BrowserContext | null = null;
+  private page: Page | null = null;
+  private options: Required<BrowserOptions>;
+ 
+  constructor(options: BrowserOptions = {}) {
+    this.options = {
+      headless: options.headless ?? true,
+      width: options.width ?? 1280,
+      height: options.height ?? 800,
+    };
+  }
+ 
+  async launch(): Promise<void> {
+    this.browser = await webkit.launch({ headless: this.options.headless });
+    this.context = await this.browser.newContext({
+      viewport: {
+        width: this.options.width,
+        height: this.options.height,
+      },
+    });
+    this.page = await this.context.newPage();
+  }
+ 
+  async close(): Promise<void> {
+    Iif (this.browser) {
+      await this.browser.close();
+      this.browser = null;
+      this.context = null;
+      this.page = null;
+    }
+  }
+ 
+  private ensurePage(): Page {
+    Eif (!this.page) {
+      throw new Error('Browser not launched. Call launch() first.');
+    }
+    return this.page;
+  }
+ 
+  async goto(url: string): Promise<{ url: string; title: string }> {
+    const page = this.ensurePage();
+    await page.goto(url, { waitUntil: 'networkidle' });
+    return { url: page.url(), title: await page.title() };
+  }
+ 
+  async click(selector: string): Promise<{ url: string }> {
+    const page = this.ensurePage();
+    await page.click(selector);
+    await page.waitForLoadState('networkidle').catch(() => {});
+    return { url: page.url() };
+  }
+ 
+  async type(selector: string, text: string): Promise<void> {
+    const page = this.ensurePage();
+    await page.fill(selector, text);
+  }
+ 
+  async query(selector: string): Promise<ElementInfo[]> {
+    const page = this.ensurePage();
+    return page.$$eval(selector, (nodes) =>
+      nodes.map((el) => {
+        const attrs: Record<string, string> = {};
+        for (const attr of el.attributes) {
+          attrs[attr.name] = attr.value;
+        }
+        return {
+          tag: el.tagName.toLowerCase(),
+          text: el.textContent?.trim().slice(0, 200) || '',
+          attributes: attrs,
+        };
+      })
+    );
+  }
+ 
+  async screenshot(path?: string, fullPage = false): Promise<{ path: string; buffer?: Buffer }> {
+    const page = this.ensurePage();
+    const resolvedPath = resolve(path || 'screenshot.png');
+    const buffer = await page.screenshot({ path: resolvedPath, fullPage });
+    return { path: resolvedPath, buffer };
+  }
+ 
+  async getUrl(): Promise<{ url: string; title: string }> {
+    const page = this.ensurePage();
+    return { url: page.url(), title: await page.title() };
+  }
+ 
+  async getHtml(full = false): Promise<string> {
+    const page = this.ensurePage();
+    const html = await page.content();
+    return full ? html : html.slice(0, 10000);
+  }
+ 
+  async back(): Promise<{ url: string }> {
+    const page = this.ensurePage();
+    await page.goBack();
+    return { url: page.url() };
+  }
+ 
+  async forward(): Promise<{ url: string }> {
+    const page = this.ensurePage();
+    await page.goForward();
+    return { url: page.url() };
+  }
+ 
+  async reload(): Promise<{ url: string }> {
+    const page = this.ensurePage();
+    await page.reload();
+    return { url: page.url() };
+  }
+ 
+  async wait(ms = 1000): Promise<void> {
+    const page = this.ensurePage();
+    await page.waitForTimeout(ms);
+  }
+ 
+  async newPage(): Promise<void> {
+    Eif (!this.context) {
+      throw new Error('Browser not launched. Call launch() first.');
+    }
+    this.page = await this.context.newPage();
+  }
+ 
+  async eval(script: string): Promise<unknown> {
+    const page = this.ensurePage();
+    return page.evaluate(script);
+  }
+ 
+  async executeCommand(cmd: BrowserCommand): Promise<CommandResponse> {
+    try {
+      switch (cmd.cmd) {
+        case 'goto': {
+          const result = await this.goto(cmd.url);
+          return { ok: true, ...result };
+        }
+        case 'click': {
+          const result = await this.click(cmd.selector);
+          return { ok: true, ...result };
+        }
+        case 'type': {
+          await this.type(cmd.selector, cmd.text);
+          return { ok: true };
+        }
+        case 'query': {
+          const elements = await this.query(cmd.selector);
+          return { ok: true, count: elements.length, elements };
+        }
+        case 'screenshot': {
+          const result = await this.screenshot(cmd.path, cmd.fullPage);
+          return { ok: true, path: result.path };
+        }
+        case 'url': {
+          const result = await this.getUrl();
+          return { ok: true, ...result };
+        }
+        case 'html': {
+          const html = await this.getHtml(cmd.full);
+          return { ok: true, html };
+        }
+        case 'back': {
+          const result = await this.back();
+          return { ok: true, ...result };
+        }
+        case 'forward': {
+          const result = await this.forward();
+          return { ok: true, ...result };
+        }
+        case 'reload': {
+          const result = await this.reload();
+          return { ok: true, ...result };
+        }
+        case 'wait': {
+          await this.wait(cmd.ms);
+          return { ok: true };
+        }
+        case 'newpage': {
+          await this.newPage();
+          return { ok: true };
+        }
+        case 'close': {
+          await this.close();
+          return { ok: true };
+        }
+        case 'eval': {
+          const result = await this.eval(cmd.script);
+          return { ok: true, result };
+        }
+        default: {
+          const _exhaustive: never = cmd;
+          return { ok: false, error: `Unknown command: ${(_exhaustive as { cmd: string }).cmd}` };
+        }
+      }
+    } catch (err) {
+      return { ok: false, error: (err as Error).message };
+    }
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/clover.xml b/coverage/clover.xml new file mode 100644 index 0000000..7e7092f --- /dev/null +++ b/coverage/clover.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000..15f3f30 --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,5 @@ +{"/Users/chi/Projects/claude-browse/src/browser.ts": {"path":"/Users/chi/Projects/claude-browse/src/browser.ts","statementMap":{"0":{"start":{"line":6,"column":36},"end":{"line":6,"column":null}},"1":{"start":{"line":7,"column":43},"end":{"line":7,"column":null}},"2":{"start":{"line":8,"column":30},"end":{"line":8,"column":null}},"3":{"start":{"line":12,"column":4},"end":{"line":16,"column":null}},"4":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"5":{"start":{"line":21,"column":4},"end":{"line":26,"column":null}},"6":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"7":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"8":{"start":{"line":32,"column":6},"end":{"line":32,"column":null}},"9":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"10":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"11":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"12":{"start":{"line":40,"column":4},"end":{"line":42,"column":null}},"13":{"start":{"line":41,"column":6},"end":{"line":41,"column":null}},"14":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"15":{"start":{"line":47,"column":17},"end":{"line":47,"column":null}},"16":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"17":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"18":{"start":{"line":53,"column":17},"end":{"line":53,"column":null}},"19":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"20":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"21":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"22":{"start":{"line":60,"column":17},"end":{"line":60,"column":null}},"23":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"24":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"25":{"start":{"line":66,"column":4},"end":{"line":78,"column":null}},"26":{"start":{"line":67,"column":6},"end":{"line":77,"column":null}},"27":{"start":{"line":68,"column":46},"end":{"line":68,"column":null}},"28":{"start":{"line":69,"column":8},"end":{"line":71,"column":null}},"29":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"30":{"start":{"line":72,"column":8},"end":{"line":76,"column":null}},"31":{"start":{"line":82,"column":17},"end":{"line":82,"column":null}},"32":{"start":{"line":83,"column":10},"end":{"line":83,"column":null}},"33":{"start":{"line":84,"column":19},"end":{"line":84,"column":null}},"34":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"35":{"start":{"line":89,"column":17},"end":{"line":89,"column":null}},"36":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"37":{"start":{"line":94,"column":17},"end":{"line":94,"column":null}},"38":{"start":{"line":95,"column":17},"end":{"line":95,"column":null}},"39":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"40":{"start":{"line":100,"column":17},"end":{"line":100,"column":null}},"41":{"start":{"line":101,"column":4},"end":{"line":101,"column":null}},"42":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"43":{"start":{"line":106,"column":17},"end":{"line":106,"column":null}},"44":{"start":{"line":107,"column":4},"end":{"line":107,"column":null}},"45":{"start":{"line":108,"column":4},"end":{"line":108,"column":null}},"46":{"start":{"line":112,"column":17},"end":{"line":112,"column":null}},"47":{"start":{"line":113,"column":4},"end":{"line":113,"column":null}},"48":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"49":{"start":{"line":118,"column":17},"end":{"line":118,"column":null}},"50":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"51":{"start":{"line":123,"column":4},"end":{"line":125,"column":null}},"52":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"53":{"start":{"line":126,"column":4},"end":{"line":126,"column":null}},"54":{"start":{"line":130,"column":17},"end":{"line":130,"column":null}},"55":{"start":{"line":131,"column":4},"end":{"line":131,"column":null}},"56":{"start":{"line":135,"column":4},"end":{"line":200,"column":null}},"57":{"start":{"line":136,"column":6},"end":{"line":197,"column":null}},"58":{"start":{"line":138,"column":25},"end":{"line":138,"column":null}},"59":{"start":{"line":139,"column":10},"end":{"line":139,"column":null}},"60":{"start":{"line":142,"column":25},"end":{"line":142,"column":null}},"61":{"start":{"line":143,"column":10},"end":{"line":143,"column":null}},"62":{"start":{"line":146,"column":10},"end":{"line":146,"column":null}},"63":{"start":{"line":147,"column":10},"end":{"line":147,"column":null}},"64":{"start":{"line":150,"column":27},"end":{"line":150,"column":null}},"65":{"start":{"line":151,"column":10},"end":{"line":151,"column":null}},"66":{"start":{"line":154,"column":25},"end":{"line":154,"column":null}},"67":{"start":{"line":155,"column":10},"end":{"line":155,"column":null}},"68":{"start":{"line":158,"column":25},"end":{"line":158,"column":null}},"69":{"start":{"line":159,"column":10},"end":{"line":159,"column":null}},"70":{"start":{"line":162,"column":23},"end":{"line":162,"column":null}},"71":{"start":{"line":163,"column":10},"end":{"line":163,"column":null}},"72":{"start":{"line":166,"column":25},"end":{"line":166,"column":null}},"73":{"start":{"line":167,"column":10},"end":{"line":167,"column":null}},"74":{"start":{"line":170,"column":25},"end":{"line":170,"column":null}},"75":{"start":{"line":171,"column":10},"end":{"line":171,"column":null}},"76":{"start":{"line":174,"column":25},"end":{"line":174,"column":null}},"77":{"start":{"line":175,"column":10},"end":{"line":175,"column":null}},"78":{"start":{"line":178,"column":10},"end":{"line":178,"column":null}},"79":{"start":{"line":179,"column":10},"end":{"line":179,"column":null}},"80":{"start":{"line":182,"column":10},"end":{"line":182,"column":null}},"81":{"start":{"line":183,"column":10},"end":{"line":183,"column":null}},"82":{"start":{"line":186,"column":10},"end":{"line":186,"column":null}},"83":{"start":{"line":187,"column":10},"end":{"line":187,"column":null}},"84":{"start":{"line":190,"column":25},"end":{"line":190,"column":null}},"85":{"start":{"line":191,"column":10},"end":{"line":191,"column":null}},"86":{"start":{"line":194,"column":37},"end":{"line":194,"column":null}},"87":{"start":{"line":195,"column":10},"end":{"line":195,"column":null}},"88":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":11,"column":2},"end":{"line":11,"column":14}},"loc":{"start":{"line":11,"column":44},"end":{"line":17,"column":null}},"line":11},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":8},"end":{"line":19,"column":32}},"loc":{"start":{"line":19,"column":32},"end":{"line":28,"column":null}},"line":19},"2":{"name":"(anonymous_2)","decl":{"start":{"line":30,"column":8},"end":{"line":30,"column":31}},"loc":{"start":{"line":30,"column":31},"end":{"line":37,"column":null}},"line":30},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":10},"end":{"line":39,"column":29}},"loc":{"start":{"line":39,"column":29},"end":{"line":44,"column":null}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":46,"column":8},"end":{"line":46,"column":13}},"loc":{"start":{"line":46,"column":67},"end":{"line":50,"column":null}},"line":46},"5":{"name":"(anonymous_5)","decl":{"start":{"line":52,"column":8},"end":{"line":52,"column":14}},"loc":{"start":{"line":52,"column":58},"end":{"line":57,"column":null}},"line":52},"6":{"name":"(anonymous_6)","decl":{"start":{"line":55,"column":53},"end":{"line":55,"column":59}},"loc":{"start":{"line":55,"column":59},"end":{"line":55,"column":61}},"line":55},"7":{"name":"(anonymous_7)","decl":{"start":{"line":59,"column":8},"end":{"line":59,"column":13}},"loc":{"start":{"line":59,"column":60},"end":{"line":62,"column":null}},"line":59},"8":{"name":"(anonymous_8)","decl":{"start":{"line":64,"column":8},"end":{"line":64,"column":14}},"loc":{"start":{"line":64,"column":56},"end":{"line":79,"column":null}},"line":64},"9":{"name":"(anonymous_9)","decl":{"start":{"line":66,"column":33},"end":{"line":66,"column":34}},"loc":{"start":{"line":67,"column":6},"end":{"line":77,"column":null}},"line":67},"10":{"name":"(anonymous_10)","decl":{"start":{"line":67,"column":16},"end":{"line":67,"column":17}},"loc":{"start":{"line":67,"column":24},"end":{"line":77,"column":7}},"line":67},"11":{"name":"(anonymous_11)","decl":{"start":{"line":81,"column":8},"end":{"line":81,"column":19}},"loc":{"start":{"line":81,"column":96},"end":{"line":86,"column":null}},"line":81},"12":{"name":"(anonymous_12)","decl":{"start":{"line":88,"column":8},"end":{"line":88,"column":58}},"loc":{"start":{"line":88,"column":58},"end":{"line":91,"column":null}},"line":88},"13":{"name":"(anonymous_13)","decl":{"start":{"line":93,"column":8},"end":{"line":93,"column":16}},"loc":{"start":{"line":93,"column":47},"end":{"line":97,"column":null}},"line":93},"14":{"name":"(anonymous_14)","decl":{"start":{"line":99,"column":8},"end":{"line":99,"column":41}},"loc":{"start":{"line":99,"column":41},"end":{"line":103,"column":null}},"line":99},"15":{"name":"(anonymous_15)","decl":{"start":{"line":105,"column":8},"end":{"line":105,"column":44}},"loc":{"start":{"line":105,"column":44},"end":{"line":109,"column":null}},"line":105},"16":{"name":"(anonymous_16)","decl":{"start":{"line":111,"column":8},"end":{"line":111,"column":43}},"loc":{"start":{"line":111,"column":43},"end":{"line":115,"column":null}},"line":111},"17":{"name":"(anonymous_17)","decl":{"start":{"line":117,"column":8},"end":{"line":117,"column":13}},"loc":{"start":{"line":117,"column":39},"end":{"line":120,"column":null}},"line":117},"18":{"name":"(anonymous_18)","decl":{"start":{"line":122,"column":8},"end":{"line":122,"column":33}},"loc":{"start":{"line":122,"column":33},"end":{"line":127,"column":null}},"line":122},"19":{"name":"(anonymous_19)","decl":{"start":{"line":129,"column":8},"end":{"line":129,"column":13}},"loc":{"start":{"line":129,"column":47},"end":{"line":132,"column":null}},"line":129},"20":{"name":"(anonymous_20)","decl":{"start":{"line":134,"column":8},"end":{"line":134,"column":23}},"loc":{"start":{"line":134,"column":70},"end":{"line":201,"column":null}},"line":134}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":14},"end":{"line":11,"column":44}},"type":"default-arg","locations":[{"start":{"line":11,"column":40},"end":{"line":11,"column":44}}],"line":11},"1":{"loc":{"start":{"line":13,"column":16},"end":{"line":13,"column":null}},"type":"binary-expr","locations":[{"start":{"line":13,"column":16},"end":{"line":13,"column":36}},{"start":{"line":13,"column":36},"end":{"line":13,"column":null}}],"line":13},"2":{"loc":{"start":{"line":14,"column":13},"end":{"line":14,"column":null}},"type":"binary-expr","locations":[{"start":{"line":14,"column":13},"end":{"line":14,"column":30}},{"start":{"line":14,"column":30},"end":{"line":14,"column":null}}],"line":14},"3":{"loc":{"start":{"line":15,"column":14},"end":{"line":15,"column":null}},"type":"binary-expr","locations":[{"start":{"line":15,"column":14},"end":{"line":15,"column":32}},{"start":{"line":15,"column":32},"end":{"line":15,"column":null}}],"line":15},"4":{"loc":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":31},"5":{"loc":{"start":{"line":40,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":40},"6":{"loc":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":16},"end":{"line":74,"column":56}},{"start":{"line":74,"column":56},"end":{"line":74,"column":null}}],"line":74},"7":{"loc":{"start":{"line":81,"column":34},"end":{"line":81,"column":96}},"type":"default-arg","locations":[{"start":{"line":81,"column":45},"end":{"line":81,"column":96}}],"line":81},"8":{"loc":{"start":{"line":83,"column":33},"end":{"line":83,"column":57}},"type":"binary-expr","locations":[{"start":{"line":83,"column":33},"end":{"line":83,"column":41}},{"start":{"line":83,"column":41},"end":{"line":83,"column":57}}],"line":83},"9":{"loc":{"start":{"line":93,"column":16},"end":{"line":93,"column":47}},"type":"default-arg","locations":[{"start":{"line":93,"column":23},"end":{"line":93,"column":47}}],"line":93},"10":{"loc":{"start":{"line":96,"column":11},"end":{"line":96,"column":null}},"type":"cond-expr","locations":[{"start":{"line":96,"column":18},"end":{"line":96,"column":25}},{"start":{"line":96,"column":25},"end":{"line":96,"column":null}}],"line":96},"11":{"loc":{"start":{"line":117,"column":13},"end":{"line":117,"column":39}},"type":"default-arg","locations":[{"start":{"line":117,"column":18},"end":{"line":117,"column":39}}],"line":117},"12":{"loc":{"start":{"line":123,"column":4},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":4},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":123},"13":{"loc":{"start":{"line":136,"column":6},"end":{"line":197,"column":null}},"type":"switch","locations":[{"start":{"line":137,"column":8},"end":{"line":140,"column":null}},{"start":{"line":141,"column":8},"end":{"line":144,"column":null}},{"start":{"line":145,"column":8},"end":{"line":148,"column":null}},{"start":{"line":149,"column":8},"end":{"line":152,"column":null}},{"start":{"line":153,"column":8},"end":{"line":156,"column":null}},{"start":{"line":157,"column":8},"end":{"line":160,"column":null}},{"start":{"line":161,"column":8},"end":{"line":164,"column":null}},{"start":{"line":165,"column":8},"end":{"line":168,"column":null}},{"start":{"line":169,"column":8},"end":{"line":172,"column":null}},{"start":{"line":173,"column":8},"end":{"line":176,"column":null}},{"start":{"line":177,"column":8},"end":{"line":180,"column":null}},{"start":{"line":181,"column":8},"end":{"line":184,"column":null}},{"start":{"line":185,"column":8},"end":{"line":188,"column":null}},{"start":{"line":189,"column":8},"end":{"line":192,"column":null}},{"start":{"line":193,"column":8},"end":{"line":196,"column":null}}],"line":136}},"s":{"0":6,"1":6,"2":6,"3":6,"4":0,"5":0,"6":0,"7":1,"8":0,"9":0,"10":0,"11":0,"12":12,"13":12,"14":0,"15":1,"16":1,"17":0,"18":1,"19":1,"20":0,"21":0,"22":1,"23":1,"24":1,"25":1,"26":0,"27":0,"28":0,"29":0,"30":0,"31":1,"32":1,"33":1,"34":0,"35":1,"36":1,"37":1,"38":1,"39":0,"40":1,"41":1,"42":0,"43":1,"44":1,"45":0,"46":1,"47":1,"48":0,"49":1,"50":1,"51":1,"52":1,"53":0,"54":1,"55":1,"56":14,"57":14,"58":1,"59":0,"60":1,"61":0,"62":1,"63":0,"64":1,"65":0,"66":1,"67":0,"68":1,"69":0,"70":1,"71":0,"72":1,"73":0,"74":1,"75":0,"76":1,"77":0,"78":1,"79":0,"80":1,"81":0,"82":1,"83":1,"84":1,"85":0,"86":0,"87":0,"88":13},"f":{"0":6,"1":0,"2":1,"3":12,"4":1,"5":1,"6":0,"7":1,"8":1,"9":0,"10":0,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":14},"b":{"0":[6],"1":[6,5],"2":[6,5],"3":[6,5],"4":[0,1],"5":[12,0],"6":[0,0],"7":[1],"8":[1,0],"9":[1],"10":[0,0],"11":[1],"12":[1,0],"13":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,0]},"meta":{"lastBranch":14,"lastFunction":21,"lastStatement":89,"seen":{"s:6:36:6:Infinity":0,"s:7:43:7:Infinity":1,"s:8:30:8:Infinity":2,"f:11:2:11:14":0,"b:11:40:11:44":0,"s:12:4:16:Infinity":3,"b:13:16:13:36:13:36:13:Infinity":1,"b:14:13:14:30:14:30:14:Infinity":2,"b:15:14:15:32:15:32:15:Infinity":3,"f:19:8:19:32":1,"s:20:4:20:Infinity":4,"s:21:4:26:Infinity":5,"s:27:4:27:Infinity":6,"f:30:8:30:31":2,"b:31:4:36:Infinity:undefined:undefined:undefined:undefined":4,"s:31:4:36:Infinity":7,"s:32:6:32:Infinity":8,"s:33:6:33:Infinity":9,"s:34:6:34:Infinity":10,"s:35:6:35:Infinity":11,"f:39:10:39:29":3,"b:40:4:42:Infinity:undefined:undefined:undefined:undefined":5,"s:40:4:42:Infinity":12,"s:41:6:41:Infinity":13,"s:43:4:43:Infinity":14,"f:46:8:46:13":4,"s:47:17:47:Infinity":15,"s:48:4:48:Infinity":16,"s:49:4:49:Infinity":17,"f:52:8:52:14":5,"s:53:17:53:Infinity":18,"s:54:4:54:Infinity":19,"s:55:4:55:Infinity":20,"f:55:53:55:59":6,"s:56:4:56:Infinity":21,"f:59:8:59:13":7,"s:60:17:60:Infinity":22,"s:61:4:61:Infinity":23,"f:64:8:64:14":8,"s:65:17:65:Infinity":24,"s:66:4:78:Infinity":25,"f:66:33:66:34":9,"s:67:6:77:Infinity":26,"f:67:16:67:17":10,"s:68:46:68:Infinity":27,"s:69:8:71:Infinity":28,"s:70:10:70:Infinity":29,"s:72:8:76:Infinity":30,"b:74:16:74:56:74:56:74:Infinity":6,"f:81:8:81:19":11,"b:81:45:81:96":7,"s:82:17:82:Infinity":31,"s:83:10:83:Infinity":32,"b:83:33:83:41:83:41:83:57":8,"s:84:19:84:Infinity":33,"s:85:4:85:Infinity":34,"f:88:8:88:58":12,"s:89:17:89:Infinity":35,"s:90:4:90:Infinity":36,"f:93:8:93:16":13,"b:93:23:93:47":9,"s:94:17:94:Infinity":37,"s:95:17:95:Infinity":38,"s:96:4:96:Infinity":39,"b:96:18:96:25:96:25:96:Infinity":10,"f:99:8:99:41":14,"s:100:17:100:Infinity":40,"s:101:4:101:Infinity":41,"s:102:4:102:Infinity":42,"f:105:8:105:44":15,"s:106:17:106:Infinity":43,"s:107:4:107:Infinity":44,"s:108:4:108:Infinity":45,"f:111:8:111:43":16,"s:112:17:112:Infinity":46,"s:113:4:113:Infinity":47,"s:114:4:114:Infinity":48,"f:117:8:117:13":17,"b:117:18:117:39":11,"s:118:17:118:Infinity":49,"s:119:4:119:Infinity":50,"f:122:8:122:33":18,"b:123:4:125:Infinity:undefined:undefined:undefined:undefined":12,"s:123:4:125:Infinity":51,"s:124:6:124:Infinity":52,"s:126:4:126:Infinity":53,"f:129:8:129:13":19,"s:130:17:130:Infinity":54,"s:131:4:131:Infinity":55,"f:134:8:134:23":20,"s:135:4:200:Infinity":56,"b:137:8:140:Infinity:141:8:144:Infinity:145:8:148:Infinity:149:8:152:Infinity:153:8:156:Infinity:157:8:160:Infinity:161:8:164:Infinity:165:8:168:Infinity:169:8:172:Infinity:173:8:176:Infinity:177:8:180:Infinity:181:8:184:Infinity:185:8:188:Infinity:189:8:192:Infinity:193:8:196:Infinity":13,"s:136:6:197:Infinity":57,"s:138:25:138:Infinity":58,"s:139:10:139:Infinity":59,"s:142:25:142:Infinity":60,"s:143:10:143:Infinity":61,"s:146:10:146:Infinity":62,"s:147:10:147:Infinity":63,"s:150:27:150:Infinity":64,"s:151:10:151:Infinity":65,"s:154:25:154:Infinity":66,"s:155:10:155:Infinity":67,"s:158:25:158:Infinity":68,"s:159:10:159:Infinity":69,"s:162:23:162:Infinity":70,"s:163:10:163:Infinity":71,"s:166:25:166:Infinity":72,"s:167:10:167:Infinity":73,"s:170:25:170:Infinity":74,"s:171:10:171:Infinity":75,"s:174:25:174:Infinity":76,"s:175:10:175:Infinity":77,"s:178:10:178:Infinity":78,"s:179:10:179:Infinity":79,"s:182:10:182:Infinity":80,"s:183:10:183:Infinity":81,"s:186:10:186:Infinity":82,"s:187:10:187:Infinity":83,"s:190:25:190:Infinity":84,"s:191:10:191:Infinity":85,"s:194:37:194:Infinity":86,"s:195:10:195:Infinity":87,"s:199:6:199:Infinity":88}}} +,"/Users/chi/Projects/claude-browse/src/logger.ts": {"path":"/Users/chi/Projects/claude-browse/src/logger.ts","statementMap":{"0":{"start":{"line":5,"column":45},"end":{"line":20,"column":null}},"1":{"start":{"line":23,"column":63},"end":{"line":38,"column":null}},"2":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"3":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"4":{"start":{"line":60,"column":2},"end":{"line":78,"column":null}},"5":{"start":{"line":62,"column":6},"end":{"line":62,"column":null}},"6":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"7":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"8":{"start":{"line":69,"column":6},"end":{"line":69,"column":null}},"9":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"10":{"start":{"line":73,"column":6},"end":{"line":73,"column":null}},"11":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"12":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"13":{"start":{"line":82,"column":16},"end":{"line":82,"column":null}},"14":{"start":{"line":83,"column":15},"end":{"line":83,"column":null}},"15":{"start":{"line":84,"column":17},"end":{"line":84,"column":null}},"16":{"start":{"line":85,"column":17},"end":{"line":85,"column":null}},"17":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"18":{"start":{"line":100,"column":80},"end":{"line":108,"column":null}},"19":{"start":{"line":101,"column":15},"end":{"line":101,"column":null}},"20":{"start":{"line":102,"column":17},"end":{"line":102,"column":null}},"21":{"start":{"line":103,"column":17},"end":{"line":103,"column":null}},"22":{"start":{"line":104,"column":22},"end":{"line":104,"column":null}},"23":{"start":{"line":105,"column":14},"end":{"line":105,"column":null}},"24":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"25":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"26":{"start":{"line":111,"column":2},"end":{"line":113,"column":null}},"27":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"28":{"start":{"line":114,"column":20},"end":{"line":114,"column":null}},"29":{"start":{"line":115,"column":14},"end":{"line":115,"column":null}},"30":{"start":{"line":116,"column":17},"end":{"line":116,"column":null}},"31":{"start":{"line":117,"column":2},"end":{"line":117,"column":null}},"32":{"start":{"line":123,"column":2},"end":{"line":130,"column":null}},"33":{"start":{"line":125,"column":6},"end":{"line":125,"column":null}},"34":{"start":{"line":128,"column":6},"end":{"line":128,"column":null}},"35":{"start":{"line":134,"column":22},"end":{"line":134,"column":null}},"36":{"start":{"line":137,"column":28},"end":{"line":137,"column":null}},"37":{"start":{"line":137,"column":50},"end":{"line":137,"column":82}}},"fnMap":{"0":{"name":"ts","decl":{"start":{"line":40,"column":16},"end":{"line":40,"column":29}},"loc":{"start":{"line":40,"column":29},"end":{"line":42,"column":null}},"line":40},"1":{"name":"truncate","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":25}},"loc":{"start":{"line":44,"column":59},"end":{"line":46,"column":null}},"line":44},"2":{"name":"getCommandDetail","decl":{"start":{"line":59,"column":16},"end":{"line":59,"column":33}},"loc":{"start":{"line":59,"column":71},"end":{"line":79,"column":null}},"line":59},"3":{"name":"formatCommand","decl":{"start":{"line":81,"column":16},"end":{"line":81,"column":30}},"loc":{"start":{"line":81,"column":56},"end":{"line":87,"column":null}},"line":81},"4":{"name":"(anonymous_4)","decl":{"start":{"line":101,"column":8},"end":{"line":101,"column":9}},"loc":{"start":{"line":101,"column":15},"end":{"line":101,"column":null}},"line":101},"5":{"name":"(anonymous_5)","decl":{"start":{"line":102,"column":9},"end":{"line":102,"column":10}},"loc":{"start":{"line":102,"column":17},"end":{"line":102,"column":null}},"line":102},"6":{"name":"(anonymous_6)","decl":{"start":{"line":103,"column":9},"end":{"line":103,"column":10}},"loc":{"start":{"line":103,"column":17},"end":{"line":103,"column":null}},"line":103},"7":{"name":"(anonymous_7)","decl":{"start":{"line":104,"column":14},"end":{"line":104,"column":15}},"loc":{"start":{"line":104,"column":22},"end":{"line":104,"column":null}},"line":104},"8":{"name":"(anonymous_8)","decl":{"start":{"line":105,"column":7},"end":{"line":105,"column":8}},"loc":{"start":{"line":105,"column":14},"end":{"line":105,"column":null}},"line":105},"9":{"name":"(anonymous_9)","decl":{"start":{"line":106,"column":8},"end":{"line":106,"column":9}},"loc":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"line":106},"10":{"name":"(anonymous_10)","decl":{"start":{"line":107,"column":8},"end":{"line":107,"column":9}},"loc":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"line":107},"11":{"name":"formatResult","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":29}},"loc":{"start":{"line":110,"column":75},"end":{"line":118,"column":null}},"line":110},"12":{"name":"createLogger","decl":{"start":{"line":122,"column":16},"end":{"line":122,"column":29}},"loc":{"start":{"line":122,"column":57},"end":{"line":131,"column":null}},"line":122},"13":{"name":"(anonymous_13)","decl":{"start":{"line":124,"column":4},"end":{"line":124,"column":12}},"loc":{"start":{"line":124,"column":36},"end":{"line":126,"column":null}},"line":124},"14":{"name":"(anonymous_14)","decl":{"start":{"line":127,"column":4},"end":{"line":127,"column":11}},"loc":{"start":{"line":127,"column":55},"end":{"line":129,"column":null}},"line":127},"15":{"name":"(anonymous_15)","decl":{"start":{"line":137,"column":41},"end":{"line":137,"column":42}},"loc":{"start":{"line":137,"column":50},"end":{"line":137,"column":82}},"line":137}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":9},"end":{"line":45,"column":null}},"type":"cond-expr","locations":[{"start":{"line":45,"column":28},"end":{"line":45,"column":56}},{"start":{"line":45,"column":56},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":60,"column":2},"end":{"line":78,"column":null}},"type":"switch","locations":[{"start":{"line":61,"column":4},"end":{"line":62,"column":null}},{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},{"start":{"line":64,"column":4},"end":{"line":65,"column":null}},{"start":{"line":66,"column":4},"end":{"line":67,"column":null}},{"start":{"line":68,"column":4},"end":{"line":69,"column":null}},{"start":{"line":70,"column":4},"end":{"line":71,"column":null}},{"start":{"line":72,"column":4},"end":{"line":73,"column":null}},{"start":{"line":74,"column":4},"end":{"line":75,"column":null}},{"start":{"line":76,"column":4},"end":{"line":77,"column":null}}],"line":60},"2":{"loc":{"start":{"line":69,"column":23},"end":{"line":69,"column":51}},"type":"binary-expr","locations":[{"start":{"line":69,"column":23},"end":{"line":69,"column":35}},{"start":{"line":69,"column":35},"end":{"line":69,"column":51}}],"line":69},"3":{"loc":{"start":{"line":71,"column":13},"end":{"line":71,"column":null}},"type":"cond-expr","locations":[{"start":{"line":71,"column":24},"end":{"line":71,"column":46}},{"start":{"line":71,"column":46},"end":{"line":71,"column":null}}],"line":71},"4":{"loc":{"start":{"line":73,"column":26},"end":{"line":73,"column":40}},"type":"binary-expr","locations":[{"start":{"line":73,"column":26},"end":{"line":73,"column":36}},{"start":{"line":73,"column":36},"end":{"line":73,"column":40}}],"line":73},"5":{"loc":{"start":{"line":75,"column":32},"end":{"line":75,"column":50}},"type":"binary-expr","locations":[{"start":{"line":75,"column":32},"end":{"line":75,"column":46}},{"start":{"line":75,"column":46},"end":{"line":75,"column":50}}],"line":75},"6":{"loc":{"start":{"line":82,"column":16},"end":{"line":82,"column":null}},"type":"binary-expr","locations":[{"start":{"line":82,"column":16},"end":{"line":82,"column":37}},{"start":{"line":82,"column":37},"end":{"line":82,"column":null}}],"line":82},"7":{"loc":{"start":{"line":83,"column":15},"end":{"line":83,"column":null}},"type":"binary-expr","locations":[{"start":{"line":83,"column":15},"end":{"line":83,"column":33}},{"start":{"line":83,"column":33},"end":{"line":83,"column":null}}],"line":83},"8":{"loc":{"start":{"line":85,"column":17},"end":{"line":85,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":26},"end":{"line":85,"column":41}},{"start":{"line":85,"column":41},"end":{"line":85,"column":null}}],"line":85},"9":{"loc":{"start":{"line":102,"column":17},"end":{"line":102,"column":null}},"type":"cond-expr","locations":[{"start":{"line":102,"column":25},"end":{"line":102,"column":40}},{"start":{"line":102,"column":40},"end":{"line":102,"column":null}}],"line":102},"10":{"loc":{"start":{"line":103,"column":17},"end":{"line":103,"column":null}},"type":"cond-expr","locations":[{"start":{"line":103,"column":41},"end":{"line":103,"column":73}},{"start":{"line":103,"column":73},"end":{"line":103,"column":null}}],"line":103},"11":{"loc":{"start":{"line":104,"column":22},"end":{"line":104,"column":null}},"type":"cond-expr","locations":[{"start":{"line":104,"column":31},"end":{"line":104,"column":54}},{"start":{"line":104,"column":54},"end":{"line":104,"column":null}}],"line":104},"12":{"loc":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"type":"cond-expr","locations":[{"start":{"line":106,"column":39},"end":{"line":106,"column":66}},{"start":{"line":106,"column":66},"end":{"line":106,"column":null}}],"line":106},"13":{"loc":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"type":"cond-expr","locations":[{"start":{"line":107,"column":41},"end":{"line":107,"column":82}},{"start":{"line":107,"column":82},"end":{"line":107,"column":null}}],"line":107},"14":{"loc":{"start":{"line":111,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":111},"15":{"loc":{"start":{"line":115,"column":14},"end":{"line":115,"column":null}},"type":"cond-expr","locations":[{"start":{"line":115,"column":26},"end":{"line":115,"column":46}},{"start":{"line":115,"column":46},"end":{"line":115,"column":null}}],"line":115},"16":{"loc":{"start":{"line":116,"column":17},"end":{"line":116,"column":null}},"type":"cond-expr","locations":[{"start":{"line":116,"column":23},"end":{"line":116,"column":46}},{"start":{"line":116,"column":46},"end":{"line":116,"column":null}}],"line":116},"17":{"loc":{"start":{"line":122,"column":29},"end":{"line":122,"column":57}},"type":"default-arg","locations":[{"start":{"line":122,"column":44},"end":{"line":122,"column":57}}],"line":122}},"s":{"0":2,"1":2,"2":23,"3":3,"4":18,"5":4,"6":5,"7":2,"8":2,"9":1,"10":1,"11":0,"12":3,"13":11,"14":11,"15":11,"16":11,"17":11,"18":2,"19":3,"20":2,"21":2,"22":0,"23":2,"24":1,"25":0,"26":12,"27":1,"28":11,"29":11,"30":12,"31":12,"32":6,"33":9,"34":9,"35":2,"36":2,"37":0},"f":{"0":23,"1":3,"2":18,"3":11,"4":3,"5":2,"6":2,"7":0,"8":2,"9":1,"10":0,"11":12,"12":6,"13":9,"14":9,"15":0},"b":{"0":[1,2],"1":[4,4,5,2,2,1,1,0,3],"2":[2,1],"3":[0,1],"4":[1,0],"5":[0,0],"6":[11,0],"7":[11,0],"8":[8,3],"9":[2,0],"10":[2,0],"11":[0,0],"12":[1,0],"13":[0,0],"14":[1,11],"15":[10,1],"16":[10,1],"17":[6]},"meta":{"lastBranch":18,"lastFunction":16,"lastStatement":38,"seen":{"s:5:45:20:Infinity":0,"s:23:63:38:Infinity":1,"f:40:16:40:29":0,"s:41:2:41:Infinity":2,"f:44:16:44:25":1,"s:45:2:45:Infinity":3,"b:45:28:45:56:45:56:45:Infinity":0,"f:59:16:59:33":2,"b:61:4:62:Infinity:63:4:63:Infinity:64:4:65:Infinity:66:4:67:Infinity:68:4:69:Infinity:70:4:71:Infinity:72:4:73:Infinity:74:4:75:Infinity:76:4:77:Infinity":1,"s:60:2:78:Infinity":4,"s:62:6:62:Infinity":5,"s:65:6:65:Infinity":6,"s:67:6:67:Infinity":7,"s:69:6:69:Infinity":8,"b:69:23:69:35:69:35:69:51":2,"s:71:6:71:Infinity":9,"b:71:24:71:46:71:46:71:Infinity":3,"s:73:6:73:Infinity":10,"b:73:26:73:36:73:36:73:40":4,"s:75:6:75:Infinity":11,"b:75:32:75:46:75:46:75:50":5,"s:77:6:77:Infinity":12,"f:81:16:81:30":3,"s:82:16:82:Infinity":13,"b:82:16:82:37:82:37:82:Infinity":6,"s:83:15:83:Infinity":14,"b:83:15:83:33:83:33:83:Infinity":7,"s:84:17:84:Infinity":15,"s:85:17:85:Infinity":16,"b:85:26:85:41:85:41:85:Infinity":8,"s:86:2:86:Infinity":17,"s:100:80:108:Infinity":18,"f:101:8:101:9":4,"s:101:15:101:Infinity":19,"f:102:9:102:10":5,"s:102:17:102:Infinity":20,"b:102:25:102:40:102:40:102:Infinity":9,"f:103:9:103:10":6,"s:103:17:103:Infinity":21,"b:103:41:103:73:103:73:103:Infinity":10,"f:104:14:104:15":7,"s:104:22:104:Infinity":22,"b:104:31:104:54:104:54:104:Infinity":11,"f:105:7:105:8":8,"s:105:14:105:Infinity":23,"f:106:8:106:9":9,"s:106:16:106:Infinity":24,"b:106:39:106:66:106:66:106:Infinity":12,"f:107:8:107:9":10,"s:107:16:107:Infinity":25,"b:107:41:107:82:107:82:107:Infinity":13,"f:110:16:110:29":11,"b:111:2:113:Infinity:undefined:undefined:undefined:undefined":14,"s:111:2:113:Infinity":26,"s:112:4:112:Infinity":27,"s:114:20:114:Infinity":28,"s:115:14:115:Infinity":29,"b:115:26:115:46:115:46:115:Infinity":15,"s:116:17:116:Infinity":30,"b:116:23:116:46:116:46:116:Infinity":16,"s:117:2:117:Infinity":31,"f:122:16:122:29":12,"b:122:44:122:57":17,"s:123:2:130:Infinity":32,"f:124:4:124:12":13,"s:125:6:125:Infinity":33,"f:127:4:127:11":14,"s:128:6:128:Infinity":34,"s:134:22:134:Infinity":35,"s:137:28:137:Infinity":36,"f:137:41:137:42":15,"s:137:50:137:82":37}}} +,"/Users/chi/Projects/claude-browse/src/server.ts": {"path":"/Users/chi/Projects/claude-browse/src/server.ts","statementMap":{"0":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"1":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"2":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"3":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"4":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"5":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"6":{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},"7":{"start":{"line":22,"column":2},"end":{"line":24,"column":null}},"8":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"9":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"10":{"start":{"line":27,"column":2},"end":{"line":29,"column":null}},"11":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"12":{"start":{"line":35,"column":10},"end":{"line":35,"column":null}},"13":{"start":{"line":36,"column":62},"end":{"line":36,"column":null}},"14":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"15":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"16":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"17":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"18":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"19":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"20":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"21":{"start":{"line":52,"column":37},"end":{"line":52,"column":65}},"22":{"start":{"line":56,"column":4},"end":{"line":74,"column":null}},"23":{"start":{"line":57,"column":34},"end":{"line":57,"column":null}},"24":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"25":{"start":{"line":60,"column":6},"end":{"line":65,"column":null}},"26":{"start":{"line":61,"column":8},"end":{"line":61,"column":null}},"27":{"start":{"line":62,"column":8},"end":{"line":62,"column":null}},"28":{"start":{"line":63,"column":8},"end":{"line":63,"column":null}},"29":{"start":{"line":64,"column":8},"end":{"line":64,"column":null}},"30":{"start":{"line":67,"column":21},"end":{"line":67,"column":null}},"31":{"start":{"line":68,"column":6},"end":{"line":68,"column":null}},"32":{"start":{"line":69,"column":6},"end":{"line":69,"column":null}},"33":{"start":{"line":71,"column":21},"end":{"line":71,"column":null}},"34":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"35":{"start":{"line":73,"column":6},"end":{"line":73,"column":null}},"36":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"37":{"start":{"line":80,"column":4},"end":{"line":85,"column":null}},"38":{"start":{"line":81,"column":6},"end":{"line":84,"column":null}},"39":{"start":{"line":82,"column":8},"end":{"line":82,"column":null}},"40":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"41":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"42":{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},"43":{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},"44":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"45":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"46":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"47":{"start":{"line":99,"column":4},"end":{"line":99,"column":null}},"48":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"49":{"start":{"line":108,"column":17},"end":{"line":108,"column":null}},"50":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"51":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}}},"fnMap":{"0":{"name":"printBanner","decl":{"start":{"line":12,"column":9},"end":{"line":12,"column":21}},"loc":{"start":{"line":12,"column":41},"end":{"line":31,"column":null}},"line":12},"1":{"name":"(anonymous_1)","decl":{"start":{"line":39,"column":2},"end":{"line":39,"column":14}},"loc":{"start":{"line":39,"column":43},"end":{"line":44,"column":null}},"line":39},"2":{"name":"(anonymous_2)","decl":{"start":{"line":46,"column":10},"end":{"line":46,"column":34}},"loc":{"start":{"line":46,"column":34},"end":{"line":49,"column":null}},"line":46},"3":{"name":"(anonymous_3)","decl":{"start":{"line":51,"column":10},"end":{"line":51,"column":30}},"loc":{"start":{"line":51,"column":30},"end":{"line":53,"column":null}},"line":51},"4":{"name":"(anonymous_4)","decl":{"start":{"line":52,"column":23},"end":{"line":52,"column":24}},"loc":{"start":{"line":52,"column":37},"end":{"line":52,"column":65}},"line":52},"5":{"name":"(anonymous_5)","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":30}},"loc":{"start":{"line":55,"column":74},"end":{"line":75,"column":null}},"line":55},"6":{"name":"(anonymous_6)","decl":{"start":{"line":77,"column":8},"end":{"line":77,"column":31}},"loc":{"start":{"line":77,"column":31},"end":{"line":86,"column":null}},"line":77},"7":{"name":"(anonymous_7)","decl":{"start":{"line":80,"column":23},"end":{"line":80,"column":24}},"loc":{"start":{"line":80,"column":36},"end":{"line":85,"column":5}},"line":80},"8":{"name":"(anonymous_8)","decl":{"start":{"line":81,"column":47},"end":{"line":81,"column":53}},"loc":{"start":{"line":81,"column":53},"end":{"line":84,"column":7}},"line":81},"9":{"name":"(anonymous_9)","decl":{"start":{"line":88,"column":8},"end":{"line":88,"column":30}},"loc":{"start":{"line":88,"column":30},"end":{"line":96,"column":null}},"line":88},"10":{"name":"(anonymous_10)","decl":{"start":{"line":98,"column":2},"end":{"line":98,"column":20}},"loc":{"start":{"line":98,"column":20},"end":{"line":100,"column":null}},"line":98},"11":{"name":"(anonymous_11)","decl":{"start":{"line":102,"column":2},"end":{"line":102,"column":11}},"loc":{"start":{"line":102,"column":11},"end":{"line":104,"column":null}},"line":102},"12":{"name":"startServer","decl":{"start":{"line":107,"column":22},"end":{"line":107,"column":34}},"loc":{"start":{"line":107,"column":87},"end":{"line":111,"column":null}},"line":107}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":14},"end":{"line":39,"column":43}},"type":"default-arg","locations":[{"start":{"line":39,"column":39},"end":{"line":39,"column":43}}],"line":39},"1":{"loc":{"start":{"line":41,"column":16},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":41,"column":16},"end":{"line":41,"column":32}},{"start":{"line":41,"column":32},"end":{"line":41,"column":null}}],"line":41},"2":{"loc":{"start":{"line":57,"column":34},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":65},"end":{"line":57,"column":88}},{"start":{"line":57,"column":88},"end":{"line":57,"column":null}}],"line":57},"3":{"loc":{"start":{"line":60,"column":6},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":60,"column":6},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":60},"4":{"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":90},"5":{"loc":{"start":{"line":107,"column":34},"end":{"line":107,"column":87}},"type":"default-arg","locations":[{"start":{"line":107,"column":59},"end":{"line":107,"column":87}}],"line":107}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":3,"13":3,"14":3,"15":3,"16":3,"17":3,"18":3,"19":3,"20":3,"21":7,"22":7,"23":7,"24":7,"25":7,"26":0,"27":0,"28":0,"29":0,"30":7,"31":7,"32":7,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":1,"42":1,"43":0,"44":0,"45":1,"46":1,"47":2,"48":7,"49":0,"50":0,"51":0},"f":{"0":0,"1":3,"2":3,"3":3,"4":7,"5":7,"6":0,"7":0,"8":0,"9":1,"10":2,"11":7,"12":0},"b":{"0":[3],"1":[3,1],"2":[1,6],"3":[0,7],"4":[0,1],"5":[0]},"meta":{"lastBranch":6,"lastFunction":13,"lastStatement":52,"seen":{"f:12:9:12:21":0,"s:13:2:13:Infinity":0,"s:14:2:14:Infinity":1,"s:15:2:15:Infinity":2,"s:16:2:16:Infinity":3,"s:17:2:17:Infinity":4,"s:18:2:18:Infinity":5,"s:19:2:21:Infinity":6,"s:22:2:24:Infinity":7,"s:25:2:25:Infinity":8,"s:26:2:26:Infinity":9,"s:27:2:29:Infinity":10,"s:30:2:30:Infinity":11,"s:35:10:35:Infinity":12,"s:36:62:36:Infinity":13,"f:39:2:39:14":1,"b:39:39:39:43":0,"s:40:4:40:Infinity":14,"s:41:4:41:Infinity":15,"b:41:16:41:32:41:32:41:Infinity":1,"s:42:4:42:Infinity":16,"s:43:4:43:Infinity":17,"f:46:10:46:34":2,"s:47:4:47:Infinity":18,"s:48:4:48:Infinity":19,"f:51:10:51:30":3,"s:52:4:52:Infinity":20,"f:52:23:52:24":4,"s:52:37:52:65":21,"f:55:16:55:30":5,"s:56:4:74:Infinity":22,"s:57:34:57:Infinity":23,"b:57:65:57:88:57:88:57:Infinity":2,"s:58:6:58:Infinity":24,"b:60:6:65:Infinity:undefined:undefined:undefined:undefined":3,"s:60:6:65:Infinity":25,"s:61:8:61:Infinity":26,"s:62:8:62:Infinity":27,"s:63:8:63:Infinity":28,"s:64:8:64:Infinity":29,"s:67:21:67:Infinity":30,"s:68:6:68:Infinity":31,"s:69:6:69:Infinity":32,"s:71:21:71:Infinity":33,"s:72:6:72:Infinity":34,"s:73:6:73:Infinity":35,"f:77:8:77:31":6,"s:78:4:78:Infinity":36,"s:80:4:85:Infinity":37,"f:80:23:80:24":7,"s:81:6:84:Infinity":38,"f:81:47:81:53":8,"s:82:8:82:Infinity":39,"s:83:8:83:Infinity":40,"f:88:8:88:30":9,"s:89:4:89:Infinity":41,"b:90:4:93:Infinity:undefined:undefined:undefined:undefined":4,"s:90:4:93:Infinity":42,"s:91:6:91:Infinity":43,"s:92:6:92:Infinity":44,"s:94:4:94:Infinity":45,"s:95:4:95:Infinity":46,"f:98:2:98:20":10,"s:99:4:99:Infinity":47,"f:102:2:102:11":11,"s:103:4:103:Infinity":48,"f:107:22:107:34":12,"b:107:59:107:87":5,"s:108:17:108:Infinity":49,"s:109:2:109:Infinity":50,"s:110:2:110:Infinity":51}}} +,"/Users/chi/Projects/claude-browse/src/types.ts": {"path":"/Users/chi/Projects/claude-browse/src/types.ts","statementMap":{},"fnMap":{},"branchMap":{},"s":{},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":0,"seen":{}}} +} diff --git a/coverage/favicon.png b/coverage/favicon.png new file mode 100644 index 0000000..c1525b8 Binary files /dev/null and b/coverage/favicon.png differ diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000..83e2a1e --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,161 @@ + + + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 60.89% + Statements + 109/179 +
+ + +
+ 70.78% + Branches + 63/89 +
+ + +
+ 76% + Functions + 38/50 +
+ + +
+ 61.01% + Lines + 108/177 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
browser.ts +
+
58.42%52/8975.67%28/3780.95%17/2158.42%52/89
logger.ts +
+
89.47%34/3866.66%28/4281.25%13/1691.89%34/37
server.ts +
+
44.23%23/5270%7/1061.53%8/1343.13%22/51
types.ts +
+
0%0/00%0/00%0/00%0/0
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/logger.ts.html b/coverage/logger.ts.html new file mode 100644 index 0000000..9101488 --- /dev/null +++ b/coverage/logger.ts.html @@ -0,0 +1,496 @@ + + + + + + Code coverage report for logger.ts + + + + + + + + + +
+
+

All files logger.ts

+
+ +
+ 89.47% + Statements + 34/38 +
+ + +
+ 66.66% + Branches + 28/42 +
+ + +
+ 81.25% + Functions + 13/16 +
+ + +
+ 91.89% + Lines + 34/37 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +23x +  +  +  +3x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +18x +  +4x +  +  +5x +  +2x +  +2x +  +1x +  +1x +  +  +  +3x +  +  +  +  +11x +11x +11x +11x +11x +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +3x +2x +2x +  +2x +1x +  +  +  +  +12x +1x +  +11x +11x +12x +12x +  +  +  +  +  +6x +  +9x +  +  +9x +  +  +  +  +  +2x +  +  +2x + 
import chalk from 'chalk';
+import logSymbols from 'log-symbols';
+ 
+// Icons for commands
+export const icons: Record<string, string> = {
+  goto: '→',
+  click: '◉',
+  type: '⌨',
+  query: '?',
+  screenshot: '📷',
+  url: '🔗',
+  html: '<>',
+  back: '←',
+  forward: '→',
+  reload: '↻',
+  wait: '⏳',
+  newpage: '+',
+  close: '✕',
+  eval: '⚡',
+};
+ 
+// Colors for command types
+export const cmdColor: Record<string, (s: string) => string> = {
+  goto: chalk.cyan,
+  click: chalk.yellow,
+  type: chalk.magenta,
+  query: chalk.blue,
+  screenshot: chalk.green,
+  url: chalk.cyan,
+  html: chalk.blue,
+  back: chalk.yellow,
+  forward: chalk.yellow,
+  reload: chalk.yellow,
+  wait: chalk.gray,
+  newpage: chalk.green,
+  close: chalk.red,
+  eval: chalk.magenta,
+};
+ 
+export function ts(): string {
+  return chalk.gray(`[${new Date().toISOString()}]`);
+}
+ 
+export function truncate(str: string, max: number): string {
+  return str.length > max ? `${str.slice(0, max)}...` : str;
+}
+ 
+export interface CommandLike {
+  cmd: string;
+  url?: string;
+  selector?: string;
+  text?: string;
+  path?: string;
+  full?: boolean;
+  ms?: number;
+  script?: string;
+}
+ 
+export function getCommandDetail(cmd: CommandLike): string | undefined {
+  switch (cmd.cmd) {
+    case 'goto':
+      return chalk.white(cmd.url);
+    case 'click':
+    case 'query':
+      return chalk.white(cmd.selector);
+    case 'type':
+      return `${chalk.white(cmd.selector)} ${chalk.dim(`="${cmd.text}"`)}`;
+    case 'screenshot':
+      return chalk.dim(cmd.path || 'screenshot.png');
+    case 'html':
+      return cmd.full ? chalk.dim('(full)') : undefined;
+    case 'wait':
+      return chalk.dim(`${cmd.ms || 1000}ms`);
+    case 'eval':
+      return chalk.dim(truncate(cmd.script || '', 50));
+    default:
+      return undefined;
+  }
+}
+ 
+export function formatCommand(cmd: CommandLike): string {
+  const color = cmdColor[cmd.cmd] || chalk.white;
+  const icon = icons[cmd.cmd] || '•';
+  const detail = getCommandDetail(cmd);
+  const suffix = detail ? ` ${detail}` : '';
+  return `${ts()} ${chalk.bold(color(icon))} ${color(cmd.cmd.toUpperCase())}${suffix}`;
+}
+ 
+export interface ResultLike {
+  ok: boolean;
+  error?: string;
+  title?: string;
+  url?: string;
+  count?: number;
+  path?: string;
+  html?: string;
+  result?: unknown;
+}
+ 
+const resultFormatters: Record<string, (r: ResultLike) => string | undefined> = {
+  goto: (r) => r.title,
+  click: (r) => (r.url ? `→ ${r.url}` : undefined),
+  query: (r) => (r.count !== undefined ? `Found ${r.count} element(s)` : undefined),
+  screenshot: (r) => (r.path ? `Saved to ${r.path}` : undefined),
+  url: (r) => r.url,
+  html: (r) => (r.html !== undefined ? `${r.html.length} chars` : undefined),
+  eval: (r) => (r.result !== undefined ? truncate(JSON.stringify(r.result), 80) : undefined),
+};
+ 
+export function formatResult(cmd: CommandLike, result: ResultLike): string {
+  if (!result.ok) {
+    return `${ts()}   ${logSymbols.error} ${chalk.red(result.error)}`;
+  }
+  const formatter = resultFormatters[cmd.cmd];
+  const msg = formatter ? formatter(result) : undefined;
+  const suffix = msg ? ` ${chalk.dim(msg)}` : '';
+  return `${ts()}   ${logSymbols.success}${suffix}`;
+}
+ 
+export type LogFn = (msg: string) => void;
+ 
+export function createLogger(logFn: LogFn = console.log) {
+  return {
+    command(cmd: CommandLike): void {
+      logFn(formatCommand(cmd));
+    },
+    result(cmd: CommandLike, result: ResultLike): void {
+      logFn(formatResult(cmd, result));
+    },
+  };
+}
+ 
+// Default logger to stdout
+export const logger = createLogger();
+ 
+// Logger to stderr (for MCP)
+export const stderrLogger = createLogger((msg) => process.stderr.write(`${msg}\n`));
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/server.ts.html b/coverage/server.ts.html new file mode 100644 index 0000000..f267ee2 --- /dev/null +++ b/coverage/server.ts.html @@ -0,0 +1,418 @@ + + + + + + Code coverage report for server.ts + + + + + + + + + +
+
+

All files server.ts

+
+ +
+ 44.23% + Statements + 23/52 +
+ + +
+ 70% + Branches + 7/10 +
+ + +
+ 61.53% + Functions + 8/13 +
+ + +
+ 43.13% + Lines + 22/51 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +3x +3x +  +  +  +3x +3x +3x +3x +  +  +  +3x +3x +  +  +  +7x +  +  +  +7x +7x +7x +  +7x +  +  +  +  +  +  +7x +7x +7x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +  +2x +  +  +  +7x +  +  +  +  +  +  +  +  + 
import chalk from 'chalk';
+import express, { type Request, type Response } from 'express';
+import logSymbols from 'log-symbols';
+import { ClaudeBrowser } from './browser.js';
+import { logger, ts } from './logger.js';
+import type { BrowserCommand, BrowserOptions } from './types.js';
+ 
+export interface ServerOptions extends BrowserOptions {
+  port?: number;
+}
+ 
+function printBanner(port: number): void {
+  console.log();
+  console.log(chalk.cyan.bold('  🌐 Claude Browse Server'));
+  console.log(chalk.dim('  ─────────────────────────'));
+  console.log(`  ${logSymbols.success} Listening on ${chalk.bold(`http://localhost:${port}`)}`);
+  console.log();
+  console.log(chalk.dim('  Commands:'));
+  console.log(
+    `    ${chalk.cyan('goto')}  ${chalk.yellow('click')}  ${chalk.magenta('type')}  ${chalk.blue('query')}  ${chalk.green('screenshot')}`
+  );
+  console.log(
+    `    ${chalk.cyan('url')}  ${chalk.blue('html')}  ${chalk.yellow('back')}  ${chalk.yellow('forward')}  ${chalk.yellow('reload')}  ${chalk.gray('wait')}  ${chalk.red('close')}`
+  );
+  console.log();
+  console.log(chalk.dim('  Example:'));
+  console.log(
+    chalk.gray(`    curl -X POST localhost:${port} -d '{"cmd":"goto","url":"https://example.com"}'`)
+  );
+  console.log();
+}
+ 
+export class BrowserServer {
+  private browser: ClaudeBrowser;
+  private app = express();
+  private server: ReturnType<typeof this.app.listen> | null = null;
+  private port: number;
+ 
+  constructor(options: ServerOptions = {}) {
+    this.browser = new ClaudeBrowser(options);
+    this.port = options.port ?? 13373;
+    this.setupMiddleware();
+    this.setupRoutes();
+  }
+ 
+  private setupMiddleware(): void {
+    this.app.use(express.json());
+    this.app.use(express.text({ type: '*/*' }));
+  }
+ 
+  private setupRoutes(): void {
+    this.app.post('/', (req, res) => this.handleCommand(req, res));
+  }
+ 
+  private async handleCommand(req: Request, res: Response): Promise<void> {
+    try {
+      const cmd: BrowserCommand = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
+      logger.command(cmd);
+ 
+      Iif (cmd.cmd === 'close') {
+        logger.result(cmd, { ok: true });
+        res.json({ ok: true });
+        await this.stop();
+        process.exit(0);
+      }
+ 
+      const result = await this.browser.executeCommand(cmd);
+      logger.result(cmd, result);
+      res.json(result);
+    } catch (err) {
+      const error = (err as Error).message;
+      console.log(`${ts()}   ${logSymbols.error} ${chalk.red(error)}`);
+      res.status(500).json({ ok: false, error });
+    }
+  }
+ 
+  async start(): Promise<void> {
+    await this.browser.launch();
+ 
+    return new Promise((resolve) => {
+      this.server = this.app.listen(this.port, () => {
+        printBanner(this.port);
+        resolve();
+      });
+    });
+  }
+ 
+  async stop(): Promise<void> {
+    console.log(chalk.dim('\n  Shutting down...'));
+    Iif (this.server) {
+      this.server.close();
+      this.server = null;
+    }
+    await this.browser.close();
+    console.log(`  ${logSymbols.success} Browser closed\n`);
+  }
+ 
+  getPort(): number {
+    return this.port;
+  }
+ 
+  getApp() {
+    return this.app;
+  }
+}
+ 
+export async function startServer(options: ServerOptions = {}): Promise<BrowserServer> {
+  const server = new BrowserServer(options);
+  await server.start();
+  return server;
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000..6ed6831 Binary files /dev/null and b/coverage/sort-arrow-sprite.png differ diff --git a/coverage/sorter.js b/coverage/sorter.js new file mode 100644 index 0000000..4ed70ae --- /dev/null +++ b/coverage/sorter.js @@ -0,0 +1,210 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } + + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/types.ts.html b/coverage/types.ts.html new file mode 100644 index 0000000..76d2a09 --- /dev/null +++ b/coverage/types.ts.html @@ -0,0 +1,424 @@ + + + + + + Code coverage report for types.ts + + + + + + + + + +
+
+

All files types.ts

+
+ +
+ 0% + Statements + 0/0 +
+ + +
+ 0% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/0 +
+ + +
+ 0% + Lines + 0/0 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
export interface BrowserOptions {
+  headless?: boolean;
+  width?: number;
+  height?: number;
+}
+ 
+export interface ElementInfo {
+  tag: string;
+  text: string;
+  attributes: Record<string, string>;
+}
+ 
+// Command types
+export interface GotoCommand {
+  cmd: 'goto';
+  url: string;
+}
+ 
+export interface ClickCommand {
+  cmd: 'click';
+  selector: string;
+}
+ 
+export interface TypeCommand {
+  cmd: 'type';
+  selector: string;
+  text: string;
+}
+ 
+export interface QueryCommand {
+  cmd: 'query';
+  selector: string;
+}
+ 
+export interface ScreenshotCommand {
+  cmd: 'screenshot';
+  path?: string;
+  fullPage?: boolean;
+}
+ 
+export interface UrlCommand {
+  cmd: 'url';
+}
+ 
+export interface HtmlCommand {
+  cmd: 'html';
+  full?: boolean;
+}
+ 
+export interface BackCommand {
+  cmd: 'back';
+}
+ 
+export interface ForwardCommand {
+  cmd: 'forward';
+}
+ 
+export interface ReloadCommand {
+  cmd: 'reload';
+}
+ 
+export interface WaitCommand {
+  cmd: 'wait';
+  ms?: number;
+}
+ 
+export interface NewPageCommand {
+  cmd: 'newpage';
+}
+ 
+export interface CloseCommand {
+  cmd: 'close';
+}
+ 
+export interface EvalCommand {
+  cmd: 'eval';
+  script: string;
+}
+ 
+export type BrowserCommand =
+  | GotoCommand
+  | ClickCommand
+  | TypeCommand
+  | QueryCommand
+  | ScreenshotCommand
+  | UrlCommand
+  | HtmlCommand
+  | BackCommand
+  | ForwardCommand
+  | ReloadCommand
+  | WaitCommand
+  | NewPageCommand
+  | CloseCommand
+  | EvalCommand;
+ 
+// Response types
+export interface SuccessResponse {
+  ok: true;
+  url?: string;
+  title?: string;
+  path?: string;
+  html?: string;
+  count?: number;
+  elements?: ElementInfo[];
+  result?: unknown;
+}
+ 
+export interface ErrorResponse {
+  ok: false;
+  error: string;
+}
+ 
+export type CommandResponse = SuccessResponse | ErrorResponse;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index db4bc95..91c2964 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@aladac/claude-browse", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@aladac/claude-browse", - "version": "0.1.0", + "version": "0.1.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.26.0", @@ -16,18 +16,83 @@ "playwright": "^1.41.0" }, "bin": { - "claude-browse": "dist/cli.js" + "claude-browse": "dist/cli.js", + "claude-browse-mcp": "dist/mcp.js" }, "devDependencies": { "@biomejs/biome": "^1.9.0", "@types/express": "^5.0.6", "@types/node": "^20.11.0", - "typescript": "^5.3.0" + "@types/supertest": "^6.0.3", + "@vitest/coverage-v8": "^4.0.18", + "supertest": "^7.2.2", + "typescript": "^5.3.0", + "vitest": "^4.0.18" }, "engines": { "node": ">=18" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@biomejs/biome": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", @@ -192,6 +257,448 @@ "node": ">=14.21.3" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@hono/node-server": { "version": "1.19.9", "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", @@ -204,6 +711,34 @@ "hono": "^4" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.26.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", @@ -244,6 +779,386 @@ } } }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", + "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", + "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", + "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", + "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", + "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", + "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", + "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", + "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", + "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", + "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", + "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", + "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", + "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", + "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", + "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", + "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", + "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", + "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", + "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", + "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", + "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", + "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", + "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", + "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", + "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", + "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -255,6 +1170,17 @@ "@types/node": "*" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -265,6 +1191,27 @@ "@types/node": "*" } }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/express": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", @@ -297,6 +1244,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.19.32", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.32.tgz", @@ -342,6 +1296,172 @@ "@types/node": "*" } }, + "node_modules/@types/superagent": { + "version": "8.1.9", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", + "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/supertest": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz", + "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz", + "integrity": "sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.18", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.18", + "vitest": "4.0.18" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", + "integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", + "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", + "integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.18", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", + "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", + "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -388,6 +1508,42 @@ } } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.11.tgz", + "integrity": "sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -450,6 +1606,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", @@ -462,6 +1628,29 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", @@ -502,6 +1691,13 @@ "node": ">=6.6.0" } }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, "node_modules/cors": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", @@ -550,6 +1746,16 @@ } } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -559,6 +1765,17 @@ "node": ">= 0.8" } }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -606,6 +1823,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -618,12 +1842,80 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -654,6 +1946,16 @@ "node": ">=18.0.0" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", @@ -721,6 +2023,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", @@ -737,6 +2046,24 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", @@ -758,6 +2085,64 @@ "url": "https://opencollective.com/express" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formidable": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -848,6 +2233,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -860,6 +2255,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -881,6 +2292,13 @@ "node": ">=16.9.0" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -965,6 +2383,45 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jose": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", @@ -974,6 +2431,13 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -1002,6 +2466,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -1032,6 +2534,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -1063,6 +2588,25 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -1093,6 +2637,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -1142,6 +2697,33 @@ "url": "https://opencollective.com/express" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pkce-challenge": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", @@ -1181,6 +2763,35 @@ "node": ">=18" } }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1242,6 +2853,51 @@ "node": ">=0.10.0" } }, + "node_modules/rollup": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", + "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.57.1", + "@rollup/rollup-android-arm64": "4.57.1", + "@rollup/rollup-darwin-arm64": "4.57.1", + "@rollup/rollup-darwin-x64": "4.57.1", + "@rollup/rollup-freebsd-arm64": "4.57.1", + "@rollup/rollup-freebsd-x64": "4.57.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", + "@rollup/rollup-linux-arm-musleabihf": "4.57.1", + "@rollup/rollup-linux-arm64-gnu": "4.57.1", + "@rollup/rollup-linux-arm64-musl": "4.57.1", + "@rollup/rollup-linux-loong64-gnu": "4.57.1", + "@rollup/rollup-linux-loong64-musl": "4.57.1", + "@rollup/rollup-linux-ppc64-gnu": "4.57.1", + "@rollup/rollup-linux-ppc64-musl": "4.57.1", + "@rollup/rollup-linux-riscv64-gnu": "4.57.1", + "@rollup/rollup-linux-riscv64-musl": "4.57.1", + "@rollup/rollup-linux-s390x-gnu": "4.57.1", + "@rollup/rollup-linux-x64-gnu": "4.57.1", + "@rollup/rollup-linux-x64-musl": "4.57.1", + "@rollup/rollup-openbsd-x64": "4.57.1", + "@rollup/rollup-openharmony-arm64": "4.57.1", + "@rollup/rollup-win32-arm64-msvc": "4.57.1", + "@rollup/rollup-win32-ia32-msvc": "4.57.1", + "@rollup/rollup-win32-x64-gnu": "4.57.1", + "@rollup/rollup-win32-x64-msvc": "4.57.1", + "fsevents": "~2.3.2" + } + }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -1264,6 +2920,19 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", @@ -1408,6 +3077,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -1417,6 +3110,106 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/superagent": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", + "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.5", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.14.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz", + "integrity": "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie-signature": "^1.2.2", + "methods": "^1.1.2", + "superagent": "^10.3.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1479,6 +3272,174 @@ "node": ">= 0.8" } }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vitest": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", + "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.18", + "@vitest/mocker": "4.0.18", + "@vitest/pretty-format": "4.0.18", + "@vitest/runner": "4.0.18", + "@vitest/snapshot": "4.0.18", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.18", + "@vitest/browser-preview": "4.0.18", + "@vitest/browser-webdriverio": "4.0.18", + "@vitest/ui": "4.0.18", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1494,6 +3455,23 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index cc3fe1d..8efc143 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "check": "biome check src/", "fix": "biome check --write src/", "typecheck": "tsc --noEmit", + "test:unit": "vitest run --coverage --passWithNoTests", + "test:watch": "vitest", + "test": "npm run fix && npm run typecheck && npm run test:unit && npm run build", "prepublishOnly": "npm run build" }, "keywords": [ @@ -52,7 +55,11 @@ "@biomejs/biome": "^1.9.0", "@types/express": "^5.0.6", "@types/node": "^20.11.0", - "typescript": "^5.3.0" + "@types/supertest": "^6.0.3", + "@vitest/coverage-v8": "^4.0.18", + "supertest": "^7.2.2", + "typescript": "^5.3.0", + "vitest": "^4.0.18" }, "files": [ "dist", diff --git a/src/browser.test.ts b/src/browser.test.ts new file mode 100644 index 0000000..ac3d74e --- /dev/null +++ b/src/browser.test.ts @@ -0,0 +1,90 @@ +import { describe, expect, it } from 'vitest'; +import { ClaudeBrowser } from './browser.js'; + +describe('ClaudeBrowser', () => { + describe('constructor', () => { + it('creates browser with default options', () => { + const browser = new ClaudeBrowser(); + expect(browser).toBeInstanceOf(ClaudeBrowser); + }); + + it('accepts custom options', () => { + const browser = new ClaudeBrowser({ + headless: false, + width: 1920, + height: 1080, + }); + expect(browser).toBeInstanceOf(ClaudeBrowser); + }); + }); + + describe('ensurePage (via executeCommand)', () => { + it('throws error when browser not launched', async () => { + const browser = new ClaudeBrowser(); + const result = await browser.executeCommand({ cmd: 'url' }); + + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error).toContain('Browser not launched'); + } + }); + }); + + describe('executeCommand', () => { + it('returns error for commands without launch', async () => { + const browser = new ClaudeBrowser(); + + const gotoResult = await browser.executeCommand({ cmd: 'goto', url: 'https://example.com' }); + expect(gotoResult.ok).toBe(false); + + const clickResult = await browser.executeCommand({ cmd: 'click', selector: '#btn' }); + expect(clickResult.ok).toBe(false); + + const typeResult = await browser.executeCommand({ + cmd: 'type', + selector: '#input', + text: 'test', + }); + expect(typeResult.ok).toBe(false); + + const queryResult = await browser.executeCommand({ cmd: 'query', selector: '.item' }); + expect(queryResult.ok).toBe(false); + + const screenshotResult = await browser.executeCommand({ cmd: 'screenshot' }); + expect(screenshotResult.ok).toBe(false); + + const htmlResult = await browser.executeCommand({ cmd: 'html' }); + expect(htmlResult.ok).toBe(false); + + const backResult = await browser.executeCommand({ cmd: 'back' }); + expect(backResult.ok).toBe(false); + + const forwardResult = await browser.executeCommand({ cmd: 'forward' }); + expect(forwardResult.ok).toBe(false); + + const reloadResult = await browser.executeCommand({ cmd: 'reload' }); + expect(reloadResult.ok).toBe(false); + + const waitResult = await browser.executeCommand({ cmd: 'wait', ms: 100 }); + expect(waitResult.ok).toBe(false); + + const evalResult = await browser.executeCommand({ cmd: 'eval', script: '1+1' }); + expect(evalResult.ok).toBe(false); + }); + + it('handles close command without error when not launched', async () => { + const browser = new ClaudeBrowser(); + const result = await browser.executeCommand({ cmd: 'close' }); + expect(result.ok).toBe(true); + }); + + it('handles newpage command error when not launched', async () => { + const browser = new ClaudeBrowser(); + const result = await browser.executeCommand({ cmd: 'newpage' }); + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error).toContain('Browser not launched'); + } + }); + }); +}); diff --git a/src/logger.test.ts b/src/logger.test.ts new file mode 100644 index 0000000..3018748 --- /dev/null +++ b/src/logger.test.ts @@ -0,0 +1,125 @@ +import { describe, expect, it, vi } from 'vitest'; +import { + createLogger, + formatCommand, + formatResult, + getCommandDetail, + icons, + truncate, +} from './logger.js'; + +describe('truncate', () => { + it('returns string unchanged if shorter than max', () => { + expect(truncate('hello', 10)).toBe('hello'); + }); + + it('truncates and adds ellipsis if longer than max', () => { + expect(truncate('hello world', 5)).toBe('hello...'); + }); + + it('handles exact length', () => { + expect(truncate('hello', 5)).toBe('hello'); + }); +}); + +describe('icons', () => { + it('has icon for each command type', () => { + expect(icons.goto).toBe('→'); + expect(icons.click).toBe('◉'); + expect(icons.type).toBe('⌨'); + expect(icons.screenshot).toBe('📷'); + }); +}); + +describe('getCommandDetail', () => { + it('returns url for goto command', () => { + const result = getCommandDetail({ cmd: 'goto', url: 'https://example.com' }); + expect(result).toContain('https://example.com'); + }); + + it('returns selector for click command', () => { + const result = getCommandDetail({ cmd: 'click', selector: '#btn' }); + expect(result).toContain('#btn'); + }); + + it('returns selector and text for type command', () => { + const result = getCommandDetail({ cmd: 'type', selector: '#input', text: 'hello' }); + expect(result).toContain('#input'); + expect(result).toContain('hello'); + }); + + it('returns path for screenshot command', () => { + const result = getCommandDetail({ cmd: 'screenshot', path: 'test.png' }); + expect(result).toContain('test.png'); + }); + + it('returns default path when none provided for screenshot', () => { + const result = getCommandDetail({ cmd: 'screenshot' }); + expect(result).toContain('screenshot.png'); + }); + + it('returns undefined for url command', () => { + expect(getCommandDetail({ cmd: 'url' })).toBeUndefined(); + }); + + it('returns ms for wait command', () => { + const result = getCommandDetail({ cmd: 'wait', ms: 500 }); + expect(result).toContain('500'); + }); +}); + +describe('formatCommand', () => { + it('formats goto command', () => { + const result = formatCommand({ cmd: 'goto', url: 'https://example.com' }); + expect(result).toContain('GOTO'); + expect(result).toContain('https://example.com'); + }); + + it('formats click command', () => { + const result = formatCommand({ cmd: 'click', selector: '#btn' }); + expect(result).toContain('CLICK'); + expect(result).toContain('#btn'); + }); +}); + +describe('formatResult', () => { + it('formats error result', () => { + const result = formatResult({ cmd: 'goto' }, { ok: false, error: 'Failed' }); + expect(result).toContain('Failed'); + }); + + it('formats successful goto result with title', () => { + const result = formatResult({ cmd: 'goto' }, { ok: true, title: 'Example' }); + expect(result).toContain('Example'); + }); + + it('formats query result with count', () => { + const result = formatResult({ cmd: 'query' }, { ok: true, count: 5 }); + expect(result).toContain('5'); + }); +}); + +describe('createLogger', () => { + it('creates logger with custom log function', () => { + const logs: string[] = []; + const logFn = (msg: string) => logs.push(msg); + const logger = createLogger(logFn); + + logger.command({ cmd: 'goto', url: 'https://example.com' }); + expect(logs).toHaveLength(1); + expect(logs[0]).toContain('GOTO'); + + logger.result({ cmd: 'goto' }, { ok: true, title: 'Example' }); + expect(logs).toHaveLength(2); + }); + + it('logs command and result', () => { + const spy = vi.fn(); + const logger = createLogger(spy); + + logger.command({ cmd: 'click', selector: '#btn' }); + logger.result({ cmd: 'click' }, { ok: true, url: '/page' }); + + expect(spy).toHaveBeenCalledTimes(2); + }); +}); diff --git a/src/server.test.ts b/src/server.test.ts new file mode 100644 index 0000000..168c635 --- /dev/null +++ b/src/server.test.ts @@ -0,0 +1,123 @@ +import request from 'supertest'; +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +import { BrowserServer } from './server.js'; + +// Mock the browser module +vi.mock('./browser.js', () => ({ + ClaudeBrowser: class MockClaudeBrowser { + async launch() {} + async close() {} + async executeCommand(cmd: { cmd: string; url?: string }) { + switch (cmd.cmd) { + case 'goto': + return { ok: true, url: cmd.url, title: 'Test Page' }; + case 'click': + return { ok: true, url: '/clicked' }; + case 'type': + return { ok: true }; + case 'query': + return { ok: true, count: 2, elements: [] }; + case 'url': + return { ok: true, url: 'https://example.com', title: 'Example' }; + case 'html': + return { ok: true, html: '' }; + default: + return { ok: true }; + } + } + }, +})); + +describe('BrowserServer', () => { + let server: BrowserServer; + + beforeAll(async () => { + server = new BrowserServer({ port: 0 }); // Use port 0 to get random available port + }); + + afterAll(async () => { + await server.stop(); + }); + + describe('constructor', () => { + it('creates server with default port', () => { + const s = new BrowserServer(); + expect(s.getPort()).toBe(13373); + }); + + it('creates server with custom port', () => { + const s = new BrowserServer({ port: 8080 }); + expect(s.getPort()).toBe(8080); + }); + }); + + describe('POST /', () => { + it('handles goto command', async () => { + const app = server.getApp(); + const res = await request(app) + .post('/') + .send({ cmd: 'goto', url: 'https://example.com' }) + .expect(200); + + expect(res.body.ok).toBe(true); + expect(res.body.url).toBe('https://example.com'); + expect(res.body.title).toBe('Test Page'); + }); + + it('handles click command', async () => { + const app = server.getApp(); + const res = await request(app).post('/').send({ cmd: 'click', selector: '#btn' }).expect(200); + + expect(res.body.ok).toBe(true); + expect(res.body.url).toBe('/clicked'); + }); + + it('handles type command', async () => { + const app = server.getApp(); + const res = await request(app) + .post('/') + .send({ cmd: 'type', selector: '#input', text: 'hello' }) + .expect(200); + + expect(res.body.ok).toBe(true); + }); + + it('handles query command', async () => { + const app = server.getApp(); + const res = await request(app) + .post('/') + .send({ cmd: 'query', selector: '.items' }) + .expect(200); + + expect(res.body.ok).toBe(true); + expect(res.body.count).toBe(2); + }); + + it('handles url command', async () => { + const app = server.getApp(); + const res = await request(app).post('/').send({ cmd: 'url' }).expect(200); + + expect(res.body.ok).toBe(true); + expect(res.body.url).toBe('https://example.com'); + }); + + it('handles html command', async () => { + const app = server.getApp(); + const res = await request(app).post('/').send({ cmd: 'html' }).expect(200); + + expect(res.body.ok).toBe(true); + expect(res.body.html).toBe(''); + }); + + it('handles JSON string body', async () => { + const app = server.getApp(); + const res = await request(app) + .post('/') + .set('Content-Type', 'text/plain') + .send(JSON.stringify({ cmd: 'url' })) + .expect(200); + + expect(res.body.ok).toBe(true); + }); + }); +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..f4b5db5 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['src/**/*.test.ts'], + coverage: { + provider: 'v8', + include: ['src/**/*.ts'], + exclude: ['src/**/*.test.ts', 'src/cli.ts', 'src/mcp.ts', 'src/index.ts'], + }, + }, +});