@substrate-kit/cli 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/LICENSE +21 -0
  3. package/README.md +25 -8
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +10 -41
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/add.d.ts +1 -0
  8. package/dist/commands/add.d.ts.map +1 -1
  9. package/dist/commands/add.js +51 -109
  10. package/dist/commands/add.js.map +1 -1
  11. package/dist/commands/docs.d.ts +4 -2
  12. package/dist/commands/docs.d.ts.map +1 -1
  13. package/dist/commands/docs.js +33 -54
  14. package/dist/commands/docs.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +158 -122
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/index.js +0 -0
  19. package/dist/mcp/server.d.ts.map +1 -1
  20. package/dist/mcp/server.js +8 -7
  21. package/dist/mcp/server.js.map +1 -1
  22. package/dist/mcp/tools/get-component.d.ts +1 -1
  23. package/dist/mcp/tools/get-component.d.ts.map +1 -1
  24. package/dist/mcp/tools/get-component.js +10 -6
  25. package/dist/mcp/tools/get-component.js.map +1 -1
  26. package/dist/mcp/tools/get-docs.d.ts +17 -0
  27. package/dist/mcp/tools/get-docs.d.ts.map +1 -0
  28. package/dist/mcp/tools/get-docs.js +23 -0
  29. package/dist/mcp/tools/get-docs.js.map +1 -0
  30. package/dist/mcp/tools/install.d.ts +2 -1
  31. package/dist/mcp/tools/install.d.ts.map +1 -1
  32. package/dist/mcp/tools/install.js +18 -27
  33. package/dist/mcp/tools/install.js.map +1 -1
  34. package/dist/mcp/tools/search.d.ts +1 -1
  35. package/dist/mcp/tools/search.d.ts.map +1 -1
  36. package/dist/mcp/tools/search.js +2 -4
  37. package/dist/mcp/tools/search.js.map +1 -1
  38. package/dist/{mcp/types.d.ts → registry.d.ts} +6 -1
  39. package/dist/registry.d.ts.map +1 -0
  40. package/dist/registry.js +48 -0
  41. package/dist/registry.js.map +1 -0
  42. package/dist/utils/agents-file.d.ts +4 -0
  43. package/dist/utils/agents-file.d.ts.map +1 -0
  44. package/dist/utils/agents-file.js +36 -0
  45. package/dist/utils/agents-file.js.map +1 -0
  46. package/dist/utils/docs.d.ts +7 -0
  47. package/dist/utils/docs.d.ts.map +1 -0
  48. package/dist/utils/docs.js +28 -0
  49. package/dist/utils/docs.js.map +1 -0
  50. package/dist/utils/shadcn.d.ts +6 -1
  51. package/dist/utils/shadcn.d.ts.map +1 -1
  52. package/dist/utils/shadcn.js +25 -12
  53. package/dist/utils/shadcn.js.map +1 -1
  54. package/dist/utils/version.d.ts +3 -0
  55. package/dist/utils/version.d.ts.map +1 -0
  56. package/dist/utils/version.js +8 -0
  57. package/dist/utils/version.js.map +1 -0
  58. package/docs/components/action.mdx +30 -0
  59. package/docs/components/alignment-controls.mdx +30 -0
  60. package/docs/components/badge.mdx +22 -0
  61. package/docs/components/breadcrumbs.mdx +25 -0
  62. package/docs/components/collapsible-pane.mdx +35 -0
  63. package/docs/components/colour-picker.mdx +66 -0
  64. package/docs/components/command-palette.mdx +36 -0
  65. package/docs/components/context-menu.mdx +31 -0
  66. package/docs/components/controls-timeline.mdx +107 -0
  67. package/docs/components/controls.mdx +168 -0
  68. package/docs/components/design-canvas.mdx +51 -0
  69. package/docs/components/document-tabs.mdx +25 -0
  70. package/docs/components/easing-curve-editor.mdx +85 -0
  71. package/docs/components/empty-state.mdx +26 -0
  72. package/docs/components/gallery.mdx +60 -0
  73. package/docs/components/history-controls.mdx +47 -0
  74. package/docs/components/image-picker.mdx +50 -0
  75. package/docs/components/layer-list.mdx +36 -0
  76. package/docs/components/node.mdx +85 -0
  77. package/docs/components/number-input.mdx +44 -0
  78. package/docs/components/number-slider.mdx +32 -0
  79. package/docs/components/pane.mdx +39 -0
  80. package/docs/components/panel.mdx +28 -0
  81. package/docs/components/popover.mdx +32 -0
  82. package/docs/components/progress-bar.mdx +24 -0
  83. package/docs/components/resizer.mdx +24 -0
  84. package/docs/components/select.mdx +31 -0
  85. package/docs/components/shortcut-overlay.mdx +43 -0
  86. package/docs/components/slider.mdx +20 -0
  87. package/docs/components/spring-editor.mdx +85 -0
  88. package/docs/components/status-bar.mdx +42 -0
  89. package/docs/components/surface.mdx +47 -0
  90. package/docs/components/swatch-palette.mdx +36 -0
  91. package/docs/components/text-area.mdx +26 -0
  92. package/docs/components/timeline.mdx +96 -0
  93. package/docs/components/toast.mdx +42 -0
  94. package/docs/components/toggle-group.mdx +40 -0
  95. package/docs/components/toggle.mdx +27 -0
  96. package/docs/components/toolbar.mdx +24 -0
  97. package/docs/components/tree-list.mdx +46 -0
  98. package/docs/components/xy-pad.mdx +49 -0
  99. package/docs/hooks/use-clipboard.mdx +70 -0
  100. package/docs/hooks/use-drag-reorder.mdx +60 -0
  101. package/docs/hooks/use-selection.mdx +68 -0
  102. package/docs/hooks/use-undoable.mdx +83 -0
  103. package/docs/hooks/use-viewport.mdx +75 -0
  104. package/docs/utilities/bounding-box.mdx +76 -0
  105. package/docs/utilities/keyboard-shortcuts.mdx +64 -0
  106. package/docs/utilities/snap.mdx +73 -0
  107. package/package.json +6 -4
  108. package/registry.json +274 -6
  109. package/skills/3d-scene/SKILL.md +2 -1
  110. package/skills/animation/SKILL.md +2 -1
  111. package/skills/canvas-2d/SKILL.md +67 -5
  112. package/skills/composing-panels/SKILL.md +1 -4
  113. package/skills/data-visualisation/SKILL.md +2 -1
  114. package/skills/image-generation/SKILL.md +2 -1
  115. package/skills/install-components/SKILL.md +22 -16
  116. package/skills/scaffold-playground/SKILL.md +39 -19
  117. package/skills/substrate-canvas/SKILL.md +5 -0
  118. package/skills/substrate-controls/SKILL.md +57 -2
  119. package/skills/substrate-interaction/SKILL.md +19 -10
  120. package/skills/substrate-scaffold/SKILL.md +4 -4
  121. package/skills/theming/SKILL.md +8 -2
  122. package/skills/wire-interactions/SKILL.md +6 -3
  123. package/templates/agents-section.md +41 -0
  124. package/dist/commands/browse.d.ts +0 -2
  125. package/dist/commands/browse.d.ts.map +0 -1
  126. package/dist/commands/browse.js +0 -25
  127. package/dist/commands/browse.js.map +0 -1
  128. package/dist/commands/create.d.ts +0 -9
  129. package/dist/commands/create.d.ts.map +0 -1
  130. package/dist/commands/create.js +0 -27
  131. package/dist/commands/create.js.map +0 -1
  132. package/dist/commands/variables.d.ts +0 -4
  133. package/dist/commands/variables.d.ts.map +0 -1
  134. package/dist/commands/variables.js +0 -111
  135. package/dist/commands/variables.js.map +0 -1
  136. package/dist/mcp/registry.d.ts +0 -3
  137. package/dist/mcp/registry.d.ts.map +0 -1
  138. package/dist/mcp/registry.js +0 -43
  139. package/dist/mcp/registry.js.map +0 -1
  140. package/dist/mcp/tools/theme.d.ts +0 -10
  141. package/dist/mcp/tools/theme.d.ts.map +0 -1
  142. package/dist/mcp/tools/theme.js +0 -37
  143. package/dist/mcp/tools/theme.js.map +0 -1
  144. package/dist/mcp/types.d.ts.map +0 -1
  145. package/dist/mcp/types.js +0 -2
  146. package/dist/mcp/types.js.map +0 -1
