diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b01f5f0..1a448c01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,12 +25,19 @@ jobs: - name: Build run: pnpm -r build + - name: Typecheck + run: pnpm -r typecheck + - name: Unit tests run: pnpm -r test # Smoke tests are NOT run here — they require a live LEADBAY_TEST_TOKEN # against a dedicated tenant. Run them manually or in a separate # nightly workflow with the secret bound. - - name: Verify packed tarball is publishable + - name: Verify @leadbay/mcp tarball is publishable working-directory: packages/mcp run: npm pack --dry-run + + - name: Verify @leadbay/leadclaw tarball is publishable + working-directory: packages/leadclaw + run: npm pack --dry-run diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3f6349c..c671be6c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,76 +1,105 @@ -name: release-mcp +name: release -# Publishes @leadbay/mcp to npm when a tag matching v* is pushed -# (e.g. `git tag v0.2.0 && git push --tags`). +# Tag-driven publishing for @leadbay/mcp (npm) and @leadbay/leadclaw (npm + ClawHub). # -# One-time setup before the first run: -# 1. Generate an npm automation token (https://www.npmjs.com/settings//tokens -# → Generate New Token → Automation). -# 2. Add it as the GitHub Actions secret NPM_TOKEN -# (Settings → Secrets and variables → Actions → New repository secret). +# Tag scheme: +# - mcp-v → publishes @leadbay/mcp only +# - leadclaw-v → publishes @leadbay/leadclaw to npm, then ClawHub +# - v → legacy alias for mcp-v (from the original release-mcp workflow) # -# What this workflow does NOT do: -# - Auto-bump versions. Bump packages/mcp/package.json (and core/leadclaw if needed) -# in a regular PR, then tag the commit on main once merged. -# - Publish @leadbay/leadclaw or @leadbay/core. Add jobs for those if you decide -# to ship them on npm too (currently leadclaw distributes through ClawHub -# and core is bundled into mcp via tsup). +# One-time setup (done in repo settings): +# - NPM_TOKEN → npm automation token, scope-owner on @leadbay +# - CLAWHUB_TOKEN → ClawHub publish token with rights to @leadbay/leadclaw +# +# No auto-version-bump, no auto-changelog. Bump `package.json` (and +# `openclaw.plugin.json` for leadclaw) in a normal PR, then tag the merge commit: +# +# git tag mcp-v0.3.0 && git push origin mcp-v0.3.0 +# git tag leadclaw-v0.3.0 && git push origin leadclaw-v0.3.0 on: push: tags: + - "mcp-v*.*.*" + - "leadclaw-v*.*.*" - "v*.*.*" workflow_dispatch: - # Lets a maintainer trigger a release manually from the Actions UI - # (e.g. for a re-publish without re-tagging). inputs: + package: + description: "Which package to publish (mcp | leadclaw)" + required: true + default: "mcp" + type: choice + options: [mcp, leadclaw] dry_run: - description: "If true, run npm publish --dry-run (no actual publish)" + description: "If true, npm half uses --dry-run (ClawHub has no dry-run; skipped on dry runs)" required: false default: "false" jobs: + preflight-npm: + name: Preflight — verify npm auth + @leadbay scope + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: "https://registry.npmjs.org" + always-auth: true + - name: whoami + scope probe + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + set -euo pipefail + echo "Logged in as: $(npm whoami --registry=https://registry.npmjs.org)" + # Scope-empty on first publish is OK; fall through. Fatal errors (401/403) + # come from npm whoami above. + npm access list packages @leadbay 2>&1 || echo "scope empty or no packages yet — first publish will create" + publish-mcp: name: Publish @leadbay/mcp to npm + needs: preflight-npm + if: | + startsWith(github.ref, 'refs/tags/mcp-v') || + startsWith(github.ref, 'refs/tags/v') || + (github.event_name == 'workflow_dispatch' && github.event.inputs.package == 'mcp') runs-on: ubuntu-latest permissions: contents: read - id-token: write # for npm provenance (optional but recommended) + id-token: write # npm provenance steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 with: version: 10 - - uses: actions/setup-node@v4 with: node-version: 22 registry-url: "https://registry.npmjs.org" - # Tells npm to send the auth token only to the npm registry. always-auth: true - - - name: Install dependencies + - name: Install run: pnpm install --frozen-lockfile - - - name: Build all packages + - name: Build run: pnpm -r build - - - name: Run unit tests + - name: Test run: pnpm -r test - - name: Verify tag matches package version + - name: Verify tag matches packages/mcp/package.json version if: github.event_name == 'push' run: | - TAG="${GITHUB_REF#refs/tags/v}" + set -euo pipefail + REF="${GITHUB_REF#refs/tags/}" + # Strip either "mcp-v" or plain "v" prefix. + TAG="${REF#mcp-v}" + TAG="${TAG#v}" PKG_VERSION=$(node -p "require('./packages/mcp/package.json').version") if [ "$TAG" != "$PKG_VERSION" ]; then - echo "Tag v$TAG does not match packages/mcp/package.json version $PKG_VERSION" + echo "Tag $REF → version $TAG does not match packages/mcp/package.json $PKG_VERSION" exit 1 fi - echo "Tag matches: v$TAG = $PKG_VERSION" + echo "Aligned: $REF = $PKG_VERSION" - - name: Publish @leadbay/mcp + - name: Publish working-directory: packages/mcp run: | if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then @@ -80,3 +109,77 @@ jobs: fi env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + publish-leadclaw: + name: Publish @leadbay/leadclaw to npm + ClawHub + needs: preflight-npm + if: | + startsWith(github.ref, 'refs/tags/leadclaw-v') || + (github.event_name == 'workflow_dispatch' && github.event.inputs.package == 'leadclaw') + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: "https://registry.npmjs.org" + always-auth: true + - name: Install + run: pnpm install --frozen-lockfile + - name: Build + run: pnpm -r build + - name: Test + run: pnpm -r test + + - name: Verify tag ↔ package.json ↔ openclaw.plugin.json version agreement + if: github.event_name == 'push' + run: | + set -euo pipefail + TAG="${GITHUB_REF#refs/tags/leadclaw-v}" + PKG=$(node -p "require('./packages/leadclaw/package.json').version") + MAN=$(node -p "require('./packages/leadclaw/openclaw.plugin.json').version") + if [ "$TAG" != "$PKG" ] || [ "$PKG" != "$MAN" ]; then + echo "Version drift: tag=$TAG pkg=$PKG manifest=$MAN — bump all three to match" + exit 1 + fi + echo "Aligned: $TAG = $PKG = $MAN" + + - name: Publish to npm + working-directory: packages/leadclaw + run: | + if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then + npm publish --access public --provenance --dry-run + else + npm publish --access public --provenance + fi + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Install ClawHub CLI + if: github.event.inputs.dry_run != 'true' + run: npm i -g clawhub@^0.9 + + - name: Authenticate ClawHub + if: github.event.inputs.dry_run != 'true' + env: + CLAWHUB_TOKEN: ${{ secrets.CLAWHUB_TOKEN }} + run: clawhub login --token "$CLAWHUB_TOKEN" --no-browser + + - name: Publish to ClawHub + if: github.event.inputs.dry_run != 'true' + run: | + set -euo pipefail + VERSION=$(node -p "require('./packages/leadclaw/package.json').version") + clawhub package publish packages/leadclaw \ + --version "$VERSION" \ + --source-repo "$GITHUB_REPOSITORY" \ + --source-commit "$GITHUB_SHA" \ + --source-ref "${GITHUB_REF_NAME}" \ + --source-path packages/leadclaw \ + --tags latest diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..b54c70e2 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,60 @@ +# Release runbook + +All releases are tag-driven. **Never run `npm publish` locally.** The GitHub Actions workflow in `.github/workflows/release.yml` owns publishing, and it verifies tag ↔ version ↔ manifest agreement before each publish. + +## One-time setup (already done, but for the record) + +Repo secrets (Settings → Secrets and variables → Actions): + +- `NPM_TOKEN` — npm automation token with publish rights on the `@leadbay` scope. +- `CLAWHUB_TOKEN` — ClawHub publish token with rights on the `@leadbay` namespace. + +npm scope: `@leadbay` must exist with publish rights for the NPM_TOKEN holder (create at if not yet). + +## Release `@leadbay/mcp` + +1. On a branch, bump `packages/mcp/package.json#version` (e.g. `0.2.0` → `0.3.0`). +2. Add a note to `packages/mcp/CHANGELOG.md`. +3. PR → `main`, land. +4. Tag the merge commit and push: + ```bash + git checkout main && git pull + git tag mcp-v0.3.0 + git push origin mcp-v0.3.0 + ``` +5. Watch the `release` workflow in Actions. It runs `preflight-npm` → `publish-mcp` (build + test + tag/version check + `npm publish --access public --provenance`). + +## Release `@leadbay/leadclaw` + +The leadclaw version must match in **three** places: `package.json`, `openclaw.plugin.json`, and the git tag. The workflow fails fast if they disagree. + +1. Bump `packages/leadclaw/package.json#version` AND `packages/leadclaw/openclaw.plugin.json#version` to the same value. +2. Add a note to `packages/leadclaw/CHANGELOG.md`. +3. PR → `main`, land. +4. Tag the merge commit and push: + ```bash + git checkout main && git pull + git tag leadclaw-v0.3.0 + git push origin leadclaw-v0.3.0 + ``` +5. Watch the `release` workflow. It runs `preflight-npm` → `publish-leadclaw` (build + test + version-parity check + `npm publish` + `clawhub login` + `clawhub package publish`). + +Order matters: npm **before** ClawHub. OpenClaw's install path resolves `@leadbay/leadclaw` via npm (`install.npmSpec`), so a ClawHub entry pointing at a missing npm version would break installs. + +## Manual dry run + +Actions → `release` → "Run workflow" → pick `package: mcp | leadclaw`, set `dry_run: true`. The npm half runs `npm publish --dry-run`. ClawHub is skipped on dry runs (the CLI has no dry-run mode). + +## Debugging a failed release + +- **`E404 Scope not found`** from `preflight-npm` → `@leadbay` org doesn't exist yet. Create at . Re-run the workflow from the Actions UI (no re-tag needed). +- **`E403`** from `publish-*` → token lacks publish rights on the scope. Regenerate the automation token with scope-owner rights, update `NPM_TOKEN`, re-run. +- **"Version drift: tag=X pkg=Y manifest=Z"** → bump the laggard(s) in a new PR, tag the new commit. +- **`clawhub login` failure** → check `CLAWHUB_TOKEN` is valid with `clawhub whoami` locally (using the same token). +- **`clawhub package publish` failure** → the CLI surfaces the HTTP error. Common causes: source-repo/source-commit mismatch (shouldn't happen, the workflow passes these from GitHub env), or the `leadbay` namespace rights missing on ClawHub. + +If a publish half-succeeds (npm ships but ClawHub fails, or vice versa), fix the underlying issue and re-run the failing job from the Actions UI; do not retag the same version. + +## No automatic version bumping, no changesets + +Versioning is manual — the cost of getting it wrong is a red CI run, not a wrong release. Two packages at this scale doesn't justify automation overhead. Revisit if the package count grows. diff --git a/packages/leadclaw/CHANGELOG.md b/packages/leadclaw/CHANGELOG.md new file mode 100644 index 00000000..35b9adc5 --- /dev/null +++ b/packages/leadclaw/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog — @leadbay/leadclaw + +## 0.2.0 — 2026-04-20 + +First public release to npm and ClawHub. + +- 50-tool surface split across composite (read-only, default), granular (`exposeGranular: true`), and write (`exposeWrite: true`) tiers. +- Composite workflow tools mirror the `@leadbay/mcp` agent-facing surface: pull_leads, research_lead, research_company, prepare_outreach, account_status, recall_ordered_titles, bulk_qualify_leads, enrich_titles. +- Write tools follow a verification-first contract — `report_outreach` requires `gmail_message_id | calendar_event_id | user_confirmed`. +- Config schema + ui hints: `region` (us/fr, required-ish), `token`, `baseUrl`, `exposeGranular`, `exposeWrite`. +- Tag-driven CI publish via `.github/workflows/release.yml` (push `leadclaw-v` to ship to npm, then ClawHub). +- Version drift guard: CI fails if `package.json` and `openclaw.plugin.json` disagree. diff --git a/packages/leadclaw/README.md b/packages/leadclaw/README.md new file mode 100644 index 00000000..a4e2ee90 --- /dev/null +++ b/packages/leadclaw/README.md @@ -0,0 +1,95 @@ +# @leadbay/leadclaw — Leadbay OpenClaw plugin + +An OpenClaw plugin that gives any OpenClaw-compatible agent a first-class, 50-tool surface for Leadbay B2B lead discovery, qualification, and enrichment — backed by the same composite-workflow API used by [`@leadbay/mcp`](https://www.npmjs.com/package/@leadbay/mcp). + +**Don't have a Leadbay account?** [Register here](https://wow.leadbay.ai/?register=true). + +## 1. Install + +### Via ClawHub (recommended) + +```bash +clawhub package install @leadbay/leadclaw +``` + +### Via OpenClaw CLI (alternative) + +```bash +openclaw plugins install @leadbay/leadclaw +``` + +### Via npm (for custom wiring) + +```bash +npm install @leadbay/leadclaw +``` + +The npm tarball contains the bundled `dist/index.js`, the `openclaw.plugin.json` manifest, this README, the license, and the plugin logo. `@leadbay/core` is bundled in — no runtime deps besides Node ≥22. + +## 2. Configuration + +Set these in your OpenClaw plugin config block (names match the `uiHints` and `configSchema` in `openclaw.plugin.json`): + +| Field | Required | Default | Purpose | +|-------|----------|---------|---------| +| `region` | **yes** (recommended) | (auto) | `"us"` or `"fr"` — pins which Leadbay backend receives your token. Strongly recommended to set explicitly; otherwise login auto-probes both regions. | +| `token` | optional | — | Pre-minted bearer token. If unset, the agent can call `leadbay_login` to mint one interactively. | +| `baseUrl` | optional | derived from region | Override API base (staging/dev). | +| `exposeGranular` | optional | `false` | Set `true` to also expose the ~30 low-level 1:1-with-API tools alongside the composite workflow tools. More surface area, more chance the agent picks the wrong one. | +| `exposeWrite` | optional | `false` | Set `true` to expose write/mutation tools (create lenses, enrich contacts, adjust audience, report outreach, etc.). Hidden by default so an LLM cannot mutate state without explicit opt-in. | + +Example OpenClaw config fragment: + +```jsonc +{ + "plugins": { + "@leadbay/leadclaw": { + "region": "us", + "token": "lb_...", + "exposeWrite": false, + "exposeGranular": false + } + } +} +``` + +## 3. Tool surface + +The plugin ships **50 tools**. Exposure is gated by the two flags above: + +- **Default (composite workflow tools)** — the agent-facing surface. Read-only end-to-end: `leadbay_pull_leads`, `leadbay_research_lead`, `leadbay_research_company`, `leadbay_prepare_outreach`, `leadbay_account_status`, `leadbay_recall_ordered_titles`, `leadbay_bulk_qualify_leads`, `leadbay_enrich_titles`, plus the login tool. +- **`exposeGranular: true`** — adds the granular API tools: lens read/filter/scoring, sector taxonomy, selection ids, enrichment job titles, contacts, quota, taste profile, user_prompt, clarifications, epilogue responses, prospecting actions, lead notes, web_fetch, etc. (23 tools.) +- **`exposeWrite: true`** — adds the write tools: `leadbay_create_lens`, `leadbay_update_lens`, `leadbay_set_active_lens`, `leadbay_set_user_prompt`, `leadbay_qualify_lead`, `leadbay_enrich_contacts`, `leadbay_add_note`, `leadbay_select_leads` / `leadbay_deselect_leads` / `leadbay_clear_selection`, `leadbay_refine_prompt`, `leadbay_report_outreach`, `leadbay_adjust_audience`, `leadbay_launch_bulk_enrichment`, etc. (17 tools.) + +Write tools follow a **verification-first** contract where relevant — `leadbay_report_outreach`, for example, requires `gmail_message_id | calendar_event_id | user_confirmed` on every call so an agent cannot silently poison your pipeline with hallucinated outreach. + +The canonical tool list + schemas live in [`openclaw.plugin.json`](./openclaw.plugin.json). + +## 4. Example agent prompts + +> *Find 20 SaaS companies in Berlin matching my Ideal Buyer Profile, research the top 3, and prepare an outreach package for the best-fit contact.* + +> *Qualify the leads I selected last session, then recall the titles we've ordered so I can plan enrichment.* + +> *Adjust my audience to include VP of Finance at Series B startups and refine the prompt if any clarifications come up.* (requires `exposeWrite: true`) + +## 5. Troubleshooting + +| Problem | Cause | Fix | +|---------|-------|-----| +| Plugin loads but agent sees no Leadbay tools | `token` missing and no login step taken | Have the agent call `leadbay_login`, or pre-set `token` in the plugin config | +| `Authentication token expired or invalid` | Token revoked or wrong region | Mint a new token at [app.leadbay.ai](https://app.leadbay.ai); verify `region` matches your account | +| `No enrichment credits remaining` | Out of quota | Buy credits at [app.leadbay.ai](https://app.leadbay.ai) | +| Agent keeps picking granular tools over composites | `exposeGranular: true` set | Flip to `false`; the composites are usually what you want | +| Write tool "not found" | `exposeWrite: false` (default) | Set `exposeWrite: true` after explicitly opting in | + +## 6. Security & privacy + +- Tokens live only in your OpenClaw plugin config; they traverse the network only to `api-{region}.leadbay.app`. +- Write tools (`exposeWrite`) and granular tools (`exposeGranular`) are **hidden by default** — opt-in per session. +- `leadbay_report_outreach` requires verification metadata (Gmail/Calendar id or explicit `user_confirmed` text) to prevent pipeline poisoning. +- No telemetry is sent by this plugin. API requests are subject to the [Leadbay privacy policy](https://leadbay.ai/privacy). + +## 7. License + +MIT. See [LICENSE](./LICENSE). diff --git a/packages/leadclaw/package.json b/packages/leadclaw/package.json index e0c07fef..fdda3b89 100644 --- a/packages/leadclaw/package.json +++ b/packages/leadclaw/package.json @@ -9,9 +9,13 @@ "dist/", "openclaw.plugin.json", "README.md", + "CHANGELOG.md", "LICENSE", "logo.png" ], + "publishConfig": { + "access": "public" + }, "openclaw": { "extensions": [ "./dist/index.js" @@ -31,7 +35,8 @@ "scripts": { "build": "tsup", "typecheck": "tsc --noEmit", - "test": "vitest run" + "test": "vitest run", + "prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run test" }, "devDependencies": { "@leadbay/core": "workspace:*" @@ -39,5 +44,23 @@ "engines": { "node": ">=22" }, + "keywords": [ + "openclaw", + "openclaw-plugin", + "leadbay", + "lead-generation", + "b2b", + "sales" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/leadbay/leadclaw.git", + "directory": "packages/leadclaw" + }, + "bugs": { + "url": "https://github.com/leadbay/leadclaw/issues" + }, + "homepage": "https://github.com/leadbay/leadclaw/tree/main/packages/leadclaw#readme", + "author": "Leadbay", "license": "MIT" } diff --git a/packages/mcp/CHANGELOG.md b/packages/mcp/CHANGELOG.md new file mode 100644 index 00000000..783d9f2a --- /dev/null +++ b/packages/mcp/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog — @leadbay/mcp + +## 0.2.0 — 2026-04-20 + +First public npm release. + +- Agent-optimized composite tool surface (pull_leads, research_lead, bulk_qualify_leads, enrich_titles, adjust_audience, refine_prompt, recall_ordered_titles, account_status, report_outreach). +- `leadbay-mcp install` one-shot setup: mints a token and registers the server with Claude Code, Claude Desktop, and Cursor. +- `leadbay-mcp login` lower-level token mint (`--write-config` drops a 0600 JSON). +- `leadbay-mcp doctor` validates token + region + quota. +- Gating: `LEADBAY_MCP_WRITE=1` for mutations, `LEADBAY_MCP_ADVANCED=1` for the granular API surface (both off by default). +- `report_outreach` requires a verification field (`gmail_message_id | calendar_event_id | user_confirmed`) to prevent pipeline poisoning. +- Mock mode via `LEADBAY_MOCK=1` for agent-author dry-running against `.context/leadbay-live-shapes/` fixtures. +- Tag-driven CI publish via `.github/workflows/release.yml` (push `mcp-v` or `v`). +- `--version` output now sourced from `package.json` at build time — no more drift between the tarball version and the binary's self-reported version. diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 440eec49..90345354 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -10,6 +10,7 @@ "dist/", "README.md", "MIGRATION.md", + "CHANGELOG.md", "LICENSE" ], "publishConfig": { @@ -20,7 +21,7 @@ "typecheck": "tsc --noEmit", "test": "vitest run", "test:smoke": "vitest run --config vitest.smoke.config.ts", - "prepublishOnly": "tsup" + "prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run test" }, "dependencies": { "@modelcontextprotocol/sdk": "1.29.0" @@ -41,5 +42,15 @@ "claude-desktop", "cursor" ], + "repository": { + "type": "git", + "url": "git+https://github.com/leadbay/leadclaw.git", + "directory": "packages/mcp" + }, + "bugs": { + "url": "https://github.com/leadbay/leadclaw/issues" + }, + "homepage": "https://github.com/leadbay/leadclaw/tree/main/packages/mcp#readme", + "author": "Leadbay", "license": "MIT" } diff --git a/packages/mcp/src/bin.ts b/packages/mcp/src/bin.ts index e85dedbd..90c47041 100644 --- a/packages/mcp/src/bin.ts +++ b/packages/mcp/src/bin.ts @@ -8,7 +8,11 @@ import { } from "@leadbay/core"; import { buildServer } from "./server.js"; -const VERSION = "0.2.0"; +// __LEADBAY_MCP_VERSION__ is replaced at build time by tsup with the string +// literal from packages/mcp/package.json#version. Single source of truth — +// bump package.json and both the tarball and --version output track it. +declare const __LEADBAY_MCP_VERSION__: string; +const VERSION = __LEADBAY_MCP_VERSION__; const HELP = ` leadbay-mcp ${VERSION} — Leadbay Model Context Protocol server @@ -167,7 +171,9 @@ async function readPassword(): Promise { // Piped: read stdin to EOF. return await new Promise((resolve) => { const chunks: Buffer[] = []; - process.stdin.on("data", (c) => chunks.push(c)); + process.stdin.on("data", (c: string | Buffer) => { + chunks.push(typeof c === "string" ? Buffer.from(c, "utf8") : c); + }); process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "")) ); diff --git a/packages/mcp/tsup.config.ts b/packages/mcp/tsup.config.ts index 58116be1..2bc38586 100644 --- a/packages/mcp/tsup.config.ts +++ b/packages/mcp/tsup.config.ts @@ -1,4 +1,7 @@ import { defineConfig } from "tsup"; +import { readFileSync } from "node:fs"; + +const pkg = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")); // @leadbay/mcp is a CLI-only package. We bundle bin.ts into a single // self-contained dist/bin.js. No library surface is exposed to npm @@ -17,4 +20,7 @@ export default defineConfig({ banner: { js: "#!/usr/bin/env node", }, + define: { + __LEADBAY_MCP_VERSION__: JSON.stringify(pkg.version), + }, }); diff --git a/packages/mcp/vitest.config.ts b/packages/mcp/vitest.config.ts index 60da776f..9c2e1292 100644 --- a/packages/mcp/vitest.config.ts +++ b/packages/mcp/vitest.config.ts @@ -1,6 +1,12 @@ import { defineConfig } from "vitest/config"; +import { readFileSync } from "node:fs"; + +const pkg = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")); export default defineConfig({ + define: { + __LEADBAY_MCP_VERSION__: JSON.stringify(pkg.version), + }, test: { environment: "node", include: ["test/**/*.test.ts"],