@agimon-ai/style-system 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,52 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: AgiFlow
6
+ Licensed Work: @agimon-ai/public-packages
7
+ The Licensed Work is (c) 2026 AgiFlow.
8
+ Additional Use Grant: None
9
+ Change Date: 2030-03-06
10
+ Change License: Apache License, Version 2.0
11
+
12
+ Terms
13
+
14
+ The Licensor hereby grants you the right to copy, modify, create derivative
15
+ works, redistribute, and make non-production use of the Licensed Work. The
16
+ Licensor may make an Additional Use Grant, above, permitting limited
17
+ production use.
18
+
19
+ Effective on the Change Date, or the fourth anniversary of the first publicly
20
+ available distribution of a specific version of the Licensed Work under this
21
+ License, whichever comes first, the Licensor hereby grants you rights under
22
+ the terms of the Change License, and the rights granted in the paragraph
23
+ above terminate.
24
+
25
+ If your use of the Licensed Work does not comply with the requirements
26
+ currently in effect as described in this License, you must purchase a
27
+ commercial license from the Licensor, its affiliated entities, or authorized
28
+ resellers, or you must refrain from using the Licensed Work.
29
+
30
+ All copies of the original and modified Licensed Work, and derivative works
31
+ of the Licensed Work, are subject to this License. This License applies
32
+ separately for each version of the Licensed Work and the Change Date may vary
33
+ for each version of the Licensed Work released by Licensor.
34
+
35
+ You must conspicuously display this License on each original or modified copy
36
+ of the Licensed Work. If you receive the Licensed Work in original or
37
+ modified form from a third party, the terms and conditions set forth in this
38
+ License apply to your use of that work.
39
+
40
+ Any use of the Licensed Work in violation of this License will automatically
41
+ terminate your rights under this License for the current and all other
42
+ versions of the Licensed Work.
43
+
44
+ This License does not grant you any right in any trademark or logo of
45
+ Licensor or its affiliates (provided that you may use a trademark or logo of
46
+ Licensor as expressly required by this License).
47
+
48
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
49
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
50
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
52
+ TITLE.
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # @agimon-ai/style-system
2
+
3
+ MCP server and CLI for exploring themes, Tailwind CSS classes, and UI components from Storybook, with
4
+ standalone component rendering.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ pnpm add -D @agimon-ai/style-system
10
+ ```
11
+
12
+ ## CLI
13
+
14
+ ```bash
15
+ style-system --help
16
+ ```
17
+
18
+ | Command | Purpose |
19
+ | ------------------------ | ----------------------------------------------------------------------- |
20
+ | `get-css-classes` | Extract the valid CSS classes from a theme CSS file |
21
+ | `get-ui-component` | Render a component to a screenshot using the app's design-system config |
22
+ | `list-app-components` | List app-specific components and package components |
23
+ | `polish-component` | Design-system-aware component polish |
24
+ | `generate-oxlint-config` | Generate an oxlint `no-restricted-classes` config from theme tokens |
25
+ | `mcp-serve` | Run as an MCP server over stdio |
26
+
27
+ ## MCP server
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "style-system": {
33
+ "command": "npx",
34
+ "args": ["-y", "@agimon-ai/style-system", "mcp-serve"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ Configuration lives in files named `style-system.config.yaml`, at two levels:
43
+
44
+ ```
45
+ <workspace-root>/style-system.config.yaml # defines defaults and presets
46
+ <project>/style-system.config.yaml # selects a preset, applies overrides
47
+ ```
48
+
49
+ The workspace root is found by walking up from the current working directory until a `.git`
50
+ directory is found, falling back to the working directory itself. It is your repository root, not
51
+ the installed package location.
52
+
53
+ ### Resolution order
54
+
55
+ ```
56
+ built-in defaults -> root `defaults` -> preset chain (parents before child) -> project config
57
+ ```
58
+
59
+ Last wins, and **fields replace wholesale**. Lists and objects are never merged element-wise, so a
60
+ project that sets `cssFiles` replaces the inherited list entirely. Use `cssFiles: []` to clear one.
61
+
62
+ Every field is optional in any individual file. Required-ness is enforced against the merged result,
63
+ so a project config can be valid while inheriting nearly everything.
64
+
65
+ Both schemas are strict: an unknown or misspelled key is a hard error rather than a silent no-op. The
66
+ project schema additionally rejects `root`, `defaults` and `presets`, so the two file types can never
67
+ be confused for one another.
68
+
69
+ ### Workspace root file
70
+
71
+ ```yaml
72
+ # <workspace-root>/style-system.config.yaml
73
+ root: true # required literal; marks this as the workspace file
74
+
75
+ # Story tags that mark a component as shared/design-system.
76
+ sharedComponentTags:
77
+ - style-system
78
+
79
+ # Optional service overrides. Paths are workspace-root relative.
80
+ # getCssClasses:
81
+ # customService: packages/.../CustomCSSClassesService.ts
82
+ # bundler:
83
+ # customService: packages/.../CustomBundlerService.ts
84
+
85
+ # Applied to every project, beneath its preset chain.
86
+ defaults:
87
+ type: tailwind
88
+ colorScheme: automatic
89
+
90
+ presets:
91
+ web-app:
92
+ viewport: { width: 1280, height: 800 }
93
+ cssFiles: ['src/assets/main.css']
94
+ componentLibrary: '@acme/web-ui'
95
+ mcp-app:
96
+ extends: web-app # presets may extend other presets
97
+ rootComponent: 'src/components/Root/index.tsx'
98
+ native-app:
99
+ bundler: vite-react-native
100
+ unistylesConfig: unistyles.ts
101
+ viewport: { width: 393, height: 852 }
102
+ ```
103
+
104
+ ### Project file
105
+
106
+ ```yaml
107
+ # <project>/style-system.config.yaml
108
+ extends: web-app # a preset name, or a list: [base, overrides]
109
+ viewport: { width: 1440, height: 900 }
110
+ ```
111
+
112
+ ### Fields
113
+
114
+ | Field | Type | Purpose |
115
+ | --------------------- | -------------------------------- | -------------------------------------------------- |
116
+ | `type` | `tailwind` \| `shadcn` | Design system flavour |
117
+ | `bundler` | string | Bundler strategy, e.g. `vite-react-native` |
118
+ | `brand` | string | Brand identifier |
119
+ | `unistylesConfig` | string | Path to the Unistyles config, for native rendering |
120
+ | `colorScheme` | `automatic` \| `light` \| `dark` | Rendering colour scheme |
121
+ | `viewport` | `{ width, height }` | Screenshot viewport, positive integers |
122
+ | `tailwindConfig` | string | Path to a Tailwind config |
123
+ | `themeProvider` | string | Module providing the theme provider component |
124
+ | `rootComponent` | string | Root component wrapped around rendered stories |
125
+ | `cssFiles` | string[] | Stylesheets loaded before rendering |
126
+ | `componentLibrary` | string | Package holding shared components |
127
+ | `themePath` | string | Path to the theme CSS |
128
+ | `sharedComponentTags` | string[] | Story tags marking a component as shared |
129
+
130
+ `bundler` is shape-dependent on level: in `defaults`, a preset, or a project file it is a **string**
131
+ naming the strategy; at the workspace root, alongside `getCssClasses`, it is a **service override
132
+ object** taking `customService`.
133
+
134
+ ## Native rendering
135
+
136
+ Rendering React Native stories additionally requires the application being rendered to provide
137
+ `react-native`, `react-native-unistyles`, `react-native-reanimated`, `@babel/core`,
138
+ `expo-modules-core` and `@expo/vector-icons`. These are resolved from the target application's
139
+ directory, not from this package, so a React Native app already satisfies them.
140
+
141
+ ## Agent skill
142
+
143
+ The published package ships a `skills/style-system` skill describing when and how an agent should use
144
+ these commands.
145
+
146
+ ## License
147
+
148
+ MIT
package/dist/cli.cjs ADDED
@@ -0,0 +1,412 @@
1
+ #!/usr/bin/env node
2
+ const require_stdio = require("./stdio-D8AH3sRD.cjs");
3
+ let node_fs = require("node:fs");
4
+ let node_path = require("node:path");
5
+ node_path = require_stdio.__toESM(node_path, 1);
6
+ let _agimon_ai_foundation_exec = require("@agimon-ai/foundation-exec");
7
+ require("reflect-metadata");
8
+ let commander = require("commander");
9
+ let chalk = require("chalk");
10
+ chalk = require_stdio.__toESM(chalk, 1);
11
+ //#region src/utils/print.ts
12
+ function resolveChalk(value, depth = 0) {
13
+ if (value && (typeof value === "object" || typeof value === "function") && "red" in value && typeof value.red === "function") return value;
14
+ if (depth < 3 && value && (typeof value === "object" || typeof value === "function") && "default" in value) return resolveChalk(value.default, depth + 1);
15
+ throw new Error("Unable to resolve chalk instance");
16
+ }
17
+ const chalk$1 = resolveChalk(chalk);
18
+ const print = {
19
+ info: (message) => {
20
+ console.log(chalk$1.cyan(message));
21
+ },
22
+ success: (message) => {
23
+ console.log(chalk$1.green(message));
24
+ },
25
+ warning: (message) => {
26
+ console.log(chalk$1.yellow(message));
27
+ },
28
+ error: (message, error) => {
29
+ if (error) {
30
+ const errorMsg = error instanceof Error ? error.message : error;
31
+ console.error(chalk$1.red(message), errorMsg);
32
+ } else console.error(chalk$1.red(message));
33
+ },
34
+ debug: (message) => {
35
+ console.log(chalk$1.gray(message));
36
+ },
37
+ header: (message) => {
38
+ console.log(chalk$1.bold.cyan(message));
39
+ },
40
+ item: (message) => {
41
+ console.log(chalk$1.white(` - ${message}`));
42
+ },
43
+ indent: (message) => {
44
+ console.log(chalk$1.white(` ${message}`));
45
+ },
46
+ highlight: (message) => {
47
+ console.log(chalk$1.bold.green(message));
48
+ },
49
+ newline: () => {
50
+ console.log();
51
+ },
52
+ divider: () => {
53
+ console.log(chalk$1.gray(".".repeat(60)));
54
+ }
55
+ };
56
+ //#endregion
57
+ //#region src/commands/generate-oxlint-config.ts
58
+ /**
59
+ * Generate Oxlint Config Command
60
+ *
61
+ * DESIGN PATTERNS:
62
+ * - Command pattern with Commander for CLI argument parsing
63
+ * - Async/await pattern for asynchronous operations
64
+ * - Error handling pattern with try-catch and proper exit codes
65
+ *
66
+ * CODING STANDARDS:
67
+ * - Use async action handlers for asynchronous operations
68
+ * - Provide clear option descriptions and default values
69
+ * - Handle errors gracefully with process.exit()
70
+ * - Log progress and errors to console
71
+ * - Use Commander's .option() and .argument() for inputs
72
+ *
73
+ * AVOID:
74
+ * - Synchronous blocking operations in action handlers
75
+ * - Missing error handling (always use try-catch)
76
+ * - Hardcoded values (use options or environment variables)
77
+ * - Not exiting with appropriate exit codes on errors
78
+ */
79
+ /**
80
+ * Generate oxlint no-restricted-classes config from theme CSS design tokens
81
+ */
82
+ const generateOxlintConfigCommand = new commander.Command("generate-oxlint-config").description("Generate oxlint no-restricted-classes config from theme CSS design tokens").option("-a, --app-path <path>", "App path to read theme path from its style-system.config.yaml").option("-t, --theme-path <path>", "Theme CSS file path relative to workspace root").option("-o, --output <path>", "Output file path (defaults to stdout)").action(async (options) => {
83
+ try {
84
+ const themePath = (options.appPath ? (await require_stdio.getAppDesignSystemConfig(options.appPath)).themePath : void 0) ?? options.themePath;
85
+ if (!themePath) throw new Error("No theme CSS path resolved. Pass --theme-path, or pass --app-path for an app that configures themePath.");
86
+ const resolvedThemePath = await require_stdio.resolveStyleSystemThemePath({
87
+ appPath: options.appPath ?? null,
88
+ themePath
89
+ });
90
+ const cssResult = await new require_stdio.TailwindCSSClassesService(require_stdio.DEFAULT_STYLE_SYSTEM_CONFIG).extractClasses("colors", resolvedThemePath);
91
+ const config = require_stdio.generateRestrictedClassesConfig(cssResult);
92
+ const jsonOutput = JSON.stringify(config, null, 2);
93
+ if (options.output) {
94
+ const outputPath = node_path.default.resolve(options.output);
95
+ await node_fs.promises.writeFile(outputPath, `${jsonOutput}\n`, "utf-8");
96
+ print.success(`Config written to ${outputPath}`);
97
+ } else print.info(jsonOutput);
98
+ } catch (error) {
99
+ print.error("Error generating oxlint config:", error instanceof Error ? error.message : String(error));
100
+ process.exit(1);
101
+ }
102
+ });
103
+ //#endregion
104
+ //#region src/commands/get-css-classes.ts
105
+ /**
106
+ * Get CSS Classes CLI Command
107
+ */
108
+ const getCSSClassesCommand = new commander.Command("get-css-classes").description("Extract and return all valid CSS classes from a theme CSS file").option("-c, --category <category>", "Category filter: 'colors', 'typography', 'spacing', 'effects', 'all'", "all").option("-a, --app-path <path>", "App path to read theme path from style-system.config.yaml (e.g., \"apps/agiflow-app\")").option("-t, --theme-path <path>", "Theme CSS file path relative to workspace root (required unless appPath resolves themePath from style-system.config.yaml)").action(async (options) => {
109
+ try {
110
+ const result = await require_stdio.createContainer({ defaultThemePath: options.themePath }).get(require_stdio.STYLE_SYSTEM_TYPES.GetCSSClassesTool).execute({
111
+ category: options.category,
112
+ appPath: options.appPath
113
+ });
114
+ if (result.isError) {
115
+ const firstContent = result.content[0];
116
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
117
+ throw new Error(errorText);
118
+ }
119
+ const firstContent = result.content[0];
120
+ print.info(firstContent?.type === "text" ? firstContent.text : "");
121
+ } catch (error) {
122
+ print.error("Error getting CSS classes:", error instanceof Error ? error.message : String(error));
123
+ process.exit(1);
124
+ }
125
+ });
126
+ //#endregion
127
+ //#region src/commands/get-ui-component.ts
128
+ /**
129
+ * Get UI Component CLI Command
130
+ */
131
+ const LIGHT_COLOR_SCHEME = "light";
132
+ const DARK_COLOR_SCHEME = "dark";
133
+ const REQUESTABLE_COLOR_SCHEMES = [LIGHT_COLOR_SCHEME, DARK_COLOR_SCHEME];
134
+ const getUiComponentCommand = new commander.Command("get-ui-component").description("Get a screenshot of a UI component rendered with app-specific design system configuration. Returns screenshot path and story file content.").requiredOption("-c, --component-name <name>", "The name of the component to capture (e.g., \"Button\", \"Card\")").requiredOption("-a, --app-path <path>", "The app path (relative or absolute) to load design system config from (e.g., \"apps/agiflow-app\")").option("-s, --story-name <name>", "The story name to render (e.g., \"Playground\", \"Default\")", "Playground").option("-d, --dark-mode", "Request dark mode for automatic-theme apps").option("--color-scheme <scheme>", "Request light or dark mode for automatic-theme apps").option("--width <pixels>", "Override the configured viewport width", Number).option("--height <pixels>", "Override the configured viewport height", Number).action(async (options) => {
135
+ try {
136
+ if (options.colorScheme !== void 0 && !REQUESTABLE_COLOR_SCHEMES.includes(options.colorScheme)) throw new Error("--color-scheme must be light or dark");
137
+ const tool = require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.GetComponentVisualTool);
138
+ const darkMode = options.colorScheme === DARK_COLOR_SCHEME ? true : options.colorScheme === LIGHT_COLOR_SCHEME ? false : options.darkMode || void 0;
139
+ const result = await tool.execute({
140
+ componentName: options.componentName,
141
+ appPath: options.appPath,
142
+ storyName: options.storyName,
143
+ darkMode,
144
+ width: options.width,
145
+ height: options.height
146
+ });
147
+ if (result.isError) {
148
+ const firstContent = result.content[0];
149
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
150
+ throw new Error(errorText);
151
+ }
152
+ const firstContent = result.content[0];
153
+ process.stdout.write(`${firstContent?.type === "text" ? firstContent.text : ""}\n`);
154
+ } catch (error) {
155
+ const errorMessage = error instanceof Error ? error.message : String(error);
156
+ require_stdio.log.error("Error:", errorMessage);
157
+ process.stderr.write(`${errorMessage.startsWith("Error:") ? errorMessage : `Error: ${errorMessage}`}\n`);
158
+ process.exitCode = 1;
159
+ }
160
+ });
161
+ //#endregion
162
+ //#region src/commands/list-app-components.ts
163
+ /**
164
+ * List App Components CLI Command
165
+ */
166
+ const listAppComponentsCommand = new commander.Command("list-app-components").description("List app-specific components and package components. Reads the app's package.json to find workspace dependencies.").requiredOption("-a, --app-path <path>", "The app path (relative or absolute) to list components for (e.g., \"apps/agiflow-app\")").option("-c, --cursor <cursor>", "Pagination cursor to fetch the next page").action(async (options) => {
167
+ try {
168
+ const result = await require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.ListAppComponentsTool).execute({
169
+ appPath: options.appPath,
170
+ cursor: options.cursor
171
+ });
172
+ if (result.isError) {
173
+ const firstContent = result.content[0];
174
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
175
+ throw new Error(errorText);
176
+ }
177
+ const firstContent = result.content[0];
178
+ print.info(firstContent?.type === "text" ? firstContent.text : "");
179
+ } catch (error) {
180
+ print.error("Error:", error instanceof Error ? error.message : String(error));
181
+ process.exit(1);
182
+ }
183
+ });
184
+ //#endregion
185
+ //#region src/commands/list-themes.ts
186
+ /**
187
+ * List Themes Command
188
+ *
189
+ * DESIGN PATTERNS:
190
+ * - Command pattern with Commander for CLI argument parsing
191
+ * - Async/await pattern for asynchronous operations
192
+ * - Error handling pattern with try-catch and proper exit codes
193
+ *
194
+ * CODING STANDARDS:
195
+ * - Use async action handlers for asynchronous operations
196
+ * - Provide clear option descriptions and default values
197
+ * - Handle errors gracefully with process.exit()
198
+ * - Log progress and errors to console
199
+ * - Use Commander's .option() and .argument() for inputs
200
+ *
201
+ * AVOID:
202
+ * - Synchronous blocking operations in action handlers
203
+ * - Missing error handling (always use try-catch)
204
+ * - Hardcoded values (use options or environment variables)
205
+ * - Not exiting with appropriate exit codes on errors
206
+ */
207
+ /**
208
+ * List all available theme configurations from CSS files
209
+ */
210
+ const listThemesCommand = new commander.Command("list-themes").description("List all available theme configurations from CSS files configured in style-system.config.yaml").option("-a, --app-path <path>", "App path to read theme config from style-system.config.yaml (e.g., \"apps/my-app\")").action(async (options) => {
211
+ try {
212
+ const result = await require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.ListThemesTool).execute({ appPath: options.appPath });
213
+ if (result.isError) {
214
+ const firstContent = result.content[0];
215
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
216
+ throw new Error(errorText);
217
+ }
218
+ const firstContent = result.content[0];
219
+ print.info(firstContent?.type === "text" ? firstContent.text : "");
220
+ } catch (error) {
221
+ print.error("Error listing themes:", error instanceof Error ? error.message : String(error));
222
+ process.exit(1);
223
+ }
224
+ });
225
+ //#endregion
226
+ //#region src/commands/list-shared-components.ts
227
+ /**
228
+ * List Shared Components CLI Command
229
+ */
230
+ const listSharedComponentsCommand = new commander.Command("list-shared-components").description("List all shared UI components available in the design system").option("-c, --cursor <cursor>", "Pagination cursor to fetch the next page").action(async (options) => {
231
+ try {
232
+ const result = await require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.ListSharedComponentsTool).execute({ cursor: options.cursor });
233
+ if (result.isError) {
234
+ const firstContent = result.content[0];
235
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
236
+ throw new Error(errorText);
237
+ }
238
+ const firstContent = result.content[0];
239
+ print.info(firstContent?.type === "text" ? firstContent.text : "");
240
+ } catch (error) {
241
+ print.error("Error listing shared components:", error instanceof Error ? error.message : String(error));
242
+ process.exit(1);
243
+ }
244
+ });
245
+ //#endregion
246
+ //#region src/commands/mcp-serve.ts
247
+ /**
248
+ * MCP Serve Command
249
+ *
250
+ * DESIGN PATTERNS:
251
+ * - Command pattern with Commander for CLI argument parsing
252
+ * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
253
+ * - Factory pattern for creating transport handlers
254
+ * - Graceful shutdown pattern with signal handling
255
+ *
256
+ * CODING STANDARDS:
257
+ * - Use async/await for asynchronous operations
258
+ * - Implement proper error handling with try-catch blocks
259
+ * - Handle process signals for graceful shutdown
260
+ * - Provide clear CLI options and help messages
261
+ *
262
+ * AVOID:
263
+ * - Hardcoded configuration values (use CLI options or environment variables)
264
+ * - Missing error handling for transport startup
265
+ * - Not cleaning up resources on shutdown
266
+ */
267
+ /**
268
+ * Start MCP server with given transport handler
269
+ */
270
+ async function startServer(handler, bundlerService, devServerPort) {
271
+ await handler.start();
272
+ let releaseProcess = async () => {};
273
+ try {
274
+ releaseProcess = await (0, _agimon_ai_foundation_exec.registerManagedProcess)({
275
+ repositoryPath: process.cwd(),
276
+ serviceName: "style-system-mcp",
277
+ serviceType: "tool",
278
+ environment: process.env["NODE_ENV"] ?? "development",
279
+ pid: process.pid,
280
+ port: devServerPort,
281
+ command: "style-system mcp-serve",
282
+ killOnRelease: true,
283
+ releasePortOnRelease: false,
284
+ metadata: devServerPort ? { devServerPort } : {}
285
+ });
286
+ } catch {}
287
+ const shutdown = async (signal) => {
288
+ console.error(`\nReceived ${signal}, shutting down gracefully...`);
289
+ try {
290
+ if (bundlerService.isServerRunning()) {
291
+ console.error("Stopping bundler dev server...");
292
+ await bundlerService.cleanup();
293
+ }
294
+ await releaseProcess();
295
+ await handler.stop();
296
+ process.exit(0);
297
+ } catch (error) {
298
+ console.error("Error during shutdown:", error);
299
+ process.exit(1);
300
+ }
301
+ };
302
+ process.on("SIGINT", () => shutdown("SIGINT"));
303
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
304
+ }
305
+ /**
306
+ * MCP Serve command
307
+ *
308
+ * Note: Design system configuration is now app-specific and read from each app's project.json.
309
+ * No global theme configuration is needed at the server level.
310
+ */
311
+ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio", "stdio").option("--theme-path <path>", "Theme CSS file path relative to workspace root for get-css-classes when app config does not define style-system.themePath").option("--dev", "Start Vite dev server for component hot reload and caching").option("--app-path <path>", "App path for dev server (e.g., apps/agiflow-app)").action(async (options) => {
312
+ try {
313
+ const transportType = options.type.toLowerCase();
314
+ let devServerPort;
315
+ const bundlerService = await require_stdio.getBundlerServiceFromConfig();
316
+ if (options.dev) {
317
+ if (!options.appPath) {
318
+ console.error("Error: --app-path is required when using --dev flag");
319
+ console.error(`Example: ${require_stdio.STYLE_SYSTEM_CLI_NAME} mcp-serve --dev --app-path apps/agiflow-app`);
320
+ process.exit(1);
321
+ }
322
+ const { url, port } = await bundlerService.startDevServer(options.appPath);
323
+ devServerPort = port;
324
+ console.error(`Dev server started at ${url} (port: ${port})`);
325
+ }
326
+ if (transportType === "stdio") {
327
+ const container = require_stdio.createContainer({ defaultThemePath: options.themePath });
328
+ const server = require_stdio.createServer(container);
329
+ await startServer(new require_stdio.StdioTransportHandler(server), bundlerService, devServerPort);
330
+ } else {
331
+ console.error(`Unknown transport type: ${transportType}. Use: stdio`);
332
+ process.exit(1);
333
+ }
334
+ } catch (error) {
335
+ console.error("Failed to start MCP server:", error);
336
+ process.exit(1);
337
+ }
338
+ });
339
+ //#endregion
340
+ //#region src/commands/polish-component.ts
341
+ /**
342
+ * Polish Component Command
343
+ *
344
+ * DESIGN PATTERNS:
345
+ * - Command pattern with Commander for CLI argument parsing
346
+ * - Async/await pattern for asynchronous operations
347
+ * - Error handling pattern with try-catch and proper exit codes
348
+ *
349
+ * CODING STANDARDS:
350
+ * - Use async action handlers for asynchronous operations
351
+ * - Handle errors gracefully with process.exit()
352
+ *
353
+ * AVOID:
354
+ * - Synchronous blocking operations in action handlers
355
+ * - Missing error handling (always use try-catch)
356
+ * - Hardcoded values (use options or environment variables)
357
+ */
358
+ const polishComponentCommand = new commander.Command("polish-component").description("Polish a UI component using Antigravity with design system context").argument("<file>", "Path to the component .tsx file to polish").option("-i, --instructions <text>", "Specific polishing instructions (e.g., \"improve spacing\")").action(async (file, options) => {
359
+ try {
360
+ const result = await require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.PolishComponentTool).execute({
361
+ filePath: file,
362
+ instructions: options.instructions
363
+ });
364
+ if (result.isError) {
365
+ const firstContent = result.content[0];
366
+ const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
367
+ throw new Error(errorText);
368
+ }
369
+ for (const content of result.content) if (content.type === "text") console.error(content.text);
370
+ } catch (error) {
371
+ console.error("Error:", error instanceof Error ? error.message : String(error));
372
+ process.exit(1);
373
+ }
374
+ });
375
+ //#endregion
376
+ //#region src/cli.ts
377
+ /**
378
+ * MCP Server CLI Entry Point
379
+ *
380
+ * DESIGN PATTERNS:
381
+ * - CLI pattern with Commander for argument parsing
382
+ * - Command pattern for organizing CLI commands
383
+ * - Transport abstraction for multiple communication methods
384
+ *
385
+ * CODING STANDARDS:
386
+ * - Use async/await for asynchronous operations
387
+ * - Handle errors gracefully with try-catch
388
+ * - Log important events for debugging
389
+ * - Register all commands in main entry point
390
+ *
391
+ * AVOID:
392
+ * - Hardcoding command logic in index.ts (use separate command files)
393
+ * - Missing error handling for command execution
394
+ */
395
+ /**
396
+ * Main entry point
397
+ */
398
+ async function main() {
399
+ const program = new commander.Command();
400
+ program.name(require_stdio.STYLE_SYSTEM_CLI_NAME).description("MCP server for design system tools").version(require_stdio.STYLE_SYSTEM_VERSION);
401
+ program.addCommand(generateOxlintConfigCommand);
402
+ program.addCommand(getCSSClassesCommand);
403
+ program.addCommand(getUiComponentCommand);
404
+ program.addCommand(listAppComponentsCommand);
405
+ program.addCommand(listThemesCommand);
406
+ program.addCommand(listSharedComponentsCommand);
407
+ program.addCommand(mcpServeCommand);
408
+ program.addCommand(polishComponentCommand);
409
+ await program.parseAsync(process.argv);
410
+ }
411
+ main();
412
+ //#endregion
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ import "reflect-metadata";
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ import "reflect-metadata";