diff --git a/.env.example b/.env.example index 52589c06..61b4dff0 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,8 @@ BACKEND_URL="http://localhost:3000" + +# Public native OAuth client for the downloadable Admin MCP (not the dashboard's confidential client). +# Register callback http://127.0.0.1:47322/callback and delegated backend:admin; see docs/mcp.md. +# ADMIN_MCP_CLIENT_ID="" # Local preview: set to true to use a fake administrator without OIDC or Redis. # Only works with pnpm dev and a local fake/test backend. AGENT_MODE="false" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 998ba6b0..fd38e890 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,8 @@ jobs: run: pnpm run typecheck - name: Run Vite+ checks run: pnpm check + - name: Tests + run: pnpm test - name: Build run: pnpm run build env: diff --git a/.gitignore b/.gitignore index 4ac50e3e..ce51b45a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ db.sqlite # production /build /dist +/public/downloads/ /.output /.tanstack diff --git a/README.md b/README.md index 4996fc63..aeda4961 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,11 @@ come from `me.access`. Identity, Telegram linking, passkeys and session manageme ## Development +The [downloadable Admin MCP](docs/mcp.md) gives local AI agents the signed-in person's dashboard operations and +permissions. `pnpm build` includes its public package at `/downloads/polinetwork-admin-mcp.tgz`. Activation requires +a separate public native OAuth client and `ADMIN_MCP_CLIENT_ID`; the Auth MCP's existing registration policy stays +unchanged. Downloading is public; accessing data requires each user's own login. + ```bash pnpm install pnpm dev diff --git a/docs/mcp.md b/docs/mcp.md new file mode 100644 index 00000000..b7236919 --- /dev/null +++ b/docs/mcp.md @@ -0,0 +1,121 @@ +# PoliNetwork Admin MCP + +Downloadable MCP server for the same account and operations as the admin dashboard. It runs locally over stdio, +signs you in with PoliNetwork Auth using authorization code, PKCE and a verified ID token, and calls the backend +through a cookie-free gateway on admin. No client secret or administrator account is included in the download. + +## Install and connect + +Requires Node.js 22 or newer on Windows, macOS or Linux. After deployment, anyone can download the package from +`https://admin.polinetwork.org/downloads/polinetwork-admin-mcp.tgz` without signing in. API access still requires +their own account and dashboard permissions. + +```sh +npm install -g https://admin.polinetwork.org/downloads/polinetwork-admin-mcp.tgz +polinetwork-admin-mcp login +``` + +Your browser opens PoliNetwork Auth. Sign in and approve the application's access. If the browser cannot be opened, +copy the link printed in the terminal. Keep the terminal open until it confirms connection. The loopback callback +uses `http://127.0.0.1:47322/callback`; port 47322 must be available. + +Add this stdio configuration to an MCP client: + +```json +{ + "mcpServers": { + "polinetwork-admin": { + "command": "polinetwork-admin-mcp", + "args": ["serve"] + } + } +} +``` + +For example, Claude Code can add the installed executable with: + +```sh +claude mcp add --scope user polinetwork-admin -- polinetwork-admin-mcp serve +``` + +On a different admin deployment, pass the same `--admin-url https://admin.example.org` to both `login` and `serve`. +Each origin has separate credentials. `logout` revokes the refresh token and removes local credentials. +This is a local stdio server; browser-hosted connectors require a remote HTTP server and cannot run this package. + +## What it can do + +`whoami` shows the signed-in subject and current permissions. The tool list contains only operations allowed to +that account, and both the gateway and backend check authorization on every call. Telegram groups, users, messages, +audit and grants; WhatsApp groups; group labels; website projects, associations, FAQs, Freshman cards and guides; +reports; Microsoft 365; People, teams, census, linking, fees and receipts; eSign requests and drive rules are included. + +Microsoft 365 follows the dashboard's fixed new-member workflow, member-number changes and read-only groups. +Existing group memberships and arbitrary user properties cannot be changed. People responses use the dashboard's +contract schemas: a backend that has not implemented a procedure reports an error, without demo data or fallback. +The Capo Admin and Team Lead views remain scoped by the backend to the caller's own record. + +Writes take `{ "input": { ... }, "confirmed": true }`; the agent sets this only after the user has authorized the +specific change. Deletions, departures, revocations and similar operations are marked destructive. Report actions +and signing-job cancellation accept a single row. Label renames or deletions may affect descendants: inspect and +confirm that entire scope first. Never perform destructive operations on multiple records without an explicit +instruction covering them. Changes are attributed by the backend to the token's user, never an author argument. +An uncertain network result must be checked before any retry; writes are never retried automatically. + +Upload tools accept `fields` (string form values) and `files` entries containing `field`, `name`, `type` and `base64`. +They never read local paths. Download tools return base64 content or CSV. CIE tools can prepare requests and tickets; +the person must complete signing with the existing CIE application and hardware. Never give a PIN to the agent. +The server accepts MCP messages up to 72 MB, enough for a 50 MB signed-receipt batch encoded as base64. MCP clients +can impose their own smaller limits, including on large download responses. + +## Activate on a deployment + +The existing Auth MCP was inspected as the reference (`src/auth/mcp-server.ts`, `mcp-token.ts`, `mcp-clients.ts` in +the auth repository). Its anonymous dynamic registration deliberately grants only `idp:mcp` for its own audience. +Admin therefore uses a separate, publicly identifiable native client with backend access, rather than widening +Auth's working registration policy or embedding the dashboard's confidential credentials. + +A Master Admin creates one application at `/applications` (granting backend API scopes requires that role): + +| Setting | Value | +| -------------------- | ---------------------------------------------------- | +| Name | PoliNetwork Admin MCP | +| Usage | Sign people in; no service/client-credentials access | +| Application type | Native (localhost allowed) | +| Authentication | Public / none (PKCE S256) | +| Redirect URI | `http://127.0.0.1:47322/callback` | +| Identity scopes | `openid profile email offline_access` | +| Delegated API scopes | `backend:admin` | +| Resource | The same backend resource as the dashboard | +| Consent | Required | + +Set `ADMIN_MCP_CLIENT_ID` on admin to that public client ID. `IDP_URL` and `BACKEND_RESOURCE` retain their existing +dashboard meanings. The manifest at `/api/mcp/config` exposes only the public ID, issuer, resource, callback and +download URL. It returns 503 until configured. The RPC gateway is also disabled until this variable is set. +The backend remains internal, reached with `BACKEND_URL`; no new backend public ingress is necessary. + +Download permission is public. Data permissions are always the person's own; installing the package grants no +roles. This implementation does not require `idp:mcp`, which governs the separate Auth MCP. + +Tokens live on the installing user's computer in `~/.polinetwork/admin-mcp/`: directory mode 0700 and files 0600 +on POSIX, atomic replacements, one refresh at a time across processes (waiting up to five seconds for another +process's refresh), and no stdout logging. Protect this directory +as other local application credentials. A refresh marker is saved before contacting the IdP: after a crash or an +ambiguous refresh response the user signs in again instead of replaying a rotating token. A crashed process can also +leave a `.lock` directory next to its credential file; remove that directory only after the process has stopped. +If logout cannot contact Auth, local credentials are still deleted and the user is told to revoke the application's +consent in Auth. Existing access tokens are subject to the backend's validation and token expiry policy. + +## Build and distribute + +```sh +pnpm mcp:build +node dist/admin-mcp/cli.mjs help +``` + +The bundle contains runtime dependencies and needs no separate npm dependency install. `pnpm build` produces the +package first and includes the public `.tgz` and SHA-256 file in the dashboard's static output. CI tests the MCP +before publishing the usual dashboard image. Deploying that image makes the download public at the URL above. +For local development use `--admin-url http://localhost:PORT` with a local Auth native client. + +Public installation and a real user login require deployment and the client registration above; creating the +downloadable artifact alone does not register a production client or publish a deployment. diff --git a/package.json b/package.json index b453317e..9f89f861 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "type": "module", "scripts": { "dev": "vp dev", - "build": "vp build", + "build": "pnpm mcp:build && vp build", + "mcp:build": "node scripts/build-mcp.mjs", "start": "NODE_ENV=production node .output/server/index.mjs", "preview": "vp preview", "test": "node --experimental-strip-types --test tests/*.test.mjs", @@ -18,6 +19,7 @@ "@dnd-kit/react": "^0.4.0", "@fontsource-variable/dm-sans": "^5.3.0", "@fontsource/dm-mono": "^5.3.0", + "@modelcontextprotocol/server": "^2.3.1", "@polinetwork/backend": "^4.0.0", "@t3-oss/env-core": "^0.13.10", "@tanstack/charts": "1.1.0", @@ -47,6 +49,7 @@ "zod": "^4.3.5" }, "devDependencies": { + "@modelcontextprotocol/client": "^2.3.1", "@tailwindcss/vite": "^4.3.2", "@trpc/server": "11.5.1", "@types/node": "^22.10.2", @@ -54,6 +57,7 @@ "@types/react-dom": "^19.2.0", "@vitejs/plugin-react": "^6.0.1", "@zap-studio/oxlint": "^2.2.1", + "esbuild": "^0.28.2", "tailwindcss": "^4.3.2", "typescript": "^6.0.2", "vite": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7398e31f..cd6909fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,6 +31,9 @@ importers: '@fontsource/dm-mono': specifier: ^5.3.0 version: 5.3.0 + '@modelcontextprotocol/server': + specifier: ^2.3.1 + version: 2.4.0 '@polinetwork/backend': specifier: ^4.0.0 version: 4.0.0 @@ -48,7 +51,7 @@ importers: version: 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-start': specifier: 1.168.27 - version: 1.168.27(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5) + version: 1.168.27(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5) '@tanstack/react-store': specifier: ^0.11.0 version: 0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -75,7 +78,7 @@ importers: version: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) nitro: specifier: 3.0.260610-beta - version: 3.0.260610-beta(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0) + version: 3.0.260610-beta(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0) openid-client: specifier: ^6.8.8 version: 6.8.8 @@ -113,9 +116,12 @@ importers: specifier: ^4.3.5 version: 4.3.5 devDependencies: + '@modelcontextprotocol/client': + specifier: ^2.3.1 + version: 2.4.0 '@tailwindcss/vite': specifier: ^4.3.2 - version: 4.3.2(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + version: 4.3.2(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) '@trpc/server': specifier: 11.5.1 version: 11.5.1(typescript@6.0.3) @@ -130,10 +136,13 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(babel-plugin-react-compiler@1.0.0) + version: 6.0.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(babel-plugin-react-compiler@1.0.0) '@zap-studio/oxlint': specifier: ^2.2.1 - version: 2.2.1(@oxlint/plugins@1.79.0)(@testing-library/dom@10.4.1)(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0))(oxlint-tsgolint@7.0.2001)(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))(tailwindcss@4.3.2)(typescript@6.0.3) + version: 2.2.1(@oxlint/plugins@1.79.0)(@testing-library/dom@10.4.1)(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0))(oxlint-tsgolint@7.0.2001)(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))(tailwindcss@4.3.2)(typescript@6.0.3) + esbuild: + specifier: ^0.28.2 + version: 0.28.2 tailwindcss: specifier: ^4.3.2 version: 4.3.2 @@ -142,10 +151,10 @@ importers: version: 6.0.3 vite: specifier: npm:@voidzero-dev/vite-plus-core@0.2.9 - version: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + version: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' vite-plus: specifier: 'catalog:' - version: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) + version: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) packages: @@ -426,6 +435,162 @@ packages: '@emnapi/wasi-threads@1.2.2': resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.10.1': resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -539,6 +704,14 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@modelcontextprotocol/client@2.4.0': + resolution: {integrity: sha512-LgrD2OphHuG12vfKFKz6SOnq7bKHQmhGJIAYdD+MZBn2npHEyry6uD8zvktodtl5CQM85MO0anUyD9JwmUmxww==} + engines: {node: '>=20'} + + '@modelcontextprotocol/core@2.4.0': + resolution: {integrity: sha512-z8QBKqdfXLPzkLQuG4xp8hrVEMm1PZ1IgxMN2sMbJiFiAKOWXnAzogXn2W4aqIBlP1ea6U5yiqVquvUNM1Cj6Q==} + engines: {node: '>=20'} + '@modelcontextprotocol/sdk@1.29.0': resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} engines: {node: '>=18'} @@ -549,6 +722,10 @@ packages: '@cfworker/json-schema': optional: true + '@modelcontextprotocol/server@2.4.0': + resolution: {integrity: sha512-rgR9yxSaAJ+bcsi/XroT/S2AfPiIWloXAnrdfYSCms9ivVju0ishu/wW0J21Ho6+ZOR1r7RyeRbjiRuF87ix5Q==} + engines: {node: '>=20'} + '@mongodb-js/saslprep@1.4.13': resolution: {integrity: sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg==} @@ -2800,6 +2977,11 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -5519,14 +5701,14 @@ snapshots: '@dotenvx/primitives@0.8.0': {} - '@e18e/eslint-plugin@0.8.0(eslint@10.9.0(jiti@2.7.0))(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))': + '@e18e/eslint-plugin@0.8.0(eslint@10.9.0(jiti@2.7.0))(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))': dependencies: empathic: 2.0.1 module-replacements: 3.2.0 semver: 7.8.5 optionalDependencies: eslint: 10.9.0(jiti@2.7.0) - oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) '@emnapi/core@1.11.1': dependencies: @@ -5544,6 +5726,84 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + '@eslint-community/eslint-utils@4.10.1(eslint@10.9.0(jiti@2.7.0))': dependencies: eslint: 10.9.0(jiti@2.7.0) @@ -5658,6 +5918,20 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@modelcontextprotocol/client@2.4.0': + dependencies: + '@modelcontextprotocol/core': 2.4.0 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.0 + jose: 6.2.12 + pkce-challenge: 5.0.1 + zod: 4.4.3 + + '@modelcontextprotocol/core@2.4.0': + dependencies: + zod: 4.4.3 + '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: '@hono/node-server': 1.19.14(hono@4.12.29) @@ -5680,6 +5954,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@modelcontextprotocol/server@2.4.0': + dependencies: + '@modelcontextprotocol/core': 2.4.0 + zod: 4.4.3 + '@mongodb-js/saslprep@1.4.13': dependencies: sparse-bitfield: 3.0.3 @@ -6265,12 +6544,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.2 '@tailwindcss/oxide-win32-x64-msvc': 4.3.2 - '@tailwindcss/vite@4.3.2(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))': + '@tailwindcss/vite@4.3.2(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.3.2 '@tailwindcss/oxide': 4.3.2 tailwindcss: 4.3.2 - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' '@tanstack/charts@1.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: @@ -6351,14 +6630,14 @@ snapshots: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - '@tanstack/react-start-rsc@0.1.26(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)': + '@tanstack/react-start-rsc@0.1.26(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)': dependencies: '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/router-core': 1.171.14 '@tanstack/router-utils': 1.162.2 '@tanstack/start-client-core': 1.170.13 '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5) + '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(rolldown@1.1.5) '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) '@tanstack/start-storage-context': 1.167.16 pathe: 2.0.3 @@ -6388,21 +6667,21 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start@1.168.27(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)': + '@tanstack/react-start@1.168.27(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)': dependencies: '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-start-client': 1.168.15(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@tanstack/react-start-rsc': 0.1.26(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5) + '@tanstack/react-start-rsc': 0.1.26(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5) '@tanstack/react-start-server': 1.167.21(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/router-utils': 1.162.2 '@tanstack/start-client-core': 1.170.13 - '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5) + '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(rolldown@1.1.5) '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) pathe: 2.0.3 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' transitivePeerDependencies: - '@farmfe/core' - '@rspack/core' @@ -6451,7 +6730,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(rolldown@1.1.5)': + '@tanstack/router-plugin@1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(rolldown@1.1.5)': dependencies: '@babel/core': 7.29.0 '@babel/template': 7.29.7 @@ -6460,11 +6739,11 @@ snapshots: '@tanstack/router-generator': 1.167.18 '@tanstack/router-utils': 1.162.2 chokidar: 5.0.0 - unplugin: 3.3.0(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(rolldown@1.1.5) + unplugin: 3.3.0(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(rolldown@1.1.5) zod: 4.4.3 optionalDependencies: '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' transitivePeerDependencies: - '@farmfe/core' - '@rspack/core' @@ -6497,14 +6776,14 @@ snapshots: '@tanstack/start-fn-stubs@1.162.0': {} - '@tanstack/start-plugin-core@1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5)': + '@tanstack/start-plugin-core@1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.2)(rolldown@1.1.5)': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.29.0 '@babel/types': 7.29.7 '@tanstack/router-core': 1.171.14 '@tanstack/router-generator': 1.167.18 - '@tanstack/router-plugin': 1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(rolldown@1.1.5) + '@tanstack/router-plugin': 1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(rolldown@1.1.5) '@tanstack/router-utils': 1.162.2 '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) exsolve: 1.1.0 @@ -6516,11 +6795,11 @@ snapshots: srvx: 0.11.21 tinyglobby: 0.2.17 ufo: 1.6.4 - vitefu: 1.1.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + vitefu: 1.1.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) xmlbuilder2: 4.0.3 zod: 4.4.3 optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' transitivePeerDependencies: - '@farmfe/core' - '@rspack/core' @@ -6748,35 +7027,35 @@ snapshots: '@typescript-eslint/types': 8.67.0 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-react@6.0.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(babel-plugin-react-compiler@1.0.0)': + '@vitejs/plugin-react@6.0.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(babel-plugin-react-compiler@1.0.0)': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' optionalDependencies: babel-plugin-react-compiler: 1.0.0 - '@vitest/browser-preview@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10)': + '@vitest/browser-preview@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10)': dependencies: '@testing-library/dom': 10.4.1 '@testing-library/user-event': 14.6.6(@testing-library/dom@10.4.1) - '@vitest/browser': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) - vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + '@vitest/browser': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) + vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10)': + '@vitest/browser@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10)': dependencies: '@blazediff/core': 1.9.1 - '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) '@vitest/utils': 4.1.10 magic-string: 0.30.21 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.1.1 - vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) ws: 8.21.3 transitivePeerDependencies: - bufferutil @@ -6793,13 +7072,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' '@vitest/pretty-format@4.1.10': dependencies: @@ -6825,7 +7104,7 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.1 - '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)': + '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)': dependencies: '@oxc-project/runtime': 0.143.0 '@oxc-project/types': 0.143.0 @@ -6843,6 +7122,7 @@ snapshots: '@voidzero-dev/vite-plus-linux-x64-musl': 0.2.9 '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.2.9 '@voidzero-dev/vite-plus-win32-x64-msvc': 0.2.9 + esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 typescript: 6.0.3 @@ -6940,9 +7220,9 @@ snapshots: '@yuku-toolchain/types@0.5.43': {} - '@zap-studio/oxlint@2.2.1(@oxlint/plugins@1.79.0)(@testing-library/dom@10.4.1)(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0))(oxlint-tsgolint@7.0.2001)(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))(tailwindcss@4.3.2)(typescript@6.0.3)': + '@zap-studio/oxlint@2.2.1(@oxlint/plugins@1.79.0)(@testing-library/dom@10.4.1)(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0))(oxlint-tsgolint@7.0.2001)(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)))(tailwindcss@4.3.2)(typescript@6.0.3)': dependencies: - '@e18e/eslint-plugin': 0.8.0(eslint@10.9.0(jiti@2.7.0))(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))) + '@e18e/eslint-plugin': 0.8.0(eslint@10.9.0(jiti@2.7.0))(oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))) '@oxlint/plugins': 1.79.0 '@stylexjs/eslint-plugin': 0.19.0 '@tanstack/eslint-plugin-query': 5.102.1(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3) @@ -6957,7 +7237,7 @@ snapshots: eslint-plugin-storybook: 10.5.10(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-tailwindcss: 4.4.0(eslint@10.9.0(jiti@2.7.0))(tailwindcss@4.3.2)(typescript@6.0.3) eslint-plugin-testing-library: 7.16.2(eslint@10.9.0(jiti@2.7.0))(typescript@6.0.3) - oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) oxlint-plugin-react-doctor: 0.9.12 oxlint-tsgolint: 7.0.2001 transitivePeerDependencies: @@ -7627,6 +7907,35 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -8762,7 +9071,7 @@ snapshots: nf3@0.3.21: {} - nitro@3.0.260610-beta(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0): + nitro@3.0.260610-beta(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0): dependencies: consola: 3.4.2 crossws: 0.4.9(srvx@0.11.21) @@ -8781,7 +9090,7 @@ snapshots: optionalDependencies: dotenv: 17.4.2 jiti: 2.7.0 - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8976,7 +9285,7 @@ snapshots: '@oxc-parser/binding-win32-ia32-msvc': 0.143.0 '@oxc-parser/binding-win32-x64-msvc': 0.143.0 - oxfmt@0.62.0(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): + oxfmt@0.62.0(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): dependencies: tinypool: 2.1.0 optionalDependencies: @@ -8999,7 +9308,7 @@ snapshots: '@oxfmt/binding-win32-arm64-msvc': 0.62.0 '@oxfmt/binding-win32-ia32-msvc': 0.62.0 '@oxfmt/binding-win32-x64-msvc': 0.62.0 - vite-plus: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) + vite-plus: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) oxlint-plugin-react-doctor@0.9.12: dependencies: @@ -9019,7 +9328,7 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 7.0.2001 '@oxlint-tsgolint/win32-x64': 7.0.2001 - oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): + oxlint@1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): optionalDependencies: '@oxlint/binding-android-arm-eabi': 1.79.0 '@oxlint/binding-android-arm64': 1.79.0 @@ -9041,7 +9350,7 @@ snapshots: '@oxlint/binding-win32-ia32-msvc': 1.79.0 '@oxlint/binding-win32-x64-msvc': 1.79.0 oxlint-tsgolint: 7.0.2001 - vite-plus: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) + vite-plus: 0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) p-limit@2.3.0: dependencies: @@ -9784,14 +10093,15 @@ snapshots: unpipe@1.0.0: {} - unplugin@3.3.0(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(rolldown@1.1.5): + unplugin@3.3.0(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(rolldown@1.1.5): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 optionalDependencies: + esbuild: 0.28.2 rolldown: 1.1.5 - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(mongodb@7.1.0)(ofetch@2.0.0-alpha.3): optionalDependencies: @@ -9835,24 +10145,24 @@ snapshots: vary@1.1.2: {} - vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0): + vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0): dependencies: '@oxc-project/types': 0.143.0 '@oxlint/plugins': 1.79.0 - '@vitest/browser': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) - '@vitest/browser-preview': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/browser': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/browser-preview': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 '@vitest/spy': 4.1.10 '@vitest/utils': 4.1.10 - '@voidzero-dev/vite-plus-core': 0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) - oxfmt: 0.62.0(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) - oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + '@voidzero-dev/vite-plus-core': 0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0) + oxfmt: 0.62.0(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + oxlint: 1.79.0(oxlint-tsgolint@7.0.2001)(vite-plus@0.2.9(@types/node@22.20.1)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) oxlint-tsgolint: 7.0.2001 - vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + vitest: 4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) optionalDependencies: '@voidzero-dev/vite-plus-darwin-arm64': 0.2.9 '@voidzero-dev/vite-plus-darwin-x64': 0.2.9 @@ -9893,14 +10203,14 @@ snapshots: - vite - yaml - vitefu@1.1.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): + vitefu@1.1.3(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' - vitest@4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): + vitest@4.1.10(@types/node@22.20.1)(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -9917,11 +10227,11 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' + vite: '@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)' why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.20.1 - '@vitest/browser-preview': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/browser-preview': 4.1.10(@voidzero-dev/vite-plus-core@0.2.9(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vitest@4.1.10) transitivePeerDependencies: - msw diff --git a/scripts/build-mcp.mjs b/scripts/build-mcp.mjs new file mode 100644 index 00000000..08b6e6ac --- /dev/null +++ b/scripts/build-mcp.mjs @@ -0,0 +1,61 @@ +import { execFileSync } from "node:child_process" +import { createHash } from "node:crypto" +import { chmod, copyFile, mkdir, readFile, writeFile } from "node:fs/promises" + +import { build } from "esbuild" + +const destination = new URL("../dist/admin-mcp/", import.meta.url) +await mkdir(destination, { recursive: true }) +await build({ + entryPoints: ["src/mcp/cli.ts"], + outfile: new URL("cli.mjs", destination).pathname, + bundle: true, + platform: "node", + format: "esm", + target: "node22", + banner: { + js: 'import { createRequire as __mcpCreateRequire } from "node:module"; const require = __mcpCreateRequire(import.meta.url);', + }, + legalComments: "linked", + logLevel: "warning", +}) +await chmod(new URL("cli.mjs", destination), 0o755) +await writeFile( + new URL("package.json", destination), + `${JSON.stringify( + { + name: "@polinetwork/admin-mcp", + version: "0.1.0", + description: "PoliNetwork Admin tools with the signed-in user's dashboard permissions", + type: "module", + bin: { "polinetwork-admin-mcp": "cli.mjs" }, + engines: { node: ">=22" }, + files: ["cli.mjs", "cli.mjs.LEGAL.txt", "README.md"], + license: "UNLICENSED", + repository: { type: "git", url: "https://github.com/PoliNetworkOrg/admin.git" }, + }, + null, + 2 + )}\n` +) +await copyFile("docs/mcp.md", new URL("README.md", destination)) +const downloads = new URL("../public/downloads/", import.meta.url) +await mkdir(downloads, { recursive: true }) +// npm pack only packages this generated directory, never the workspace or its .env files. +const packages = JSON.parse( + execFileSync("npm", ["pack", "--json", "--ignore-scripts", "--pack-destination", downloads.pathname], { + cwd: destination, + encoding: "utf8", + }) +) +// npm 11+ keys its JSON result by package name; earlier versions return an array. +const packed = Object.values(packages)[0] +if (!packed?.filename) throw new Error("npm pack did not return an archive filename.") +const archive = new URL("polinetwork-admin-mcp.tgz", downloads) +await copyFile(new URL(packed.filename, downloads), archive) +const bytes = await readFile(archive) +await writeFile( + new URL("polinetwork-admin-mcp.tgz.sha256", downloads), + `${createHash("sha256").update(bytes).digest("hex")} polinetwork-admin-mcp.tgz\n` +) +console.error(`Built public admin MCP download (${Math.round(bytes.length / 1024)} KB).`) diff --git a/src/features/account/account-page.tsx b/src/features/account/account-page.tsx index 43acce4c..03743374 100644 --- a/src/features/account/account-page.tsx +++ b/src/features/account/account-page.tsx @@ -1,5 +1,6 @@ import { Cloud, + Download, ExternalLink, Globe, Info, @@ -21,6 +22,7 @@ import { PageBar, PageContent, useSignOut } from "@/components/shell" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import type { DashboardUser } from "@/lib/auth" +import { MCP_DOWNLOAD } from "@/mcp/protocol" type AccountPageProps = { user: DashboardUser @@ -39,6 +41,7 @@ export function AccountPage({ user, permissions, accountUrl }: AccountPageProps)
+
@@ -48,6 +51,34 @@ export function AccountPage({ user, permissions, accountUrl }: AccountPageProps) ) } +function McpCard() { + return ( + }> + + Download MCP + + } + > +
+

+ Connect a local AI agent to the dashboard with your account and permissions. Requires Node.js 22 or newer. +

+
+          {"npm install -g ./polinetwork-admin-mcp.tgz\npolinetwork-admin-mcp login"}
+        
+

+ Then configure your agent to run polinetwork-admin-mcp serve. Installation + instructions are included in the download. +

+
+
+ ) +} + function IdpLink({ href, children }: { href: string; children: string }) { return (