@agimon-ai/po-style-system-tooling 0.2.14-alpha.3 → 0.2.14-alpha.30

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 CHANGED
@@ -21,7 +21,6 @@ style-system --help
21
21
  | `get-css-classes` | Extract the valid CSS classes from a theme CSS file |
22
22
  | `get-ui-component` | Render a component to a screenshot using the app's design-system config |
23
23
  | `list-app-components` | List app-specific components and package components |
24
- | `polish-component` | Design-system-aware component polish |
25
24
  | `generate-oxlint-config` | Generate an oxlint `no-restricted-classes` config from theme tokens |
26
25
  | `mcp-serve` | Run as an MCP server over stdio |
27
26
 
package/dist/cli.cjs CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- const require_stdio = require("./stdio-BiO1Kn_N.cjs");
2
+ const require_stdio = require("./stdio-Bu0NEnig.cjs");
3
3
  let node_fs = require("node:fs");
4
4
  let node_path = require("node:path");
5
5
  node_path = require_stdio.__toESM(node_path, 1);
6
6
  let zod = require("zod");
7
- let _agimon_ai_foundation_exec = require("@agimon-ai/foundation-exec");
8
7
  let _modelcontextprotocol_server = require("@modelcontextprotocol/server");
9
8
  require("reflect-metadata");
10
9
  let commander = require("commander");
11
10
  let chalk = require("chalk");
12
11
  chalk = require_stdio.__toESM(chalk, 1);
12
+ let _agimon_ai_foundation_exec = require("@agimon-ai/foundation-exec");
13
13
  let node_http = require("node:http");
14
14
  let _modelcontextprotocol_node = require("@modelcontextprotocol/node");
15
15
  //#region src/utils/print.ts
@@ -425,42 +425,6 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
425
425
  }
426
426
  });
427
427
  //#endregion
428
- //#region src/commands/polish-component.ts
429
- /**
430
- * Polish Component Command
431
- *
432
- * DESIGN PATTERNS:
433
- * - Command pattern with Commander for CLI argument parsing
434
- * - Async/await pattern for asynchronous operations
435
- * - Error handling pattern with try-catch and proper exit codes
436
- *
437
- * CODING STANDARDS:
438
- * - Use async action handlers for asynchronous operations
439
- * - Handle errors gracefully with process.exit()
440
- *
441
- * AVOID:
442
- * - Synchronous blocking operations in action handlers
443
- * - Missing error handling (always use try-catch)
444
- * - Hardcoded values (use options or environment variables)
445
- */
446
- 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) => {
447
- try {
448
- const result = await require_stdio.createContainer().get(require_stdio.STYLE_SYSTEM_TYPES.PolishComponentTool).execute({
449
- filePath: file,
450
- instructions: options.instructions
451
- });
452
- if (result.isError) {
453
- const firstContent = result.content[0];
454
- const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
455
- throw new Error(errorText);
456
- }
457
- for (const content of result.content) if (content.type === "text") console.error(content.text);
458
- } catch (error) {
459
- console.error("Error:", error instanceof Error ? error.message : String(error));
460
- process.exit(1);
461
- }
462
- });
463
- //#endregion
464
428
  //#region src/cli.ts