@@ -39,6 +39,7 @@ Keyboard events (DOM)
39
39
  | `creating` | Drag with shape tool on empty canvas | Preview element dimensions | Commit new element to store |
40
40
  | `moving` | Drag on selected element | Update element positions | Commit positions |
41
41
  | `resizing` | Drag on resize handle | Update element bounds | Commit bounds |
42
+ | `rotating` | Drag on the rotate handle above a single selection | Turn the element about its centre (hold Shift to snap to 15°) | Commit rotation |
42
43
  | `marquee_selecting` | Drag on empty canvas with select tool | Draw selection rectangle | Select contained elements |
43
44
 
44
45
  ### Pointer down logic
@@ -66,7 +67,8 @@ Keyboard events (DOM)
66
67
  - "pan": update camera
67
68
  - "create": preview element (stored on drag ref, rendered by renderer)
68
69
  - "move": update element positions (delta from start)
69
- - "resize": update element bounds respecting handle position
70
+ - "resize": update element bounds with `resizeBounds`, which respects the handle and the element's rotation
71
+ - "rotate": set `rotation` from the pointer's angle around the element centre
70
72
  - "marquee": update selection rectangle
71
73
  5. Call markDirty() to trigger repaint
72
74
  ```
@@ -77,7 +79,7 @@ Keyboard events (DOM)
77
79
  1. End drag (useCanvasDrag.endDrag)
78
80
  2. Based on drag type:
79
81
  - "create": push snapshot, add element to store, select it, reset tool to select
80
- - "move"/"resize": push snapshot (positions already updated during drag)
82
+ - "move"/"resize"/"rotate": nothing to push; the snapshot was taken when the drag first moved, so a click without a drag leaves no undo step
81
83
  - "marquee": select all elements within the marquee bounds
82
84
  - "pan": nothing to commit
83
85
  ```
