@feniix/bridgekit
Advanced tools
+29
-0
@@ -7,2 +7,31 @@ # Changelog | ||
| ## [0.12.0] - 2026-05-27 | ||
| ### Documentation | ||
| - `README.md` gets a full `bin-wrapper` adapter section under "API | ||
| reference" — usage example, options breakdown, `runServer` | ||
| contract, trusted-literal security note, and the missing-entry | ||
| behavior matrix. Previously the subpath had a single line in the | ||
| entrypoint table and zero body documentation. Closes the largest | ||
| gap surfaced by the post-0.11.0 doc audit. | ||
| - `README.md` "Why" bullet and "Packaging" section updated for the | ||
| four-entrypoint shape and the `runBinWrapper` recommendation | ||
| (replaces the pre-0.11.0 manual checked-in-wrapper recipe). | ||
| - `llms.txt` rewrites the "Mixed source-loaded hosts and compiled | ||
| MCP bins" section to lead with `runBinWrapper`. The 8-bullet | ||
| manual-wrapper recipe is demoted to a fallback bullet for | ||
| authors writing their own wrapper. | ||
| - `dist/src/bin-wrapper.d.ts` added to the published-declarations | ||
| lists in `README.md` and `llms.txt`. | ||
| - `docs/README.md` lists `docs/rfc-host-extras.md` in the | ||
| maintainer-docs catalog. The RFC is JSDoc-linked from | ||
| `src/core/define-tool.ts` and was missing from the catalog. | ||
| - `src/adapters/mcp.typecheck.ts` fixes a wrong version stamp on | ||
| the `signalFromExtra` adversarial-pin comment (was `0.10.0 (#3)`, | ||
| should be `0.11.0 (#3)`). The pin's code is correct; only the | ||
| comment was wrong. | ||
| No API or behavior changes. | ||
| ## [0.11.0] - 2026-05-27 | ||
@@ -9,0 +38,0 @@ |
+16
-4
@@ -10,3 +10,3 @@ # @feniix/bridgekit | ||
| 3. `examples/README.md` — copyable end-to-end layouts for shared tools, pi extension wiring, MCP stdio server wiring, and per-host metadata via `hostExtras`. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/mcp.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain implementation context. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, `dist/src/mcp.d.ts`, and `dist/src/bin-wrapper.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain implementation context. | ||
@@ -108,8 +108,20 @@ ## Import map | ||
| - Add a package-local MCP build and point npm `bin` at a checked-in wrapper under `bin/`, not directly at generated `dist/` output. | ||
| - The wrapper should resolve the package-local generated MCP server, run the package-local build when output is missing in workspace/local execution, and preserve non-zero build failures. | ||
| - **Use the built-in `runBinWrapper` helper** (since 0.11.0) instead of a hand-rolled wrapper. It resolves the package-local generated entry, runs the package-local build when output is missing in workspace/local execution, preserves non-zero build failures, recovers when the build emits the entry despite a non-zero exit, and emits a distinct timeout diagnostic when `spawnSync` is killed by `buildTimeoutMs`: | ||
| ```js | ||
| #!/usr/bin/env node | ||
| import { runBinWrapper } from "@feniix/bridgekit/bin-wrapper"; | ||
| await runBinWrapper({ | ||
| metaUrl: import.meta.url, | ||
| mcpEntry: "dist/extensions/mcp-server.js", | ||
| buildScript: "build:mcp", | ||
| }); | ||
| ``` | ||
| `mcpEntry` and `buildScript` must be literal strings — sourcing them from CLI args or env vars opens arbitrary-file import and Windows command injection. The MCP entry module must export `async function runServer(): Promise<void>`. | ||
| - Narrow the MCP build to the MCP entrypoint and shared host-neutral modules; avoid compiling pi adapter entrypoints into the standalone MCP path. | ||
| - Put runtime imports used by the compiled MCP bin in `dependencies`, not only peers or dev dependencies. | ||
| - Declare BridgeKit's Node engine requirement in the downstream package (`>=22.19.0`). | ||
| - Ensure the checked-in wrapper is executable (`chmod +x` or equivalent) and verify the mode with `npm pack --dry-run --json`. | ||
| - Test wrapper behavior for existing output, missing output, failed builds, and builds that exit successfully without creating the expected file. | ||
| - Ensure the bin script is executable (`chmod +x` or equivalent) and verify the mode with `npm pack --dry-run --json`. | ||
| - If you write your own wrapper instead of using `runBinWrapper`, test the four behavior modes: existing output, missing output that the build creates, failed builds (non-zero exit), and builds that exit successfully without creating the expected file. | ||
@@ -116,0 +128,0 @@ ## Anti-patterns |
+1
-1
| { | ||
| "name": "@feniix/bridgekit", | ||
| "version": "0.11.0", | ||
| "version": "0.12.0", | ||
| "description": "BridgeKit defines TypeBox-backed tools once and adapts them to pi, MCP, and other hosts.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+39
-4
@@ -69,3 +69,3 @@ # BridgeKit | ||
| - TypeBox schemas pass through to MCP `inputSchema` directly — no JSON Schema conversion step. | ||
| - Import-passive, `sideEffects: false`, three-entrypoint split (`.`, `./pi`, `./mcp`) so pi-only consumers do not pull the MCP SDK and vice versa. | ||
| - Import-passive, `sideEffects: false`, four-entrypoint split (`.`, `./pi`, `./mcp`, `./bin-wrapper`) so pi-only consumers do not pull the MCP SDK and vice versa. | ||
| - Conformance-tested public surface: a packed-install smoke test enforces the runtime export set, deep-import rejection, and type-level strictness against the installed declarations. | ||
@@ -237,2 +237,37 @@ | ||
| ### bin-wrapper (since 0.11.0) | ||
| The `bin-wrapper` subpath ships a helper for npm `bin` scripts that load a compiled MCP entrypoint and build it on first invocation when the compiled output is missing. Replaces the ~25-line "resolve dist path → spawn build if missing → import and run" boilerplate that downstream consumers with mixed source-loaded pi + compiled MCP packages previously hand-rolled. | ||
| ```js | ||
| #!/usr/bin/env node | ||
| import { runBinWrapper } from "@feniix/bridgekit/bin-wrapper"; | ||
| await runBinWrapper({ | ||
| metaUrl: import.meta.url, | ||
| mcpEntry: "dist/extensions/mcp-server.js", | ||
| buildScript: "build:mcp", | ||
| }); | ||
| ``` | ||
| Options: | ||
| - `metaUrl` (required): `import.meta.url` of the bin script. Used to locate the package root (the bin's parent directory). | ||
| - `mcpEntry` (required): path to the compiled MCP entry, relative to the package root (e.g. `"dist/extensions/mcp-server.js"`). | ||
| - `buildScript` (required): npm script to invoke when the entry is missing (e.g. `"build:mcp"`). | ||
| - `buildTimeoutMs` (optional, default `60_000`): timeout for the build subprocess. Distinct "Build timed out…" diagnostic fires when exceeded. | ||
| - `logPrefix` (optional, default `"bridgekit-bin"`): prefix on the "Failed to build…" diagnostic. | ||
| The MCP entry module must export `async function runServer(): Promise<void>`. Consumers with a different export name can alias on export. | ||
| **Security: `mcpEntry` and `buildScript` must be literal strings in the caller's source.** The helper joins `mcpEntry` onto the resolved package root and dynamically `import()`s it, and it passes `buildScript` to `spawnSync` (with `shell: true` on Windows where `&`, `|`, and `^` are shell metacharacters). Sourcing either from CLI args or environment variables exposes arbitrary-file import and Windows command injection. | ||
| Behavior on missing entry: | ||
| - Build emits the entry → import and call `runServer()`. | ||
| - Build exits non-zero but the entry exists → recover (import and call `runServer()`). | ||
| - Build exits 0 but the entry is still missing → exit with code 1, generic "Failed to build…" diagnostic. | ||
| - Build exits non-zero with entry missing → exit with the build's status code, generic diagnostic. | ||
| - Build killed by timeout (SIGTERM) → exit 1, distinct timeout diagnostic naming `buildTimeoutMs`. | ||
| ## Best practices | ||
@@ -263,3 +298,3 @@ | ||
| - For MCP stdio bins, ensure the executable entrypoint starts with a Node shebang, has executable mode (`chmod +x` or equivalent), and is included by `npm pack --dry-run --json`. | ||
| - If an npm-launched bin depends on generated output, prefer a checked-in wrapper under `bin/` over pointing `bin` directly at `dist/`; the wrapper should resolve the package-local generated file and may run the package-local build for workspace/local execution. | ||
| - If an npm-launched bin depends on generated output, use `runBinWrapper` from `@feniix/bridgekit/bin-wrapper` (since 0.11.0) — it resolves the package-local generated entry, runs the package-local build when output is missing in workspace/local execution, preserves build failures, and distinguishes timeout from build error in its diagnostic. The bin script becomes a three-line invocation; no hand-rolled wrapper needed. | ||
| - If a package keeps a source-loaded host entrypoint (for example a pi extension source file), use a package-local MCP build behind that wrapper and narrow the build to the MCP entrypoint plus shared host-neutral modules. | ||
@@ -278,3 +313,3 @@ - Declare a compatible Node engine (`>=22.19.0`) in downstream packages that expose BridgeKit-powered MCP bins. | ||
| 2. `llms.txt` — compact agent-facing usage rules and anti-patterns. | ||
| 3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers, and per-host metadata via `hostExtras`. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/mcp.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain the same implementation context. | ||
| 3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers, per-host metadata via `hostExtras`, and bin wrappers via `runBinWrapper`. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, `dist/src/mcp.d.ts`, and `dist/src/bin-wrapper.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain the same implementation context. |
131259
3.73%312
12.64%