465
429
  /**
466
430
  * MCP Server CLI Entry Point
@@ -493,7 +457,6 @@ async function main() {
493
457
  program.addCommand(listThemesCommand);
494
458
  program.addCommand(listSharedComponentsCommand);
495
459
  program.addCommand(mcpServeCommand);
496
- program.addCommand(polishComponentCommand);
497
460
  await program.parseAsync(process.argv);
498
461
  }
499
462
  main();
package/dist/cli.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { A as STYLE_SYSTEM_TYPES, C as getAppDesignSystemConfig, N as DEFAULT_STYLE_SYSTEM_CONFIG, P as TailwindCSSClassesService, R as log, a as STYLE_SYSTEM_CLI_NAME, b as getBundlerServiceFromConfig, i as createServer$1, k as resolveStyleSystemThemePath, o as STYLE_SYSTEM_VERSION, r as generateRestrictedClassesConfig, s as createContainer, t as StdioTransportHandler } from "./stdio-B2oCIjrt.mjs";
2
+ import { A as resolveStyleSystemThemePath, B as STYLE_SYSTEM_TYPES, F as TailwindCSSClassesService, P as DEFAULT_STYLE_SYSTEM_CONFIG, a as STYLE_SYSTEM_CLI_NAME, i as createServer$1, o as STYLE_SYSTEM_VERSION, r as generateRestrictedClassesConfig, s as createContainer, t as StdioTransportHandler, w as getAppDesignSystemConfig, y as getBundlerServiceFromConfig, z as log } from "./stdio-CSCT2Hj0.mjs";
3
3
  import { promises } from "node:fs";
4
4
  import path, { join } from "node:path";
5
5
  import { z } from "zod";
6
- import { registerManagedProcess } from "@agimon-ai/foundation-exec";
7
6
  import { createMcpHandler } from "@modelcontextprotocol/server";
8
7
  import "reflect-metadata";
9
8
  import { Command } from "commander";
10
9
  import * as chalkImport from "chalk";
10
+ import { registerManagedProcess } from "@agimon-ai/foundation-exec";
11
11
  import { createServer } from "node:http";
12
12
  import { localhostHostValidation, localhostOriginValidation, toNodeHandler } from "@modelcontextprotocol/node";
13
13
  //#region src/utils/print.ts
@@ -423,42 +423,6 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
423
423
  }
424
424
  });
425
425
  //#endregion
426
- //#region src/commands/polish-component.ts
427
- /**
428
- * Polish Component Command
429
- *
430
- * DESIGN PATTERNS:
431
- * - Command pattern with Commander for CLI argument parsing
432
- * - Async/await pattern for asynchronous operations
433
- * - Error handling pattern with try-catch and proper exit codes
434
- *
435
- * CODING STANDARDS:
436
- * - Use async action handlers for asynchronous operations
437
- * - Handle errors gracefully with process.exit()
438
- *
439
- * AVOID:
440
- * - Synchronous blocking operations in action handlers
441
- * - Missing error handling (always use try-catch)
442
- * - Hardcoded values (use options or environment variables)
443
- */
444
- const polishComponentCommand = new 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) => {
445
- try {
446
- const result = await createContainer().get(STYLE_SYSTEM_TYPES.PolishComponentTool).execute({
447
- filePath: file,
448
- instructions: options.instructions
449
- });
450
- if (result.isError) {
451
- const firstContent = result.content[0];
452
- const errorText = firstContent?.type === "text" ? firstContent.text : "Unknown error";
453
- throw new Error(errorText);
454
- }
455
- for (const content of result.content) if (content.type === "text") console.error(content.text);
456
- } catch (error) {
457
- console.error("Error:", error instanceof Error ? error.message : String(error));
458
- process.exit(1);
459
- }
460
- });
461
- //#endregion
462
426
  //#region src/cli.ts
463
427
  /**
464
428
  * Main entry point
@@ -473,7 +437,6 @@ async function main() {
473
437
  program.addCommand(listThemesCommand);
474
438
  program.addCommand(listSharedComponentsCommand);
475
439
  program.addCommand(mcpServeCommand);
476
- program.addCommand(polishComponentCommand);
477
440
  await program.parseAsync(process.argv);
478
441
  }
479
442
  main();
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_stdio = require("./stdio-BiO1Kn_N.cjs");
2
+ const require_stdio = require("./stdio-Bu0NEnig.cjs");
3
3
  let node_fs = require("node:fs");
4
4
  let node_path = require("node:path");
5
5
  node_path = require_stdio.__toESM(node_path, 1);
@@ -16,7 +16,7 @@ var StoryPreviewService = class {
16
16
  bundlerFactory;
17
17
  previews = /* @__PURE__ */ new Map();
