@feniix/bridgekit 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +39 -4
- package/llms.txt +16 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to `@feniix/bridgekit` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.12.0] - 2026-05-27
|
|
8
|
+
|
|
9
|
+
### Documentation
|
|
10
|
+
|
|
11
|
+
- `README.md` gets a full `bin-wrapper` adapter section under "API
|
|
12
|
+
reference" — usage example, options breakdown, `runServer`
|
|
13
|
+
contract, trusted-literal security note, and the missing-entry
|
|
14
|
+
behavior matrix. Previously the subpath had a single line in the
|
|
15
|
+
entrypoint table and zero body documentation. Closes the largest
|
|
16
|
+
gap surfaced by the post-0.11.0 doc audit.
|
|
17
|
+
- `README.md` "Why" bullet and "Packaging" section updated for the
|
|
18
|
+
four-entrypoint shape and the `runBinWrapper` recommendation
|
|
19
|
+
(replaces the pre-0.11.0 manual checked-in-wrapper recipe).
|
|
20
|
+
- `llms.txt` rewrites the "Mixed source-loaded hosts and compiled
|
|
21
|
+
MCP bins" section to lead with `runBinWrapper`. The 8-bullet
|
|
22
|
+
manual-wrapper recipe is demoted to a fallback bullet for
|
|
23
|
+
authors writing their own wrapper.
|
|
24
|
+
- `dist/src/bin-wrapper.d.ts` added to the published-declarations
|
|
25
|
+
lists in `README.md` and `llms.txt`.
|
|
26
|
+
- `docs/README.md` lists `docs/rfc-host-extras.md` in the
|
|
27
|
+
maintainer-docs catalog. The RFC is JSDoc-linked from
|
|
28
|
+
`src/core/define-tool.ts` and was missing from the catalog.
|
|
29
|
+
- `src/adapters/mcp.typecheck.ts` fixes a wrong version stamp on
|
|
30
|
+
the `signalFromExtra` adversarial-pin comment (was `0.10.0 (#3)`,
|
|
31
|
+
should be `0.11.0 (#3)`). The pin's code is correct; only the
|
|
32
|
+
comment was wrong.
|
|
33
|
+
|
|
34
|
+
No API or behavior changes.
|
|
35
|
+
|
|
7
36
|
## [0.11.0] - 2026-05-27
|
|
8
37
|
|
|
9
38
|
### Added
|
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ This package is ESM-only and supports Node.js 22.19.0 or newer. Published module
|
|
|
66
66
|
- Define a tool once; ship it to pi and MCP without per-host forks.
|
|
67
67
|
- Host-neutral tool files: no pi or MCP SDK imports in the tool definition itself.
|
|
68
68
|
- TypeBox schemas pass through to MCP `inputSchema` directly — no JSON Schema conversion step.
|
|
69
|
-
- Import-passive, `sideEffects: false`,
|
|
69
|
+
- Import-passive, `sideEffects: false`, four-entrypoint split (`.`, `./pi`, `./mcp`, `./bin-wrapper`) so pi-only consumers do not pull the MCP SDK and vice versa.
|
|
70
70
|
- 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.
|
|
71
71
|
|
|
72
72
|
## API reference
|
|
@@ -233,6 +233,41 @@ Portable validation failures and portable `isError: true` results return `CallTo
|
|
|
233
233
|
|
|
234
234
|
The two adapters now read in parallel: invalid args and portable `isError` results return `{ isError: true }` from both hosts by default, and the same result-guard helpers (`isValidationFailure`, `isDomainFailure`) narrow them on either side.
|
|
235
235
|
|
|
236
|
+
### bin-wrapper (since 0.11.0)
|
|
237
|
+
|
|
238
|
+
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.
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
#!/usr/bin/env node
|
|
242
|
+
import { runBinWrapper } from "@feniix/bridgekit/bin-wrapper";
|
|
243
|
+
|
|
244
|
+
await runBinWrapper({
|
|
245
|
+
metaUrl: import.meta.url,
|
|
246
|
+
mcpEntry: "dist/extensions/mcp-server.js",
|
|
247
|
+
buildScript: "build:mcp",
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Options:
|
|
252
|
+
|
|
253
|
+
- `metaUrl` (required): `import.meta.url` of the bin script. Used to locate the package root (the bin's parent directory).
|
|
254
|
+
- `mcpEntry` (required): path to the compiled MCP entry, relative to the package root (e.g. `"dist/extensions/mcp-server.js"`).
|
|
255
|
+
- `buildScript` (required): npm script to invoke when the entry is missing (e.g. `"build:mcp"`).
|
|
256
|
+
- `buildTimeoutMs` (optional, default `60_000`): timeout for the build subprocess. Distinct "Build timed out…" diagnostic fires when exceeded.
|
|
257
|
+
- `logPrefix` (optional, default `"bridgekit-bin"`): prefix on the "Failed to build…" diagnostic.
|
|
258
|
+
|
|
259
|
+
The MCP entry module must export `async function runServer(): Promise<void>`. Consumers with a different export name can alias on export.
|
|
260
|
+
|
|
261
|
+
**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.
|
|
262
|
+
|
|
263
|
+
Behavior on missing entry:
|
|
264
|
+
|
|
265
|
+
- Build emits the entry → import and call `runServer()`.
|
|
266
|
+
- Build exits non-zero but the entry exists → recover (import and call `runServer()`).
|
|
267
|
+
- Build exits 0 but the entry is still missing → exit with code 1, generic "Failed to build…" diagnostic.
|
|
268
|
+
- Build exits non-zero with entry missing → exit with the build's status code, generic diagnostic.
|
|
269
|
+
- Build killed by timeout (SIGTERM) → exit 1, distinct timeout diagnostic naming `buildTimeoutMs`.
|
|
270
|
+
|
|
236
271
|
## Best practices
|
|
237
272
|
|
|
238
273
|
Tool definition best practices:
|
|
@@ -258,7 +293,7 @@ Package and release checklist:
|
|
|
258
293
|
- Avoid `workspace:` or `file:` dependency ranges in publishable packages.
|
|
259
294
|
- Avoid dangling `sourceMappingURL` comments: publish maps and useful sources together, or disable source maps for package builds.
|
|
260
295
|
- 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`.
|
|
261
|
-
- If an npm-launched bin depends on generated output,
|
|
296
|
+
- 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.
|
|
262
297
|
- 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.
|
|
263
298
|
- Declare a compatible Node engine (`>=22.19.0`) in downstream packages that expose BridgeKit-powered MCP bins.
|
|
264
299
|
- Run `npm run check`, `npm run test`, `npm run pack:dry-run`, and `npm run package-smoke` before publishing.
|
|
@@ -272,5 +307,5 @@ Read these files in order:
|
|
|
272
307
|
|
|
273
308
|
1. `README.md` — public API, contracts, and best practices.
|
|
274
309
|
2. `llms.txt` — compact agent-facing usage rules and anti-patterns.
|
|
275
|
-
3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers,
|
|
276
|
-
4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/
|
|
310
|
+
3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers, per-host metadata via `hostExtras`, and bin wrappers via `runBinWrapper`.
|
|
311
|
+
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.
|
package/llms.txt
CHANGED
|
@@ -7,7 +7,7 @@ Use this package when you need to define a tool once and expose it through both
|
|
|
7
7
|
1. `README.md` — public API, contracts, best practices, packaging notes.
|
|
8
8
|
2. `llms.txt` — compact agent-facing usage rules and anti-patterns.
|
|
9
9
|
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`.
|
|
10
|
-
4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/
|
|
10
|
+
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.
|
|
11
11
|
|
|
12
12
|
## Import map
|
|
13
13
|
|
|
@@ -104,12 +104,24 @@ Some hosts, such as pi in source-extension packages, may intentionally load Type
|
|
|
104
104
|
|
|
105
105
|
- Keep the host source entrypoint if that is the package convention, e.g. `pi.extensions: ["./extensions/index.ts"]`.
|
|
106
106
|
- Add a package-local MCP build and point npm `bin` at a checked-in wrapper under `bin/`, not directly at generated `dist/` output.
|
|
107
|
-
-
|
|
107
|
+
- **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`:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
#!/usr/bin/env node
|
|
111
|
+
import { runBinWrapper } from "@feniix/bridgekit/bin-wrapper";
|
|
112
|
+
await runBinWrapper({
|
|
113
|
+
metaUrl: import.meta.url,
|
|
114
|
+
mcpEntry: "dist/extensions/mcp-server.js",
|
|
115
|
+
buildScript: "build:mcp",
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`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>`.
|
|
108
120
|
- Narrow the MCP build to the MCP entrypoint and shared host-neutral modules; avoid compiling pi adapter entrypoints into the standalone MCP path.
|
|
109
121
|
- Put runtime imports used by the compiled MCP bin in `dependencies`, not only peers or dev dependencies.
|
|
110
122
|
- Declare BridgeKit's Node engine requirement in the downstream package (`>=22.19.0`).
|
|
111
|
-
- Ensure the
|
|
112
|
-
-
|
|
123
|
+
- Ensure the bin script is executable (`chmod +x` or equivalent) and verify the mode with `npm pack --dry-run --json`.
|
|
124
|
+
- 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.
|
|
113
125
|
|
|
114
126
|
## Anti-patterns
|
|
115
127
|
|