@savvy-web/mcp 0.1.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.
Files changed (34) hide show
  1. package/547.js +417 -0
  2. package/bin/savvy-mcp.js +153 -0
  3. package/index.d.ts +127 -0
  4. package/index.js +3 -0
  5. package/package.json +80 -0
  6. package/resources/content/_templates/guides.md +12 -0
  7. package/resources/content/_templates/packages.md +21 -0
  8. package/resources/content/_templates/standards.md +17 -0
  9. package/resources/content/guides/api-docs-from-api-extractor.md +160 -0
  10. package/resources/content/guides/building-a-github-action.md +233 -0
  11. package/resources/content/guides/choosing-a-builder.md +140 -0
  12. package/resources/content/guides/llm-friendly-json-schemas.md +64 -0
  13. package/resources/content/manifest.json +490 -0
  14. package/resources/content/packages/cli/command-tree.md +70 -0
  15. package/resources/content/packages/cli/init-and-check.md +51 -0
  16. package/resources/content/packages/mcp/resource-taxonomy.md +63 -0
  17. package/resources/content/packages/rslib-builder/overview.md +68 -0
  18. package/resources/content/packages/silk/export-map.md +67 -0
  19. package/resources/content/packages/silk/install-and-setup.md +59 -0
  20. package/resources/content/packages/silk-effects/index.md +76 -0
  21. package/resources/content/packages/silk-effects/managed-section.md +84 -0
  22. package/resources/content/packages/silk-effects/platform-layers.md +94 -0
  23. package/resources/content/standards/api-model-pipeline.md +63 -0
  24. package/resources/content/standards/catalog-usage.md +48 -0
  25. package/resources/content/standards/changeset-discipline.md +52 -0
  26. package/resources/content/standards/changeset-format.md +131 -0
  27. package/resources/content/standards/commit-contract.md +58 -0
  28. package/resources/content/standards/dependency-conventions.md +82 -0
  29. package/resources/content/standards/linting-conventions.md +47 -0
  30. package/resources/content/standards/publishability.md +57 -0
  31. package/resources/content/standards/semver.md +51 -0
  32. package/resources/content/standards/test-classification.md +49 -0
  33. package/resources/content/tags.json +27 -0
  34. package/tsdoc-metadata.json +11 -0
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ var src_CURRENT_MCP_VERSION = "0.0.0";
2
+ export { SilkRuntimeLive, startMcpServer } from "./547.js";
3
+ export { src_CURRENT_MCP_VERSION as CURRENT_MCP_VERSION };
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@savvy-web/mcp",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "The savvy MCP server — Silk Suite tooling and library knowledge for coding agents",
6
+ "homepage": "https://github.com/savvy-web/systems/tree/main/packages/mcp",
7
+ "bugs": {
8
+ "url": "https://github.com/savvy-web/systems/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/savvy-web/systems.git",
13
+ "directory": "packages/mcp"
14
+ },
15
+ "license": "MIT",
16
+ "author": {
17
+ "name": "C. Spencer Beggs",
18
+ "email": "spencer@savvyweb.systems",
19
+ "url": "https://savvyweb.systems"
20
+ },
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./index.d.ts",
25
+ "import": "./index.js"
26
+ }
27
+ },
28
+ "bin": {
29
+ "savvy-mcp": "bin/savvy-mcp.js"
30
+ },
31
+ "dependencies": {
32
+ "@effect/platform": "^0.96.1",
33
+ "@effect/platform-node": "^0.106.0",
34
+ "@modelcontextprotocol/sdk": "^1.29.0",
35
+ "@savvy-web/silk-effects": "0.6.0",
36
+ "effect": "^3.21.2",
37
+ "fuse.js": "^7.4.0",
38
+ "workspaces-effect": "^1.1.0",
39
+ "zod": "^4.4.3"
40
+ },
41
+ "files": [
42
+ "!mcp.api.json",
43
+ "!tsconfig.json",
44
+ "!tsdoc.json",
45
+ "547.js",
46
+ "bin/savvy-mcp.js",
47
+ "index.d.ts",
48
+ "index.js",
49
+ "package.json",
50
+ "resources/content/_templates/guides.md",
51
+ "resources/content/_templates/packages.md",
52
+ "resources/content/_templates/standards.md",
53
+ "resources/content/guides/api-docs-from-api-extractor.md",
54
+ "resources/content/guides/building-a-github-action.md",
55
+ "resources/content/guides/choosing-a-builder.md",
56
+ "resources/content/guides/llm-friendly-json-schemas.md",
57
+ "resources/content/manifest.json",
58
+ "resources/content/packages/cli/command-tree.md",
59
+ "resources/content/packages/cli/init-and-check.md",
60
+ "resources/content/packages/mcp/resource-taxonomy.md",
61
+ "resources/content/packages/rslib-builder/overview.md",
62
+ "resources/content/packages/silk-effects/index.md",
63
+ "resources/content/packages/silk-effects/managed-section.md",
64
+ "resources/content/packages/silk-effects/platform-layers.md",
65
+ "resources/content/packages/silk/export-map.md",
66
+ "resources/content/packages/silk/install-and-setup.md",
67
+ "resources/content/standards/api-model-pipeline.md",
68
+ "resources/content/standards/catalog-usage.md",
69
+ "resources/content/standards/changeset-discipline.md",
70
+ "resources/content/standards/changeset-format.md",
71
+ "resources/content/standards/commit-contract.md",
72
+ "resources/content/standards/dependency-conventions.md",
73
+ "resources/content/standards/linting-conventions.md",
74
+ "resources/content/standards/publishability.md",
75
+ "resources/content/standards/semver.md",
76
+ "resources/content/standards/test-classification.md",
77
+ "resources/content/tags.json",
78
+ "tsdoc-metadata.json"
79
+ ]
80
+ }
@@ -0,0 +1,12 @@
1
+ # Guide title
2
+
3
+ A short intro framing the problem and when to read this guide.
4
+
5
+ ## A section
6
+
7
+ Free-form prose, lists, and code as the topic demands. Keep each guide a single
8
+ focused page; split when it outgrows the body budget.
9
+
10
+ ## Another section
11
+
12
+ Close with concrete recommendations or a checklist where it helps.
@@ -0,0 +1,21 @@
1
+ # Package topic title
2
+
3
+ ## What
4
+
5
+ One paragraph: what this package or service is and the problem it solves.
6
+
7
+ ## API
8
+
9
+ The key shapes, signatures, and statics a consumer touches. Condensed, not a full port.
10
+
11
+ ## Layer
12
+
13
+ The Effect layer(s) and their platform requirements, or the install/build wiring.
14
+
15
+ ## Usage
16
+
17
+ A short, runnable example of the common path.
18
+
19
+ ## Related
20
+
21
+ Cross-link sibling digests and the standards they implement.
@@ -0,0 +1,17 @@
1
+ # Standard title
2
+
3
+ ## Rule
4
+
5
+ State the durable rule in one or two sentences. This is the thing that must hold.
6
+
7
+ ## Why
8
+
9
+ Explain the reasoning the rule encodes, so a reader can apply judgment at the edges.
10
+
11
+ ## Examples
12
+
13
+ Show a conforming case and a non-conforming case.
14
+
15
+ ## See also
16
+
17
+ Cross-link related standards and package digests by `silk://` URI.
@@ -0,0 +1,160 @@
1
+ ---
2
+ id: guides/api-docs-from-api-extractor
3
+ title: Generating API docs from API Extractor
4
+ summary: Configure apiModel, build the model, and render LLM-lean markdown with api-extractor-llms.
5
+ tier: guides
6
+ source: hand
7
+ tags: [api, build]
8
+ priority: 0.5
9
+ related: [standards/api-model-pipeline, packages/rslib-builder/overview]
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ The Silk Suite generates API-reference docs from Microsoft API Extractor models
15
+ rather than hand-authoring them. The pipeline has three stages: emit a model,
16
+ render it to markdown, and compile rendered docs into the MCP resource corpus.
17
+ This guide walks through each stage as implemented in this repo.
18
+
19
+ For the policy contract (what is generated, what must not be edited, where docs
20
+ land), see `silk://standards/api-model-pipeline`.
21
+
22
+ ## Step 1 — Enable the API model in `rslib.config.ts`
23
+
24
+ A library package opts in by passing an `apiModel` option to `NodeLibraryBuilder.create()`:
25
+
26
+ ```typescript
27
+ import { NodeLibraryBuilder } from "@savvy-web/rslib-builder";
28
+
29
+ export default NodeLibraryBuilder.create({
30
+ apiModel: {
31
+ tsdoc: {
32
+ tagDefinitions: [{ tagName: "@since", syntaxKind: "block" }],
33
+ },
34
+ },
35
+ });
36
+ ```
37
+
38
+ Passing any truthy value for `apiModel` enables model emission. Options under
39
+ `apiModel` are forwarded to the API Extractor TSDoc runner. A plain `apiModel: true`
40
+ works when no custom tag definitions are needed.
41
+
42
+ The entry point and package name are derived from the package's `exports` field.
43
+ Only public API surfaces are captured; members annotated `@internal` are excluded.
44
+
45
+ See `silk://packages/rslib-builder/overview` for full builder configuration.
46
+
47
+ ## Step 2 — Build the model
48
+
49
+ ```bash
50
+ pnpm --filter @savvy-web/your-package run build:prod
51
+ ```
52
+
53
+ The production build writes `dist/npm/<unscoped-name>.api.json`. For example,
54
+ `@savvy-web/silk-effects` emits `dist/npm/silk-effects.api.json`. The filename
55
+ is the unscoped package name with an `.api.json` suffix.
56
+
57
+ `dist/dev/` may also contain a model depending on the build configuration.
58
+ The generator script probes `dist/dev/` first, then `dist/npm/`.
59
+
60
+ ## Step 3 — Render with `api-extractor-llms`
61
+
62
+ The rendering library takes a model path, two injectable callbacks, and returns
63
+ one `RenderedDoc` per top-level public member.
64
+
65
+ ### Core API
66
+
67
+ ```typescript
68
+ import { loadApiModel, renderPackage } from "api-extractor-llms";
69
+ import type { FrontmatterRenderer, RouteFormatter } from "api-extractor-llms";
70
+
71
+ const pkg = await loadApiModel("/path/to/silk-effects.api.json");
72
+
73
+ const routeFor: RouteFormatter = (ref) =>
74
+ `silk://packages/silk-effects/api/${ref.kind}/${ref.slug}`;
75
+
76
+ const frontmatter: FrontmatterRenderer = (meta) =>
77
+ `---\nid: packages/silk-effects/api/${meta.kind}/${meta.slug}\ntitle: "${meta.name}"\n---\n\n`;
78
+
79
+ const docs = renderPackage(pkg, { packageName: "@savvy-web/silk-effects", routeFor, frontmatter });
80
+
81
+ for (const doc of docs) {
82
+ // doc.markdown = frontmatter block + rendered body
83
+ // doc.kind, doc.name, doc.slug identify the item
84
+ }
85
+ ```
86
+
87
+ ### What `renderPackage` produces
88
+
89
+ For each top-level public member, the shared body renderer emits:
90
+
91
+ - An ATX `# Name` heading
92
+ - The TypeScript signature in a fenced `ts` code block (via `TypeSignatureFormatter`)
93
+ - TSDoc summary paragraph
94
+ - `## Parameters` list with types and descriptions (if any)
95
+ - `## Returns` section (if documented)
96
+ - `## Members` section listing class/interface/namespace members with signatures and summaries
97
+ - `## Examples` blocks with language-tagged fences (from `@example` TSDoc tags)
98
+ - Cross-links in prose resolved through the injected `routeFor` (via `CrossLinker`)
99
+
100
+ The two injectable callbacks — `routeFor` (URL scheme) and `frontmatter` (YAML
101
+ block) — are the only consumer-specific pieces. The body rendering is shared
102
+ across all consumers.
103
+
104
+ ## Step 4 — The MCP generator script
105
+
106
+ `packages/mcp/scripts/generate-api-docs.ts` is the reference implementation of
107
+ steps 3 and 4 for the MCP resource corpus. It iterates `API_TARGETS` (defined in
108
+ `packages/mcp/scripts/api-targets.ts`), loads each model, injects silk-specific
109
+ frontmatter and `silk://` crosslink routes, and writes output under
110
+ `content/packages/<dir>/api/<kind>/<slug>.md` (gitignored).
111
+
112
+ ```typescript
113
+ // The silk crosslink scheme
114
+ const routeFor = (target: ApiTarget) => (ref: ApiItemRef) =>
115
+ `silk://${target.idPrefix}/api/${ref.kind}/${ref.slug}`;
116
+
117
+ // The silk frontmatter renderer (derives id, title, summary, tags)
118
+ const frontmatter = (meta: DocMeta) => toYaml(frontMatterFor(target, meta));
119
+
120
+ const docs = renderPackage(pkg, {
121
+ packageName: target.packageName,
122
+ routeFor: routeFor(target),
123
+ frontmatter,
124
+ });
125
+ ```
126
+
127
+ Current targets (from `api-targets.ts`): `silk-effects`, `templates`,
128
+ `github-action-effects`, `github-action-builder`. The MCP package itself and `cli`/`silk`
129
+ are excluded (a generate→mcp build dependency would create a Turborepo cycle; cli
130
+ and silk are not library APIs).
131
+
132
+ ## Step 5 — Compile into the corpus
133
+
134
+ After `generate-api-docs.ts` writes the markdown files, `build:catalog` picks them
135
+ up along with hand-authored docs and compiles the unified manifest. Generated docs
136
+ appear in `silk://catalog` marked `(generated)`.
137
+
138
+ In Turborepo the pipeline is:
139
+
140
+ ```text
141
+ build:prod (each library) → generate-api-docs → build:catalog
142
+ ```
143
+
144
+ ## Authoring notes
145
+
146
+ - TSDoc coverage determines output quality. Undocumented public members produce
147
+ sparse rendered docs with no summary or parameter descriptions.
148
+ - The slug is the lowercased display name. A class `MyService` maps to
149
+ `silk://packages/foo/api/class/myservice`.
150
+ - Cross-links in prose (`{@link OtherClass}`) resolve only if `OtherClass` is in
151
+ the same package's rendered set.
152
+ - Do not edit generated files under `content/packages/*/api/` — changes are
153
+ overwritten on the next `generate-api-docs` run.
154
+
155
+ ## See also
156
+
157
+ - `silk://standards/api-model-pipeline` — policy: what is generated, provenance
158
+ markers, coverage scope
159
+ - `silk://packages/rslib-builder/overview` — configuring the builder that emits
160
+ the model
@@ -0,0 +1,233 @@
1
+ ---
2
+ id: guides/building-a-github-action
3
+ title: Building a GitHub Action
4
+ summary: Scaffold a Node.js 24 GitHub Action with @savvy-web/github-action-builder and the github-action-effects services.
5
+ tier: guides
6
+ source: hand
7
+ tags: [github-actions, build]
8
+ priority: 0.5
9
+ related: [guides/choosing-a-builder, standards/api-model-pipeline]
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ Two packages work together to build and power Node.js 24 GitHub Actions in the
15
+ Silk Suite:
16
+
17
+ - **`@savvy-web/github-action-builder`** — zero-config rsbuild-based build tool
18
+ that bundles TypeScript source into self-contained ESM files and validates
19
+ `action.yml`
20
+ - **`@savvy-web/github-action-effects`** — Effect service library replacing all
21
+ `@actions/*` packages with native ESM implementations
22
+
23
+ Neither package depends on the other at build time. The builder bundles whatever
24
+ action code you write; the effects library provides the services that code uses.
25
+
26
+ For choosing the right builder, see `silk://guides/choosing-a-builder`. The
27
+ github-action-builder is separate from rslib-builder and bun-builder — it targets
28
+ a different output shape (single-file committed ESM bundles, not npm-published
29
+ libraries).
30
+
31
+ ## Step 1 — Project structure
32
+
33
+ ```text
34
+ my-action/
35
+ ├── src/
36
+ │ ├── main.ts # Required — main action logic
37
+ │ ├── pre.ts # Optional — pre-action hook
38
+ │ └── post.ts # Optional — post-action hook
39
+ ├── action.yml # GitHub metadata; must have runs.using: "node24"
40
+ └── package.json
41
+ ```
42
+
43
+ The builder auto-detects `src/pre.ts` and `src/post.ts` if they exist. Only
44
+ `src/main.ts` is required.
45
+
46
+ `action.yml` must declare `runs.using: "node24"`. The builder validates this and
47
+ fails if any other value is present.
48
+
49
+ ## Step 2 — Install and configure the builder
50
+
51
+ ```bash
52
+ pnpm add -D @savvy-web/github-action-builder
53
+ ```
54
+
55
+ Zero-config usage — no config file needed:
56
+
57
+ ```bash
58
+ github-action-builder build
59
+ ```
60
+
61
+ Or create an optional `action.config.ts` for customization:
62
+
63
+ ```typescript
64
+ import { defineConfig } from "@savvy-web/github-action-builder";
65
+
66
+ export default defineConfig({
67
+ build: {
68
+ minify: true, // default: true
69
+ sourceMap: false, // default: false
70
+ externals: [], // exclude from bundle (must be available at runtime)
71
+ ignore: [], // replace with a throwing stub
72
+ },
73
+ validation: {
74
+ requireActionYml: true,
75
+ strict: undefined, // auto-detects CI; warn locally, error in CI
76
+ },
77
+ persistLocal: {
78
+ enabled: true, // auto-copy to .github/actions/local/ after build
79
+ path: ".github/actions/local",
80
+ },
81
+ });
82
+ ```
83
+
84
+ ### Build output
85
+
86
+ Each detected entry emits one flat ESM file:
87
+
88
+ | Input | Output |
89
+ | --- | --- |
90
+ | `src/main.ts` | `dist/main.js` |
91
+ | `src/pre.ts` | `dist/pre.js` |
92
+ | `src/post.ts` | `dist/post.js` |
93
+ | (generated) | `dist/package.json` |
94
+
95
+ All output files are self-contained ESM bundles. Dynamic `import()` calls are
96
+ folded back into the parent file (`asyncChunks: false`), so `action.yml` can
97
+ always reference a known single-file path.
98
+
99
+ The builder also copies output to `.github/actions/local/` for local testing with
100
+ [nektos/act](https://github.com/nektos/act) unless `persistLocal.enabled: false`.
101
+
102
+ ## Step 3 — Write action logic with `github-action-effects`
103
+
104
+ ```bash
105
+ pnpm add @savvy-web/github-action-effects
106
+ ```
107
+
108
+ The library provides 37 Effect service interfaces across six domains:
109
+
110
+ | Domain | Services cover |
111
+ | --- | --- |
112
+ | Core action I/O | Outputs, state, logging, environment, cache |
113
+ | Git operations | Branches, commits, tags via Git Data API |
114
+ | GitHub API | REST client, GraphQL, releases, issues, PR lifecycle, check runs, rate limiting |
115
+ | Build tooling | Command execution, npm registry, workspace detection, changeset analysis |
116
+ | Attestation | SLSA statement construction, Sigstore signing, CycloneDX SBOM generation |
117
+ | Runtime layer | GitHub Actions workflow command protocol, `ActionsConfigProvider`, `ActionsLogger`, `Step` |
118
+
119
+ ### Runtime layer
120
+
121
+ The runtime layer replaces all `@actions/*` packages with native ESM implementations:
122
+
123
+ ```typescript
124
+ import { Effect, Config } from "effect";
125
+ import { ActionsRuntime, Action, Step } from "@savvy-web/github-action-effects";
126
+
127
+ const program = Effect.gen(function* () {
128
+ // Inputs via Effect's Config API (reads INPUT_* env vars)
129
+ const name = yield* Config.string("name");
130
+ const count = yield* Config.integer("count");
131
+
132
+ // Logging maps to workflow commands
133
+ yield* Effect.log("Processing..."); // plain stdout
134
+ yield* Effect.logDebug("detail"); // ::debug::detail
135
+ yield* Effect.logWarning("heads up"); // ::warning::heads up
136
+
137
+ // Step buffering: one success line on pass, spills debug buffer on fail
138
+ yield* Step.withStep("fetch data", fetchData(name));
139
+ });
140
+
141
+ // Provide the runtime layer
142
+ Action.run(program);
143
+ // or: program.pipe(Effect.provide(ActionsRuntime.Default))
144
+ ```
145
+
146
+ ### Reading inputs
147
+
148
+ Action inputs are read via Effect's `Config` API backed by `ActionsConfigProvider`,
149
+ which translates config keys to `INPUT_*` environment variables:
150
+
151
+ ```typescript
152
+ const repoName = yield* Config.string("repo-name"); // reads INPUT_REPO-NAME
153
+ ```
154
+
155
+ ### Composing services
156
+
157
+ Services are provided via Effect Layers. The programmatic pattern:
158
+
159
+ ```typescript
160
+ import { Effect } from "effect";
161
+ import {
162
+ ActionsRuntime,
163
+ GitHubClient,
164
+ GitHubClientLive,
165
+ } from "@savvy-web/github-action-effects";
166
+
167
+ const program = Effect.gen(function* () {
168
+ const client = yield* GitHubClient;
169
+ // use client ...
170
+ });
171
+
172
+ program.pipe(
173
+ Effect.provide(GitHubClientLive),
174
+ Effect.provide(ActionsRuntime.Default),
175
+ Effect.runPromise,
176
+ );
177
+ ```
178
+
179
+ ### Testing
180
+
181
+ The library exports a `./testing` subpath that excludes `GitHubClientLive` and
182
+ `OctokitAuthAppLive` (which import `@octokit/rest`/`@octokit/auth-app`). Use this
183
+ in test files to avoid pulling in those dependencies:
184
+
185
+ ```typescript
186
+ import { ... } from "@savvy-web/github-action-effects/testing";
187
+ ```
188
+
189
+ ## Step 4 — Validate and CI
190
+
191
+ ```bash
192
+ # Validate action.yml and entry structure without building
193
+ github-action-builder validate
194
+
195
+ # Full build with validation
196
+ github-action-builder build
197
+ ```
198
+
199
+ In CI (`CI=true` or `GITHUB_ACTIONS=true`), validation warnings become errors and
200
+ fail the build. Locally they are displayed as warnings and the build continues.
201
+
202
+ Add to `package.json`:
203
+
204
+ ```json
205
+ {
206
+ "scripts": {
207
+ "build": "github-action-builder build",
208
+ "validate": "github-action-builder validate"
209
+ }
210
+ }
211
+ ```
212
+
213
+ ## Step 5 — Reference the built output in `action.yml`
214
+
215
+ ```yaml
216
+ name: My Action
217
+ description: Does something useful
218
+ runs:
219
+ using: node24
220
+ main: dist/main.js
221
+ post: dist/post.js # if you have a post step
222
+ ```
223
+
224
+ The `dist/` directory must be committed to the repository so GitHub runners can
225
+ execute it. The builder's `persistLocal` feature also syncs to
226
+ `.github/actions/local/` for local `act` runs.
227
+
228
+ ## See also
229
+
230
+ - `silk://guides/choosing-a-builder` — when to use github-action-builder vs the
231
+ library builders
232
+ - `silk://standards/api-model-pipeline` — if your action repo also publishes a
233
+ library whose API is documented
@@ -0,0 +1,140 @@
1
+ ---
2
+ id: guides/choosing-a-builder
3
+ title: Choosing a builder (rslib vs bun)
4
+ summary: When to reach for @savvy-web/rslib-builder vs @savvy-web/bun-builder for a Silk package.
5
+ tier: guides
6
+ source: hand
7
+ tags: [build]
8
+ priority: 0.5
9
+ related: [packages/rslib-builder/overview]
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ The Silk Suite has two zero-config build tools for TypeScript libraries:
15
+
16
+ | Package | Bundler core | Primary target |
17
+ | --- | --- | --- |
18
+ | `@savvy-web/rslib-builder` | rsbuild / rspack | Node.js (pnpm monorepos) |
19
+ | `@savvy-web/bun-builder` | Bun.build() | Bun monorepos |
20
+
21
+ Both tools auto-detect entry points from `package.json` `exports`, emit `dist/dev/`
22
+ and `dist/npm/` build modes, generate rolled-up `.d.ts` declarations via API
23
+ Extractor, resolve `catalog:` and `workspace:` protocol references for publishing,
24
+ and transform the output `package.json` for publish readiness.
25
+
26
+ ## `@savvy-web/rslib-builder`
27
+
28
+ The **ecosystem default** for packages inside the `savvy-web/systems` monorepo and
29
+ any pnpm-managed Silk Suite package.
30
+
31
+ ### What it does
32
+
33
+ - Zero-config builds via `NodeLibraryBuilder.create({})` in `rslib.config.ts`
34
+ - Reads `exports` to discover entry points; builds `dist/dev/` and `dist/npm/`
35
+ - Generates type declarations and emits a Microsoft API Extractor model
36
+ (`<unscoped>.api.json`) on the npm build
37
+ - Transforms the output `package.json`: resolves `pnpm catalog:` references,
38
+ flips `private: true` to publish-ready based on `publishConfig.access`, rewrites
39
+ export paths from `.ts` to `.js`, adds type conditions
40
+ - Supports dual-format ESM+CJS builds when needed (e.g. `@savvy-web/silk` for CJS
41
+ consumers)
42
+ - Peer dependencies: `@rslib/core`, `@typescript/native-preview`
43
+
44
+ ### Configuration
45
+
46
+ ```typescript
47
+ import { NodeLibraryBuilder } from "@savvy-web/rslib-builder";
48
+
49
+ export default NodeLibraryBuilder.create({
50
+ externals: ["effect", "@effect/platform"],
51
+ apiModel: {
52
+ tsdoc: {
53
+ tagDefinitions: [{ tagName: "@since", syntaxKind: "block" }],
54
+ },
55
+ },
56
+ });
57
+ ```
58
+
59
+ Pass `apiModel: true` (or an options object) to enable API Extractor model
60
+ emission. See `silk://packages/rslib-builder/overview` for full details.
61
+
62
+ ### When to use it
63
+
64
+ - You are building a package inside `savvy-web/systems` (or a pnpm-based Silk repo)
65
+ - You need dual-format ESM+CJS output
66
+ - You want API Extractor model emission for MCP doc generation
67
+ - The package uses `pnpm catalog:` or `workspace:` protocol in its dependencies
68
+
69
+ ## `@savvy-web/bun-builder`
70
+
71
+ For **Bun-managed monorepos** where Bun.build() is the preferred bundler.
72
+
73
+ ### What it does
74
+
75
+ - Zero-config builds via `BunLibraryBuilder.create({})` in `bun.config.ts`
76
+ - Auto-detects entry points from `package.json` `exports`
77
+ - Bundled or bundleless output (`bundle: false` preserves source structure)
78
+ - Rolled-up `.d.ts` in bundled mode; raw `.d.ts` in bundleless mode
79
+ - API Extractor model generation on npm builds (enabled by default)
80
+ - TSDoc warnings reported with source locations; severity configurable per
81
+ environment (`"fail"` in CI, `"log"` locally)
82
+ - Resolves Bun `catalog:` and `workspace:` protocol references for publishing
83
+ - Peer dependencies: `@microsoft/api-extractor`, `@typescript/native-preview`,
84
+ `typescript`, `@types/bun`
85
+
86
+ ### Configuration
87
+
88
+ ```typescript
89
+ import { BunLibraryBuilder } from "@savvy-web/bun-builder";
90
+
91
+ export default BunLibraryBuilder.create({
92
+ bundle: true, // default; set false for bundleless
93
+ apiModel: true, // default; emits model on npm build
94
+ });
95
+ ```
96
+
97
+ Build via:
98
+
99
+ ```bash
100
+ bun run bun.config.ts # all modes
101
+ bun run bun.config.ts --env-mode dev
102
+ bun run bun.config.ts --env-mode npm
103
+ ```
104
+
105
+ ### When to use it
106
+
107
+ - You are in a Bun-managed workspace (`bun.lock`, Bun catalog protocol)
108
+ - You want sub-second build iteration times
109
+ - You do not need rspack's CJS-to-ESM interop (which is important for certain
110
+ bundled GitHub Actions scenarios)
111
+
112
+ ## Decision guide
113
+
114
+ ```text
115
+ Is this a package in savvy-web/systems (pnpm monorepo)?
116
+ Yes → rslib-builder
117
+
118
+ Does the package need dual-format ESM+CJS output?
119
+ Yes → rslib-builder
120
+
121
+ Is this a Bun-managed workspace?
122
+ Yes → bun-builder
123
+
124
+ Are you building a GitHub Action (bundled Node.js 24 binary)?
125
+ Use @savvy-web/github-action-builder instead — see silk://guides/building-a-github-action
126
+ ```
127
+
128
+ ## Common pitfalls
129
+
130
+ **rslib-builder:** Relative imports inside source must use `.js` extensions
131
+ (ESM requirement). The build will report "cannot find module" on missing extensions.
132
+
133
+ **bun-builder:** The Bun catalog protocol uses `workspaces.catalog` in the root
134
+ `package.json`, distinct from pnpm's catalog. Do not mix the two in the same
135
+ workspace.
136
+
137
+ ## See also
138
+
139
+ - `silk://packages/rslib-builder/overview` — full rslib-builder reference
140
+ - `silk://guides/building-a-github-action` — GitHub Actions use a separate builder