18
18
  constructor(options = {}) {
19
- this.workspaceRoot = node_path.default.resolve(options.workspaceRoot ?? require_stdio.TemplatesManagerService.getWorkspaceRootSync());
19
+ this.workspaceRoot = options.workspaceRoot !== void 0 ? Promise.resolve(node_path.default.resolve(options.workspaceRoot)) : void 0;
20
20
  this.storiesIndexFactory = options.storiesIndexFactory ?? ((workspaceRoot, storyFilePath) => new require_stdio.StoriesIndexService({
21
21
  workspaceRoot,
22
22
  storyFiles: [storyFilePath],
@@ -27,7 +27,8 @@ var StoryPreviewService = class {
27
27
  }
28
28
  async build(input) {
29
29
  if (!STORY_EXPORT_PATTERN.test(input.storyExport)) throw new Error("storyExport must be an exact JavaScript named export");
30
- const workspaceRoot = await node_fs.promises.realpath(this.workspaceRoot);
30
+ const root = await (this.workspaceRoot ??= require_stdio.TemplatesManagerService.getWorkspaceRoot());
31
+ const workspaceRoot = await node_fs.promises.realpath(root);
31
32
  const appPath = await this.resolveContainedPath(workspaceRoot, input.appPath, "appPath");
32
33
  const storyFilePath = await this.resolveContainedPath(workspaceRoot, input.storyFilePath, "storyFilePath");
33
34
  if (!STORY_FILE_PATTERN.test(storyFilePath)) throw new Error("storyFilePath must name a .stories.ts or .stories.tsx file");
@@ -87,6 +88,244 @@ var StoryPreviewService = class {
87
88
  }
88
89
  };
89
90
  //#endregion
91
+ //#region src/utils/storyBrowser.ts
92
+ const BROWSER_IDLE_MS = 18e5;
93
+ /** Server-owned Chrome. Each capture borrows it until its context cleanup settles. */
94
+ function createStoryBrowser() {
95
+ let pending;
96
+ let closing;
97
+ let timer;
98
+ let active = 0;
99
+ let disposed = false;
100
+ let drained = Promise.resolve();
101
+ let resolveDrained;
102
+ const clearIdle = () => {
103
+ clearTimeout(timer);
104
+ timer = void 0;
105
+ };
106
+ const close = () => {
107
+ if (closing) return closing;
108
+ const generation = pending;
109
+ if (!generation) return Promise.resolve();
110
+ closing = generation.then((browser) => browser.close()).then(() => {
111
+ if (pending === generation) pending = void 0;
112
+ }).finally(() => {
113
+ closing = void 0;
114
+ });
115
+ return closing;
116
+ };
117
+ const idle = () => {
118
+ if (disposed || active !== 0 || !pending) return;
119
+ clearIdle();
120
+ const generation = pending;
121
+ timer = setTimeout(() => {
122
+ timer = void 0;
123
+ if (active !== 0 || pending !== generation) return;
124
+ close().catch((error) => {
125
+ require_stdio.log.error("[story-browser] Idle close failed:", error);
126
+ idle();
127
+ });
128
+ }, BROWSER_IDLE_MS);
129
+ timer.unref();
130
+ };
131
+ return {
132
+ async acquire() {
133
+ if (disposed) throw new Error("The story browser is shut down.");
134
+ clearIdle();
135
+ if (active++ === 0) drained = new Promise((resolve) => {
136
+ resolveDrained = resolve;
137
+ });
138
+ let released = false;
139
+ const release = () => {
140
+ if (released) return;
141
+ released = true;
142
+ if (--active === 0) {
143
+ resolveDrained?.();
144
+ idle();
145
+ }
146
+ };
147
+ try {
148
+ if (closing) await closing;
149
+ if (disposed) throw new Error("The story browser is shut down.");
150
+ if (!pending) {
151
+ const generation = require_stdio.launchBrowserWithFallback().then((browser) => {
152
+ browser.once("disconnected", () => {
153
+ if (pending === generation) {
154
+ pending = void 0;
155
+ clearIdle();
156
+ }
157
+ });
158
+ return browser;
159
+ }).catch((error) => {
160
+ if (pending === generation) pending = void 0;
161
+ throw error;
162
+ });
163
+ pending = generation;
164
+ }
165
+ const browser = await pending;
166
+ if (disposed) throw new Error("The story browser is shut down.");
167
+ return {
168
+ browser,
169
+ release
170
+ };
171
+ } catch (error) {
172
+ release();
173
+ throw error;
174
+ }
175
+ },
176
+ async dispose() {
177
+ disposed = true;
178
+ clearIdle();
179
+ await drained;
180
+ await close();
181
+ }
182
+ };
183
+ }
184
+ //#endregion
185
+ //#region src/services/WarmStoryRenderer/WarmStoryRenderer.ts
186
+ /** The style-system tools a warm host exposes, by tool name. */
187
+ const WARM_RENDERER_TOOLS = {
188
+ get_component_visual: require_stdio.STYLE_SYSTEM_TYPES.GetComponentVisualTool,
189
+ get_css_classes: require_stdio.STYLE_SYSTEM_TYPES.GetCSSClassesTool,
190
+ list_themes: require_stdio.STYLE_SYSTEM_TYPES.ListThemesTool,
191
+ list_shared_components: require_stdio.STYLE_SYSTEM_TYPES.ListSharedComponentsTool,
192
+ list_app_components: require_stdio.STYLE_SYSTEM_TYPES.ListAppComponentsTool
193
+ };
194
+ /** Long enough to cover an edit-and-render loop; an idle dev server still holds its module graph and watchers. */
195
+ const IDLE_CLOSE_MS = 6e5;
196
+ /**
197
+ * Keeps one browser and one Vite dev server warm across renders, so a render after the first
198
+ * skips the browser launch and the static build. Rendered screenshots come back as base64.
199
+ * After IDLE_CLOSE_MS without a call it stops them; the next call starts them again.
200
+ */
201
+ function createWarmStoryRenderer(options = {}) {
202
+ const workspaceRoot = options.workspaceRoot ? node_path.default.resolve(options.workspaceRoot) : void 0;
203
+ let browser;
204
+ const sharedBrowser = () => {
205
+ browser ??= require_stdio.launchBrowserWithFallback().catch((error) => {
206
+ browser = void 0;
207
+ throw error;
208
+ });
209
+ return browser;
210
+ };
211
+ let activeBundler;
212
+ const bundlers = /* @__PURE__ */ new Map();
213
+ const container = require_stdio.createContainer({
214
+ ...options,
215
+ workspaceRoot,
216
+ sharedBrowser: options.sharedBrowser ?? sharedBrowser,
217
+ bundlerFactory: () => {
218
+ if (!activeBundler) throw new Error("The story bundler has not been initialized.");
219
+ return activeBundler;
220
+ }
221
+ });
222
+ const configLoader = container.get(require_stdio.STYLE_SYSTEM_TYPES.StyleSystemConfigLoader);
223
+ const createBundler = (config) => config.bundler ? require_stdio.getBundlerService(config.bundler, workspaceRoot) : require_stdio.createDefaultBundlerService(workspaceRoot);
224
+ let queue = Promise.resolve();
225
+ let disposed = false;
226
+ let captures = 0;
227
+ let inFlight = 0;
228
+ let idleTimer;
229
+ const ensureDevServer = async (appPath) => {
230
+ const resolved = node_path.default.resolve(workspaceRoot ?? ".", appPath);
231
+ const { config } = await configLoader.resolveProject(resolved);
232
+ const key = config.bundler ?? "vite-react";
233
+ let pending = bundlers.get(key);
234
+ if (!pending) {
235
+ pending = workspaceRoot ? require_stdio.getBundlerServiceFromConfig({
236
+ workspaceRoot,
237
+ configLoader,
238
+ defaultFactory: () => createBundler(config)
239
+ }) : Promise.resolve(createBundler(config));
240
+ bundlers.set(key, pending);
241
+ pending.catch(() => bundlers.delete(key));
242
+ }
243
+ const bundler = await pending;
244
+ if (activeBundler && activeBundler !== bundler && activeBundler.isServerRunning()) await activeBundler.cleanup();
245
+ activeBundler = bundler;
246
+ const recycle = bundler.getBundlerId() === "vite" && captures >= 100;
247
+ if (bundler.isServerRunning() && bundler.getCurrentAppPath() === resolved && !recycle) return;
248
+ if (bundler.isServerRunning()) await bundler.cleanup();
249
+ captures = 0;
250
+ await bundler.startDevServer(resolved);
251
+ };
252
+ const reset = async () => {
253
+ const open = browser;
254
+ browser = void 0;
255
+ captures = 0;
256
+ await Promise.allSettled([open?.then((instance) => instance.close()), ...[...bundlers.values()].map((pending) => pending.then((bundler) => bundler.cleanup()))]);
257
+ };
258
+ const run = async (tool, input) => {
259
+ if (disposed) throw new Error("The story renderer is shut down.");
260
+ if (workspaceRoot && typeof input.appPath === "string") {
261
+ const [root, appPath] = await Promise.all([node_fs.promises.realpath(workspaceRoot), node_fs.promises.realpath(node_path.default.resolve(workspaceRoot, input.appPath))]);
262
+ if (!require_stdio.isContained(root, appPath)) throw new Error("appPath must remain inside the configured workspace root.");
263
+ input = {
264
+ ...input,
265
+ appPath
266
+ };
267
+ }
268
+ const visualAppPath = tool === "get_component_visual" && typeof input.appPath === "string" ? input.appPath : void 0;
269
+ const execute = async () => {
270
+ if (visualAppPath) {
271
+ await ensureDevServer(visualAppPath);
272
+ captures++;
273
+ }
274
+ const result = await container.get(WARM_RENDERER_TOOLS[tool]).execute(input);
275
+ return {
276
+ result,
277
+ text: result.content.flatMap((item) => item.type === "text" && item.text ? [item.text] : []).join("\n\n")
278
+ };
279
+ };
280
+ let { result, text } = await execute();
281
+ if (visualAppPath && result.isError && text.includes("Failed to render component")) {
282
+ await reset();
283
+ ({result, text} = await execute());
284
+ }
285
+ const images = [];
286
+ if (tool === "get_component_visual" && !result.isError) {
287
+ const imagePath = /"imagePath":\s*"([^"]+)"/u.exec(text)?.[1];
288
+ if (imagePath) images.push({
289
+ data: (await node_fs.promises.readFile(imagePath)).toString("base64"),
290
+ mimeType: "image/png"
291
+ });
292
+ }
293
+ return {
294
+ text,
295
+ images,
296
+ isError: result.isError === true
297
+ };
298
+ };
299
+ const enqueue = (task) => {
300
+ const next = queue.then(task);
301
+ queue = next.catch(() => void 0);
302
+ return next;
303
+ };
304
+ const armIdleClose = () => {
305
+ if (--inFlight > 0 || disposed) return;
306
+ idleTimer = setTimeout(() => void enqueue(reset), IDLE_CLOSE_MS);
307
+ idleTimer.unref();
308
+ };
309
+ return {
310
+ call(tool, input) {
311
+ clearTimeout(idleTimer);
312
+ inFlight++;
313
+ const next = enqueue(() => run(tool, input));
314
+ next.then(armIdleClose, armIdleClose);
315
+ return next;
316
+ },
317
+ restart() {
318
+ return enqueue(reset);
319
+ },
320
+ async dispose() {
321
+ disposed = true;
322
+ clearTimeout(idleTimer);
323
+ await queue;
324
+ await reset();
325
+ }
326
+ };
327
+ }
328
+ //#endregion
90
329
  exports.BaseBundlerService = require_stdio.BaseBundlerService;
91
330
  exports.BaseCSSClassesService = require_stdio.BaseCSSClassesService;
92
331
  Object.defineProperty(exports, "CSSClassesServiceFactory", {
@@ -133,12 +372,7 @@ Object.defineProperty(exports, "ListThemesTool", {
133
372
  return require_stdio.ListThemesTool;
134
373
  }
135
374
  });
136
- Object.defineProperty(exports, "PolishComponentTool", {
137
- enumerable: true,
138
- get: function() {
139
- return require_stdio.PolishComponentTool;
140
- }
141
- });
375
+ exports.MAX_STYLE_SYSTEM_VIEWPORT_DIMENSION = require_stdio.MAX_STYLE_SYSTEM_VIEWPORT_DIMENSION;
142
376
  exports.STYLE_SYSTEM_TYPES = require_stdio.STYLE_SYSTEM_TYPES;
143
377
  exports.StdioTransportHandler = require_stdio.StdioTransportHandler;
144
378
  Object.defineProperty(exports, "StoriesIndexService", {
@@ -157,10 +391,14 @@ Object.defineProperty(exports, "StyleSystemConfigLoader", {
157
391
  exports.TailwindCSSClassesService = require_stdio.TailwindCSSClassesService;
158
392
  exports.ThemeService = require_stdio.ThemeService;
159
393
  exports.ViteReactBundlerService = require_stdio.ViteReactBundlerService;
394
+ exports.ViteReactNativeBundlerService = require_stdio.ViteReactNativeBundlerService;
395
+ exports.WARM_RENDERER_TOOLS = WARM_RENDERER_TOOLS;
160
396
  exports.createContainer = require_stdio.createContainer;
161
397
  exports.createDefaultBundlerService = require_stdio.createDefaultBundlerService;
162
398
  exports.createServer = require_stdio.createServer;
399
+ exports.createStoryBrowser = createStoryBrowser;
163
400
  exports.createStyleSystemModule = require_stdio.createStyleSystemModule;
401
+ exports.createWarmStoryRenderer = createWarmStoryRenderer;
164
402
  exports.extractCustomTokenNames = require_stdio.extractCustomTokenNames;
165
403
  exports.generateRestrictedClassesConfig = require_stdio.generateRestrictedClassesConfig;
166
404
  exports.getAppDesignSystemConfig = require_stdio.getAppDesignSystemConfig;
@@ -168,6 +406,7 @@ exports.getBundlerService = require_stdio.getBundlerService;
168
406
  exports.getBundlerServiceFromConfig = require_stdio.getBundlerServiceFromConfig;
169
407
  exports.getSharedComponentTags = require_stdio.getSharedComponentTags;
170
408
  exports.hasStyleSystemProjectConfig = require_stdio.hasStyleSystemProjectConfig;
409
+ exports.launchBrowserWithFallback = require_stdio.launchBrowserWithFallback;
171
410
  exports.resetStyleSystemConfigCache = require_stdio.resetStyleSystemConfigCache;
172
411
  exports.resolveAppDesignSystemConfig = require_stdio.resolveAppDesignSystemConfig;
173
412
  exports.resolveStyleSystemThemePath = require_stdio.resolveStyleSystemThemePath;