From 0962df875c7cf3056a7ee9db42583cdca775e599 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 18 May 2026 17:35:30 -0700 Subject: [PATCH 1/2] refactor: migrate build output to dist directory and update configurations - Changed build output from `build/` to `dist/` across various files, including Dockerfile, package.json, and integration tests. - Updated entry points and scripts to reflect the new output structure. - Removed obsolete CommonJS configuration and introduced `tsdown` for building. - Added logo asset and updated server configuration to include versioning and logo data. - Adjusted test fixtures to align with the new module paths. --- .github/workflows/dependabot-review.yml | 2 +- CONTRIBUTE.md | 4 +- Dockerfile | 12 +- mcp-server/.gitignore | 2 +- mcp-server/assets/logo.png | Bin 0 -> 36464 bytes mcp-server/package-lock.json | 953 +++++++++++++++--- mcp-server/package.json | 27 +- mcp-server/scripts/sync-readme-tools.mjs | 2 +- mcp-server/scripts/write-cjs-package-json.mjs | 8 - mcp-server/src/cli-bin.integration.test.ts | 6 +- .../package-environments.integration.test.ts | 12 +- .../package-published-esm.integration.test.ts | 12 +- mcp-server/src/server.ts | 107 +- .../fixtures/consumer-cjs-dynamic-import.cjs | 2 +- mcp-server/test/fixtures/consumer-cjs.cjs | 2 +- mcp-server/test/fixtures/consumer-esm.mjs | 2 +- mcp-server/tsconfig.cjs.json | 18 - mcp-server/tsdown.config.ts | 22 + mcp-server/vitest.config.ts | 3 +- 19 files changed, 963 insertions(+), 233 deletions(-) create mode 100644 mcp-server/assets/logo.png delete mode 100644 mcp-server/scripts/write-cjs-package-json.mjs delete mode 100644 mcp-server/tsconfig.cjs.json create mode 100644 mcp-server/tsdown.config.ts diff --git a/.github/workflows/dependabot-review.yml b/.github/workflows/dependabot-review.yml index 49a46c0..8d95cf4 100644 --- a/.github/workflows/dependabot-review.yml +++ b/.github/workflows/dependabot-review.yml @@ -54,7 +54,7 @@ jobs: Verify the package can start without runtime errors: ``` - cd mcp-server && timeout 10 node build/index.js --help || true + cd mcp-server && timeout 10 node dist/index.mjs --help || true ``` If a `--help` flag is not available, start the process and kill it after a few seconds to confirm it boots. diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 6d7696e..1c86b07 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -45,7 +45,7 @@ You should see: `Currents MCP Server running on stdio`. To test with a local MCP client (e.g., Cursor or Claude Desktop), point the client to your built server: - Command: `node` -- Args: `./mcp-server/build/index.js` +- Args: `./mcp-server/dist/index.mjs` - Env: set `CURRENTS_API_KEY` to a valid key Example snippet for a client config: @@ -55,7 +55,7 @@ Example snippet for a client config: "mcpServers": { "currents": { "command": "node", - "args": ["./mcp-server/build/index.js"], + "args": ["./mcp-server/dist/index.mjs"], "env": { "CURRENTS_API_KEY": "your-api-key" } diff --git a/Dockerfile b/Dockerfile index e0fbac2..8b2a169 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # syntax=docker/dockerfile:1 # Build stage -FROM node:20-alpine AS build +FROM node:24-alpine AS build WORKDIR /app # Install dependencies @@ -10,8 +10,8 @@ COPY mcp-server/package.json mcp-server/package-lock.json ./ RUN npm ci --production=false # Copy source code -COPY mcp-server/tsconfig.json mcp-server/tsconfig.cjs.json ./ -COPY mcp-server/scripts ./scripts +COPY mcp-server/tsconfig.json mcp-server/tsdown.config.ts ./ +COPY mcp-server/assets ./assets COPY mcp-server/src ./src # Build the project @@ -22,10 +22,12 @@ FROM node:20-alpine AS runtime WORKDIR /app # Copy build artifacts and dependencies -COPY --from=build /app/build ./build +COPY --from=build /app/dist ./dist +COPY --from=build /app/assets ./assets +COPY --from=build /app/package.json ./package.json COPY --from=build /app/node_modules ./node_modules # Default API URL environment variable ENV CURRENTS_API_URL=https://api.currents.dev -ENTRYPOINT ["node", "build/index.js"] +ENTRYPOINT ["node", "dist/index.mjs"] diff --git a/mcp-server/.gitignore b/mcp-server/.gitignore index 8c09060..2ec6443 100644 --- a/mcp-server/.gitignore +++ b/mcp-server/.gitignore @@ -1,5 +1,5 @@ # Build output -build/ +dist/ # README is copied from root during publish README.md diff --git a/mcp-server/assets/logo.png b/mcp-server/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bca6ca9249764e20cd392109d6cc813d61b4a001 GIT binary patch literal 36464 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

+PmZ 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 BK9T?c literal 0 HcmV?d00001 diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json index e818405..f29d9ba 100644 --- a/mcp-server/package-lock.json +++ b/mcp-server/package-lock.json @@ -16,13 +16,13 @@ "zod": "^4.3.5" }, "bin": { - "mcp": "build/index.js" + "mcp": "dist/index.mjs" }, "devDependencies": { "@release-it/conventional-changelog": "^11.0.0", "@types/node": "^20.19.0", "release-it": "^20.0.1", - "rimraf": "^6.0.1", + "tsdown": "^0.21.0", "typescript": "^5.9.3", "vitest": "^4.0.18" }, @@ -30,6 +30,74 @@ "node": ">=20" } }, + "node_modules/@babel/generator": { + "version": "8.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.0-rc.3.tgz", + "integrity": "sha512-em37/13/nR320G4jab/nIIHZgc2Wz2y/D39lxnTyxB4/D/omPQncl/lSdlnJY1OhQcRGugTSIF2l/69o31C9dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^8.0.0-rc.3", + "@babel/types": "^8.0.0-rc.3", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "@types/jsesc": "^2.5.0", + "jsesc": "^3.0.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "8.0.0-rc.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.0-rc.5.tgz", + "integrity": "sha512-sN7R8rBvDurfaziNfDEIjIntlazmlkCDGO4SNl2RJ3wRCn+QxspLV7hzYAE8WWVd2joVuT8sUxeePdLp2idI1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "8.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-rc.3.tgz", + "integrity": "sha512-8AWCJ2VJJyDFlGBep5GpaaQ9AAaE/FjAcrqI7jyssYhtL7WGV0DOKpJsQqM037xDbpRLHXsY8TwU7zDma7coOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@babel/parser": { + "version": "8.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.0-rc.3.tgz", + "integrity": "sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^8.0.0-rc.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@babel/types": { + "version": "8.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.0-rc.3.tgz", + "integrity": "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^8.0.0-rc.3", + "@babel/helper-validator-identifier": "^8.0.0-rc.3" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@conventional-changelog/git-client": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz", @@ -57,6 +125,40 @@ } } }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -855,6 +957,27 @@ } } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -862,6 +985,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.28.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.28.0.tgz", @@ -902,6 +1036,25 @@ } } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@octokit/auth-token": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", @@ -1068,6 +1221,16 @@ "@octokit/openapi-types": "^27.0.0" } }, + "node_modules/@oxc-project/types": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", + "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@phun-ky/typeof": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@phun-ky/typeof/-/typeof-2.0.3.tgz", @@ -1082,6 +1245,19 @@ "url": "https://github.com/phun-ky/typeof?sponsor=1" } }, + "node_modules/@quansync/fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/@release-it/conventional-changelog": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-11.0.0.tgz", @@ -1117,6 +1293,288 @@ "node": ">=10" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz", + "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz", + "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz", + "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -1527,6 +1985,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -1552,6 +2021,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.19.37", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", @@ -1756,6 +2232,16 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/ansis": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.0.tgz", + "integrity": "sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", @@ -1773,6 +2259,24 @@ "node": ">=12" } }, + "node_modules/ast-kit": { + "version": "3.0.0-beta.1", + "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-3.0.0-beta.1.tgz", + "integrity": "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^8.0.0-beta.4", + "estree-walker": "^3.0.3", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -1803,16 +2307,6 @@ "node": ">=8.0.0" } }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/basic-ftp": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", @@ -1830,6 +2324,16 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/birpc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz", + "integrity": "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -1854,19 +2358,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1928,6 +2419,16 @@ } } }, + "node_modules/cac": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -2462,6 +2963,27 @@ "url": "https://dotenvx.com" } }, + "node_modules/dts-resolver": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz", + "integrity": "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "oxc-resolver": ">=11.0.0" + }, + "peerDependenciesMeta": { + "oxc-resolver": { + "optional": true + } + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2482,6 +3004,16 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, + "node_modules/empathic": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz", + "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -2986,6 +3518,19 @@ "node": ">= 0.4" } }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/get-uri": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-7.0.0.tgz", @@ -3040,24 +3585,6 @@ "git-up": "^8.1.0" } }, - "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -3130,6 +3657,13 @@ "node": ">=16.9.0" } }, + "node_modules/hookable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz", + "integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==", + "dev": true, + "license": "MIT" + }, "node_modules/hosted-git-info": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", @@ -3214,6 +3748,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/import-without-cache": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.3.3.tgz", + "integrity": "sha512-bDxwDdF04gm550DfZHgffvlX+9kUlcz32UD0AeBTmVPFiWkrexF2XVmiuFFbDhiFuP8fQkrkvI2KdSNPYWAXkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -3401,6 +3948,19 @@ "node": ">=10" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -3580,22 +4140,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -3604,16 +4148,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3928,13 +4462,6 @@ "quickjs-wasi": "^0.0.1" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/parse-path": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", @@ -3976,33 +4503,6 @@ "node": ">=8" } }, - "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/path-to-regexp": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", @@ -4264,6 +4764,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -4405,6 +4922,16 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -4431,24 +4958,84 @@ "node": ">= 4" } }, - "node_modules/rimraf": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", - "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "node_modules/rolldown": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz", + "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "glob": "^13.0.0", - "package-json-from-dist": "^1.0.1" + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" }, "bin": { - "rimraf": "dist/esm/bin.mjs" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": "20 || >=22" + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "node_modules/rolldown-plugin-dts": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.23.2.tgz", + "integrity": "sha512-PbSqLawLgZBGcOGT3yqWBGn4cX+wh2nt5FuBGdcMHyOhoukmjbhYAl8NT9sE4U38Cm9tqLOIQeOrvzeayM0DLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/generator": "8.0.0-rc.3", + "@babel/helper-validator-identifier": "8.0.0-rc.3", + "@babel/parser": "8.0.0-rc.3", + "@babel/types": "8.0.0-rc.3", + "ast-kit": "^3.0.0-beta.1", + "birpc": "^4.0.0", + "dts-resolver": "^2.1.3", + "get-tsconfig": "^4.13.7", + "obug": "^2.1.1", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=20.19.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@ts-macro/tsc": "^0.3.6", + "@typescript/native-preview": ">=7.0.0-dev.20260325.1", + "rolldown": "^1.0.0-rc.12", + "typescript": "^5.0.0 || ^6.0.0", + "vue-tsc": "~3.2.0" + }, + "peerDependenciesMeta": { + "@ts-macro/tsc": { + "optional": true + }, + "@typescript/native-preview": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue-tsc": { + "optional": true + } } }, "node_modules/rollup": { @@ -4961,9 +5548,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", "dev": true, "license": "MIT", "engines": { @@ -5006,6 +5593,99 @@ "node": ">=0.6" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tsdown": { + "version": "0.21.10", + "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.21.10.tgz", + "integrity": "sha512-3wk73yBhZe/wX7REqSdivNQ84TDs1mJ+IlnzrrEREP70xlJ/AEIzqaI04l/TzMKVIdkTdC3CPaADn2Lk/0SkdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansis": "^4.2.0", + "cac": "^7.0.0", + "defu": "^6.1.7", + "empathic": "^2.0.0", + "hookable": "^6.1.1", + "import-without-cache": "^0.3.3", + "obug": "^2.1.1", + "picomatch": "^4.0.4", + "rolldown": "1.0.0-rc.17", + "rolldown-plugin-dts": "^0.23.2", + "semver": "^7.7.4", + "tinyexec": "^1.1.1", + "tinyglobby": "^0.2.16", + "tree-kill": "^1.2.2", + "unconfig-core": "^7.5.0", + "unrun": "^0.2.37" + }, + "bin": { + "tsdown": "dist/run.mjs" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@arethetypeswrong/core": "^0.18.1", + "@tsdown/css": "0.21.10", + "@tsdown/exe": "0.21.10", + "@vitejs/devtools": "*", + "publint": "^0.3.0", + "typescript": "^5.0.0 || ^6.0.0", + "unplugin-unused": "^0.5.0" + }, + "peerDependenciesMeta": { + "@arethetypeswrong/core": { + "optional": true + }, + "@tsdown/css": { + "optional": true + }, + "@tsdown/exe": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "publint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "unplugin-unused": { + "optional": true + } + } + }, + "node_modules/tsdown/node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -5062,6 +5742,20 @@ "node": ">=0.8.0" } }, + "node_modules/unconfig-core": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/undici": { "version": "7.24.5", "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.5.tgz", @@ -5094,6 +5788,33 @@ "node": ">= 0.8" } }, + "node_modules/unrun": { + "version": "0.2.39", + "resolved": "https://registry.npmjs.org/unrun/-/unrun-0.2.39.tgz", + "integrity": "sha512-h9FxYVpztY/wwq+bauLOh6Y3CWu2IVeRLq5lxzneBiIU9Tn86OGp9xiQrGhnYspAmg5dzdY0Cc8+Y70kuTARCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rolldown": "1.0.0-rc.17" + }, + "bin": { + "unrun": "dist/cli.mjs" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/Gugustinette" + }, + "peerDependencies": { + "synckit": "^0.11.11" + }, + "peerDependenciesMeta": { + "synckit": { + "optional": true + } + } + }, "node_modules/url-join": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", diff --git a/mcp-server/package.json b/mcp-server/package.json index 41f78e8..1df9003 100644 --- a/mcp-server/package.json +++ b/mcp-server/package.json @@ -2,7 +2,8 @@ "name": "@currents/mcp", "type": "module", "files": [ - "build", + "dist", + "assets", "README.md" ], "keywords": [ @@ -12,25 +13,25 @@ "dashboard", "reporting" ], - "bin": "./build/index.js", + "bin": "./dist/index.mjs", "version": "2.3.0", "description": "Currents MCP server", - "main": "./build/cjs/api.js", - "module": "./build/api.js", - "types": "./build/api.d.ts", + "main": "./dist/api.cjs", + "module": "./dist/api.mjs", + "types": "./dist/api.d.ts", "exports": { ".": { - "types": "./build/api.d.ts", - "import": "./build/api.js", - "require": "./build/cjs/api.js" + "types": "./dist/api.d.ts", + "import": "./dist/api.mjs", + "require": "./dist/api.cjs" } }, "scripts": { - "build": "tsc && tsc -p tsconfig.cjs.json && node ./scripts/write-cjs-package-json.mjs && chmod 755 build/index.js", + "build": "tsdown && chmod 755 dist/index.mjs", "publish:mcp": "npm run publish:npm", - "publish:npm": "npm run rm && npm run build && ./publish.cjs", - "start": "node build/index.js", - "rm": "rimraf dist", + "publish:npm": "npm run rm && npm run build && ./publish.cjs", + "start": "node dist/index.mjs", + "rm": "rm -rf dist", "prepare": "git config core.hooksPath mcp-server/scripts/hooks", "sync-readme": "node scripts/sync-readme-tools.mjs", "test": "vitest", @@ -61,7 +62,7 @@ "@release-it/conventional-changelog": "^11.0.0", "@types/node": "^20.19.0", "release-it": "^20.0.1", - "rimraf": "^6.0.1", + "tsdown": "^0.21.0", "typescript": "^5.9.3", "vitest": "^4.0.18" } diff --git a/mcp-server/scripts/sync-readme-tools.mjs b/mcp-server/scripts/sync-readme-tools.mjs index 8a5ed52..eedcd73 100644 --- a/mcp-server/scripts/sync-readme-tools.mjs +++ b/mcp-server/scripts/sync-readme-tools.mjs @@ -25,7 +25,7 @@ const origResolve = await (async () => { // then patch globalThis so the built server.js picks it up. // Dynamically import the built server module after shimming the dep. - // The built output lives at build/server.js and uses: + // The built output lives at dist/ and uses: // import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" // import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" // diff --git a/mcp-server/scripts/write-cjs-package-json.mjs b/mcp-server/scripts/write-cjs-package-json.mjs deleted file mode 100644 index 84d17aa..0000000 --- a/mcp-server/scripts/write-cjs-package-json.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { mkdirSync, writeFileSync } from "node:fs"; -import { join, dirname } from "node:path"; -import { fileURLToPath } from "node:url"; - -const root = join(dirname(fileURLToPath(import.meta.url)), ".."); -const cjsDir = join(root, "build", "cjs"); -mkdirSync(cjsDir, { recursive: true }); -writeFileSync(join(cjsDir, "package.json"), `${JSON.stringify({ type: "commonjs" })}\n`); diff --git a/mcp-server/src/cli-bin.integration.test.ts b/mcp-server/src/cli-bin.integration.test.ts index a2953cd..e9e214e 100644 --- a/mcp-server/src/cli-bin.integration.test.ts +++ b/mcp-server/src/cli-bin.integration.test.ts @@ -4,7 +4,7 @@ * `package-published-esm.integration.test.ts` for `import "@currents/mcp"`). * - * 1. Prerequisite: `build/index.js` exists (`npm run test:run` runs `build` + * 1. Prerequisite: `dist/index.mjs` exists (`npm run test:run` runs `build` * first). If missing, the suite is skipped so `vitest` without a prior * build does not fail noisily. * 2. `packTarball`: `npm pack` from the package root → one `.tgz` under a @@ -20,7 +20,7 @@ import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; const root = fileURLToPath(new URL("..", import.meta.url)); -const buildIndex = path.join(root, "build", "index.js"); +const buildIndex = path.join(root, "dist", "index.mjs"); function packTarball(packDest: string): string { // Respect `files` and standard pack rules; do not mutate package.json (unlike release `publish.cjs`). @@ -74,7 +74,7 @@ describe.skipIf(!existsSync(buildIndex))( * - `npm init -y` and `npm install ` in a fresh temp project. npm links * `node_modules/.bin/mcp` (or `mcp.cmd` on Windows) to the packed CLI. * - Assert the shim exists. This catches broken `bin`, wrong `files` (missing - * `build/index.js`), or install layout issues without spawning the server. + * `dist/index.mjs`), or install layout issues without spawning the server. * */ it("exposes mcp bin after npm install from tarball", () => { const packDir = mkdtempSync(path.join(tmpdir(), "mcp-pack-")); diff --git a/mcp-server/src/package-environments.integration.test.ts b/mcp-server/src/package-environments.integration.test.ts index a088fba..0124cd4 100644 --- a/mcp-server/src/package-environments.integration.test.ts +++ b/mcp-server/src/package-environments.integration.test.ts @@ -3,17 +3,15 @@ * real Node child process (not Vitest’s module graph). * * Flow (each `it`): - * 1. `npm run test:run` has already run `build`, so `build/` and `build/cjs/` - * exist under the package root (`mcp-server/`). + * 1. `npm run test:run` has already run `build`, so `dist/` exists under the + * package root (`mcp-server/`). * 2. Spawn `process.execPath` (Node) with a small script under * `test/fixtures/*.mjs` or `*.cjs`. * 3. Set `cwd` to that package root so paths and semantics match “consumer runs * next to a checked-out / linked package,” not the Vitest test file’s dir. * 4. The fixture imports the **built** API: - * - ESM: relative file URL to `build/api.js` (Node ESM resolution, `.js` - * extension required). - * - CJS: `require("../../build/cjs/api.js")` with `build/cjs/package.json` - * `type: commonjs` so nested `.js` files load as CommonJS. + * - ESM: relative import to `dist/api.mjs`. + * - CJS: `require("../../dist/api.cjs")`. * - CJS + dynamic `import()`: CommonJS script `import()`s the ESM build; * exercises interop from a `.cjs` entry. * 5. Each script prints a single token to stdout; the parent asserts it to @@ -40,7 +38,7 @@ describe("package consumers (Node ESM, CJS require, CJS dynamic import)", () => expect(out.trim()).toBe("esm-ok"); }); - it("loads programmatic API from CJS require (build/cjs)", () => { + it("loads programmatic API from CJS require (dist/api.cjs)", () => { const out = execFileSync( process.execPath, [path.join(root, "test", "fixtures", "consumer-cjs.cjs")], diff --git a/mcp-server/src/package-published-esm.integration.test.ts b/mcp-server/src/package-published-esm.integration.test.ts index 28e2db8..d2dcf2f 100644 --- a/mcp-server/src/package-published-esm.integration.test.ts +++ b/mcp-server/src/package-published-esm.integration.test.ts @@ -4,16 +4,16 @@ * tarball (same shape users get from the registry). * * Why a separate file from `package-environments.integration.test.ts`: - * workspace tests import `build/*.js` via relative paths; they never ask Node + * workspace tests import `dist/*` via relative paths; they never ask Node * to apply `"exports"` for the scoped name. This suite closes that gap. * * Flow (`it`): - * 1. Prerequisite: `build/index.js` exists (`test:run` runs `build` first). + * 1. Prerequisite: `dist/index.mjs` exists (`test:run` runs `build` first). * If missing, the suite is skipped (same gate as CLI pack tests). * 2. `packTarball`: run `npm pack` with `cwd` = package root. npm creates a * `.tgz` containing exactly what publishing would ship (`package.json` - * `files`, plus auto-included `package.json`). That includes `build/` and - * the `exports` map pointing `"import"` → `./build/api.js`. + * `files`, plus auto-included `package.json`). That includes `dist/` and + * the `exports` map pointing `"import"` → `./dist/api.mjs`. * 3. Create two temp dirs: one receives the `.tgz`, one is a minimal consumer * project (`npm init -y`, then `npm install `). npm unpacks into * `/node_modules/@currents/mcp`. @@ -25,7 +25,7 @@ * 5. Run `node run-published-esm.mjs` with `cwd = installDir`. Node loads the * ESM entry via the `"import"` condition and must find `startMcpServer`. * 6. Assert stdout `published-esm-ok`. Failures here typically mean broken - * `exports`, missing files from the packed `build/`, or a bad dual-package + * `exports`, missing files from the packed `dist/`, or a bad dual-package * layout. * */ import { execFileSync } from "node:child_process"; @@ -36,7 +36,7 @@ import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; const root = fileURLToPath(new URL("..", import.meta.url)); -const buildIndex = path.join(root, "build", "index.js"); +const buildIndex = path.join(root, "dist", "index.mjs"); /** Run `npm pack` from the package root and return the path to the single `.tgz` in `packDest`. */ function packTarball(packDest: string): string { diff --git a/mcp-server/src/server.ts b/mcp-server/src/server.ts index 4993205..1a68292 100644 --- a/mcp-server/src/server.ts +++ b/mcp-server/src/server.ts @@ -6,28 +6,28 @@ import { } from "./lib/env.js"; import { logger } from "./lib/logger.js"; // Actions tools -import { listActionsTool } from "./tools/actions/list-actions.js"; import { createActionTool } from "./tools/actions/create-action.js"; -import { getActionTool } from "./tools/actions/get-action.js"; -import { updateActionTool } from "./tools/actions/update-action.js"; import { deleteActionTool } from "./tools/actions/delete-action.js"; -import { enableActionTool } from "./tools/actions/enable-action.js"; import { disableActionTool } from "./tools/actions/disable-action.js"; -import { listAffectedTestsTool } from "./tools/actions/list-affected-tests.js"; -import { getAffectedTestExecutionsTool } from "./tools/actions/get-affected-test-executions.js"; +import { enableActionTool } from "./tools/actions/enable-action.js"; +import { getActionTool } from "./tools/actions/get-action.js"; import { getAffectedTestExecutionsByActionTool } from "./tools/actions/get-affected-test-executions-by-action.js"; +import { getAffectedTestExecutionsTool } from "./tools/actions/get-affected-test-executions.js"; +import { listActionsTool } from "./tools/actions/list-actions.js"; +import { listAffectedTestsTool } from "./tools/actions/list-affected-tests.js"; +import { updateActionTool } from "./tools/actions/update-action.js"; // Projects tools -import { getProjectsTool } from "./tools/projects/get-projects.js"; -import { getProjectTool } from "./tools/projects/get-project.js"; import { getProjectInsightsTool } from "./tools/projects/get-project-insights.js"; +import { getProjectTool } from "./tools/projects/get-project.js"; +import { getProjectsTool } from "./tools/projects/get-projects.js"; // Runs tools -import { getRunsTool } from "./tools/runs/get-runs.js"; -import { getRunDetailsTool } from "./tools/runs/get-run.js"; -import { findRunTool } from "./tools/runs/find-run.js"; +import { cancelRunByGithubCITool } from "./tools/runs/cancel-run-github-ci.js"; import { cancelRunTool } from "./tools/runs/cancel-run.js"; -import { resetRunTool } from "./tools/runs/reset-run.js"; import { deleteRunTool } from "./tools/runs/delete-run.js"; -import { cancelRunByGithubCITool } from "./tools/runs/cancel-run-github-ci.js"; +import { findRunTool } from "./tools/runs/find-run.js"; +import { getRunDetailsTool } from "./tools/runs/get-run.js"; +import { getRunsTool } from "./tools/runs/get-runs.js"; +import { resetRunTool } from "./tools/runs/reset-run.js"; // Specs tools import { getSpecFilesPerformanceTool } from "./tools/specs/get-spec-files-performance.js"; import { getSpecInstancesTool } from "./tools/specs/get-spec-instances.js"; @@ -38,15 +38,28 @@ import { getTestSignatureTool } from "./tools/tests/get-tests-signature.js"; // Errors tools import { getErrorsExplorerTool } from "./tools/errors/get-errors-explorer.js"; // Webhooks tools -import { listWebhooksTool } from "./tools/webhooks/list-webhooks.js"; import { createWebhookTool } from "./tools/webhooks/create-webhook.js"; +import { deleteWebhookTool } from "./tools/webhooks/delete-webhook.js"; import { getWebhookTool } from "./tools/webhooks/get-webhook.js"; +import { listWebhooksTool } from "./tools/webhooks/list-webhooks.js"; import { updateWebhookTool } from "./tools/webhooks/update-webhook.js"; -import { deleteWebhookTool } from "./tools/webhooks/delete-webhook.js"; + +declare const __LOGO_BASE64__: string; +declare const __VERSION__: string; + +const logoBase64 = __LOGO_BASE64__; +const version = __VERSION__; const server = new McpServer({ name: "currents", - version: "1.0.0", + version, + icons: [ + { + src: `data:image/png;base64,${logoBase64}`, + mimeType: "image/png", + sizes: ["256x256", "128x128", "64x64", "32x32", "16x16"], + }, + ], }); // Actions API tools @@ -57,7 +70,7 @@ server.registerTool( "List all actions for a project with optional filtering. Actions are rules that automatically modify test behavior (skip, quarantine, tag). Supports filtering by status (active/disabled/archived/expired) and search by name. Requires a projectId.", inputSchema: listActionsTool.schema, }, - listActionsTool.handler + listActionsTool.handler, ); server.registerTool( @@ -67,7 +80,7 @@ server.registerTool( "Create a new action for a project. Actions define rules that automatically skip, quarantine, or tag tests based on conditions like test title, file path, git branch, etc. Requires projectId, name, action array, and matcher object.", inputSchema: createActionTool.schema, }, - createActionTool.handler + createActionTool.handler, ); server.registerTool( @@ -77,7 +90,7 @@ server.registerTool( "Get a single action by ID. The actionId is globally unique, so projectId is not required. Returns full action details including matcher conditions and current status.", inputSchema: getActionTool.schema, }, - getActionTool.handler + getActionTool.handler, ); server.registerTool( @@ -87,7 +100,7 @@ server.registerTool( "Update an existing action. The actionId is globally unique. You can update name, description, action array, matcher, or expiration date. All fields are optional.", inputSchema: updateActionTool.schema, }, - updateActionTool.handler + updateActionTool.handler, ); server.registerTool( @@ -97,7 +110,7 @@ server.registerTool( "Delete (archive) an action. This is a soft delete - the action will be marked as archived but not permanently removed. The actionId is globally unique.", inputSchema: deleteActionTool.schema, }, - deleteActionTool.handler + deleteActionTool.handler, ); server.registerTool( @@ -107,7 +120,7 @@ server.registerTool( "Enable a disabled action. Changes the action status from disabled to active, making it apply to matching tests again. The actionId is globally unique.", inputSchema: enableActionTool.schema, }, - enableActionTool.handler + enableActionTool.handler, ); server.registerTool( @@ -117,7 +130,7 @@ server.registerTool( "Disable an active action. Changes the action status to disabled, temporarily preventing it from applying to tests. The actionId is globally unique.", inputSchema: disableActionTool.schema, }, - disableActionTool.handler + disableActionTool.handler, ); server.registerTool( @@ -127,7 +140,7 @@ server.registerTool( "List tests affected by actions (quarantine, skip, tag) for a project within a date range. Returns aggregated data grouped by test signature. Supports filtering by action types, action ID, status, and search. Requires projectId, date_start, and date_end. Preview endpoint: fields and path may change.", inputSchema: listAffectedTestsTool.schema, }, - listAffectedTestsTool.handler + listAffectedTestsTool.handler, ); server.registerTool( @@ -137,7 +150,7 @@ server.registerTool( "Get execution details for a specific affected test (by signature) within a date range. Returns individual test execution records with action info. Uses cursor-based pagination. Requires projectId, signature, date_start, and date_end.", inputSchema: getAffectedTestExecutionsTool.schema, }, - getAffectedTestExecutionsTool.handler + getAffectedTestExecutionsTool.handler, ); server.registerTool( @@ -147,7 +160,7 @@ server.registerTool( "List test executions where a specific action/rule was applied, within a date range. Uses cursor-based pagination. Requires actionId, date_start, and date_end.", inputSchema: getAffectedTestExecutionsByActionTool.schema, }, - getAffectedTestExecutionsByActionTool.handler + getAffectedTestExecutionsByActionTool.handler, ); // Projects API tools @@ -158,7 +171,7 @@ server.registerTool( "Retrieves projects available in the Currents platform. Supports cursor-based pagination with limit, starting_after, ending_before parameters, or set fetchAll=true for automatic pagination. This is a prerequisite for using any other tools that require project-specific information.", inputSchema: getProjectsTool.schema, }, - getProjectsTool.handler + getProjectsTool.handler, ); server.registerTool( @@ -168,7 +181,7 @@ server.registerTool( "Get a single project by ID. Returns project details including name, creation date, failFast setting, inactivity timeout, and default branch name.", inputSchema: getProjectTool.schema, }, - getProjectTool.handler + getProjectTool.handler, ); server.registerTool( @@ -178,7 +191,7 @@ server.registerTool( "Get aggregated run and test metrics for a project within a date range. Returns overall metrics and timeline data with configurable resolution (1h/1d/1w). Supports filtering by tags, branches, groups, and authors. Requires projectId, date_start, and date_end.", inputSchema: getProjectInsightsTool.schema, }, - getProjectInsightsTool.handler + getProjectInsightsTool.handler, ); // Runs API tools @@ -189,7 +202,7 @@ server.registerTool( "Retrieves a list of runs for a specific project with optional filtering. Supports filtering by branch, tags (with AND/OR operators), status (PASSED/FAILED/RUNNING/FAILING), completion state, date range, commit author, and search by ciBuildId or commit message. Requires a projectId. If the projectId is not known, first call 'currents-get-projects' and ask the user to select the project.", inputSchema: getRunsTool.schema, }, - getRunsTool.handler + getRunsTool.handler, ); server.registerTool( @@ -199,7 +212,7 @@ server.registerTool( "Retrieves details of a specific test run. Requires a user-provided runId.", inputSchema: getRunDetailsTool.schema, }, - getRunDetailsTool.handler + getRunDetailsTool.handler, ); server.registerTool( @@ -209,7 +222,7 @@ server.registerTool( "Find a run by query parameters. Returns the most recent completed run matching the criteria. Can search by ciBuildId (exact match) or by branch/tags. Supports pwLastRun flag for Playwright last run info. Requires projectId.", inputSchema: findRunTool.schema, }, - findRunTool.handler + findRunTool.handler, ); server.registerTool( @@ -219,7 +232,7 @@ server.registerTool( "Cancel a run in progress. This will stop the run and mark it as cancelled. Requires runId.", inputSchema: cancelRunTool.schema, }, - cancelRunTool.handler + cancelRunTool.handler, ); server.registerTool( @@ -229,7 +242,7 @@ server.registerTool( "Reset failed spec files in a run to allow re-execution. Requires runId and machineId array (1-63 machine IDs). Optionally supports batched orchestration.", inputSchema: resetRunTool.schema, }, - resetRunTool.handler + resetRunTool.handler, ); server.registerTool( @@ -239,7 +252,7 @@ server.registerTool( "Delete a run and all associated data. This is a permanent deletion. Requires runId.", inputSchema: deleteRunTool.schema, }, - deleteRunTool.handler + deleteRunTool.handler, ); server.registerTool( @@ -249,7 +262,7 @@ server.registerTool( "Cancel a run by GitHub Actions workflow run ID and attempt number. Optionally scope by projectId or ciBuildId. Requires githubRunId and githubRunAttempt.", inputSchema: cancelRunByGithubCITool.schema, }, - cancelRunByGithubCITool.handler + cancelRunByGithubCITool.handler, ); // Specs API tools @@ -260,7 +273,7 @@ server.registerTool( "Retrieves debugging data from a specific execution of a test spec file by instanceId.", inputSchema: getSpecInstancesTool.schema, }, - getSpecInstancesTool.handler + getSpecInstancesTool.handler, ); server.registerTool( @@ -270,7 +283,7 @@ server.registerTool( "Retrieves spec files performance metrics for a specific project within a date range. Supports ordering by avgDuration, failedExecutions, failureRate, flakeRate, flakyExecutions, fullyReported, overallExecutions, suiteSize, timeoutExecutions, or timeoutRate. Supports filtering by tags, branches, groups, and authors. Requires a projectId. If the projectId is not known, first call 'currents-get-projects' and ask the user to select the project.", inputSchema: getSpecFilesPerformanceTool.schema, }, - getSpecFilesPerformanceTool.handler + getSpecFilesPerformanceTool.handler, ); // Tests API tools @@ -281,7 +294,7 @@ server.registerTool( "Retrieves aggregated test metrics for a specific project within a date range. Supports ordering by failures, passes, flakiness, duration, executions, title, and various delta metrics. Supports filtering by spec name, test title, tags, branches, groups, authors, minimum executions, test state, and annotations. Requires a projectId. If the projectId is not known, first call 'currents-get-projects' and ask the user to select the project.", inputSchema: getTestsPerformanceTool.schema, }, - getTestsPerformanceTool.handler + getTestsPerformanceTool.handler, ); server.registerTool( @@ -291,7 +304,7 @@ server.registerTool( "Generates a unique test signature based on project, spec file path, and test title. The test title can be a string or array of strings (for nested describe blocks). Requires a projectId. If the projectId is not known, first call 'currents-get-projects' and ask the user to select the project.", inputSchema: getTestSignatureTool.schema, }, - getTestSignatureTool.handler + getTestSignatureTool.handler, ); server.registerTool( @@ -301,7 +314,7 @@ server.registerTool( "Retrieves historical test execution results for a specific test signature. Supports filtering by date range, branch, tags, git author, test status (passed/failed/pending/skipped), run group, flaky status, and annotations. Requires the test signature. If the signature is not known, first call 'currents-get-tests-signatures'.", inputSchema: getTestResultsTool.schema, }, - getTestResultsTool.handler + getTestResultsTool.handler, ); // Errors API tools @@ -312,7 +325,7 @@ server.registerTool( "Get aggregated error metrics for a project within a date range. Supports filtering by error_target, error_message, error_category, error_action, tags, branches, authors, and groups. Supports grouping by target, action, category, or message. Returns error counts, affected tests and branches, with timeline data. Requires projectId, date_start, and date_end.", inputSchema: getErrorsExplorerTool.schema, }, - getErrorsExplorerTool.handler + getErrorsExplorerTool.handler, ); // Webhooks API tools @@ -323,7 +336,7 @@ server.registerTool( "List all webhooks for a project. Webhooks allow you to receive HTTP POST notifications when certain events occur in your test runs: RUN_FINISH (run completed), RUN_START (run started), RUN_TIMEOUT (run timed out), RUN_CANCELED (run was cancelled). Requires a projectId.", inputSchema: listWebhooksTool.schema, }, - listWebhooksTool.handler + listWebhooksTool.handler, ); server.registerTool( @@ -333,7 +346,7 @@ server.registerTool( "Create a new webhook for a project. Specify the URL to receive POST notifications, optional custom headers (as JSON string), events to trigger on (RUN_FINISH, RUN_START, RUN_TIMEOUT, RUN_CANCELED), and an optional label. Requires projectId and url.", inputSchema: createWebhookTool.schema, }, - createWebhookTool.handler + createWebhookTool.handler, ); server.registerTool( @@ -343,7 +356,7 @@ server.registerTool( "Get a single webhook by ID. The hookId is a UUID. Returns full webhook details including url, headers, events, label, and timestamps.", inputSchema: getWebhookTool.schema, }, - getWebhookTool.handler + getWebhookTool.handler, ); server.registerTool( @@ -353,7 +366,7 @@ server.registerTool( "Update an existing webhook. You can update the url, headers (as JSON string), hookEvents array, or label. All fields are optional. The hookId is a UUID.", inputSchema: updateWebhookTool.schema, }, - updateWebhookTool.handler + updateWebhookTool.handler, ); server.registerTool( @@ -363,7 +376,7 @@ server.registerTool( "Delete a webhook. This permanently removes the webhook. The hookId is a UUID.", inputSchema: deleteWebhookTool.schema, }, - deleteWebhookTool.handler + deleteWebhookTool.handler, ); /** Starts the MCP server over stdio (used by the CLI and programmatic embedders). */ diff --git a/mcp-server/test/fixtures/consumer-cjs-dynamic-import.cjs b/mcp-server/test/fixtures/consumer-cjs-dynamic-import.cjs index 1452820..2b203ac 100644 --- a/mcp-server/test/fixtures/consumer-cjs-dynamic-import.cjs +++ b/mcp-server/test/fixtures/consumer-cjs-dynamic-import.cjs @@ -1,6 +1,6 @@ const assert = require("node:assert"); -import("../../build/api.js") +import("../../dist/api.mjs") .then(({ startMcpServer }) => { assert.strictEqual(typeof startMcpServer, "function"); console.log("cjs-dynamic-import-ok"); diff --git a/mcp-server/test/fixtures/consumer-cjs.cjs b/mcp-server/test/fixtures/consumer-cjs.cjs index cb48245..dc90270 100644 --- a/mcp-server/test/fixtures/consumer-cjs.cjs +++ b/mcp-server/test/fixtures/consumer-cjs.cjs @@ -1,5 +1,5 @@ const assert = require("node:assert"); -const { startMcpServer } = require("../../build/cjs/api.js"); +const { startMcpServer } = require("../../dist/api.cjs"); assert.strictEqual(typeof startMcpServer, "function"); console.log("cjs-require-ok"); diff --git a/mcp-server/test/fixtures/consumer-esm.mjs b/mcp-server/test/fixtures/consumer-esm.mjs index 732cc94..52c90ae 100644 --- a/mcp-server/test/fixtures/consumer-esm.mjs +++ b/mcp-server/test/fixtures/consumer-esm.mjs @@ -1,5 +1,5 @@ import assert from "node:assert"; -import { startMcpServer } from "../../build/api.js"; +import { startMcpServer } from "../../dist/api.mjs"; assert.strictEqual(typeof startMcpServer, "function"); console.log("esm-ok"); diff --git a/mcp-server/tsconfig.cjs.json b/mcp-server/tsconfig.cjs.json deleted file mode 100644 index 5b87ad0..0000000 --- a/mcp-server/tsconfig.cjs.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - /* TS5110: CommonJS + Node16/NodeNext resolution is invalid; this build targets Node 20+ runtime only. */ - "module": "CommonJS", - "moduleResolution": "Node10", - "outDir": "./build/cjs", - "declaration": false, - "declarationMap": false - }, - "include": ["src/**/*.ts"], - "exclude": [ - "node_modules", - "**/*.test.ts", - "**/*.spec.ts", - "src/index.ts" - ] -} diff --git a/mcp-server/tsdown.config.ts b/mcp-server/tsdown.config.ts new file mode 100644 index 0000000..bb225a5 --- /dev/null +++ b/mcp-server/tsdown.config.ts @@ -0,0 +1,22 @@ +import { readFileSync } from "node:fs"; +import { defineConfig } from "tsdown"; + +const logoBase64 = readFileSync("./assets/logo.png").toString("base64"); +const { version } = JSON.parse(readFileSync("./package.json", "utf-8")); + +export default defineConfig({ + entry: { + index: "./src/index.ts", + api: "./src/api.ts", + }, + format: ["esm", "cjs"], + dts: true, + clean: true, + define: { + __LOGO_BASE64__: JSON.stringify(logoBase64), + __VERSION__: JSON.stringify(version), + }, + deps: { + neverBundle: [/^@modelcontextprotocol/, /^pino/, /^commander/, /^zod/], + }, +}); diff --git a/mcp-server/vitest.config.ts b/mcp-server/vitest.config.ts index f16c400..bd575e1 100644 --- a/mcp-server/vitest.config.ts +++ b/mcp-server/vitest.config.ts @@ -5,13 +5,12 @@ export default defineConfig({ globals: true, environment: "node", include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], - exclude: ["node_modules", "build", "dist"], + exclude: ["node_modules", "dist"], coverage: { provider: "v8", reporter: ["text", "json", "html"], exclude: [ "node_modules/", - "build/", "dist/", "**/*.d.ts", "**/*.config.*", From 5b4a31c1db23d3d106e12e19bb58e3a76e09c790 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 18 May 2026 17:58:53 -0700 Subject: [PATCH 2/2] fix: define __LOGO_BASE64__ and __VERSION__ in vitest config The tsdown build injects these globals via `define`, but Vitest runs source directly and was missing them, causing server.test.ts to fail. Co-authored-by: Cursor --- mcp-server/vitest.config.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mcp-server/vitest.config.ts b/mcp-server/vitest.config.ts index bd575e1..c8b6b2b 100644 --- a/mcp-server/vitest.config.ts +++ b/mcp-server/vitest.config.ts @@ -1,6 +1,14 @@ +import { readFileSync } from "node:fs"; import { defineConfig } from "vitest/config"; +const logoBase64 = readFileSync("./assets/logo.png").toString("base64"); +const { version } = JSON.parse(readFileSync("./package.json", "utf-8")); + export default defineConfig({ + define: { + __LOGO_BASE64__: JSON.stringify(logoBase64), + __VERSION__: JSON.stringify(version), + }, test: { globals: true, environment: "node",