@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.
- package/547.js +417 -0
- package/bin/savvy-mcp.js +153 -0
- package/index.d.ts +127 -0
- package/index.js +3 -0
- package/package.json +80 -0
- package/resources/content/_templates/guides.md +12 -0
- package/resources/content/_templates/packages.md +21 -0
- package/resources/content/_templates/standards.md +17 -0
- package/resources/content/guides/api-docs-from-api-extractor.md +160 -0
- package/resources/content/guides/building-a-github-action.md +233 -0
- package/resources/content/guides/choosing-a-builder.md +140 -0
- package/resources/content/guides/llm-friendly-json-schemas.md +64 -0
- package/resources/content/manifest.json +490 -0
- package/resources/content/packages/cli/command-tree.md +70 -0
- package/resources/content/packages/cli/init-and-check.md +51 -0
- package/resources/content/packages/mcp/resource-taxonomy.md +63 -0
- package/resources/content/packages/rslib-builder/overview.md +68 -0
- package/resources/content/packages/silk/export-map.md +67 -0
- package/resources/content/packages/silk/install-and-setup.md +59 -0
- package/resources/content/packages/silk-effects/index.md +76 -0
- package/resources/content/packages/silk-effects/managed-section.md +84 -0
- package/resources/content/packages/silk-effects/platform-layers.md +94 -0
- package/resources/content/standards/api-model-pipeline.md +63 -0
- package/resources/content/standards/catalog-usage.md +48 -0
- package/resources/content/standards/changeset-discipline.md +52 -0
- package/resources/content/standards/changeset-format.md +131 -0
- package/resources/content/standards/commit-contract.md +58 -0
- package/resources/content/standards/dependency-conventions.md +82 -0
- package/resources/content/standards/linting-conventions.md +47 -0
- package/resources/content/standards/publishability.md +57 -0
- package/resources/content/standards/semver.md +51 -0
- package/resources/content/standards/test-classification.md +49 -0
- package/resources/content/tags.json +27 -0
- package/tsdoc-metadata.json +11 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/mcp/resource-taxonomy
|
|
3
|
+
title: The silk:// resource taxonomy
|
|
4
|
+
summary: Load to understand how silk:// docs are addressed, tiered, and discovered.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [mcp]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk-effects/]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`@savvy-web/mcp` serves a curated documentation corpus over the `silk://` URI
|
|
15
|
+
scheme. The load-bearing principle is **information lives in the MCP, direction
|
|
16
|
+
lives in the plugins**: the server carries every resource regardless of project,
|
|
17
|
+
and each plugin points an agent at the subset it needs. Docs are markdown files
|
|
18
|
+
with YAML front-matter under three tiers — `standards`, `packages`, `guides`.
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
Every doc has a stable `id` — the URI suffix, tier-prefixed and slash-separated.
|
|
23
|
+
`silk://<id>` is the address skills hard-code, `related[]` entries point at, and
|
|
24
|
+
the catalog and search return. **The `id` is the contract; the URI derives from
|
|
25
|
+
`id`, not the file path** — a `git mv` or filename tidy never silently breaks an
|
|
26
|
+
inbound link. A directory-index doc uses a trailing-slash id (e.g.
|
|
27
|
+
`packages/silk-effects/`) so its URI resolves to `index.md`.
|
|
28
|
+
|
|
29
|
+
Front-matter carries `id`, `title`, `summary` (the "is this the doc I need" hook),
|
|
30
|
+
`tier`, `source` (`hand` | `generated`), `status`, `tags` (a controlled
|
|
31
|
+
vocabulary), `priority`, and `related`. The compile step
|
|
32
|
+
(`scripts/build-catalog.ts`) fails the build on any integrity violation: `id`
|
|
33
|
+
uniqueness, the file living under the directory matching its `tier`, every
|
|
34
|
+
`related[]` resolving to a known id, every tag resolving against `tags.json`, the
|
|
35
|
+
per-tier body budget, and a dead-name gate against the pre-rename identifiers.
|
|
36
|
+
|
|
37
|
+
## Layer
|
|
38
|
+
|
|
39
|
+
The tier rule: a doc's `tier` MUST equal its top-level content directory, and its
|
|
40
|
+
`id` MUST start with `<tier>/`. `priority` follows a tier-based rubric —
|
|
41
|
+
launch-core ≈ 0.8 (standards), fast-follow ≈ 0.5 (packages, guides), deep reference
|
|
42
|
+
≈ 0.3 — so it is real data and doubles as a search tie-break. Each tier ships a
|
|
43
|
+
one-screen structure template (standards: Rule / Why / Examples / See also;
|
|
44
|
+
package topic: What / API / Layer / Usage / Related).
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
Discovery surfaces, in priority order:
|
|
49
|
+
|
|
50
|
+
1. `silk://catalog` — token-cheap orientation, grouped by tier, each line a URI +
|
|
51
|
+
`summary` hint; an agent's first read.
|
|
52
|
+
2. The `silk_docs_search` tool — the primary path, plain-keyword input.
|
|
53
|
+
3. `resources/read` by explicit URI — how skills point precisely.
|
|
54
|
+
4. `resources/list` via one `ResourceTemplate` — fallback enumeration, excluding
|
|
55
|
+
`silk://catalog`.
|
|
56
|
+
|
|
57
|
+
The compiler emits `manifest.json`, the single source the catalog, search, and
|
|
58
|
+
`list()` all derive from, so there is no drift. Bodies stay in the markdown files;
|
|
59
|
+
the manifest indexes them.
|
|
60
|
+
|
|
61
|
+
## Related
|
|
62
|
+
|
|
63
|
+
The library these docs describe: `silk://packages/silk-effects/`.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/rslib-builder/overview
|
|
3
|
+
title: rslib-builder overview
|
|
4
|
+
summary: Load when setting up or understanding the rslib-builder build for a Silk package.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [build]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [standards/catalog-usage, standards/publishability]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`@savvy-web/rslib-builder` is a zero-config rsbuild-based build tool for Silk Suite
|
|
15
|
+
TypeScript packages. It reads a package's `exports` field to discover entry points,
|
|
16
|
+
builds dev and production outputs, generates type declarations, and transforms the
|
|
17
|
+
output `package.json` for publishing. A package opts in with a one-line
|
|
18
|
+
`rslib.config.ts`.
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { NodeLibraryBuilder } from "@savvy-web/rslib-builder";
|
|
24
|
+
|
|
25
|
+
export default NodeLibraryBuilder.create({
|
|
26
|
+
externals: ["@rslib/core"], // optional: do not bundle these
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Entry points come from `package.json` `exports` (e.g. `"."` → `./src/index.ts`,
|
|
31
|
+
`"./utils"` → `./src/utils/index.ts`). Peer dependencies are `@rslib/core` and
|
|
32
|
+
`@typescript/native-preview`.
|
|
33
|
+
|
|
34
|
+
## Layer
|
|
35
|
+
|
|
36
|
+
Build scripts:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "rslib build --env-mode dev",
|
|
42
|
+
"build:npm": "rslib build --env-mode npm"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The dev build writes `dist/dev/` with bundled JS, source maps, declarations, and a
|
|
48
|
+
transformed `package.json`. The npm build writes `dist/npm/` optimized for publish
|
|
49
|
+
(no source maps, bundled declarations, a publish-ready `package.json`).
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
The output `package.json` is transformed from source: export paths move from `.ts`
|
|
54
|
+
to `.js`, type conditions are added to exports, pnpm `catalog:` references resolve
|
|
55
|
+
to concrete versions, and the `files` array is generated. This is the mechanism
|
|
56
|
+
behind the convention that a source `package.json` is `private: true` while its
|
|
57
|
+
`publishConfig` declares publish intent — the builder flips `private` based on
|
|
58
|
+
`publishConfig.access` at build time.
|
|
59
|
+
|
|
60
|
+
First builds are slower due to cache warming; subsequent builds use `.rslib/cache/`.
|
|
61
|
+
A common pitfall: relative imports must use `.js` extensions (the ESM requirement),
|
|
62
|
+
or the build reports "cannot find module".
|
|
63
|
+
|
|
64
|
+
## Related
|
|
65
|
+
|
|
66
|
+
Dependency pinning the build resolves: `silk://standards/catalog-usage`. How
|
|
67
|
+
`private` and `publishConfig` decide what publishes:
|
|
68
|
+
`silk://standards/publishability`.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/silk/export-map
|
|
3
|
+
title: silk subpath export map
|
|
4
|
+
summary: Load when wiring a config file to a @savvy-web/silk subpath, or auditing the export map.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [silk]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk/install-and-setup]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`@savvy-web/silk` has no root barrel. It exposes a set of nested config-integration
|
|
15
|
+
entry points, each loaded by a different external tool. The nested subpaths mirror
|
|
16
|
+
exactly the module shapes those tools load, rather than implying a coherent library
|
|
17
|
+
API.
|
|
18
|
+
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
./changesets ← changeset class/services API surface
|
|
23
|
+
./changesets/changelog ← ChangelogFunctions default for .changeset/config.json
|
|
24
|
+
./changesets/markdownlint ← markdownlint-cli2 rules (default array + named)
|
|
25
|
+
./changesets/remark ← remark transform plugins + presets + lint rules
|
|
26
|
+
./commitlint ← CommitlintConfig (auto-detecting factory) + types
|
|
27
|
+
./commitlint/static ← static config default (no auto-detection)
|
|
28
|
+
./commitlint/prompt ← commitizen adapter
|
|
29
|
+
./commitlint/formatter ← custom error formatter
|
|
30
|
+
./lint ← handlers / Preset / createConfig / utils / section data
|
|
31
|
+
./biome ← static silk.jsonc asset (copied, not a shim)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The shim contract per subpath:
|
|
35
|
+
|
|
36
|
+
- `./changesets/changelog` — default export is the `@changesets/types`
|
|
37
|
+
`ChangelogFunctions` object the Changesets CLI loads from the config's
|
|
38
|
+
`changelog` field.
|
|
39
|
+
- `./changesets/markdownlint` — default export is the rule array markdownlint-cli2
|
|
40
|
+
loads, plus the named rule objects.
|
|
41
|
+
- `./changesets/remark` — named exports for every transform plugin, preset, and
|
|
42
|
+
lint rule remark configs import.
|
|
43
|
+
- `./commitlint/static` — default export is the static config object (no
|
|
44
|
+
auto-detection); the root `./commitlint` default-exports the auto-detecting
|
|
45
|
+
`CommitlintConfig` factory.
|
|
46
|
+
- `./lint` — the full lint-staged consumer surface (handlers, `Preset`,
|
|
47
|
+
`createConfig`, workspace utils, section/template data). CLI commands are
|
|
48
|
+
deliberately NOT re-exported here — those belong to the `savvy` CLI.
|
|
49
|
+
|
|
50
|
+
## Layer
|
|
51
|
+
|
|
52
|
+
The `exports` field in silk's `package.json` is the authoritative wiring; the shim
|
|
53
|
+
files under `src/` are the single source of truth for the exact reshaping. The
|
|
54
|
+
`./biome` entry is a copied asset, not a shim.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
A markdownlint config loading the Silk rules:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
extends: "@savvy-web/silk/biome" # biome.jsonc
|
|
62
|
+
@savvy-web/silk/changesets/markdownlint # markdownlint-cli2 customRules
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Related
|
|
66
|
+
|
|
67
|
+
Install and setup: `silk://packages/silk/install-and-setup`.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/silk/install-and-setup
|
|
3
|
+
title: Installing @savvy-web/silk
|
|
4
|
+
summary: Load when installing the Silk dev-tooling system into a consumer repo.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [silk, init]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk/export-map, packages/cli/init-and-check]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`@savvy-web/silk` is the single package a consumer installs to get the whole Silk
|
|
15
|
+
Suite dev-tooling system. It is an install surface, not a library: each subpath
|
|
16
|
+
export is a thin config-integration **shim** that re-exports `@savvy-web/silk-effects`
|
|
17
|
+
logic shaped into the exact module form an external tool's config loader expects.
|
|
18
|
+
The shims carry no logic. It is a `fixed` changeset group with `@savvy-web/cli`.
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
A shim is a drop-in replacement: a config file that imported a subpath of one of
|
|
23
|
+
the three old packages (`@savvy-web/changesets`, `@savvy-web/commitlint`,
|
|
24
|
+
`@savvy-web/lint-staged`) works unchanged after swapping the import to the matching
|
|
25
|
+
`@savvy-web/silk` subpath. Each shim reproduces the **module shape** the loader
|
|
26
|
+
consumes — default vs named, array vs object — not just the symbols. The full
|
|
27
|
+
subpath map is at `silk://packages/silk/export-map`.
|
|
28
|
+
|
|
29
|
+
## Layer
|
|
30
|
+
|
|
31
|
+
silk's only dependency is `@savvy-web/silk-effects` (`workspace:*`). Its
|
|
32
|
+
`peerDependencies` declare `@savvy-web/cli` (install-wiring) plus the merged
|
|
33
|
+
real-tool peers (`@biomejs/biome` optional, `husky`, `@commitlint/*`, `commitizen`,
|
|
34
|
+
`@changesets/cli`, `lint-staged`, `markdownlint-cli2`) via `catalog:silkPeers`.
|
|
35
|
+
silk ships dual-format (esm + cjs) because some consumers `require()` its subpaths
|
|
36
|
+
from CommonJS — notably markdownlint-cli2's custom-rule loader, which loads
|
|
37
|
+
`./changesets/markdownlint` through a CJS path; silk-effects therefore also exposes
|
|
38
|
+
a CJS entry. Dual-format is mandatory, not cosmetic.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
The consumer model:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
install @savvy-web/silk
|
|
46
|
+
→ autoInstallPeers pulls cli (the savvy bin) + biome/husky/@commitlint/
|
|
47
|
+
@changesets/lint-staged/markdownlint
|
|
48
|
+
→ savvy init seeds configs that reference @savvy-web/silk/* and wires husky
|
|
49
|
+
hooks to savvy subcommands
|
|
50
|
+
→ at runtime both silk (via shims) and cli (via handlers) resolve their logic
|
|
51
|
+
from silk-effects
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The Biome preset is referenced as `extends: "@savvy-web/silk/biome"`.
|
|
55
|
+
|
|
56
|
+
## Related
|
|
57
|
+
|
|
58
|
+
The export map: `silk://packages/silk/export-map`. The `init` step that follows
|
|
59
|
+
install: `silk://packages/cli/init-and-check`.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/silk-effects/
|
|
3
|
+
title: silk-effects overview
|
|
4
|
+
summary: Load to orient on the shared Effect library and its service map before diving into a service.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [silk-effects, effect]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk-effects/platform-layers, packages/silk-effects/managed-section, standards/publishability]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`@savvy-web/silk-effects` is a platform-agnostic Effect library holding the shared
|
|
15
|
+
conventions of the Silk Suite. It extracts repeated patterns — publishability
|
|
16
|
+
rules, changeset config reading, managed file sections, tool discovery — into one
|
|
17
|
+
package consumed by the `savvy` CLI, `@savvy-web/silk`, GitHub Actions, and build
|
|
18
|
+
scripts. It builds on `@effect/platform` abstractions rather than importing Node or
|
|
19
|
+
Bun APIs directly, so the same service implementations run on any `@effect/platform`
|
|
20
|
+
runtime once the consumer provides a context layer at the edge.
|
|
21
|
+
|
|
22
|
+
## API
|
|
23
|
+
|
|
24
|
+
Every service is a `Context.Tag` accessed with `yield*` inside `Effect.gen`. The
|
|
25
|
+
entire public API ships from the single package root — there are no subpath exports.
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import {
|
|
29
|
+
SilkPublishability,
|
|
30
|
+
ManagedSection, ManagedSectionLive, SectionDefinition, SectionBlock,
|
|
31
|
+
ToolDiscovery, ToolDiscoveryLive, ToolDefinition,
|
|
32
|
+
} from "@savvy-web/silk-effects";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Service index:
|
|
36
|
+
|
|
37
|
+
- `SilkPublishability` — static publishability `detect` plus detector layers.
|
|
38
|
+
- `TagStrategy` — git tag formatting (pure, no platform layer).
|
|
39
|
+
- `ChangesetConfig` / `ChangesetConfigReader` — read and query `.changeset/config.json`.
|
|
40
|
+
- `VersioningStrategy` — version resolution.
|
|
41
|
+
- `ManagedSection` — BEGIN/END tool-owned regions in user-editable files.
|
|
42
|
+
- `ConfigDiscovery` — locate config files.
|
|
43
|
+
- `BiomeSchemaSync` — keep the Biome schema in sync.
|
|
44
|
+
- `ToolDiscovery` — resolve and execute project tools (biome, husky, and the rest).
|
|
45
|
+
|
|
46
|
+
It also hosts the dev-tooling business logic under three namespace exports —
|
|
47
|
+
`Changesets`, `Commitlint`, `Lint` — which the `savvy` CLI and `@savvy-web/silk`
|
|
48
|
+
shims both consume so neither imports the other.
|
|
49
|
+
|
|
50
|
+
## Layer
|
|
51
|
+
|
|
52
|
+
Services fall into three platform tiers: pure (no layer), `FileSystem`, and
|
|
53
|
+
`FileSystem` + `CommandExecutor`. See `silk://packages/silk-effects/platform-layers`
|
|
54
|
+
for the full guide. `effect` and `@effect/platform` are peer dependencies;
|
|
55
|
+
`workspaces-effect`, `semver-effect`, `jsonc-effect`, and `yaml-effect` are direct.
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { SilkPublishability } from "@savvy-web/silk-effects";
|
|
61
|
+
|
|
62
|
+
const targets = SilkPublishability.detect("@my-org/pkg", {
|
|
63
|
+
private: true,
|
|
64
|
+
publishConfig: { access: "public", targets: ["npm"] },
|
|
65
|
+
});
|
|
66
|
+
// => [PublishTarget { registry: "https://registry.npmjs.org/", access: "public", ... }]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
All errors extend `Data.TaggedError` with a `_tag` discriminant, so they are
|
|
70
|
+
pattern-matchable with `Effect.catchTag`.
|
|
71
|
+
|
|
72
|
+
## Related
|
|
73
|
+
|
|
74
|
+
Platform layers: `silk://packages/silk-effects/platform-layers`. Managed sections:
|
|
75
|
+
`silk://packages/silk-effects/managed-section`. The publishability rules this
|
|
76
|
+
package encodes: `silk://standards/publishability`.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/silk-effects/managed-section
|
|
3
|
+
title: ManagedSection
|
|
4
|
+
summary: Load when reading, writing, or syncing tool-owned BEGIN/END regions in user-editable files.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [managed-section, effect]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk-effects/, packages/silk-effects/platform-layers]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
`ManagedSection` lets a tool own a delimited region of a file while leaving the
|
|
15
|
+
rest user-editable, using BEGIN/END markers. The motivating case is a husky hook
|
|
16
|
+
that runs a tool's command inside a managed region surrounded by user commands.
|
|
17
|
+
The service ships with value objects — `SectionDefinition` (section identity:
|
|
18
|
+
tool name + comment style) and `SectionBlock` (the content between markers).
|
|
19
|
+
Platform layer: `FileSystem`. Since 0.2.0.
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
`SectionDefinition` and `SectionBlock` are `Schema.TaggedClass` value objects with
|
|
24
|
+
structural equality — `SectionBlock` compares on normalized (trimmed,
|
|
25
|
+
whitespace-collapsed) content, so whitespace-only differences are equal. Comment
|
|
26
|
+
style is `"#"` (shell/YAML) or `"//"` (C-style); the tool name is uppercased into
|
|
27
|
+
the markers. `SectionDefinition.block(content)` mints a block;
|
|
28
|
+
`.generate(fn)` / `.generateEffect(fn)` build typed factories; `.withValidation`
|
|
29
|
+
attaches a content predicate that throws `SectionValidationError`.
|
|
30
|
+
|
|
31
|
+
The service Tag exposes (all dual-API, data-first or data-last):
|
|
32
|
+
|
|
33
|
+
- `read(path, def)` → `SectionBlock | null` (null if no file or no markers).
|
|
34
|
+
- `isManaged(path, def)` → `boolean` (always succeeds).
|
|
35
|
+
- `write(path, block)` → replaces the managed region, appends if markerless,
|
|
36
|
+
creates the file if absent; preserves content outside the markers.
|
|
37
|
+
- `sync(path, block)` → smart write reporting `SyncResult`: `Created`,
|
|
38
|
+
`Updated({ diff })`, or `Unchanged`; writes only when different.
|
|
39
|
+
- `syncMany(path, blocks)` → syncs several ordered sections in one file
|
|
40
|
+
idempotently, inserting missing siblings and normalizing drift; returns one
|
|
41
|
+
`SyncResult` per block in input order.
|
|
42
|
+
- `check(path, block)` → read-only `CheckResult`: `Found({ isUpToDate, diff })`
|
|
43
|
+
or `NotFound`.
|
|
44
|
+
- `remove(path, def)` → deletes the span including markers and collapses the
|
|
45
|
+
leftover blank line; `true` if removed, `false` if absent (missing file → false).
|
|
46
|
+
|
|
47
|
+
Identity-only operations (`read`, `isManaged`, `remove`) take a `SectionDefinition`;
|
|
48
|
+
content operations take a `SectionBlock`. Errors: `SectionParseError`,
|
|
49
|
+
`SectionWriteError`, `SectionValidationError`.
|
|
50
|
+
|
|
51
|
+
## Layer
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export const ManagedSectionLive: Layer.Layer<ManagedSection, never, FileSystem.FileSystem>;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { Effect } from "effect";
|
|
61
|
+
import { NodeContext } from "@effect/platform-node";
|
|
62
|
+
import { ManagedSection, ManagedSectionLive, SectionDefinition } from "@savvy-web/silk-effects";
|
|
63
|
+
|
|
64
|
+
const def = SectionDefinition.make({ toolName: "LINT-STAGED" });
|
|
65
|
+
|
|
66
|
+
await Effect.runPromise(
|
|
67
|
+
Effect.gen(function* () {
|
|
68
|
+
const ms = yield* ManagedSection;
|
|
69
|
+
const result = yield* ms.sync(".husky/pre-commit", def.block("\nnpx lint-staged\n"));
|
|
70
|
+
// result._tag => "Created" | "Updated" | "Unchanged"
|
|
71
|
+
}).pipe(Effect.provide(ManagedSectionLive), Effect.provide(NodeContext.layer)),
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The `SavvySections` helpers (since 0.5.0) provide ready-made husky-hook shells:
|
|
76
|
+
`SavvyBaseSection` + `savvyBasePreamble()` define a shared package-manager preamble
|
|
77
|
+
(`ROOT`, the `in_ci` predicate, `PM`, `pm_exec`), and `savvyToolSection(toolName,
|
|
78
|
+
command)` builds a consumer's one-line tool section. Pass the base first to
|
|
79
|
+
`syncMany` so `in_ci` and `pm_exec` are defined before a tool section uses them.
|
|
80
|
+
|
|
81
|
+
## Related
|
|
82
|
+
|
|
83
|
+
Overview: `silk://packages/silk-effects/`. Layer wiring:
|
|
84
|
+
`silk://packages/silk-effects/platform-layers`.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: packages/silk-effects/platform-layers
|
|
3
|
+
title: Providing platform layers
|
|
4
|
+
summary: Load when wiring silk-effects services into a program and deciding which layers to provide.
|
|
5
|
+
tier: packages
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [silk-effects, effect]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/silk-effects/, packages/silk-effects/managed-section]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
|
|
14
|
+
silk-effects is platform-agnostic: services declare their dependencies through
|
|
15
|
+
Effect's `Layer` type system, and the consumer provides concrete implementations at
|
|
16
|
+
the edge of the program. There are three tiers.
|
|
17
|
+
|
|
18
|
+
## API
|
|
19
|
+
|
|
20
|
+
**Tier 0 — no platform layer.** Pure services with no I/O. `SilkPublishability.detect`
|
|
21
|
+
is a static needing no layer or runtime. `TagStrategy` is a `Context.Tag`, so provide
|
|
22
|
+
its `TagStrategyLive`.
|
|
23
|
+
|
|
24
|
+
**Tier 1 — FileSystem.** Read/write services depend on `FileSystem` from
|
|
25
|
+
`@effect/platform`, supplied by the runtime context layer (`NodeContext.layer` or
|
|
26
|
+
`BunContext.layer`). Members: `SilkPublishabilityDetectorLive`,
|
|
27
|
+
`PublishabilityDetectorAdaptiveLive`, `ChangesetConfig`, `ChangesetConfigReader`,
|
|
28
|
+
`VersioningStrategy`, `ManagedSection`, `ConfigDiscovery`, `BiomeSchemaSync`.
|
|
29
|
+
|
|
30
|
+
**Tier 2 — FileSystem + CommandExecutor.** `ToolDiscovery` also needs
|
|
31
|
+
`CommandExecutor` plus `PackageManagerDetector` and `WorkspaceRoot` from
|
|
32
|
+
`workspaces-effect`. `NodeContext.layer` provides `FileSystem` and `CommandExecutor`.
|
|
33
|
+
|
|
34
|
+
Dependency graph:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
SilkPublishability.detect (pure static, no layer)
|
|
38
|
+
TagStrategy (no deps)
|
|
39
|
+
SilkPublishabilityDetectorLive --> FileSystem
|
|
40
|
+
PublishabilityDetectorAdaptiveLive --> FileSystem, ChangesetConfig
|
|
41
|
+
ChangesetConfigReader --> FileSystem
|
|
42
|
+
ChangesetConfig --> ChangesetConfigReader
|
|
43
|
+
VersioningStrategy --> ChangesetConfigReader
|
|
44
|
+
ManagedSection, ConfigDiscovery, BiomeSchemaSync --> FileSystem
|
|
45
|
+
ToolDiscovery --> CommandExecutor, PackageManagerDetector, WorkspaceRoot
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Layer
|
|
49
|
+
|
|
50
|
+
Compose with `Effect.provide` / `Layer.mergeAll`; services sharing a dependency
|
|
51
|
+
(like `FileSystem`) need the platform layer provided once.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { Effect } from "effect";
|
|
55
|
+
import { NodeContext } from "@effect/platform-node";
|
|
56
|
+
import { ManagedSection, ManagedSectionLive } from "@savvy-web/silk-effects";
|
|
57
|
+
|
|
58
|
+
await Effect.runPromise(
|
|
59
|
+
Effect.gen(function* () {
|
|
60
|
+
const ms = yield* ManagedSection;
|
|
61
|
+
// ...
|
|
62
|
+
}).pipe(Effect.provide(ManagedSectionLive), Effect.provide(NodeContext.layer)),
|
|
63
|
+
);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
The adaptive detector overrides `workspaces-effect`'s `PublishabilityDetector` Tag
|
|
69
|
+
and dispatches by changeset mode; it needs `ChangesetConfig`, which needs
|
|
70
|
+
`ChangesetConfigReader`:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { Layer } from "effect";
|
|
74
|
+
import { NodeContext } from "@effect/platform-node";
|
|
75
|
+
import {
|
|
76
|
+
ChangesetConfigLive, ChangesetConfigReaderLive,
|
|
77
|
+
PublishabilityDetectorAdaptiveLive,
|
|
78
|
+
} from "@savvy-web/silk-effects";
|
|
79
|
+
|
|
80
|
+
const layer = Layer.mergeAll(
|
|
81
|
+
PublishabilityDetectorAdaptiveLive.pipe(Layer.provide(ChangesetConfigLive)),
|
|
82
|
+
ChangesetConfigLive,
|
|
83
|
+
ChangesetConfigReaderLive,
|
|
84
|
+
).pipe(Layer.provide(NodeContext.layer));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For unconditional Silk rules without changeset awareness, use
|
|
88
|
+
`SilkPublishabilityDetectorLive`, which needs only the platform layer. For tests,
|
|
89
|
+
provide a mock `FileSystem` layer in place of `NodeContext.layer`.
|
|
90
|
+
|
|
91
|
+
## Related
|
|
92
|
+
|
|
93
|
+
Overview: `silk://packages/silk-effects/`. ManagedSection:
|
|
94
|
+
`silk://packages/silk-effects/managed-section`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: standards/api-model-pipeline
|
|
3
|
+
title: API Extractor as docs source of truth
|
|
4
|
+
summary: How package API surfaces become generated silk://packages/<pkg>/api docs via API Extractor models.
|
|
5
|
+
tier: standards
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [api, build]
|
|
8
|
+
priority: 0.5
|
|
9
|
+
related: [packages/mcp/resource-taxonomy]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Rule
|
|
13
|
+
|
|
14
|
+
Package API-reference docs are **generated** from Microsoft API Extractor models,
|
|
15
|
+
not hand-written. Do not edit generated docs directly — changes are overwritten on
|
|
16
|
+
the next build.
|
|
17
|
+
|
|
18
|
+
### Pipeline
|
|
19
|
+
|
|
20
|
+
1. A library package sets `apiModel` in its rslib config.
|
|
21
|
+
2. `build:prod` emits `<unscoped>.api.json` (a Microsoft API Extractor model file).
|
|
22
|
+
3. The `api-extractor-llms` library renders that model into LLM-lean
|
|
23
|
+
markdown.
|
|
24
|
+
4. The rendered docs appear in the MCP resource layer under
|
|
25
|
+
`silk://packages/<pkg>/api/<kind>/<name>`.
|
|
26
|
+
5. The `silk://catalog` lists these entries marked `(generated)`.
|
|
27
|
+
|
|
28
|
+
Generated docs carry a provenance marker indicating they must not be hand-edited.
|
|
29
|
+
|
|
30
|
+
### Coverage scope
|
|
31
|
+
|
|
32
|
+
Only public API surfaces are included. Internal and `@internal`-tagged members are
|
|
33
|
+
excluded. Quality tracks TSDoc coverage: undocumented public members degrade the
|
|
34
|
+
model and produce sparse rendered output.
|
|
35
|
+
|
|
36
|
+
## Why
|
|
37
|
+
|
|
38
|
+
Hand-written API docs drift from code. Generating docs from the type surface and
|
|
39
|
+
TSDoc comments keeps them accurate by construction: a renamed export, a removed
|
|
40
|
+
parameter, or a new option surfaces automatically in the next build. The API
|
|
41
|
+
Extractor model format is the standard Microsoft toolchain for TypeScript API
|
|
42
|
+
management, making the pipeline compatible with upstream tooling.
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
A package `@savvy-web/silk-effects` with `apiModel` in its rslib config builds
|
|
47
|
+
`silk-effects.api.json`. The renderer produces entries such as:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
silk://packages/silk-effects/api/class/SilkPublishability
|
|
51
|
+
silk://packages/silk-effects/api/namespace/Changesets
|
|
52
|
+
silk://packages/silk-effects/api/class/ChangesetConfig
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
These appear in `silk://catalog` as `(generated)` entries alongside hand-authored
|
|
56
|
+
docs.
|
|
57
|
+
|
|
58
|
+
## See also
|
|
59
|
+
|
|
60
|
+
The resource taxonomy that governs where generated and hand-authored docs live is at
|
|
61
|
+
`silk://packages/mcp/resource-taxonomy`. The `api-extractor-llms` library
|
|
62
|
+
is the renderer; the `@savvy-web/rslib-builder` build tool exposes the `apiModel`
|
|
63
|
+
config option.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: standards/catalog-usage
|
|
3
|
+
title: Catalog usage
|
|
4
|
+
summary: Load when adding or pinning a dependency in a Silk Suite package.
|
|
5
|
+
tier: standards
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [catalog, dependencies]
|
|
8
|
+
priority: 0.8
|
|
9
|
+
related: [standards/publishability]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Rule
|
|
13
|
+
|
|
14
|
+
Pin dependencies through the named catalogs that `@savvy-web/pnpm-plugin-silk`
|
|
15
|
+
merges into `pnpm-workspace.yaml` during `pnpm install`. Use `catalog:silk` for
|
|
16
|
+
direct `dependencies` and `devDependencies`; use `catalog:silkPeers` for
|
|
17
|
+
`peerDependencies`. Do not hard-code version strings for catalog-managed packages.
|
|
18
|
+
|
|
19
|
+
## Why
|
|
20
|
+
|
|
21
|
+
`catalog:silk` carries current/latest pinned versions; `catalog:silkPeers` carries
|
|
22
|
+
wider permissive ranges so a consuming package does not force its users to upgrade
|
|
23
|
+
in lockstep. Centralizing versions in the plugin keeps every repo in the ecosystem
|
|
24
|
+
on one coordinated set, and lets security overrides for transitive CVEs land
|
|
25
|
+
without per-repo edits.
|
|
26
|
+
|
|
27
|
+
The 26 Effect ecosystem packages are updated together as one batch to preserve
|
|
28
|
+
cross-package compatibility. For `@effect/*` packages (all at `0.x`), `silkPeers`
|
|
29
|
+
uses `>=` floor-only ranges rather than `^` caret ranges, because `^0.x.y`
|
|
30
|
+
restricts to patch-only and would not overlap with the `silk` pinned version one
|
|
31
|
+
minor ahead. For `effect` itself (at `3.x`) the standard `^` caret works.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"devDependencies": { "typescript": "catalog:silk", "vitest": "catalog:silk" },
|
|
38
|
+
"peerDependencies": { "typescript": "catalog:silkPeers" }
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
To override a catalog entry locally, add it under `catalogs.silk` in
|
|
43
|
+
`pnpm-workspace.yaml`; the local value wins and the plugin prints a warning so the
|
|
44
|
+
divergence is visible. Remove the local entry to revert to the Silk default.
|
|
45
|
+
|
|
46
|
+
## See also
|
|
47
|
+
|
|
48
|
+
Publishability and registry targets are at `silk://standards/publishability`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: standards/changeset-discipline
|
|
3
|
+
title: Changeset discipline
|
|
4
|
+
summary: Load when deciding whether a branch needs a changeset and how to author one.
|
|
5
|
+
tier: standards
|
|
6
|
+
source: hand
|
|
7
|
+
tags: [changeset, release]
|
|
8
|
+
priority: 0.8
|
|
9
|
+
related: [packages/silk-effects/, standards/publishability]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Rule
|
|
13
|
+
|
|
14
|
+
Every branch that changes a publishable package's runtime behavior, public API, or
|
|
15
|
+
shipped output ships a changeset that describes the change in user-facing terms.
|
|
16
|
+
Changes that do not affect what a consumer installs — AI context files, design
|
|
17
|
+
docs, internal tests, trivial config — do not get a changeset. The Silk ecosystem
|
|
18
|
+
formats changelogs through `@savvy-web/changesets`, a section-aware formatter that
|
|
19
|
+
categorizes entries with `h2`/`h3` headings (Features, Bug Fixes, Breaking Changes,
|
|
20
|
+
and the rest of the 13 valid headings) and enriches them with PR links and
|
|
21
|
+
contributor attribution.
|
|
22
|
+
|
|
23
|
+
## Why
|
|
24
|
+
|
|
25
|
+
A changeset is release documentation, not a commit log. It answers "what changed
|
|
26
|
+
for someone consuming this package" one level above the diff. Reconciling the
|
|
27
|
+
changeset set against the branch diff before merge keeps the `.changeset/`
|
|
28
|
+
directory an accurate description of the pending release: stale entries that name
|
|
29
|
+
packages no longer touched are removed, and missing entries for shipped work are
|
|
30
|
+
added. Pure dependency bumps follow a one-package-per-changeset, one-dependency-
|
|
31
|
+
changeset-per-package convention so the changelog reads cleanly.
|
|
32
|
+
|
|
33
|
+
A config is detected as Silk (versus vanilla changesets) when its `changelog`
|
|
34
|
+
field references `@savvy-web/changesets`; Silk mode is what enables the
|
|
35
|
+
section-aware pipeline and the ignore-aware publishability rules.
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
A `feat` that adds a public export needs a `minor` changeset under a Features
|
|
40
|
+
heading. A `fix` that corrects shipped behavior needs a `patch` changeset under
|
|
41
|
+
Bug Fixes. A branch that only edits `CLAUDE.md` and `.claude/design/` needs no
|
|
42
|
+
changeset. A breaking signature change needs a `major` changeset under Breaking
|
|
43
|
+
Changes.
|
|
44
|
+
|
|
45
|
+
## See also
|
|
46
|
+
|
|
47
|
+
Authoring and reconciliation are handled by the changeset skills — the
|
|
48
|
+
`changeset-create` skill reconciles changesets against the branch diff, and the
|
|
49
|
+
`changeset-style` skill carries the full format spec (the 13 headings and rules
|
|
50
|
+
CSH001–CSH005). The publishability rules that decide which packages a changeset
|
|
51
|
+
may name live at `silk://standards/publishability`; the config reader and the
|
|
52
|
+
fixed/ignore groups it exposes are documented at `silk://packages/silk-effects/`.
|