@aitrien/motifspec 1.13.2 → 1.14.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 CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  Every release of MotifSpec (named brand-codex until 1.10.0), newest first. Entries before 1.10.0 keep the names they were released under. Versions follow the rules in `CONVENTIONS.md`: renaming or removing a semantic token is major, adding tokens, components or icons is minor, and changing a value or fixing a description is a patch. `npm run build` fails if the version in `package.json` has no entry here.
4
4
 
5
+ ## [1.14.0] - 2026-10-28
6
+
7
+ ### Added
8
+ - The MotifSpec MCP server, at `https://mcp.motifspec.com/mcp`, for any AI assistant that supports remote MCP servers. Read-only, no sign-in. Five tools:
9
+ - `get_rules`: the README's rules and what the checker enforces.
10
+ - `find_tokens`: semantic tokens matching a query, with usage rule, CSS property, light and dark values, and the surfaces a colour may sit on.
11
+ - `get_component`: a component's doc with its Hugo partial and Markdown form, or the list.
12
+ - `get_doc`: `docs/hugo.md` or `docs/templates.md`.
13
+ - `check`: the rule checker on a piece of markup, Markdown or CSS.
14
+
15
+ It answers from this release's own files and tells assistants which version it serves. Built with the official MCP SDK (stateless Streamable HTTP, JSON responses).
16
+ - Hosting: AWS Lambda behind an API Gateway HTTP API on the custom domain, rate-limited, defined in `infra/mcp.yml`. The release workflow bundles the server (`npm run mcp:bundle`, about 260 KB), tests the bundle, deploys it with a role GitHub assumes through OIDC (no stored AWS key; only main can use it, and it can only replace the function's code), and checks the live server reports the new version.
17
+ - `npm run test:mcp`, run in CI on the source and on the bundle: calls every tool through the Lambda handler.
18
+ - README: "Using it from an AI assistant", with how to connect Claude, Claude Code, VS Code and others.
19
+
20
+ The npm package is unchanged apart from the version: the server's SDK, zod and esbuild are dev dependencies, and `mcp/` and `infra/` aren't in the package.
21
+
22
+ ## [1.13.3] - 2026-10-27
23
+
24
+ ### Changed
25
+ - Docs: each fact now lives in one place. The README's Hugo section points to `docs/hugo.md` (which now has the stylesheet path note and the full front-matter example from `docs/templates.md`), the release process lives in `CONVENTIONS.md`, and `docs/hugo.md` points to the README's list of what the checker checks. Statements about an MCP server that doesn't exist yet are removed, as are the planned-only `mcp/README.md` and the SCSS row in `CONVENTIONS.md`, which the build has never generated. The npm install line pins whatever version is current instead of naming 1.13.0.
26
+ - `AGENTS.md` (with `CLAUDE.md` pointing to it): where a change goes in this repo, what to run before finishing, and how releasing works, linking to the README and `CONVENTIONS.md` for everything else. Repo-only; not in the npm package.
27
+
5
28
  ## [1.13.2] - 2026-10-27
6
29
 
7
30
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MotifSpec
2
2
 
3
- Liam Marshall's design system: the single source of truth for aitrien.com and every project after it. Tokens are [DTCG](https://www.designtokens.org/) JSON, components are documented rules with markup to copy, and an MCP server serves both to AI coding assistants.
3
+ Liam Marshall's design system: the single source of truth for aitrien.com and every project after it. Tokens are [DTCG](https://www.designtokens.org/) JSON, components are documented rules with markup to copy, one checker holds every project that uses it to those rules, and an MCP server gives AI assistants all three.
4
4
 
5
5
  ## Principles
6
6
 
@@ -33,6 +33,7 @@ Liam Marshall's design system: the single source of truth for aitrien.com and ev
33
33
 
34
34
  ```
35
35
  LICENSE MIT, for code, tokens and docs
36
+ AGENTS.md Instructions for AI agents changing this repo (CLAUDE.md points to it)
36
37
  CHANGELOG.md Every release, newest first (the build fails without an entry for the current version)
37
38
  tokens/ DTCG source of truth (color, typography, space, size, radius, border, motion)
38
39
  css/components.css Reference implementation of every component (tokens only)
@@ -44,14 +45,15 @@ docs/hugo.md The Hugo partials and render hooks, their contexts and the f
44
45
  layouts/ Hugo partials (_partials/motifspec/) and Markdown render hooks (_markup/), mounted by the module
45
46
  docs/syntax-highlighting.md
46
47
  fonts/ Self-hosted WOFF2 (Latin subsets) and their OFL licences
47
- scripts/ validate, build, audit, check (the rule checker sites run) and release
48
+ scripts/ validate, build, audit, check (the rule checker projects run), pack-check and release
48
49
  js/codex.js Theme toggle, copy buttons, tooltip dismissal, TOC docking and active section (shared by sites and the showcase)
49
50
  js/theme-init.js One-line <head> snippet that applies a stored theme before first paint
50
51
  js/plate.js Contour survey generator for the backdrop and the specimen plate: draws the static contours at build time and animates them in the browser
51
52
  showcase/ Source of the system's showcase page
52
- mcp/ MCP server (Phase 3)
53
+ mcp/ The MCP server (server.mjs), its Lambda handler, bundle step and tests
54
+ infra/mcp.yml The server's AWS stack and deploy role (CloudFormation, applied by hand)
53
55
  hugo.toml, go.mod Hugo module definition and its mounts
54
- dist/ Generated: tokens.css, components in codex.css, chroma.css, fonts.css, icons.svg (sprite), tokens.json (for MCP), tokens.js (ES module export), codex.js and theme-init.js (behaviour), backdrop.html, plate.html and plate.js (backdrop and specimen plate), contrast.md, showcase.html (fragment for publishing), showcase.standalone.html (open locally)
56
+ dist/ Generated: tokens.css, components in codex.css, chroma.css, fonts.css, icons.svg (sprite), tokens.json, tokens.js (ES module export), codex.js and theme-init.js (behaviour), backdrop.html, plate.html and plate.js (backdrop and specimen plate), contrast.md, showcase.html (fragment for publishing), showcase.standalone.html (open locally)
55
57
  ```
56
58
 
57
59
  ## Commands
@@ -63,9 +65,11 @@ npm run audit # prove dist/showcase.html and the shipped scripts have no raw
63
65
  npm run release:check # what merging this would release, and whether that release is valid
64
66
  npm run pack:check # the npm package has every file the README and package.json promise
65
67
  npm run check -- <dir> # check a project that uses MotifSpec (see below)
68
+ npm run test:mcp # call every MCP tool through the Lambda handler
69
+ npm run mcp:bundle # build/mcp.zip, the server's Lambda package
66
70
  ```
67
71
 
68
- `scripts/check.mjs` is the one rule checker: this repo's audit runs it on `layouts/` and the component docs' markup, sites run it from their pinned module, and the MCP server's `check_styles` will call it. It checks a project's `layouts/` and `content/` against the release it comes from, and fails on:
72
+ `scripts/check.mjs` is the one rule checker: this repo's audit runs it on `layouts/` and the component docs' markup, and projects run it from the version they pin. It checks a project's `layouts/` and `content/` against the release it comes from, and fails on:
69
73
 
70
74
  - a stylesheet anywhere in the project, or a `style` attribute
71
75
  - a raw colour, or a number with a length or time unit (zero is allowed)
@@ -73,43 +77,21 @@ npm run check -- <dir> # check a project that uses MotifSpec (see below)
73
77
  - a `cx-` class that the stylesheet and scripts don't define, or a `cx-icon-` that isn't in `icons/manifest.json`
74
78
  - "·" used as a separator
75
79
 
76
- Releases are automatic. Bump `version` in `package.json` and add its `CHANGELOG.md` entry in the PR; once it is merged and CI passes on main, `.github/workflows/release.yml` tags that commit, publishes a GitHub release with the entry as its notes, and publishes that commit to npm with provenance (npm trusted publishing: no token is stored). A merge that doesn't change the version releases nothing.
80
+ Releases are automatic; `CONVENTIONS.md` (Versioning) says how.
77
81
 
78
- Node 20 or later, no dependencies.
82
+ Node 20 or later. The package has no dependencies; the MCP server's are dev dependencies, bundled into its deployment.
79
83
 
80
84
  ## Using it in Hugo
81
85
 
82
- Import the module and pin a release with `hugo mod get github.com/aitrien/motifspec@vX.Y.Z`. It mounts `dist/` at `assets/motifspec`, `fonts/` at `static/fonts`, and `layouts/` at `layouts`, so a site gets the component partials and the Markdown render hooks as well as the CSS and scripts:
83
-
84
- ```toml
85
- [module]
86
- [[module.imports]]
87
- path = "github.com/aitrien/motifspec"
88
- ```
89
-
90
- A page template then needs only the shell partials around its own content:
91
-
92
- ```go-html-template
93
- <head>
94
- {{ partial "motifspec/head.html" . }}
95
- </head>
96
- <body class="cx-backdrop-page">
97
- {{ partial "motifspec/body-start.html" . }}
98
- {{ partial "motifspec/site-header.html" . }}
99
- <main id="main" tabindex="-1">…</main>
100
- {{ partial "motifspec/body-end.html" . }}
101
- </body>
102
- ```
103
-
104
- `docs/hugo.md` lists every partial with its context, the front matter they read, the render hooks and the Markdown they expect, and the Goldmark settings they need. Keep the stylesheet's published path one level below the site root (Hugo publishes it at `/motifspec/`): its font URLs are `../fonts/…`, which resolve to the mounted `/fonts/`.
86
+ Import `github.com/aitrien/motifspec` as a Hugo module and pin a release with `hugo mod get github.com/aitrien/motifspec@vX.Y.Z`. The site then gets the CSS, scripts, fonts, component partials and Markdown render hooks; `docs/hugo.md` covers setup, every partial and the front matter they read.
105
87
 
106
88
  ## Using it from npm
107
89
 
108
90
  ```sh
109
- npm install @aitrien/motifspec@1.13.0
91
+ npm install --save-exact @aitrien/motifspec
110
92
  ```
111
93
 
112
- Pin an exact version, as a Hugo site pins a tag: the version you install is the version the checker and (later) the MCP server hold you to. The package has the CSS, scripts, tokens, fonts, icons, component docs, Hugo templates and the checker; it leaves out the showcase.
94
+ Pin an exact version, as a Hugo site pins a tag: the version you install is the version the checker holds you to. The package has the CSS, scripts, tokens, fonts, icons, component docs, Hugo templates and the checker; it leaves out the showcase.
113
95
 
114
96
  | Import | What it is |
115
97
  |---|---|
@@ -131,6 +113,27 @@ npx motifspec-check . --dirs src
131
113
 
132
114
  It reads `.html`, `.jsx`, `.tsx`, `.vue`, `.svelte`, `.astro`, `.md` and `.mdx` (both `class` and `className`), and skips `node_modules`, `dist` and `build`. Its stylesheet rule applies here too: a project using MotifSpec has no CSS of its own.
133
115
 
116
+ ## Using it from an AI assistant
117
+
118
+ The MCP server at `https://mcp.motifspec.com/mcp` serves the latest release to any assistant that supports remote MCP servers. It needs no sign-in and only reads.
119
+
120
+ | Tool | What it returns |
121
+ |---|---|
122
+ | `get_rules` | The rules above, and what the checker enforces |
123
+ | `find_tokens` | Semantic tokens matching a query: CSS property, usage rule, light and dark values, the surfaces a colour may sit on |
124
+ | `get_component` | A component's doc (markup, do and don't, accessibility), with its Hugo partial and Markdown form; without a name, the list |
125
+ | `get_doc` | `docs/hugo.md` or `docs/templates.md` |
126
+ | `check` | The checker's problems in a piece of markup, Markdown or CSS |
127
+
128
+ To connect it:
129
+
130
+ - **Claude (web, desktop):** Customize → Connectors → Add custom connector, with the URL above and "No sign in".
131
+ - **Claude Code:** `claude mcp add --transport http motifspec https://mcp.motifspec.com/mcp`, or a project `.mcp.json`.
132
+ - **VS Code:** add it to `.vscode/mcp.json` with `"type": "http"` and the URL.
133
+ - **Others:** add a remote MCP server by URL.
134
+
135
+ It serves the latest release. A project pinned to an older version can be offered something its version doesn't have yet; its own checker, at its pinned version, catches that.
136
+
134
137
  ## The identity in brief
