From ca200bfa470d393f17569039614f642ed7fa000c Mon Sep 17 00:00:00 2001 From: milstan Date: Wed, 22 Apr 2026 10:56:31 -0700 Subject: [PATCH] fix(mcp,core,dxt): #3504 DXT install warning, 401 message, .dxt bundle (0.2.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to Ludo's 2026-04-22 handoff session on @leadbay/mcp@0.2.2. This release addresses three client-side items from product#3504 and reships the already-merged refine_prompt fix (product#3508) that didn't make it to npm. - `install` now detects Claude Desktop 2026 DXT (via Claude Extensions/, extensions-installations.json, or dxt:* keys in config.json) and default-skips the legacy claude_desktop_config.json write — the app overwrites that file on every prefs save, so our previous "registered" message was misleading. Pass --force-legacy to override. The warning points at the .dxt bundle. - New @leadbay/dxt workspace builds a DXT 0.2 bundle (manifest + bundled server + icon) and CI uploads it to each GitHub Release. Users can drag-drop into Claude Desktop → Settings → Extensions; dialog asks for token + region + write-toggle (no terminal). - `login` 401 errors no longer end with a dangling colon on empty-body responses. New shared helper formatLoginError in @leadbay/core adds status-appropriate hints (wrong email or password? / rate-limited / server error). - README note on `npm install -g` EACCES (sudo / npx / nvm workarounds). - Also shipping: refine_prompt / set_user_prompt wire-key fix from 307d97a (product#3508) that was merged to main but hasn't been published yet. Tests: +8 login-error units, +9 dxt-detection units, +5 dxt-package smoke. All 144 existing tests still green. Out of scope: the adjust_audience 500 from Ludo's session is a backend taxonomy-resolution bug; tracked separately. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release.yml | 25 +- packages/core/src/client.ts | 37 +- packages/core/src/index.ts | 1 + packages/core/test/unit/login-error.test.ts | 73 ++ packages/dxt/manifest.template.json | 71 ++ packages/dxt/package.json | 17 + packages/dxt/scripts/build.mjs | 101 +++ packages/leadclaw/CHANGELOG.md | 4 + packages/leadclaw/openclaw.plugin.json | 2 +- packages/leadclaw/package.json | 2 +- packages/mcp/CHANGELOG.md | 10 + packages/mcp/README.md | 12 + packages/mcp/package.json | 2 +- packages/mcp/src/bin.ts | 110 ++- packages/mcp/test/smoke/dxt-package.test.ts | 79 ++ packages/mcp/test/unit/dxt-detection.test.ts | 118 +++ pnpm-lock.yaml | 866 +++++++++++++++++++ 17 files changed, 1506 insertions(+), 24 deletions(-) create mode 100644 packages/core/test/unit/login-error.test.ts create mode 100644 packages/dxt/manifest.template.json create mode 100644 packages/dxt/package.json create mode 100644 packages/dxt/scripts/build.mjs create mode 100644 packages/mcp/test/smoke/dxt-package.test.ts create mode 100644 packages/mcp/test/unit/dxt-detection.test.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 67aed90..bdf48d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,8 +65,8 @@ jobs: (github.event_name == 'workflow_dispatch' && github.event.inputs.package == 'mcp') runs-on: ubuntu-latest permissions: - contents: read - id-token: write # npm provenance + contents: write # gh release create/upload for the .dxt bundle + id-token: write # npm provenance steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 @@ -117,6 +117,27 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Build .dxt bundle + if: github.event_name == 'push' + run: pnpm --filter @leadbay/dxt build + + - name: Upload .dxt to GitHub Release + if: github.event_name == 'push' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + TAG="${GITHUB_REF#refs/tags/}" + # gh release upload needs a release to exist. Create it if the tag + # wasn't already promoted to a release (auto-tag.yml only pushes tags). + if ! gh release view "$TAG" >/dev/null 2>&1; then + gh release create "$TAG" \ + --title "$TAG" \ + --notes "Automated release for $TAG — see CHANGELOG.md" + fi + gh release upload "$TAG" packages/dxt/dist/*.dxt --clobber + echo "Uploaded .dxt to release $TAG" + publish-leadclaw: name: Publish @leadbay/leadclaw to npm + ClawHub needs: preflight-npm diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 12dc215..6d266c1 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -93,6 +93,26 @@ export function createClient(config: CreateClientConfig = {}): LeadbayClient { return new LeadbayClient(baseUrl, config.token, region); } +// Human-readable login error. Backends sometimes return 401 with an empty body; +// naive `${baseUrl}: ${body}` leaves a dangling colon. Attach a status-specific +// hint so non-technical users see "wrong email or password?" instead of a bare +// status code. +export function formatLoginError( + status: number, + body: string, + baseUrl: string +): string { + const trimmed = body.trim(); + const head = `login failed (${status}) at ${baseUrl}`; + const hint = + status === 401 ? " (wrong email or password?)" + : status === 429 ? " (rate-limited; wait and retry)" + : status >= 500 ? " (server error; try again shortly)" + : ""; + if (!trimmed) return head + hint; + return `${head}: ${trimmed.slice(0, 200)}${hint}`; +} + // Probe both regions to find which one this email/password works on. // Returns the region (us|fr) and bearer token. Throws if neither succeeds. export async function resolveRegion( @@ -103,7 +123,9 @@ export async function resolveRegion( const order: Array<"us" | "fr"> = startWith === "fr" ? ["fr", "us"] : ["us", "fr"]; - let lastErr: any = null; + let lastErr: { kind: "http"; status: number; body: string; region: "us" | "fr"; baseUrl: string } | + { kind: "network"; error: unknown; region: "us" | "fr"; baseUrl: string } | + null = null; for (const region of order) { const baseUrl = REGIONS[region]; const body = JSON.stringify({ email, password }); @@ -125,16 +147,19 @@ export async function resolveRegion( }; } } - lastErr = { status: res.status, body: res.body, region }; + lastErr = { kind: "http", status: res.status, body: res.body, region, baseUrl }; } catch (e) { - lastErr = { error: e, region }; + lastErr = { kind: "network", error: e, region, baseUrl }; } } + const detail = lastErr?.kind === "http" + ? formatLoginError(lastErr.status, lastErr.body, lastErr.baseUrl) + : lastErr?.kind === "network" + ? `network error at ${lastErr.baseUrl}: ${(lastErr.error as Error)?.message ?? String(lastErr.error)}` + : "no attempts made"; throw new Error( - `Leadbay login failed in both regions (us, fr). Last response: ${JSON.stringify( - lastErr - )}` + `Leadbay login failed in both regions (us, fr). ${detail}` ); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 14fdbf9..d8f3439 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,6 +2,7 @@ export { LeadbayClient, createClient, resolveRegion, + formatLoginError, getMockJournal, clearMockJournal, REGIONS, diff --git a/packages/core/test/unit/login-error.test.ts b/packages/core/test/unit/login-error.test.ts new file mode 100644 index 0000000..c35f7be --- /dev/null +++ b/packages/core/test/unit/login-error.test.ts @@ -0,0 +1,73 @@ +/** + * Unit tests for formatLoginError. + * + * Regression guard for #3504: when the backend returns 401 with an empty body, + * the previous message ended with a dangling colon ("login failed (401) at + * https://api-fr.leadbay.app:"). This formatter has to stay user-legible for + * the main failure modes: bad credentials, rate-limiting, server error. + */ +import { describe, it, expect } from "vitest"; +import { formatLoginError } from "../../src/client.js"; + +const URL_US = "https://api-us.leadbay.app"; +const URL_FR = "https://api-fr.leadbay.app"; + +describe("formatLoginError", () => { + it("401 with empty body → suggests wrong credentials, no dangling colon", () => { + const msg = formatLoginError(401, "", URL_FR); + expect(msg).toBe( + "login failed (401) at https://api-fr.leadbay.app (wrong email or password?)" + ); + expect(msg).not.toMatch(/:\s*$/); + expect(msg).not.toMatch(/:\s*\(/); // no " : (" sequence + }); + + it("401 with body → includes body AND the credentials hint", () => { + const msg = formatLoginError(401, '{"error":"invalid_credentials"}', URL_FR); + expect(msg).toContain("login failed (401) at https://api-fr.leadbay.app"); + expect(msg).toContain('{"error":"invalid_credentials"}'); + expect(msg).toContain("(wrong email or password?)"); + }); + + it("429 with empty body → rate-limit hint", () => { + const msg = formatLoginError(429, "", URL_US); + expect(msg).toBe( + "login failed (429) at https://api-us.leadbay.app (rate-limited; wait and retry)" + ); + }); + + it("500 with body → server error hint", () => { + const msg = formatLoginError(500, "internal server error", URL_US); + expect(msg).toContain("login failed (500)"); + expect(msg).toContain("internal server error"); + expect(msg).toContain("(server error; try again shortly)"); + }); + + it("502 with empty body → server error hint, no dangling colon", () => { + const msg = formatLoginError(502, "", URL_FR); + expect(msg).toBe( + "login failed (502) at https://api-fr.leadbay.app (server error; try again shortly)" + ); + }); + + it("403 (uncommon) with empty body → no hint, but also no dangling colon", () => { + const msg = formatLoginError(403, "", URL_US); + expect(msg).toBe("login failed (403) at https://api-us.leadbay.app"); + }); + + it("very long body is truncated at 200 chars", () => { + const long = "x".repeat(500); + const msg = formatLoginError(401, long, URL_US); + // 200 chars of body + separator/hint framing. + expect(msg).toContain("x".repeat(200)); + expect(msg).not.toContain("x".repeat(201)); + expect(msg).toContain("(wrong email or password?)"); + }); + + it("body with surrounding whitespace is treated as empty", () => { + const msg = formatLoginError(401, " \n\t ", URL_FR); + expect(msg).toBe( + "login failed (401) at https://api-fr.leadbay.app (wrong email or password?)" + ); + }); +}); diff --git a/packages/dxt/manifest.template.json b/packages/dxt/manifest.template.json new file mode 100644 index 0000000..e14602e --- /dev/null +++ b/packages/dxt/manifest.template.json @@ -0,0 +1,71 @@ +{ + "dxt_version": "0.2", + "name": "leadbay", + "display_name": "Leadbay", + "version": "{{VERSION}}", + "description": "AI lead discovery, qualification, and outreach prep. Ask Claude to find, research, and prepare outreach on B2B prospects using your Leadbay account.", + "long_description": "Leadbay MCP surfaces your Leadbay inbox to Claude — fresh daily batches of AI-qualified leads, deep research on any company or contact, outreach-ready prep (email + LinkedIn), and outreach logging. Requires a Leadbay account (https://leadbay.ai).", + "icon": "icon.png", + "author": { + "name": "Leadbay", + "email": "support@leadbay.ai", + "url": "https://leadbay.ai" + }, + "homepage": "https://github.com/leadbay/leadclaw", + "documentation": "https://github.com/leadbay/leadclaw#readme", + "support": "https://github.com/leadbay/leadclaw/issues", + "repository": { + "type": "git", + "url": "https://github.com/leadbay/leadclaw" + }, + "license": "MIT", + "keywords": [ + "leadbay", + "mcp", + "b2b", + "lead-generation", + "sales" + ], + "server": { + "type": "node", + "entry_point": "server/index.js", + "mcp_config": { + "command": "node", + "args": ["${__dirname}/server/index.js"], + "env": { + "LEADBAY_TOKEN": "${user_config.leadbay_token}", + "LEADBAY_REGION": "${user_config.leadbay_region}", + "LEADBAY_MCP_WRITE": "${user_config.leadbay_mcp_write}" + } + } + }, + "user_config": { + "leadbay_token": { + "type": "string", + "title": "Leadbay bearer token", + "description": "Mint one with: npx -y @leadbay/mcp login --email --region --write-config ~/leadbay.json (then copy the token from that file)", + "sensitive": true, + "required": true + }, + "leadbay_region": { + "type": "string", + "title": "Region", + "description": "Leadbay backend for your account (us or fr). If you don't know, try fr first — EU accounts are the default.", + "enum": ["us", "fr"], + "default": "fr", + "required": true + }, + "leadbay_mcp_write": { + "type": "boolean", + "title": "Enable write tools", + "description": "Let Claude mutate your Leadbay account (refine_prompt, adjust_audience, report_outreach). Off by default — enable only when you want the agent to modify state.", + "default": false, + "required": false + } + }, + "compatibility": { + "runtimes": { + "node": ">=22" + } + } +} diff --git a/packages/dxt/package.json b/packages/dxt/package.json new file mode 100644 index 0000000..4be4de7 --- /dev/null +++ b/packages/dxt/package.json @@ -0,0 +1,17 @@ +{ + "name": "@leadbay/dxt", + "version": "0.2.4", + "private": true, + "type": "module", + "description": "Builds the Leadbay .dxt bundle (Claude Desktop 2026 extension format) from @leadbay/mcp.", + "scripts": { + "build": "node scripts/build.mjs", + "typecheck": "node -e \"1\"", + "test": "node -e \"1\"" + }, + "devDependencies": { + "@leadbay/mcp": "workspace:*", + "archiver": "^7.0.1", + "esbuild": "^0.25.0" + } +} diff --git a/packages/dxt/scripts/build.mjs b/packages/dxt/scripts/build.mjs new file mode 100644 index 0000000..c21c53b --- /dev/null +++ b/packages/dxt/scripts/build.mjs @@ -0,0 +1,101 @@ +#!/usr/bin/env node +// Build the Leadbay .dxt bundle. +// +// Output: packages/dxt/dist/leadbay-.dxt +// +// The .dxt is a zip with: +// - manifest.json (from manifest.template.json, version substituted) +// - server/index.js (esbuild bundle of packages/mcp/src/bin.ts, +// plus a "stdio-entry.mjs"-style wrapper that +// always runs the MCP server, never the CLI) +// - icon.png (from packages/leadclaw/logo.png) +// - README.md (from packages/mcp/README.md) +// +// Why bundle bin.ts? Its `isEntrypoint` guard already handles the dual CLI / +// server mode. When DXT invokes `node server/index.js`, process.argv[1] is +// server/index.js and no subcommand is passed → the server starts. +import { mkdirSync, writeFileSync, readFileSync, rmSync, createWriteStream, existsSync, copyFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; +import { build } from "esbuild"; +import archiver from "archiver"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const DXT_DIR = dirname(__dirname); // packages/dxt +const REPO_ROOT = dirname(dirname(DXT_DIR)); // +const MCP_DIR = join(REPO_ROOT, "packages", "mcp"); +const LEADCLAW_DIR = join(REPO_ROOT, "packages", "leadclaw"); +const DIST_DIR = join(DXT_DIR, "dist"); +const STAGE_DIR = join(DIST_DIR, "stage"); + +function readJson(path) { + return JSON.parse(readFileSync(path, "utf8")); +} + +async function main() { + const mcpPkg = readJson(join(MCP_DIR, "package.json")); + const version = mcpPkg.version; + + // Fresh staging. + if (existsSync(DIST_DIR)) rmSync(DIST_DIR, { recursive: true, force: true }); + mkdirSync(join(STAGE_DIR, "server"), { recursive: true }); + + // 1. Render manifest. + const manifestTpl = readFileSync(join(DXT_DIR, "manifest.template.json"), "utf8"); + const manifest = manifestTpl.replaceAll("{{VERSION}}", version); + // Validate it parses. + JSON.parse(manifest); + writeFileSync(join(STAGE_DIR, "manifest.json"), manifest, "utf8"); + + // 2. Bundle bin.ts into a single server/index.js. + // - platform: node, format: esm (bin.ts uses top-level await + import.meta). + // - target: node22 (DXT ships Node 22+ in Claude Desktop). + // - External: nothing. DXT bundles are self-contained; we don't want the + // Claude Desktop runtime resolving our deps. + // - Define __LEADBAY_MCP_VERSION__ the same way tsup does. + await build({ + entryPoints: [join(MCP_DIR, "src", "bin.ts")], + bundle: true, + platform: "node", + format: "esm", + target: "node22", + outfile: join(STAGE_DIR, "server", "index.js"), + external: [], + define: { + __LEADBAY_MCP_VERSION__: JSON.stringify(version), + }, + banner: { + js: "#!/usr/bin/env node", + }, + logLevel: "info", + }); + + // 3. Assets. + copyFileSync(join(LEADCLAW_DIR, "logo.png"), join(STAGE_DIR, "icon.png")); + if (existsSync(join(MCP_DIR, "README.md"))) { + copyFileSync(join(MCP_DIR, "README.md"), join(STAGE_DIR, "README.md")); + } + + // 4. Zip. + const dxtPath = join(DIST_DIR, `leadbay-${version}.dxt`); + await new Promise((resolve, reject) => { + const out = createWriteStream(dxtPath); + const archive = archiver("zip", { zlib: { level: 9 } }); + out.on("close", resolve); + out.on("error", reject); + archive.on("error", reject); + archive.pipe(out); + archive.directory(STAGE_DIR, false); + archive.finalize(); + }); + + const { statSync } = await import("node:fs"); + const bytes = statSync(dxtPath).size; + console.log(`\n✓ built ${dxtPath} (${(bytes / 1024).toFixed(1)} KB)`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/packages/leadclaw/CHANGELOG.md b/packages/leadclaw/CHANGELOG.md index da816c0..0aa2e26 100644 --- a/packages/leadclaw/CHANGELOG.md +++ b/packages/leadclaw/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog — @leadbay/leadclaw +## 0.2.4 — 2026-04-22 + +Version kept in sync with `@leadbay/mcp@0.2.4`. Picks up `@leadbay/core`'s new `formatLoginError` helper so login failures surface a readable error instead of a dangling colon ([product#3504](https://github.com/leadbay/product/issues/3504)). No OpenClaw-facing contract changes in this release. + ## 0.2.3 — 2026-04-21 Bug fix release. Picks up `@leadbay/core@0.2.2` underneath. diff --git a/packages/leadclaw/openclaw.plugin.json b/packages/leadclaw/openclaw.plugin.json index 027fde4..91154c5 100644 --- a/packages/leadclaw/openclaw.plugin.json +++ b/packages/leadclaw/openclaw.plugin.json @@ -2,7 +2,7 @@ "id": "leadclaw", "name": "LeadClaw", "description": "Leadbay for AI agents: a daily sales-lead inbox with firmographic + AI qualification layers, plus on-demand deeper qualification and contact enrichment. Each login delivers a fresh batch of leads paced by the user's recent consumption; the agent skims, deepens promising ones, and proposes outreach.", - "version": "0.2.3", + "version": "0.2.4", "contracts": { "tools": [ "leadbay_login", diff --git a/packages/leadclaw/package.json b/packages/leadclaw/package.json index a34b4ca..56a2acc 100644 --- a/packages/leadclaw/package.json +++ b/packages/leadclaw/package.json @@ -1,6 +1,6 @@ { "name": "@leadbay/leadclaw", - "version": "0.2.3", + "version": "0.2.4", "description": "OpenClaw plugin for Leadbay — AI lead discovery, qualification, and enrichment", "type": "module", "main": "dist/index.js", diff --git a/packages/mcp/CHANGELOG.md b/packages/mcp/CHANGELOG.md index 6c26fe9..3b658ea 100644 --- a/packages/mcp/CHANGELOG.md +++ b/packages/mcp/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog — @leadbay/mcp +## 0.2.4 — 2026-04-22 + +Claude Desktop 2026 compatibility + install UX polish. Also publishes the `refine_prompt` `/user_prompt` wire-key fix that landed on `main` in 0.2.3 but never reached npm. + +- **Fix [product#3504](https://github.com/leadbay/product/issues/3504)** — `install --target claude-desktop` no longer silently no-ops on Claude Desktop 2026. The app moved to the DXT (Desktop Extension) system; the legacy `claude_desktop_config.json` is UI-prefs-only there and gets overwritten on every prefs save, so a block written to it disappears a few minutes later. `install` now detects DXT (via `Claude Extensions/`, `extensions-installations.json`, or `dxt:*` keys in `config.json`), prints a loud warning pointing at the `.dxt` bundle, and default-skips the legacy write. Pass `--force-legacy` to override. +- **New: shipping a `.dxt` bundle** — drag-drop into Claude Desktop 2026 → Settings → Extensions. Uploaded to each [GitHub Release](https://github.com/leadbay/leadclaw/releases). Dialog asks for token + region + write-toggle; no terminal required. Manifest is DXT 0.2 (`dxt_version: "0.2"`, `user_config.leadbay_token.sensitive: true`). Source for the build lives in `packages/dxt/`. +- **Fix**: `login` 401 errors no longer end with a dangling `:` when the backend returns an empty body. Messages now read `login failed (401) at (wrong email or password?)`. 429/5xx get their own hints too. The core helper `formatLoginError` is exported from `@leadbay/core` so the MCP and ClawHub surfaces stay in sync. +- **README**: new section on `npm install -g` EACCES (sudo / npx / nvm workarounds — common on the official nodejs.org `.pkg`), and a pointer to the `.dxt` install for Claude Desktop 2026. +- **Also shipping** (previously merged but not yet published to npm) — `leadbay_refine_prompt` / `leadbay_set_user_prompt` now send `{ user_prompt }` instead of `{ prompt }` to `POST /user_prompt` ([product#3508](https://github.com/leadbay/product/issues/3508)). Fixes the JSON deserialization 400 Ludo hit during the 0.2.2 install session. + ## 0.2.3 — 2026-04-21 Bug fix release. diff --git a/packages/mcp/README.md b/packages/mcp/README.md index 9190a04..45d38d1 100644 --- a/packages/mcp/README.md +++ b/packages/mcp/README.md @@ -35,6 +35,18 @@ The token is **session-scoped** (full account access, password-equivalent). Trea **Don't have a Leadbay account?** [Register here](https://wow.leadbay.ai/?register=true). +### Claude Desktop 2026 (DXT) + +Claude Desktop 2026 ships the DXT (Desktop Extension) system — the legacy `claude_desktop_config.json` is UI-prefs-only there and gets overwritten by the app. If you're on 2026, **install the `.dxt` bundle** from [Releases](https://github.com/leadbay/leadclaw/releases/latest) (drag-drop into Settings → Extensions). `leadbay-mcp install` detects this and skips the legacy write automatically. + +### `npm install -g` says "EACCES" / "permission denied" + +If you installed Node from the official [nodejs.org](https://nodejs.org) `.pkg`, `/usr/local/lib/node_modules` is root-owned. Any of these works: + +- **Use `npx` (recommended, no global install):** all examples above use `npx -y @leadbay/mcp@0.2 ...` — no global install needed. +- **`sudo npm install -g @leadbay/mcp`** (enter your macOS password). +- **Use a Node version manager** — [nvm](https://github.com/nvm-sh/nvm), [volta](https://volta.sh), [fnm](https://github.com/Schniz/fnm). They install Node under your home directory, so `npm install -g` works without sudo. + ### If you'd rather mint a token without auto-install ```bash diff --git a/packages/mcp/package.json b/packages/mcp/package.json index ca7c8bf..d897269 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@leadbay/mcp", - "version": "0.2.3", + "version": "0.2.4", "description": "Model Context Protocol (MCP) server for Leadbay — AI lead discovery, qualification, and enrichment for Claude Desktop, Cursor, and Claude Code.", "type": "module", "bin": { diff --git a/packages/mcp/src/bin.ts b/packages/mcp/src/bin.ts index 8bce56a..ac89ed8 100644 --- a/packages/mcp/src/bin.ts +++ b/packages/mcp/src/bin.ts @@ -4,6 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { createClient, createDefaultBulkStore, + formatLoginError, LeadbayClient, resolveRegion, type CreateClientConfig, @@ -397,9 +398,7 @@ async function loginAt(baseUrl: string, email: string, password: string): Promis } } reject( - new Error( - `login failed (${res.statusCode}) at ${baseUrl}: ${raw.slice(0, 200)}` - ) + new Error(formatLoginError(res.statusCode ?? 0, raw, baseUrl)) ); }); } @@ -412,11 +411,48 @@ async function loginAt(baseUrl: string, email: string, password: string): Promis // ─── install: one-shot mint + register ──────────────────────────────────── +interface DesktopMode { + legacy: boolean; // claude_desktop_config.json exists + dxt: boolean; // DXT extension system is in use + markers: string[]; // which DXT markers were seen (for warning text) +} + interface DetectedClient { id: "claude-code" | "claude-desktop" | "cursor"; label: string; // Where it'll be installed (path or "(claude CLI)" for shell-out targets). detail: string; + // Claude Desktop only: which config system is on this machine. + mode?: DesktopMode; +} + +// Claude Desktop 2026 uses DXT (Desktop Extension) packaging. The legacy +// claude_desktop_config.json still exists for UI prefs but MCP servers +// written there are wiped by the app. Detect the new system so `install` +// can warn / default-skip instead of silently failing. +export function detectClaudeDesktopMode(claudeSupportDir: string): DesktopMode { + const { existsSync, readFileSync } = require_("node:fs"); + const { join } = require_("node:path"); + const markers: string[] = []; + const legacy = existsSync(join(claudeSupportDir, "claude_desktop_config.json")); + if (existsSync(join(claudeSupportDir, "Claude Extensions"))) { + markers.push("Claude Extensions/"); + } + if (existsSync(join(claudeSupportDir, "extensions-installations.json"))) { + markers.push("extensions-installations.json"); + } + const cfgPath = join(claudeSupportDir, "config.json"); + if (existsSync(cfgPath)) { + try { + const raw = readFileSync(cfgPath, "utf8"); + const parsed = JSON.parse(raw); + if (parsed && typeof parsed === "object") { + const hasDxtKey = Object.keys(parsed).some((k) => k.startsWith("dxt:")); + if (hasDxtKey) markers.push("config.json (dxt:* keys)"); + } + } catch { /* malformed — ignore */ } + } + return { legacy, dxt: markers.length > 0, markers }; } async function detectClients(): Promise { @@ -440,16 +476,28 @@ async function detectClients(): Promise { out.push({ id: "claude-code", label: "Claude Code", detail: `${claudeBin} mcp add ...` }); } - // Claude Desktop config file. + // Claude Desktop: check both legacy file and DXT markers. const home = os.homedir(); - const cdPath = + const claudeSupportDir = process.platform === "win32" - ? `${process.env.APPDATA ?? `${home}\\AppData\\Roaming`}\\Claude\\claude_desktop_config.json` + ? `${process.env.APPDATA ?? `${home}\\AppData\\Roaming`}\\Claude` : process.platform === "darwin" - ? `${home}/Library/Application Support/Claude/claude_desktop_config.json` - : `${home}/.config/Claude/claude_desktop_config.json`; - if (existsSync(cdPath)) { - out.push({ id: "claude-desktop", label: "Claude Desktop", detail: cdPath }); + ? `${home}/Library/Application Support/Claude` + : `${home}/.config/Claude`; + const cdPath = + process.platform === "win32" + ? `${claudeSupportDir}\\claude_desktop_config.json` + : `${claudeSupportDir}/claude_desktop_config.json`; + const mode = detectClaudeDesktopMode(claudeSupportDir); + // Include claude-desktop if EITHER the legacy file or DXT markers exist, + // so we can warn even when the app has already wiped the legacy block. + if (mode.legacy || mode.dxt) { + out.push({ + id: "claude-desktop", + label: "Claude Desktop", + detail: cdPath, + mode, + }); } // Cursor config — Cursor stores MCP config in ~/.cursor/mcp.json. @@ -626,13 +674,17 @@ async function runInstall(args: string[]): Promise { process.stderr.write( "Usage: leadbay-mcp install --email you@example.com [--region us|fr]\n" + " [--allow-region-fallback] [--include-write]\n" + - " [--target claude-code,claude-desktop,cursor] [--yes]\n" + + " [--target claude-code,claude-desktop,cursor]\n" + + " [--yes] [--force-legacy]\n" + " Mints a token AND registers the MCP server with your installed clients.\n" + " --target Comma-separated subset; default = all detected.\n" + " --include-write Enable LEADBAY_MCP_WRITE=1 (composite write tools — refine_prompt,\n" + " report_outreach, adjust_audience). Off by default; off means the\n" + " agent can read your Leadbay account but not mutate it.\n" + - " --yes Don't ask before installing into each detected client.\n" + " --yes Don't ask before installing into each detected client.\n" + + " --force-legacy Write to claude_desktop_config.json even when Claude Desktop 2026\n" + + " DXT is detected. Not recommended — the app overwrites that file.\n" + + " Use the .dxt bundle instead: https://github.com/leadbay/leadclaw/releases\n" ); return 2; } @@ -684,9 +736,29 @@ async function runInstall(args: string[]): Promise { process.stderr.write( `\nleadbay-mcp install — detected MCP clients on this machine:\n` ); - for (const c of chosen) process.stderr.write(` • ${c.label.padEnd(16)} ${c.detail}\n`); + for (const c of chosen) { + const dxtSuffix = c.mode?.dxt ? " [DXT — legacy write will be skipped]" : ""; + process.stderr.write(` • ${c.label.padEnd(16)} ${c.detail}${dxtSuffix}\n`); + } process.stderr.write("\n"); + // Surface the DXT warning BEFORE prompting for password so the user can + // abort without typing credentials if they realize the legacy path is + // hopeless on this machine. Per-client loop below also short-circuits. + const forceLegacy = hasFlag(args, "force-legacy"); + const hasDxtClient = chosen.some((c) => c.id === "claude-desktop" && c.mode?.dxt); + if (hasDxtClient && !forceLegacy) { + const dxtClient = chosen.find((c) => c.id === "claude-desktop" && c.mode?.dxt)!; + process.stderr.write( + `⚠️ Claude Desktop 2026 DXT detected (markers: ${dxtClient.mode!.markers.join(", ")}).\n` + + ` The legacy claude_desktop_config.json is UI-prefs-only in this version —\n` + + ` Claude Desktop will overwrite any \`mcpServers\` block written there.\n` + + ` Install the Leadbay .dxt instead (drag-drop into Settings → Extensions):\n` + + ` https://github.com/leadbay/leadclaw/releases/latest\n` + + ` Override with --force-legacy to write the legacy file anyway (not recommended).\n\n` + ); + } + // Prompt for password BEFORE asking confirmations — so users who change their // mind after typing the password don't have to redo it. const password = await readPassword(); @@ -727,6 +799,18 @@ async function runInstall(args: string[]): Promise { const results: Array<{ id: string; label: string; ok: boolean; message: string }> = []; for (const c of chosen) { + // Claude Desktop 2026 ships DXT: writing to the legacy file is futile — + // the app overwrites it on the next prefs save. We already printed the + // warning above (before password prompt); here we just short-circuit. + if (c.id === "claude-desktop" && c.mode?.dxt && !forceLegacy) { + results.push({ + id: c.id, + label: c.label, + ok: false, + message: "skipped (DXT detected — install the .dxt bundle instead)", + }); + continue; + } const ok = skipPrompts || (await readChoice(`Install into ${c.label} (${c.detail})?`, true)); if (!ok) { results.push({ id: c.id, label: c.label, ok: false, message: "skipped by user" }); diff --git a/packages/mcp/test/smoke/dxt-package.test.ts b/packages/mcp/test/smoke/dxt-package.test.ts new file mode 100644 index 0000000..446d941 --- /dev/null +++ b/packages/mcp/test/smoke/dxt-package.test.ts @@ -0,0 +1,79 @@ +/** + * Smoke test for the .dxt bundle built by @leadbay/dxt. + * + * Guards the published archive's shape so a broken manifest doesn't ship: + * - dxt_version / name / version wire-match + * - server entry_point file is actually in the archive + * - user_config.leadbay_token is marked sensitive + * + * Gated on the .dxt existing — `pnpm --filter @leadbay/dxt build` produces it; + * if not built, this test is skipped (same pattern as npx-entrypoint.test.ts). + */ +import { describe, it, expect } from "vitest"; +import { existsSync, readFileSync, readdirSync } from "node:fs"; +import { execFileSync } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const DXT_DIST = path.resolve(__dirname, "..", "..", "..", "dxt", "dist"); + +function findDxt(): string | null { + if (!existsSync(DXT_DIST)) return null; + const entries = readdirSync(DXT_DIST).filter((f) => f.endsWith(".dxt")); + if (entries.length === 0) return null; + return path.join(DXT_DIST, entries[0]); +} + +const dxtPath = findDxt(); +if (!dxtPath) { + console.log(`[smoke] SMOKE_SKIPPED: no .dxt found in ${DXT_DIST} — run 'pnpm --filter @leadbay/dxt build' first`); +} + +describe.skipIf(!dxtPath)("@leadbay/dxt — .dxt bundle shape", () => { + const mcpVersion = JSON.parse( + readFileSync(path.resolve(__dirname, "..", "..", "package.json"), "utf8") + ).version as string; + + it("archive filename includes the mcp package version", () => { + expect(path.basename(dxtPath!)).toBe(`leadbay-${mcpVersion}.dxt`); + }); + + it("manifest.json has the expected DXT 0.2 shape", () => { + const entries = listZip(dxtPath!); + expect(entries).toContain("manifest.json"); + const manifest = JSON.parse(readFromZip(dxtPath!, "manifest.json")); + expect(manifest.dxt_version).toBe("0.2"); + expect(manifest.name).toBe("leadbay"); + expect(manifest.version).toBe(mcpVersion); + expect(manifest.server?.type).toBe("node"); + expect(manifest.server?.entry_point).toBe("server/index.js"); + }); + + it("bundles the server entry point", () => { + const entries = listZip(dxtPath!); + expect(entries).toContain("server/index.js"); + }); + + it("leadbay_token user_config is marked sensitive and required", () => { + const manifest = JSON.parse(readFromZip(dxtPath!, "manifest.json")); + expect(manifest.user_config.leadbay_token.sensitive).toBe(true); + expect(manifest.user_config.leadbay_token.required).toBe(true); + }); + + it("leadbay_region is an enum of us|fr", () => { + const manifest = JSON.parse(readFromZip(dxtPath!, "manifest.json")); + expect(manifest.user_config.leadbay_region.enum).toEqual(["us", "fr"]); + }); +}); + +function listZip(p: string): string[] { + // -Z1 = one filename per line, no other metadata. + const out = execFileSync("unzip", ["-Z1", p], { encoding: "utf8" }); + return out.split("\n").map((s) => s.trim()).filter(Boolean); +} + +function readFromZip(p: string, entry: string): string { + // -p = pipe to stdout. + return execFileSync("unzip", ["-p", p, entry], { encoding: "utf8" }); +} diff --git a/packages/mcp/test/unit/dxt-detection.test.ts b/packages/mcp/test/unit/dxt-detection.test.ts new file mode 100644 index 0000000..b785ac2 --- /dev/null +++ b/packages/mcp/test/unit/dxt-detection.test.ts @@ -0,0 +1,118 @@ +/** + * Unit tests for detectClaudeDesktopMode. + * + * Regression guard for #3504: Claude Desktop 2026 ships DXT (Desktop Extension) + * packaging. Writing to the legacy claude_desktop_config.json on those machines + * is a silent no-op — Claude Desktop overwrites our mcpServers block on the + * next prefs save. `install` needs to detect DXT and default-skip the legacy + * write; the helper here is what drives that decision. + */ +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { detectClaudeDesktopMode } from "../../src/bin.js"; + +let dir: string; + +beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), "leadbay-dxt-test-")); +}); + +afterEach(() => { + rmSync(dir, { recursive: true, force: true }); +}); + +describe("detectClaudeDesktopMode", () => { + it("empty dir → not legacy, not dxt, no markers", () => { + const m = detectClaudeDesktopMode(dir); + expect(m).toEqual({ legacy: false, dxt: false, markers: [] }); + }); + + it("legacy file only → legacy, not dxt", () => { + writeFileSync(join(dir, "claude_desktop_config.json"), "{}", "utf8"); + const m = detectClaudeDesktopMode(dir); + expect(m.legacy).toBe(true); + expect(m.dxt).toBe(false); + expect(m.markers).toEqual([]); + }); + + it("Claude Extensions/ dir → dxt detected", () => { + mkdirSync(join(dir, "Claude Extensions")); + const m = detectClaudeDesktopMode(dir); + expect(m.dxt).toBe(true); + expect(m.markers).toContain("Claude Extensions/"); + }); + + it("extensions-installations.json → dxt detected", () => { + writeFileSync(join(dir, "extensions-installations.json"), "[]", "utf8"); + const m = detectClaudeDesktopMode(dir); + expect(m.dxt).toBe(true); + expect(m.markers).toContain("extensions-installations.json"); + }); + + it("config.json with dxt:* keys → dxt detected", () => { + writeFileSync( + join(dir, "config.json"), + JSON.stringify({ + "dxt:allowlistEnabled": true, + "dxt:allowlistCache": {}, + other: "ignored", + }), + "utf8" + ); + const m = detectClaudeDesktopMode(dir); + expect(m.dxt).toBe(true); + expect(m.markers).toContain("config.json (dxt:* keys)"); + }); + + it("config.json without dxt:* keys → not dxt", () => { + writeFileSync( + join(dir, "config.json"), + JSON.stringify({ preferences: { theme: "dark" } }), + "utf8" + ); + const m = detectClaudeDesktopMode(dir); + expect(m.dxt).toBe(false); + expect(m.markers).toEqual([]); + }); + + it("malformed config.json → silently ignored (no crash)", () => { + writeFileSync(join(dir, "config.json"), "{not json", "utf8"); + const m = detectClaudeDesktopMode(dir); + expect(m.dxt).toBe(false); + }); + + it("legacy file AND dxt markers (Ludo's actual Mac state) → both flagged", () => { + writeFileSync( + join(dir, "claude_desktop_config.json"), + JSON.stringify({ preferences: { sidebarMode: "task" } }), + "utf8" + ); + mkdirSync(join(dir, "Claude Extensions")); + writeFileSync( + join(dir, "config.json"), + JSON.stringify({ "dxt:allowlistEnabled": true }), + "utf8" + ); + const m = detectClaudeDesktopMode(dir); + expect(m.legacy).toBe(true); + expect(m.dxt).toBe(true); + expect(m.markers.length).toBeGreaterThanOrEqual(2); + }); + + it("all three dxt markers → all listed", () => { + mkdirSync(join(dir, "Claude Extensions")); + writeFileSync(join(dir, "extensions-installations.json"), "[]", "utf8"); + writeFileSync( + join(dir, "config.json"), + JSON.stringify({ "dxt:allowlistEnabled": true }), + "utf8" + ); + const m = detectClaudeDesktopMode(dir); + expect(m.markers).toContain("Claude Extensions/"); + expect(m.markers).toContain("extensions-installations.json"); + expect(m.markers).toContain("config.json (dxt:* keys)"); + expect(m.markers.length).toBe(3); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a02149..f54867b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,18 @@ importers: packages/core: {} + packages/dxt: + devDependencies: + '@leadbay/mcp': + specifier: workspace:* + version: link:../mcp + archiver: + specifier: ^7.0.1 + version: 7.0.1 + esbuild: + specifier: ^0.25.0 + version: 0.25.12 + packages/leadclaw: devDependencies: '@leadbay/core': @@ -53,6 +65,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} @@ -65,6 +83,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} @@ -77,6 +101,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} @@ -89,6 +119,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} @@ -101,6 +137,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} @@ -113,6 +155,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} @@ -125,6 +173,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} @@ -137,6 +191,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} @@ -149,6 +209,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} @@ -161,6 +227,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} @@ -173,6 +245,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} @@ -185,6 +263,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} @@ -197,6 +281,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} @@ -209,6 +299,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} @@ -221,6 +317,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} @@ -233,6 +335,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} @@ -245,12 +353,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} @@ -263,12 +383,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} @@ -281,12 +413,24 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} @@ -299,6 +443,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} @@ -311,6 +461,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} @@ -323,6 +479,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} @@ -335,6 +497,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} @@ -347,6 +515,10 @@ packages: peerDependencies: hono: ^4 + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -370,6 +542,10 @@ packages: '@cfworker/json-schema': optional: true + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@rollup/rollup-android-arm-eabi@4.60.2': resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} cpu: [arm] @@ -577,20 +753,112 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.7.1: + resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-os@3.9.0: + resolution: {integrity: sha512-JTjuZyNIDpw+GytMO4a6TK1VXdVKKJr6DRxEHasyuYyShV2deuiHJK/ahGZlebc+SG0/wJCB9XK8gprBGDFi/Q==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-stream@2.13.0: + resolution: {integrity: sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==} + peerDependencies: + bare-abort-controller: '*' + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.4.2: + resolution: {integrity: sha512-/9a2j4ac6ckpmAHvod/ob7x439OAHst/drc2Clnq+reRYd/ovddwcF4LfoxHyNk5AuGBnPg+HqFjmE/Zpq6v0A==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} + brace-expansion@2.1.0: + resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bundle-require@5.1.0: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -625,6 +893,13 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -633,6 +908,10 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -656,10 +935,22 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -689,9 +980,18 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -720,6 +1020,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.27.7: resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} @@ -739,6 +1044,13 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.0.8: resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} engines: {node: '>=18.0.0'} @@ -764,6 +1076,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -783,6 +1098,10 @@ packages: fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} @@ -818,10 +1137,18 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -849,6 +1176,9 @@ packages: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -860,12 +1190,26 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jose@6.2.2: resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} @@ -879,6 +1223,10 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -890,9 +1238,15 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -924,6 +1278,18 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -956,6 +1322,10 @@ packages: encoding: optional: true + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -971,6 +1341,9 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -979,6 +1352,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@8.4.2: resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} @@ -1032,6 +1409,13 @@ packages: resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -1048,6 +1432,16 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -1069,6 +1463,12 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -1110,6 +1510,10 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1128,11 +1532,45 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + streamx@2.25.0: + resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true + tar-stream@3.1.8: + resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1217,6 +1655,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -1302,9 +1743,21 @@ packages: engines: {node: '>=8'} hasBin: true + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zod-to-json-schema@3.25.2: resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: @@ -1330,147 +1783,225 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true + '@esbuild/aix-ppc64@0.25.12': + optional: true + '@esbuild/aix-ppc64@0.27.7': optional: true '@esbuild/android-arm64@0.21.5': optional: true + '@esbuild/android-arm64@0.25.12': + optional: true + '@esbuild/android-arm64@0.27.7': optional: true '@esbuild/android-arm@0.21.5': optional: true + '@esbuild/android-arm@0.25.12': + optional: true + '@esbuild/android-arm@0.27.7': optional: true '@esbuild/android-x64@0.21.5': optional: true + '@esbuild/android-x64@0.25.12': + optional: true + '@esbuild/android-x64@0.27.7': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true + '@esbuild/darwin-arm64@0.25.12': + optional: true + '@esbuild/darwin-arm64@0.27.7': optional: true '@esbuild/darwin-x64@0.21.5': optional: true + '@esbuild/darwin-x64@0.25.12': + optional: true + '@esbuild/darwin-x64@0.27.7': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true + '@esbuild/freebsd-arm64@0.25.12': + optional: true + '@esbuild/freebsd-arm64@0.27.7': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true + '@esbuild/freebsd-x64@0.25.12': + optional: true + '@esbuild/freebsd-x64@0.27.7': optional: true '@esbuild/linux-arm64@0.21.5': optional: true + '@esbuild/linux-arm64@0.25.12': + optional: true + '@esbuild/linux-arm64@0.27.7': optional: true '@esbuild/linux-arm@0.21.5': optional: true + '@esbuild/linux-arm@0.25.12': + optional: true + '@esbuild/linux-arm@0.27.7': optional: true '@esbuild/linux-ia32@0.21.5': optional: true + '@esbuild/linux-ia32@0.25.12': + optional: true + '@esbuild/linux-ia32@0.27.7': optional: true '@esbuild/linux-loong64@0.21.5': optional: true + '@esbuild/linux-loong64@0.25.12': + optional: true + '@esbuild/linux-loong64@0.27.7': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true + '@esbuild/linux-mips64el@0.25.12': + optional: true + '@esbuild/linux-mips64el@0.27.7': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true + '@esbuild/linux-ppc64@0.25.12': + optional: true + '@esbuild/linux-ppc64@0.27.7': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true + '@esbuild/linux-riscv64@0.25.12': + optional: true + '@esbuild/linux-riscv64@0.27.7': optional: true '@esbuild/linux-s390x@0.21.5': optional: true + '@esbuild/linux-s390x@0.25.12': + optional: true + '@esbuild/linux-s390x@0.27.7': optional: true '@esbuild/linux-x64@0.21.5': optional: true + '@esbuild/linux-x64@0.25.12': + optional: true + '@esbuild/linux-x64@0.27.7': optional: true + '@esbuild/netbsd-arm64@0.25.12': + optional: true + '@esbuild/netbsd-arm64@0.27.7': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true + '@esbuild/netbsd-x64@0.25.12': + optional: true + '@esbuild/netbsd-x64@0.27.7': optional: true + '@esbuild/openbsd-arm64@0.25.12': + optional: true + '@esbuild/openbsd-arm64@0.27.7': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true + '@esbuild/openbsd-x64@0.25.12': + optional: true + '@esbuild/openbsd-x64@0.27.7': optional: true + '@esbuild/openharmony-arm64@0.25.12': + optional: true + '@esbuild/openharmony-arm64@0.27.7': optional: true '@esbuild/sunos-x64@0.21.5': optional: true + '@esbuild/sunos-x64@0.25.12': + optional: true + '@esbuild/sunos-x64@0.27.7': optional: true '@esbuild/win32-arm64@0.21.5': optional: true + '@esbuild/win32-arm64@0.25.12': + optional: true + '@esbuild/win32-arm64@0.27.7': optional: true '@esbuild/win32-ia32@0.21.5': optional: true + '@esbuild/win32-ia32@0.25.12': + optional: true + '@esbuild/win32-ia32@0.27.7': optional: true '@esbuild/win32-x64@0.21.5': optional: true + '@esbuild/win32-x64@0.25.12': + optional: true + '@esbuild/win32-x64@0.27.7': optional: true @@ -1478,6 +2009,15 @@ snapshots: dependencies: hono: 4.12.14 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -1514,6 +2054,9 @@ snapshots: transitivePeerDependencies: - supports-color + '@pkgjs/parseargs@0.11.0': + optional: true + '@rollup/rollup-android-arm-eabi@4.60.2': optional: true @@ -1670,12 +2213,86 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + any-promise@1.3.0: {} + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.18.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.8 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + assertion-error@2.0.1: {} + async@3.2.6: {} + asynckit@0.4.0: {} + b4a@1.8.0: {} + + balanced-match@1.0.2: {} + + bare-events@2.8.2: {} + + bare-fs@4.7.1: + dependencies: + bare-events: 2.8.2 + bare-path: 3.0.0 + bare-stream: 2.13.0(bare-events@2.8.2) + bare-url: 2.4.2 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-os@3.9.0: {} + + bare-path@3.0.0: + dependencies: + bare-os: 3.9.0 + + bare-stream@2.13.0(bare-events@2.8.2): + dependencies: + streamx: 2.25.0 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - react-native-b4a + + bare-url@2.4.2: + dependencies: + bare-path: 3.0.0 + + base64-js@1.5.1: {} + body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -1690,6 +2307,17 @@ snapshots: transitivePeerDependencies: - supports-color + brace-expansion@2.1.0: + dependencies: + balanced-match: 1.0.2 + + buffer-crc32@1.0.0: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bundle-require@5.1.0(esbuild@0.27.7): dependencies: esbuild: 0.27.7 @@ -1723,12 +2351,26 @@ snapshots: dependencies: readdirp: 4.1.2 + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 commander@4.1.1: {} + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + confbox@0.1.8: {} consola@3.4.2: {} @@ -1741,11 +2383,20 @@ snapshots: cookie@0.7.2: {} + core-util-is@1.0.3: {} + cors@2.8.6: dependencies: object-assign: 4.1.1 vary: 1.1.2 + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -1768,8 +2419,14 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + ee-first@1.1.1: {} + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + encodeurl@2.0.0: {} es-define-property@1.0.1: {} @@ -1815,6 +2472,35 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -1854,6 +2540,14 @@ snapshots: event-target-shim@5.0.1: {} + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + eventsource-parser@3.0.8: {} eventsource@3.0.7: @@ -1902,6 +2596,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-uri@3.1.0: {} fdir@6.5.0(picomatch@4.0.4): @@ -1925,6 +2621,11 @@ snapshots: mlly: 1.8.2 rollup: 4.60.2 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + form-data-encoder@1.7.2: {} form-data@4.0.5: @@ -1967,8 +2668,19 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -1997,16 +2709,30 @@ snapshots: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: {} + inherits@2.0.4: {} ip-address@10.1.0: {} ipaddr.js@1.9.1: {} + is-fullwidth-code-point@3.0.0: {} + is-promise@4.0.0: {} + is-stream@2.0.1: {} + + isarray@1.0.0: {} + isexe@2.0.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jose@6.2.2: {} joycon@3.1.1: {} @@ -2015,14 +2741,22 @@ snapshots: json-schema-typed@8.0.2: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} load-tsconfig@0.2.5: {} + lodash@4.18.1: {} + loupe@3.2.1: {} + lru-cache@10.4.3: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2045,6 +2779,16 @@ snapshots: dependencies: mime-db: 1.54.0 + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.0 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.0 + + minipass@7.1.3: {} + mlly@1.8.2: dependencies: acorn: 8.16.0 @@ -2070,6 +2814,8 @@ snapshots: dependencies: whatwg-url: 5.0.0 + normalize-path@3.0.0: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -2082,10 +2828,17 @@ snapshots: dependencies: wrappy: 1.0.2 + package-json-from-dist@1.0.1: {} + parseurl@1.3.3: {} path-key@3.1.1: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-to-regexp@8.4.2: {} pathe@1.1.2: {} @@ -2120,6 +2873,10 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -2138,6 +2895,28 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + readdirp@4.1.2: {} require-from-string@2.0.2: {} @@ -2185,6 +2964,10 @@ snapshots: transitivePeerDependencies: - supports-color + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} send@1.2.1: @@ -2250,6 +3033,8 @@ snapshots: siginfo@2.0.0: {} + signal-exit@4.1.0: {} + source-map-js@1.2.1: {} source-map@0.7.6: {} @@ -2260,6 +3045,43 @@ snapshots: std-env@3.10.0: {} + streamx@2.25.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -2270,6 +3092,30 @@ snapshots: tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 + tar-stream@3.1.8: + dependencies: + b4a: 1.8.0 + bare-fs: 4.7.1 + fast-fifo: 1.3.2 + streamx: 2.25.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + teex@1.0.1: + dependencies: + streamx: 2.25.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + text-decoder@1.2.7: + dependencies: + b4a: 1.8.0 + transitivePeerDependencies: + - react-native-b4a + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -2345,6 +3191,8 @@ snapshots: unpipe@1.0.0: {} + util-deprecate@1.0.2: {} + vary@1.1.2: {} vite-node@2.1.9(@types/node@25.6.0): @@ -2427,8 +3275,26 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + zod-to-json-schema@3.25.2(zod@4.3.6): dependencies: zod: 4.3.6