@@ -104,12 +106,13 @@ Always convert pointer event coordinates to world space before doing hit-testing
104
106
 
105
107
  ```ts
106
108
  interface DragInfo {
107
- type: DragType // "create" | "move" | "resize" | "marquee" | "pan"
109
+ type: DragType // "create" | "move" | "resize" | "rotate" | "marquee" | "pan"
108
110
  startWorld: Point // Where the drag began (world space)
109
111
  startScreen: Point // Where the drag began (screen space)
110
112
  currentWorld: Point // Current position (updated on every move)
111
113
  currentScreen: Point
112
114
  handle?: HandlePosition // Which resize handle, if resizing
115
+ rotate?: { id, center, startAngle, startRotation } // Set for a rotate drag
113
116
  elementStartPositions?: Record<string, { x, y, width, height }> // Snapshot for move/resize
114
117
  }
115
118
  ```
@@ -0,0 +1,41 @@
1
+ # Substrate
2
+
3
+ This project uses [Substrate](https://substrate.georgedrury.co.uk), a set of primitives for building creative tools: scaffold (toolbar, panels, panes, shortcuts), canvas and node helpers, and config-driven controls.
4
+
5
+ ## Use Substrate components first
6
+
7
+ Components are installed into the project with the Substrate CLI, which wraps shadcn. Never run `npx shadcn@latest add` for them directly.
8
+
9
+ ```bash
10
+ npx substrate-kit add panel slider toolbar # install by name, in one call
11
+ npx substrate-kit add # interactive picker
12
+ npx substrate-kit docs <component> # props, CSS variables, usage
13
+ npx substrate-kit docs <component> --open # open its docs page in the browser
14
+ npx substrate-kit docs --list # every component
15
+ ```
16
+
17
+ Before writing a custom slider, input, panel, timeline or colour picker, check `docs --list`. If the Substrate MCP server is connected, use `search_components`, `get_component` and `get_docs` instead of the commands above, and `install_components` to install.
18
+
19
+ ## Tune values with Controls
20
+
21
+ For parameters you want to adjust live (sizes, colours, springs, toggles), describe them as an object and render them with `Controls` instead of building a form:
22
+
23
+ ```tsx
24
+ const card = useControls("Card", {
25
+ radius: [16, 0, 48], // [default, min, max, step?] slider
26
+ colour: "#a78bfa", // colour picker
27
+ visible: true, // toggle
28
+ motion: { type: "spring", visualDuration: 0.3, bounce: 0.2 },
29
+ })
30
+ // <Panel><Controls /></Panel> renders every registered panel
31
+ ```
32
+
33
+ The returned values keep the shape of the config. Panels have versions, reset, keyboard shortcuts (`shortcuts` option) and a copy button that gives an agent the tuned values to paste back in as the new defaults. Install with `npx substrate-kit add controls`, and read `docs controls` for every control type and option. Controls and the timeline are built on [DialKit](https://github.com/joshpuckett/dialkit) (MIT, by Josh Puckett), which installs as the `dialkit` dependency.
34
+
35
+ ## Tune animation with the timeline
36
+
37
+ For motion, define clips with `useControlsTimeline` and bind `clip.current` to your UI. `ControlsTimeline` is the editor: scrub, move and resize clips, edit curves, and copy the tuned timing back as defaults. Install with `npx substrate-kit add controls-timeline`, and read `docs controls-timeline` for clip types, looping and zoom.
38
+
39
+ ## Skills
40
+
41
+ Substrate skills are in `.claude/skills/` and `.agents/skills/`. Surface guides explain how to build each kind of tool (`scaffold-playground`, `canvas-2d`, `3d-scene`, `animation`, `image-generation`, `data-visualisation`) and workflows (`composing-panels`, `wire-interactions`, `create-custom-tool`, `theming`). Component references (`substrate-scaffold`, `substrate-controls`, `substrate-canvas`, `substrate-nodes`, `substrate-feedback`, `substrate-interaction`) say what to use. `install-components` lists everything available.
@@ -1,2 +0,0 @@
1
- export declare function browse(component?: string): void;
2
- //# sourceMappingURL=browse.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAKA,wBAAgB,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAiB/C"}
@@ -1,25 +0,0 @@
1
- import { execSync } from "node:child_process";
2
- import { log } from "../utils/logger.js";
3
- const DOCS_BASE = "https://substrate.georgedrury.co.uk/docs/components";
4
- export function browse(component) {
5
- const url = component
6
- ? `${DOCS_BASE}/${component}`
7
- : "https://substrate.georgedrury.co.uk/docs";
8
- log.info(`Opening ${url}`);
9
- try {
10
- const platform = process.platform;
11
- if (platform === "darwin") {
12
- execSync(`open "${url}"`);
13
- }
14
- else if (platform === "win32") {
15
- execSync(`start "${url}"`);
16
- }
17
- else {
18
- execSync(`xdg-open "${url}"`);
19
- }
20
- }
21
- catch {
22
- log.error(`Could not open browser. Visit: ${url}`);
23
- }
24
- }
25
- //# sourceMappingURL=browse.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"browse.js","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAExC,MAAM,SAAS,GAAG,qDAAqD,CAAA;AAEvE,MAAM,UAAU,MAAM,CAAC,SAAkB;IACxC,MAAM,GAAG,GAAG,SAAS;QACpB,CAAC,CAAC,GAAG,SAAS,IAAI,SAAS,EAAE;QAC7B,CAAC,CAAC,0CAA0C,CAAA;IAC7C,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,CAAA;IAC1B,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACjC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC3B,QAAQ,CAAC,SAAS,GAAG,GAAG,CAAC,CAAA;QAC1B,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC,CAAA;QAC3B,CAAC;aAAM,CAAC;YACP,QAAQ,CAAC,aAAa,GAAG,GAAG,CAAC,CAAA;QAC9B,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,GAAG,CAAC,KAAK,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAA;IACnD,CAAC;AACF,CAAC"}
@@ -1,9 +0,0 @@
1
- import type { PackageManager } from "../utils/detect-pm.js";
2
- export interface CreateOptions {
3
- surface?: string;
4
- skipInstall?: boolean;
5
- skipGit?: boolean;
6
- packageManager?: PackageManager;
7
- }
8
- export declare function create(projectName: string | undefined, options?: CreateOptions): void;
9
- //# sourceMappingURL=create.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,cAAc,CAAA;CAC/B;AAID,wBAAgB,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,aAAkB,GAAG,IAAI,CAkBzF"}
@@ -1,27 +0,0 @@
1
- import { spawnSync } from "node:child_process";
2
- import { log } from "../utils/logger.js";
3
- // create-substrate owns the project templates; this command only forwards to
4
- // it. SUBSTRATE_CREATE_BIN points at a local build of it for testing.
5
- export function create(projectName, options = {}) {
6
- const args = [];
7
- if (projectName)
8
- args.push(projectName);
9
- if (options.surface)
10
- args.push("--surface", options.surface);
11
- if (options.packageManager)
12
- args.push("--pm", options.packageManager);
13
- if (options.skipInstall)
14
- args.push("--skip-install");
15
- if (options.skipGit)
16
- args.push("--skip-git");
17
- const localBin = process.env.SUBSTRATE_CREATE_BIN;
18
- const result = localBin
19
- ? spawnSync("node", [localBin, ...args], { stdio: "inherit" })
20
- : spawnSync("npx", ["--yes", "create-substrate@latest", ...args], { stdio: "inherit" });
21
- if (result.error) {
22
- log.error(`Could not run create-substrate: ${result.error.message}`);
23
- process.exit(1);
24
- }
25
- process.exit(result.status ?? 1);
26
- }
27
- //# sourceMappingURL=create.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAUxC,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,UAAU,MAAM,CAAC,WAA+B,EAAE,UAAyB,EAAE;IAClF,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,IAAI,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACvC,IAAI,OAAO,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5D,IAAI,OAAO,CAAC,cAAc;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IACrE,IAAI,OAAO,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;IACpD,IAAI,OAAO,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAA;IACjD,MAAM,MAAM,GAAG,QAAQ;QACtB,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC9D,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,yBAAyB,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAExF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,GAAG,CAAC,KAAK,CAAC,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAA;AACjC,CAAC"}
@@ -1,4 +0,0 @@
1
- export declare function variables(component: string | undefined, options: {
2
- all?: boolean;
3
- }): Promise<void>;
4
- //# sourceMappingURL=variables.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../src/commands/variables.ts"],"names":[],"mappings":"AAmEA,wBAAsB,SAAS,CAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACxB,OAAO,CAAC,IAAI,CAAC,CAuEf"}
@@ -1,111 +0,0 @@
1
- import { readFileSync, existsSync } from "node:fs";
2
- import { join, dirname } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { log } from "../utils/logger.js";
5
- const __dirname = dirname(fileURLToPath(import.meta.url));
6
- const REGISTRY_URL = "https://substrate.georgedrury.co.uk/registry.json";
7
- async function loadRegistry() {
8
- const localPath = join(process.cwd(), "registry.json");
9
- if (existsSync(localPath)) {
10
- try {
11
- return JSON.parse(readFileSync(localPath, "utf-8"));
12
- }
13
- catch {
14
- /* fall through */
15
- }
16
- }
17
- try {
18
- const res = await fetch(REGISTRY_URL);
19
- if (res.ok)
20
- return (await res.json());
21
- }
22
- catch {
23
- /* fall through */
24
- }
25
- const bundledPaths = [
26
- join(__dirname, "..", "..", "registry.json"),
27
- join(__dirname, "..", "..", "..", "registry.json"),
28
- ];
29
- for (const p of bundledPaths) {
30
- if (existsSync(p)) {
31
- try {
32
- return JSON.parse(readFileSync(p, "utf-8"));
33
- }
34
- catch {
35
- /* fall through */
36
- }
37
- }
38
- }
39
- return null;
40
- }
41
- function extractOverrideKeys(item) {
42
- const theme = item.cssVars?.theme;
43
- if (!theme)
44
- return [];
45
- const keys = [];
46
- for (const value of Object.values(theme)) {
47
- const match = value.match(/^var\(--([^,)]+)/);
48
- if (match)
49
- keys.push(`--${match[1]}`);
50
- }
51
- return keys;
52
- }
53
- export async function variables(component, options) {
54
- const registry = await loadRegistry();
55
- if (!registry) {
56
- log.error("Could not load the component registry");
57
- process.exit(1);
58
- }
59
- if (options.all) {
60
- const withVars = registry.items
61
- .map((item) => ({ item, keys: extractOverrideKeys(item) }))
62
- .filter(({ keys }) => keys.length > 0)
63
- .sort((a, b) => a.item.name.localeCompare(b.item.name));
64
- if (withVars.length === 0) {
65
- log.info("No components have theme variables");
66
- return;
67
- }
68
- log.blank();
69
- log.info(`${withVars.length} components with theme variables:`);
70
- log.blank();
71
- for (const { item, keys } of withVars) {
72
- console.log(` ${item.name}`);
73
- for (const key of keys) {
74
- console.log(` ${key}`);
75
- }
76
- console.log();
77
- }
78
- return;
79
- }
80
- if (!component) {
81
- log.error("Provide a component name, e.g. substrate variables panel");
82
- log.info("Use --all to list every component's variables");
83
- process.exit(1);
84
- }
85
- const item = registry.items.find((i) => i.name.toLowerCase() === component.toLowerCase());
86
- if (!item) {
87
- log.error(`Component "${component}" not found`);
88
- const query = component.toLowerCase();
89
- const suggestions = registry.items
90
- .filter((i) => i.name.toLowerCase().includes(query))
91
- .slice(0, 5);
92
- if (suggestions.length > 0) {
93
- log.info("Did you mean:");
94
- for (const s of suggestions) {
95
- console.log(` ${s.name}`);
96
- }
97
- }
98
- process.exit(1);
99
- }
100
- const keys = extractOverrideKeys(item);
101
- if (keys.length === 0) {
102
- log.info("No theme variables — this component uses base theme values only");
103
- return;
104
- }
105
- log.blank();
106
- for (const key of keys) {
107
- console.log(` ${key}`);
108
- }
109
- log.blank();
110
- }
111
- //# sourceMappingURL=variables.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variables.js","sourceRoot":"","sources":["../../src/commands/variables.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { Registry } from "./types.js";
2
- export declare function loadRegistry(): Promise<Registry>;
3
- //# sourceMappingURL=registry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAK1C,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAmCtD"}
@@ -1,43 +0,0 @@
1
- import { readFileSync, existsSync } from "node:fs";
2
- import { join, dirname } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- const __dirname = dirname(fileURLToPath(import.meta.url));
5
- const REGISTRY_URL = "https://substrate.georgedrury.co.uk/registry.json";
6
- export async function loadRegistry() {
7
- // Try local
8
- const localPath = join(process.cwd(), "registry.json");
9
- if (existsSync(localPath)) {
10
- try {
11
- return JSON.parse(readFileSync(localPath, "utf-8"));
12
- }
13
- catch {
14
- /* fall through */
15
- }
16
- }
17
- // Try remote
18
- try {
19
- const res = await fetch(REGISTRY_URL);
20
- if (res.ok)
21
- return (await res.json());
22
- }
23
- catch {
24
- /* fall through */
25
- }
26
- // Try bundled
27
- const bundledPaths = [
28
- join(__dirname, "..", "..", "registry.json"),
29
- join(__dirname, "..", "..", "..", "registry.json"),
30
- ];
31
- for (const p of bundledPaths) {
32
- if (existsSync(p)) {
33
- try {
34
- return JSON.parse(readFileSync(p, "utf-8"));
35
- }
36
- catch {
37
- /* fall through */
38
- }
39
- }
40
- }
41
- throw new Error("Could not load Substrate registry");
42
- }
43
- //# sourceMappingURL=registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,YAAY,GAAG,mDAAmD,CAAA;AAExE,MAAM,CAAC,KAAK,UAAU,YAAY;IACjC,YAAY;IACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAA;IACtD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;QACpD,CAAC;QAAC,MAAM,CAAC;YACR,kBAAkB;QACnB,CAAC;IACF,CAAC;IAED,aAAa;IACb,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,CAAA;QACrC,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAa,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACR,kBAAkB;IACnB,CAAC;IAED,cAAc;IACd,MAAM,YAAY,GAAG;QACpB,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC;KAClD,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC9B,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACR,kBAAkB;YACnB,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;AACrD,CAAC"}
@@ -1,10 +0,0 @@
1
- import type { Registry } from "../types.js";
2
- export declare function handleGetThemeVariables(registry: Registry, args: {
3
- components?: string[];
4
- }): Promise<{
5
- content: {
6
- type: "text";
7
- text: string;
8
- }[];
9
- }>;
10
- //# sourceMappingURL=theme.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,aAAa,CAAA;AAazD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;;;;;GA2BhC"}
@@ -1,37 +0,0 @@
1
- function extractOverrideKeys(item) {
2
- const theme = item.cssVars?.theme;
3
- if (!theme)
4
- return [];
5
- const keys = [];
6
- for (const value of Object.values(theme)) {
7
- const match = value.match(/^var\(--([^,)]+)/);
8
- if (match)
9
- keys.push(`--${match[1]}`);
10
- }
11
- return keys;
12
- }
13
- export async function handleGetThemeVariables(registry, args) {
14
- let items = registry.items;
15
- if (args.components && args.components.length > 0) {
16
- const names = new Set(args.components.map((n) => n.toLowerCase()));
17
- items = items.filter((i) => names.has(i.name.toLowerCase()));
18
- }
19
- const result = {};
20
- for (const item of items) {
21
- if (!item.cssVars)
22
- continue;
23
- result[item.name] = {
24
- cssVars: item.cssVars,
25
- overrideKeys: extractOverrideKeys(item),
26
- };
27
- }
28
- return {
29
- content: [
30
- {
31
- type: "text",
32
- text: JSON.stringify(result, null, 2),
33
- },
34
- ],
35
- };
36
- }
37
- //# sourceMappingURL=theme.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../../src/mcp/tools/theme.ts"],"names":[],"mappings":"AAEA,SAAS,mBAAmB,CAAC,IAAkB;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAA;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA;QAC7C,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAkB,EAClB,IAA+B;IAE/B,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAA;IAE1B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAClE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,MAAM,GAAoF,EAAE,CAAA;IAElG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,SAAQ;QAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAClB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY,EAAE,mBAAmB,CAAC,IAAI,CAAC;SACxC,CAAA;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACtC;SACF;KACF,CAAA;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACjD,CAAA;IACD,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAC9B,CAAA;IACD,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB"}
package/dist/mcp/types.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":""}