135
138
 
136
139
  | | |
package/dist/codex.css CHANGED
@@ -2,7 +2,7 @@
2
2
  @font-face { font-family: "JetBrains Mono"; src: url("../fonts/jetbrains-mono-latin-wght.woff2") format("woff2"); font-weight: 100 800; font-style: normal; font-display: swap; }
3
3
  @font-face { font-family: "Yarndings 12"; src: url("../fonts/yarndings-12-latin.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: block; }
4
4
 
5
- /* MotifSpec 1.13.2 — generated from tokens/*.json. Do not edit.
5
+ /* MotifSpec 1.14.0 — generated from tokens/*.json. Do not edit.
6
6
  Themes: semantic colours use light-dark(); color-scheme follows the system unless
7
7
  <html data-theme="light|dark"> pins it. --cx-primitive-* are for this file only. */
8
8
  :root {
package/dist/tokens.css CHANGED
@@ -1,4 +1,4 @@
1
- /* MotifSpec 1.13.2 — generated from tokens/*.json. Do not edit.
1
+ /* MotifSpec 1.14.0 — generated from tokens/*.json. Do not edit.
2
2
  Themes: semantic colours use light-dark(); color-scheme follows the system unless
3
3
  <html data-theme="light|dark"> pins it. --cx-primitive-* are for this file only. */
4
4
  :root {
package/dist/tokens.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Generated by npm run build. Do not edit.
2
- export const version = "1.13.2";
2
+ export const version = "1.14.0";
3
3
  export const changelog = "https://github.com/Aitrien/motifspec/blob/main/CHANGELOG.md";
4
4
  export const tokens = [
5
5
  {
package/dist/tokens.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.13.2",
2
+ "version": "1.14.0",
3
3
  "changelog": "https://github.com/Aitrien/motifspec/blob/main/CHANGELOG.md",
4
4
  "tokens": [
5
5
  {
@@ -21,7 +21,7 @@ One sentence: what it is for.
21
21
  ## Markup
22
22
 
23
23
  ```html preview
24
- <!-- Minimal markup. The dashboard renders this block as a live preview, and the MCP server returns it as the pattern to copy. -->
24
+ <!-- Minimal markup: the pattern to copy. -->
25
25
  ```
26
26
 
27
27
  ## Do
package/docs/hugo.md CHANGED
@@ -18,7 +18,7 @@ The module ships the components as Hugo partials and the Markdown render hooks t
18
18
  block = true # {caption="…"} on tables, {file="…"} on code, {width="prose"} on figures
19
19
  ```
20
20
 
21
- Pin a release with `hugo mod get github.com/aitrien/motifspec@vX.Y.Z`. The module mounts `dist/` at `assets/motifspec`, `fonts/` at `static/fonts` and `layouts/` at `layouts`.
21
+ Pin a release with `hugo mod get github.com/aitrien/motifspec@vX.Y.Z`. The module mounts `dist/` at `assets/motifspec`, `fonts/` at `static/fonts` and `layouts/` at `layouts`. Hugo publishes the stylesheet at `/motifspec/`; keep it one level below the site root, because its font URLs are `../fonts/…`.
22
22
 
23
23
  ## The page shell
24
24
 
@@ -76,6 +76,18 @@ Every partial below is called as `partial "motifspec/<name>.html" <context>`.
76
76
 
77
77
  ## Front matter the partials read
78
78
 
79
+ ```yaml
80
+ title: Interactive WebGL globe
81
+ accession: LM-W-001
82
+ date: 2026-03-14
83
+ summary: A React app that renders live routes on a 3D globe.
84
+ role: Sole engineer
85
+ stack: [React, WebGL, Vite]
86
+ status: live # live | building | archived
87
+ tags: [react, webgl, a11y]
88
+ hero: { src: hero.png, alt: "…", caption: "…" }
89
+ ```
90
+
79
91
  | Field | Used by | Notes |
80
92
  |---|---|---|
81
93
  | `summary` | cards, rows | The lede and the card or row summary. |
@@ -113,7 +125,7 @@ const motifspec = mounts.split(/\n(?=\{)/).map((m) => JSON.parse(m)).find((m) =>
113
125
  execFileSync('node', [join(motifspec.dir, 'scripts', 'check.mjs'), '.'], { stdio: 'inherit' });
114
126
  ```
115
127
 
116
- It checks `layouts/` and `content/` and fails on stylesheets, style attributes, raw colours and units, primitive, unknown or deprecated tokens, classes and icons MotifSpec doesn't define, and "·" separators. In GitHub Actions each problem is also an annotation on the pull request; `--json` prints the problems as JSON. In CI, give the step the same `HUGO_CACHEDIR` and `HUGO_MODULE_PROXY` as the build, because `hugo config mounts` downloads the module if it isn't cached.
128
+ It checks `layouts/` and `content/` for what the README's Commands section lists. In GitHub Actions each problem is also an annotation on the pull request; `--json` prints the problems as JSON. In CI, give the step the same `HUGO_CACHEDIR` and `HUGO_MODULE_PROXY` as the build, because `hugo config mounts` downloads the module if it isn't cached.
117
129
 
118
130
  ## Overriding
119
131
 
package/docs/templates.md CHANGED
@@ -16,15 +16,6 @@ Content hierarchy for the six page types. Every template sits on the backdrop (`
16
16
  - Work: `LM-W-001` onward. Writing: `LM-P-001` onward. Zero-padded, never reused, stored in front matter as `accession`.
17
17
  - They appear on cards, post rows, post meta lines and case-study labels.
18
18
 
19
- ## Hugo front matter
19
+ ## Front matter
20
20
 
21
- ```yaml
22
- title: Interactive WebGL globe
23
- accession: LM-W-001
24
- date: 2026-03-14
25
- summary: A React app that renders live routes on a 3D globe.
26
- role: Sole engineer
27
- stack: [React, WebGL, Vite]
28
- status: live # live | building | archived
29
- tags: [react, webgl, a11y]
30
- ```
21
+ The fields each template reads are in `docs/hugo.md` (Front matter the partials read).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aitrien/motifspec",
3
- "version": "1.13.2",
3
+ "version": "1.14.0",
4
4
  "description": "Liam Marshall's design system: DTCG tokens, component rules, generated CSS, Hugo templates and a rule checker.",
5
5
  "keywords": [
6
6
  "design-system",
@@ -60,9 +60,16 @@
60
60
  "audit": "node scripts/audit.mjs",
61
61
  "check": "node scripts/check.mjs",
62
62
  "release:check": "node scripts/release.mjs",
63
- "pack:check": "node scripts/pack-check.mjs"
63
+ "pack:check": "node scripts/pack-check.mjs",
64
+ "test:mcp": "node --test mcp/test.mjs",
65
+ "mcp:bundle": "node mcp/build.mjs"
64
66
  },
65
67
  "engines": {
66
68
  "node": ">=20"
69
+ },
70
+ "devDependencies": {
71
+ "@modelcontextprotocol/sdk": "1.32.2",
72
+ "esbuild": "0.28.2",
73
+ "zod": "4.6.7"
67
74
  }
68
75
  }
package/scripts/check.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // The MotifSpec rule checker: one implementation for this repo's templates (npm run audit), for sites that use
3
- // MotifSpec (their CI runs this file from the pinned module) and for the MCP server's check_styles tool.
3
+ // MotifSpec (their CI runs this file from the pinned module) and for any tool that imports checkText.
4
4
  //
5
5
  // node scripts/check.mjs [project-root] check a consuming project's layouts/ and content/
6
6
  // node scripts/check.mjs [project-root] --dirs src,app check other folders instead (a non-Hugo project)