@handamade/psi-mcp 0.6.0 → 0.7.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/README.md +1 -1
- package/dist/psi-index.json +84 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @handamade/psi-mcp
|
|
2
2
|
|
|
3
|
-
MCP server and agent-context generator for the Psi (Ψ) design system. Documents the system — the
|
|
3
|
+
MCP server and agent-context generator for the Psi (Ψ) design system. Documents the system — the 15 React 19 components, 3 composition patterns (D47) that recipe them together with gap-annotated compose trees, every semantic token with its OKLCH derivation formula resolved across all four themes, and the usage guidance — through two read-only tools. It does not write code.
|
|
4
4
|
|
|
5
5
|
## Connect
|
|
6
6
|
|
package/dist/psi-index.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.7.0",
|
|
3
3
|
"themes": [
|
|
4
4
|
"light",
|
|
5
5
|
"dark",
|
|
@@ -164,6 +164,42 @@
|
|
|
164
164
|
"slots": [],
|
|
165
165
|
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Card\n\nContent container with an optional edge-to-edge media slot; `stacked` (media above body) or `featured` (media beside body) layout.\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `variant` | `\"stacked\" \\| \"featured\"` | stacked | no | stacked = media above body; featured = media beside body (~1.6fr/1fr), stacks under md. |\n| `media` | `ReactNode` | — | no | Media slot rendered edge-to-edge (img, AspectRatio, …). |\n| `hoverLift` | `boolean` | false | no | Lift on hover: translateY(-6px) over --psi-duration-350. |\n| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root element. |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Theming\n\nOverride `--psi-card-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n## Variant guidance\n\n- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.\n- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.\n- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.\n- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.\n- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.\n- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.\n- **danger** — Destructive action. Delete, remove, disconnect.\n- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.\n- **success | warning** — Status communication (Tag only). Status badges, labels.\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
166
166
|
},
|
|
167
|
+
{
|
|
168
|
+
"name": "Panel",
|
|
169
|
+
"description": "Elevated surface panel (D51): secondary background, faint hairline, radius-12 — the shared --psi-surface-* recipe Dialog's panel also binds. Not a Card: no media slot, no hover lift, opaque by design.",
|
|
170
|
+
"props": [
|
|
171
|
+
{
|
|
172
|
+
"name": "padding",
|
|
173
|
+
"type": "16 | 24",
|
|
174
|
+
"required": false,
|
|
175
|
+
"default": 24,
|
|
176
|
+
"description": "Inner padding in px."
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "ref",
|
|
180
|
+
"type": "Ref<HTMLDivElement>",
|
|
181
|
+
"required": false,
|
|
182
|
+
"default": null,
|
|
183
|
+
"description": "Forwarded ref to the root element."
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "className",
|
|
187
|
+
"type": "string",
|
|
188
|
+
"required": false,
|
|
189
|
+
"default": null,
|
|
190
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"slots": [
|
|
194
|
+
{
|
|
195
|
+
"name": "body",
|
|
196
|
+
"accepts": {},
|
|
197
|
+
"cardinality": "1..*",
|
|
198
|
+
"order": 1
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Panel\n\nElevated surface panel (D51): secondary background, faint hairline, radius-12 — the shared --psi-surface-* recipe Dialog's panel also binds. Not a Card: no media slot, no hover lift, opaque by design.\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `padding` | `16 \\| 24` | 24 | no | Inner padding in px. |\n| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root element. |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Keyboard & assistive tech\n\n| Keys | Behavior |\n|---|---|\n| Tab | Skipped — Panel itself is not focusable; focus moves through its children. |\n\nPlain <div> container with no implicit role. Pass aria-* host props if the panel should announce as a region.\n\n## Theming\n\nOverride `--psi-panel-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
202
|
+
},
|
|
167
203
|
{
|
|
168
204
|
"name": "Input",
|
|
169
205
|
"description": "Single-line text input with pixel-true heights (24–48) and an error state. Inside a Field, id/aria-describedby/aria-invalid/required are wired automatically (D49).",
|
|
@@ -189,6 +225,13 @@
|
|
|
189
225
|
"default": null,
|
|
190
226
|
"description": "Forwarded ref to the underlying `<input>` element."
|
|
191
227
|
},
|
|
228
|
+
{
|
|
229
|
+
"name": "placeholder",
|
|
230
|
+
"type": "string",
|
|
231
|
+
"required": false,
|
|
232
|
+
"default": null,
|
|
233
|
+
"description": "Native placeholder text shown while the field is empty (only on components whose host element supports it)."
|
|
234
|
+
},
|
|
192
235
|
{
|
|
193
236
|
"name": "className",
|
|
194
237
|
"type": "string",
|
|
@@ -198,7 +241,7 @@
|
|
|
198
241
|
}
|
|
199
242
|
],
|
|
200
243
|
"slots": [],
|
|
201
|
-
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Input\n\nSingle-line text input with pixel-true heights (24–48) and an error state. Inside a Field, id/aria-describedby/aria-invalid/required are wired automatically (D49).\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `size` | `24 \\| 32 \\| 40 \\| 48` | 32 | no | Height in px (24 \\| 32 \\| 40 \\| 48). |\n| `error` | `boolean` | false | no | Show error styling. Inside a Field, the Field's error also lights this. |\n| `ref` | `Ref<HTMLInputElement>` | — | no | Forwarded ref to the underlying `<input>` element. |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Keyboard & assistive tech\n\n| Keys | Behavior |\n|---|---|\n| Tab | Focuses the native <input>; focus ring on the field. |\n\nerror sets a red border only. Inside a Field, aria-invalid and aria-describedby are wired automatically (D49); standalone, pair them yourself.\n\n## Theming\n\nOverride `--psi-input-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
244
|
+
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Input\n\nSingle-line text input with pixel-true heights (24–48) and an error state. Inside a Field, id/aria-describedby/aria-invalid/required are wired automatically (D49).\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `size` | `24 \\| 32 \\| 40 \\| 48` | 32 | no | Height in px (24 \\| 32 \\| 40 \\| 48). |\n| `error` | `boolean` | false | no | Show error styling. Inside a Field, the Field's error also lights this. |\n| `ref` | `Ref<HTMLInputElement>` | — | no | Forwarded ref to the underlying `<input>` element. |\n| `placeholder` | `string` | — | no | Native placeholder text shown while the field is empty (only on components whose host element supports it). |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Keyboard & assistive tech\n\n| Keys | Behavior |\n|---|---|\n| Tab | Focuses the native <input>; focus ring on the field. |\n\nerror sets a red border only. Inside a Field, aria-invalid and aria-describedby are wired automatically (D49); standalone, pair them yourself.\n\n## Theming\n\nOverride `--psi-input-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
202
245
|
},
|
|
203
246
|
{
|
|
204
247
|
"name": "Select",
|
|
@@ -514,6 +557,42 @@
|
|
|
514
557
|
"slots": [],
|
|
515
558
|
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Tag\n\nCompact label for status or category; semantic variants, optional subtle tint and dismiss button.\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `variant` | `\"neutral\" \\| \"accent\" \\| \"success\" \\| \"warning\" \\| \"danger\"` | neutral | no | Semantic color variant. |\n| `subtle` | `boolean` | false | no | Use tinted background with semantic foreground. |\n| `onDismiss` | `(() => void)` | — | no | When provided, renders a dismiss button that calls this handler. |\n| `ref` | `Ref<HTMLSpanElement>` | — | no | Forwarded ref to the underlying `<span>` element. |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Keyboard & assistive tech\n\n| Keys | Behavior |\n|---|---|\n| Enter / Space (dismiss button) | onDismiss renders a real <button>; keyboard-dismissible. |\n\nPassive label otherwise; not in the tab order without onDismiss.\n\n## Theming\n\nOverride `--psi-tag-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n## Variant guidance\n\n- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.\n- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.\n- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.\n- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.\n- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.\n- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.\n- **danger** — Destructive action. Delete, remove, disconnect.\n- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.\n- **success | warning** — Status communication (Tag only). Status badges, labels.\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
516
559
|
},
|
|
560
|
+
{
|
|
561
|
+
"name": "Toolbar",
|
|
562
|
+
"description": "Horizontal grouping row for filter/search controls (D52). Wraps on overflow; zero JS. Deliberately NOT ARIA role=\"toolbar\" — that role contracts roving-tabindex arrow-key navigation, wrong for form controls. With aria-label it announces as role=\"group\".",
|
|
563
|
+
"props": [
|
|
564
|
+
{
|
|
565
|
+
"name": "gap",
|
|
566
|
+
"type": "8 | 12 | 16",
|
|
567
|
+
"required": false,
|
|
568
|
+
"default": 8,
|
|
569
|
+
"description": "Gap between controls in px."
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"name": "ref",
|
|
573
|
+
"type": "Ref<HTMLDivElement>",
|
|
574
|
+
"required": false,
|
|
575
|
+
"default": null,
|
|
576
|
+
"description": "Forwarded ref to the root element."
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"name": "className",
|
|
580
|
+
"type": "string",
|
|
581
|
+
"required": false,
|
|
582
|
+
"default": null,
|
|
583
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
584
|
+
}
|
|
585
|
+
],
|
|
586
|
+
"slots": [
|
|
587
|
+
{
|
|
588
|
+
"name": "body",
|
|
589
|
+
"accepts": {},
|
|
590
|
+
"cardinality": "0..*",
|
|
591
|
+
"order": 1
|
|
592
|
+
}
|
|
593
|
+
],
|
|
594
|
+
"doc": "<!-- Generated by emit-docs.ts — do not edit. -->\n# Toolbar\n\nHorizontal grouping row for filter/search controls (D52). Wraps on overflow; zero JS. Deliberately NOT ARIA role=\"toolbar\" — that role contracts roving-tabindex arrow-key navigation, wrong for form controls. With aria-label it announces as role=\"group\".\n\n## Props\n\n| Prop | Type | Default | Required | Description |\n|---|---|---|---|---|\n| `gap` | `8 \\| 12 \\| 16` | 8 | no | Gap between controls in px. |\n| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root element. |\n| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |\n\n## Keyboard & assistive tech\n\n| Keys | Behavior |\n|---|---|\n| Tab | Moves through the controls in DOM order — no roving tabindex (deliberately not role=toolbar, D52). |\n\nWith aria-label it renders role=group so the control cluster announces with a name; unlabeled it is a plain layout div.\n\n## Theming\n\nOverride `--psi-toolbar-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).\n\n\n\n## Rules\n\n- One accent per visual group; everything else neutral or ghost.\n- danger only for actions with real consequences.\n- Sizes are px numbers (24|32|40|48), never S/M/L.\n- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.\n- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.\n- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).\n- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.\n- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.\n"
|
|
595
|
+
},
|
|
517
596
|
{
|
|
518
597
|
"name": "Tooltip",
|
|
519
598
|
"description": "Short hover/focus hint attached to a single trigger element.",
|
|
@@ -2204,11 +2283,9 @@
|
|
|
2204
2283
|
"content": {
|
|
2205
2284
|
"example-filter": "<active filter>"
|
|
2206
2285
|
},
|
|
2207
|
-
"gaps": [
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
"blocked": true,
|
|
2211
|
-
"preset": null
|
|
2286
|
+
"gaps": [],
|
|
2287
|
+
"blocked": false,
|
|
2288
|
+
"preset": "<Toolbar>\n <Input />\n <Select />\n <Tag><active filter></Tag>\n</Toolbar>\n"
|
|
2212
2289
|
},
|
|
2213
2290
|
{
|
|
2214
2291
|
"id": "settings-form-row",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@handamade/psi-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "MCP server and agent-context generator for the Psi (Ψ) design system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"tsx": "^4.22.4",
|
|
33
33
|
"typescript": "^5.7.0",
|
|
34
34
|
"vitest": "^3.2.6",
|
|
35
|
-
"@handamade/psi-
|
|
36
|
-
"@handamade/psi-
|
|
35
|
+
"@handamade/psi-tokens": "0.7.0",
|
|
36
|
+
"@handamade/psi-react": "0.7.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "tsx scripts/build-index.ts && tsc -p tsconfig.build.json"
|