@craft-ts/mcp 0.7.0-beta.13 → 0.7.0-beta.16

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.
@@ -1,3 +1,11 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
1
9
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
10
  import { z } from 'zod';
3
11
  import { findPage, pageUrl, searchPages } from './catalog.js';
@@ -121,8 +129,77 @@ export function createCraftMcpServer(resources) {
121
129
  url: `${pageUrl(page.path)}.md`,
122
130
  })),
123
131
  }));
132
+ registerStyleTools(server);
124
133
  return server;
125
134
  }
135
+ const DEFAULT_STYLE_DUMP = 'tmp/craft-style-graph.json';
136
+ const STYLE_REPORT_MODULE = '@craft-ts/dev-tools/style-report';
137
+ const styleReport = async () => {
138
+ // Resolved at call time, through a specifier this package's own build does
139
+ // not need to see: `@craft-ts/dev-tools` is a peer of the workspace, not of
140
+ // the published bundle. An installation without it fails here, with a
141
+ // message, rather than failing to start.
142
+ const loaded = (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ STYLE_REPORT_MODULE)).catch(() => {
143
+ throw new Error(`The style tools need '${STYLE_REPORT_MODULE}'. Install @craft-ts/dev-tools alongside this server, or use \`craft-graph --style-matrix\` from the repository instead.`);
144
+ }));
145
+ return loaded;
146
+ };
147
+ const DUMP_INPUT = {
148
+ dumpPath: z
149
+ .string()
150
+ .optional()
151
+ .describe(`Path to the style dump the build plugin writes. Defaults to ${DEFAULT_STYLE_DUMP}.`),
152
+ };
153
+ /**
154
+ * The style questions, read-only, answered from the emitted dump.
155
+ *
156
+ * They call the same functions the CLI calls rather than reimplementing the
157
+ * queries: one question must not have two answers depending on who asked. The
158
+ * import is dynamic so that opening the server does not pull the graph
159
+ * machinery into memory for an agent that only wanted the documentation.
160
+ */
161
+ function registerStyleTools(server) {
162
+ const loadDump = async (dumpPath) => {
163
+ const path = dumpPath ?? DEFAULT_STYLE_DUMP;
164
+ const { readFile } = await import('node:fs/promises');
165
+ try {
166
+ return JSON.parse(await readFile(path, 'utf8'));
167
+ }
168
+ catch {
169
+ throw new Error(`No style dump at '${path}'. It is written by the build plugin: give craftStyle({ dumpPath }) a path and run a build, or pass dumpPath.`);
170
+ }
171
+ };
172
+ server.registerTool('style_impact', {
173
+ description: 'Which sheet classes a change to one or more CSS custom properties can be seen in. Use it before rerunning a visual suite: changing one token should recapture what reaches it, not everything. Answers `narrowed: false` when a name is unknown to the graph, in which case the answer is the whole application on purpose.',
174
+ inputSchema: {
175
+ changed: z
176
+ .array(z.string().min(1))
177
+ .min(1)
178
+ .describe('Custom property names, e.g. --ds-accent'),
179
+ ...DUMP_INPUT,
180
+ },
181
+ annotations: { readOnlyHint: true, destructiveHint: false },
182
+ }, async ({ changed, dumpPath }) => {
183
+ const { styleImpact } = await styleReport();
184
+ return toolResult(styleImpact(await loadDump(dumpPath), changed));
185
+ });
186
+ server.registerTool('style_matrix', {
187
+ description: 'What the application costs to capture: the number of visual states per sheet class, the total, the median and the largest. The median and the largest are the two numbers that decide whether matrix reduction is worth opening at all.',
188
+ inputSchema: { ...DUMP_INPUT },
189
+ annotations: { readOnlyHint: true, destructiveHint: false },
190
+ }, async ({ dumpPath }) => {
191
+ const { styleMatrix } = await styleReport();
192
+ return toolResult(styleMatrix(await loadDump(dumpPath)));
193
+ });
194
+ server.registerTool('style_debt', {
195
+ description: 'What the style system is owed: escape hatches taken with their stated reason, context obligations required and discharged nowhere, variables declared and never read, and the components no sheet is known to style. Read `extractionGaps` first — the rest is only worth its answer on a complete graph.',
196
+ inputSchema: { ...DUMP_INPUT },
197
+ annotations: { readOnlyHint: true, destructiveHint: false },
198
+ }, async ({ dumpPath }) => {
199
+ const { styleDebt } = await styleReport();
200
+ return toolResult(styleDebt(await loadDump(dumpPath)));
201
+ });
202
+ }
126
203
  function serializePage(page) {
127
204
  return {
128
205
  path: page.path,
@@ -135,9 +212,7 @@ function serializePage(page) {
135
212
  }
136
213
  function toolResult(result) {
137
214
  return {
138
- content: [
139
- { type: 'text', text: JSON.stringify(result, null, 2) },
140
- ],
215
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
141
216
  structuredContent: { result },
142
217
  };
143
218
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craft-ts/mcp",
3
- "version": "0.7.0-beta.13",
3
+ "version": "0.7.0-beta.16",
4
4
  "description": "MCP server, Agent Skills, and LLM files for coding agents using @craft-ts/core",
5
5
  "author": "Romain Geffrault",
6
6
  "license": "MIT",
@@ -32,9 +32,10 @@
32
32
  "bundle-docs": "node scripts/bundle-docs.mjs",
33
33
  "build": "node scripts/build.mjs",
34
34
  "start": "npm run build && node dist/main.js",
35
- "test": "vitest run"
35
+ "test": "vitest run --config vitest.config.mts"
36
36
  },
37
37
  "dependencies": {
38
+ "@craft-ts/dev-tools": "^0.7.0-beta.0",
38
39
  "@modelcontextprotocol/sdk": "1.26.0",
39
40
  "zod": "4.3.6"
40
41
  },
@@ -19,7 +19,20 @@ required and must not be introduced just to solve a Craft problem.
19
19
  - `craft-ts-routes` — type-safe routes and DI checks
20
20
  - `craft-ts-service-migration` — Angular services → `craftService`
21
21
  - `migrate-to-craft-ts` — run `craft-migrate`, then finish diagnostics
22
- - `craft-ts-effect-v4` — use Effect v4 services, Layers and `queryEffect`
22
+ - `craft-ts-effect-v4` — use Effect v4 services, Layers, `queryEffect`, and
23
+ the synchronous-member declaration (`SyncOp` / `computedEffect`)
24
+ - `craft-ts-style` — the typed design system: sheets, axes, the visual
25
+ matrix, context obligations
26
+ - `craft-ts-i18n` — typed catalogues, locale parity, semantic tokens
27
+
28
+ For a project created by `craft create`, keep the generated development
29
+ surface enabled. Run `npm run logs:server` for the local JSONL ingestion
30
+ server and `npm run registry:mcp` for the browser page MCP bridge; the
31
+ generated `.mcp.json` also registers the Craft guidance and log-reader MCP
32
+ servers. Use Craft `Console.*` for entries that must be searchable through
33
+ `npm run logs:mcp`; raw `console.*` calls stay in the browser or server
34
+ process console. These facilities are development-only and must not be added
35
+ to a production provider graph.
23
36
 
24
37
  If MCP is not configured, read https://ng-angular-stack.github.io/craft/llms.txt and the `AGENTS.md` snippet in this package (`content/agents.md`).
25
38
 
@@ -36,8 +49,22 @@ If MCP is not configured, read https://ng-angular-stack.github.io/craft/llms.txt
36
49
  required, and `hydrateCraft` when hydration must be forced or customized.
37
50
  - Use `renderCraft` for one isolated SSR request. Create a new render per
38
51
  request; never reuse its injector, platform, primitive registry, or history.
39
- - Keep SSR data behavior explicit with `pendingBlock({ ssr: 'block' | 'fallback' | 'client' })`
52
+ - Keep SSR data behavior explicit with `pendingNode({ ssr: 'block' | 'fallback' | 'client' })`
40
53
  or a route-level `ssr` policy. Do not let a suspended source reach SSR
41
54
  without a policy.
55
+ - Visual rules live in a `*.style.ts` sheet. Static variation becomes a class
56
+ the emitter wrote; dynamic variation goes through a typed custom property.
57
+ Never assemble a class string at render time — the template sets one constant
58
+ class and a `data-*` attribute. `@craft-ts/style` is a **build step**: without
59
+ `craftStyle()` from `@craft-ts/style/vite` in the Vite config, the sheets
60
+ typecheck and emit nothing. Load `craft-ts-style` before touching one.
61
+ - Translations live in a `@craft-ts/i18n` catalogue: `defineCatalog` + `msg` for
62
+ the reference locale, `defineLocaleLike` for every other one, so a missing key
63
+ is a compile error. `@craft-ts/i18n` has no framework and no Effect import;
64
+ use `@craft-ts/i18n-effect` only inside an Effect program. Load
65
+ `craft-ts-i18n` before adding a key, a locale or a token.
42
66
  - Run existing architecture tests. Do not add an architecture rule for the feature.
67
+ - Keep `npm run typecheck` in the project CI; for generated projects this is
68
+ already wired into `.github/workflows/ci.yml` alongside the architecture
69
+ and build checks.
43
70
  - Confirm symbols against the installed `node_modules/@craft-ts/core`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: craft-ts-effect-v4
3
- description: Build Effect v4 integrations in framework-independent CraftTS applications with typed services, Layers, queryEffect and Effect diagnostics. Use when a project selected EffectTS during craft create or when editing Effect domain code.
3
+ description: Build Effect v4 integrations in framework-independent CraftTS applications with typed services, Layers, queryEffect, methodEffect, synchronous members (SyncOp / computedEffect / syncEffect) and Effect diagnostics. Use when a project selected EffectTS during craft create or when editing Effect domain code.
4
4
  ---
5
5
 
6
6
  # CraftTS + Effect v4
@@ -16,6 +16,20 @@ examples copied from older documentation.
16
16
  the Craft app config.
17
17
  - UI data loading uses `queryEffect`; do not call `Effect.runPromise` from a
18
18
  component or bypass the Craft reactive lifecycle.
19
+ - `Effect<A, E, R>` does not say whether running it suspends, and a service
20
+ member hides it further: a `Layer` closes over its dependencies, so a network
21
+ call and a pure calculation both surface as `R = never`. Declare the members
22
+ that never suspend by putting `SyncOp` in their requirements — in the shape
23
+ when it is written by hand, with `yield* SyncOp` when `R` is inferred.
24
+ - A declared-synchronous Effect is the only one allowed where Craft runs the
25
+ synchronous driver. Use `computedEffect` for a derived value (the Effect
26
+ counterpart of `craftComputed`) and `methodEffect` for a callable method (the
27
+ Effect counterpart of `craftMethod`). Use `syncEffect(...)` directly in a
28
+ `params`, a `craftMethod` or a `state` updater. Anything that suspends belongs
29
+ to a `loader`.
30
+ - Never declare `SyncOp` on a member that can suspend. The claim is checked by
31
+ `craft-ts/sync-effect-body` on the body and by `Effect.runSyncExitWith` at
32
+ runtime, which throws `CraftEffectNotSynchronous` on the first call.
19
33
  - Install `installCraftEffectBridge()` once during bootstrap.
20
34
  - Run the Effect diagnostics command from `package.json` after changing an
21
35
  Effect generator, service, schema or Layer.
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: craft-ts-i18n
3
+ description: Build and review type-safe internationalisation in a CraftTS project with @craft-ts/i18n — closed key unions, locale parity, typed message parameters, per-locale plural categories, semantic tokens, the reactive translator, and the @craft-ts/i18n-effect adapter. Use when adding a translation, a locale, a token, or when a translation typecheck or i18n:check fails.
4
+ ---
5
+
6
+ # CraftTS type-safe i18n
7
+
8
+ `@craft-ts/i18n` has **no CraftTS, Angular or Effect import**. The catalogue is
9
+ a plain TypeScript value and the runtime works in a browser, a server, a worker
10
+ or a test without a framework. Do not reach for Effect to translate a string.
11
+
12
+ The contract it enforces, all at typecheck time:
13
+
14
+ 1. the set of keys is a **closed union** — an unknown key does not compile;
15
+ 2. every locale has the **same keys with the same parameters**;
16
+ 3. message parameters are **typed by their token**, so a date cannot be passed
17
+ where a currency amount belongs;
18
+ 4. a plural message must carry **every category the locale requires** — Polish
19
+ needs `one`, `few`, `many`, `other`; French needs `one` and `other`.
20
+
21
+ ## Writing a catalogue
22
+
23
+ ```ts
24
+ import { defineCatalog, defineLocale, defineLocaleLike, money, msg, number, plural } from '@craft-ts/i18n';
25
+
26
+ const amount = money('amount', undefined, { currency: 'EUR' });
27
+ const count = number('count');
28
+
29
+ const en = defineLocale('en-US', defineCatalog({
30
+ order: {
31
+ total: msg`Order total ${amount}.`,
32
+ items: plural(count, {
33
+ one: msg`${count} item is in the order.`,
34
+ other: msg`${count} items are in the order.`,
35
+ }),
36
+ },
37
+ }));
38
+
39
+ const fr = defineLocaleLike(en, 'fr-FR', { order: { /* same shape */ } });
40
+ ```
41
+
42
+ `msg` is a **tagged template**: the interpolations are tokens, and the params
43
+ type of the message is derived from them. `defineLocale` is for the reference
44
+ locale; every other locale uses `defineLocaleLike(reference, id, catalog)`,
45
+ which is what turns a missing or renamed key into a compile error instead of a
46
+ runtime fallback. Keys nest freely; a key is the dotted path.
47
+
48
+ ## Tokens
49
+
50
+ Shipped, semantic, and locale-aware through `Intl`: `number`, `integer`,
51
+ `percent`, `compactNumber`, `money`, `dateShort`, `dateLong`, `dateTime`,
52
+ `relativeTime`. Each is a factory — `factory(name, adapter?, options?)` — where
53
+ `name` becomes the parameter name.
54
+
55
+ For a business value, `defineToken({ name, kind, tokenId, validate, format })`;
56
+ for a family of them, `defineTokenFactory({ kind, format })`. Keep business
57
+ vocabulary in the project, in `src/i18n/project-tokens.ts`, not in the shared
58
+ library.
59
+
60
+ ## The runtime
61
+
62
+ ```ts
63
+ const i18n = createI18nRuntime({ locales, defaultLocale: 'en-US' });
64
+ i18n.t('order.total', { amount: 1234.5 });
65
+ ```
66
+
67
+ - `t` is `translate`; both take the key and, when the message has parameters, a
68
+ typed params object.
69
+ - `strict` defaults to **on**: every catalogue is validated and every locale is
70
+ checked for parity against the first one at construction.
71
+ - `setLocale(id)` throws `I18nRuntimeError('LOCALE_NOT_LOADED')` for a locale
72
+ that was never loaded. Note the current limit: `setLocale` and `loadLocale`
73
+ are keyed on the ids in `locales`, and a locale listed there already counts as
74
+ loaded — so list every locale, and treat `createI18nLoader` as the retry-safe
75
+ cache (it evicts failed loads) rather than as a fully lazy catalogue.
76
+ - `timeZone` belongs on the runtime, not on each call site.
77
+
78
+ ### Reactive translation
79
+
80
+ `runtime.bind(dependency)` returns a translator whose result re-reads when the
81
+ dependency changes. The dependency is a Craft reader — typically the `state`
82
+ holding the current locale — so a component consumes one service rather than
83
+ building a local binding:
84
+
85
+ ```ts
86
+ return { language, setLocale: language.setLocale, translate: runtime.bind(language) };
87
+ ```
88
+
89
+ `bind(...)('key', params)` returns a generator the template yields, like any
90
+ other Craft reader.
91
+
92
+ ## With Effect
93
+
94
+ `@craft-ts/i18n-effect` is the adapter, and only the adapter:
95
+
96
+ - `provideI18nRuntime(runtime)` → `Layer.Layer<I18nEffectService>`;
97
+ - `translateEffect(key, params)` →
98
+ `Effect.Effect<string, never, I18nEffectService>`.
99
+
100
+ Same keys, same params, same result as `runtime.t`. Use it inside an Effect
101
+ program; in plain component code, call `t` directly.
102
+
103
+ **`translateEffect` cannot infer the locales.** It has no value parameter
104
+ carrying them, so called bare its key parameter resolves to `never` and even a
105
+ valid key is rejected. Either pass the type arguments —
106
+ `translateEffect<typeof locales, 'order.total'>(…)` — or bind them once in a
107
+ project-local wrapper, which is the pattern in `/guide/i18n/effect`.
108
+
109
+ ## Checks
110
+
111
+ - `npm run i18n:check` — catalogue validity and locale parity, outside the
112
+ typechecker.
113
+ - `npm run i18n:test` — the runtime behaviour.
114
+
115
+ Run both after touching `src/i18n/`. A failing parity check names the key and
116
+ the locale; add the key rather than loosening the catalogue type.
117
+
118
+ Full guide: `/guide/i18n/`, `/guide/i18n/catalog`, `/guide/i18n/tokens`,
119
+ `/guide/i18n/runtime`, `/guide/i18n/effect`.
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: craft-ts-style
3
+ description: Build and review the typed design system of a CraftTS project with @craft-ts/style — palettes, axes, typed custom properties, sheets, context obligations, the visual matrix, and the style_impact / style_matrix / style_debt MCP tools. Use when adding or changing visual rules, a variant, a theme, dark mode, or a visual test.
4
+ ---
5
+
6
+ # CraftTS typed styles
7
+
8
+ `@craft-ts/style` makes a component's visual surface **derivable** rather than
9
+ guessed: what the exhaustive set of visual states is, which are impossible, and
10
+ whether the context a rule needs exists — all from the same values the CSS is
11
+ emitted from.
12
+
13
+ ## First: is it wired at all?
14
+
15
+ The system is a **build step**, not a runtime library. Before writing a rule,
16
+ confirm three things exist; without them the sheets typecheck and emit nothing.
17
+
18
+ 1. `@craft-ts/style` in `dependencies`, `@craft-ts/style-testing` in
19
+ `devDependencies`.
20
+ 2. `craftStyle()` from `@craft-ts/style/vite` in the Vite `plugins` array, with
21
+ a `dumpPath`. The dump is what the graph and the MCP tools below read; no
22
+ `dumpPath`, no answers.
23
+ 3. `import 'virtual:craft-style.css'` once, at the app entry.
24
+
25
+ A project created by `craft create` already has all three.
26
+
27
+ ## Hard rules
28
+
29
+ - **Static variation goes to a class the emitter wrote; dynamic variation goes
30
+ through a typed custom property.** No class is ever assembled in the browser.
31
+ - **A variant is an axis, never a class name.** The template sets one constant
32
+ class and a `data-*` attribute. `class:` bound to a string, a template
33
+ literal or a function is a visual state nothing recorded — `no-raw-class`
34
+ reports it in every file that imports `@craft-ts/style`.
35
+ - **A `*.style.ts` imports vocabulary and nothing else.** That is what makes it
36
+ safe for the plugin to import it in Node. `style-file-boundary` enforces it.
37
+ - **Components read theme variables, never palette tokens.** The theme is the
38
+ one place that decides what a variable holds in light and in dark, which is
39
+ what makes dark mode one rule instead of one per component.
40
+ - **No value is a string.** `space(4)`, `unit.rem(1.5)`, `palette.text.strong` —
41
+ never `'12px'`. The scales are closed; when a step is missing, add it to the
42
+ scale. `no-raw-css-value` reports the rest.
43
+ - **`overflow` is not in the property table.** The only road to
44
+ `overflow-block: auto` is `provides(scrollPort.block)`.
45
+ - **`:has()` is not free-form.** `no-free-has` reports a hand-written one; use
46
+ the `descendant` axis.
47
+ - Escape hatches — `unsafeLength(value, reason)`, `unsafeAssume(id, reason)` —
48
+ compile and propagate `unproven` to the graph, where the debt is counted.
49
+ Take one only with a reason a reader can act on.
50
+
51
+ ## Where things are declared
52
+
53
+ | you need | call |
54
+ | --------------------- | ------------------------------------------- |
55
+ | colours | `definePalette({ group: { token: { light, dark } } })` |
56
+ | viewport breakpoints | `defineBreakpoints({ md: at.minInlineSize(unit.rem(48)) })` |
57
+ | a state variant | `defineStateAxis('tone', ['neutral', 'danger'])` |
58
+ | an axis that may only write one kind | `defineAxis(name, values, onlyVarsOfKind(kind.color))` |
59
+ | the size of a box | `defineContainer({ name, type }, points)` |
60
+ | typed custom properties | `cssVars('prefix', { ink: kind.color(token) })` |
61
+ | the rules themselves | `craftStyles('name', { root: [...] }, { axes: [...] })` |
62
+
63
+ `scheme`, `motion`, `forcedColors`, `contrast`, `scrollState` and `descendant`
64
+ ship with the package and need no declaration.
65
+
66
+ Two details the types cannot enforce and the browser does:
67
+
68
+ - a registered `initial-value` must be computationally independent —
69
+ `kind.length(unit.px(16))`, never `unit.rem(1)`, or the browser drops the
70
+ `@property` rule silently;
71
+ - `inherits: true` belongs to theme variables and to nothing else.
72
+
73
+ ## Context obligations
74
+
75
+ `requires(scrollPort.block)` on a class travels up the tree until a
76
+ `provides(...)` answers it, and becomes an error only where a component seals
77
+ (`{ seals: [true] }`) or `seal(node)` closes it. Put the provider on the layout
78
+ component that owns the area — an `overflow` on the direct parent creates a
79
+ second scroll port and moves the bug instead of fixing it.
80
+
81
+ Level 3 is a **per-route** guarantee. One component in the path handing back a
82
+ loosely typed subtree stops the requirement travelling, and a partial adoption
83
+ gives zero of the guarantee, not most of it.
84
+
85
+ ## Testing
86
+
87
+ ```ts
88
+ import { applyScenario, visualMatrix } from '@craft-ts/style-testing';
89
+
90
+ for (const scenario of visualMatrix(sheet)) {
91
+ await applyScenario(page, scenario);
92
+ await expect(page).toHaveScreenshot(`${scenario.id}.png`);
93
+ }
94
+ ```
95
+
96
+ `visualMatrix` takes **sheets**, not a component. `assertExhaustiveVisualMatrix`
97
+ fails in both directions: a baseline nothing produces any more is as wrong as a
98
+ missing one.
99
+
100
+ ## Asking the graph
101
+
102
+ Three MCP tools read the dump, so you do not have to write a script:
103
+
104
+ - `style_impact` — which classes a change to given custom properties reaches.
105
+ Run it before rerunning a visual suite; changing one token should not
106
+ recapture everything.
107
+ - `style_matrix` — what the app costs to capture, with the median and the
108
+ largest. Those two numbers decide whether matrix reduction is worth opening.
109
+ - `style_debt` — escape hatches with their reasons, obligations discharged
110
+ nowhere, variables never read, components no sheet is known to style. Read
111
+ `extractionGaps` first; the rest is only meaningful on a complete graph.
112
+
113
+ An empty `style_matrix` is the signature of a missing `dumpPath`.
114
+
115
+ Full guide: `/guide/style/setup`, `/guide/style/define`, `/guide/style/tokens`,
116
+ `/guide/style/variants`, `/guide/style/obligations`, `/guide/style/testing`.