Skip to content

Instantly share code, notes, and snippets.

@eonist
Created May 29, 2025 08:19
Show Gist options
  • Save eonist/b9e2b8f34449f5a472921fdf32791a2d to your computer and use it in GitHub Desktop.
Save eonist/b9e2b8f34449f5a472921fdf32791a2d to your computer and use it in GitHub Desktop.
comment improvements

Looking at the additional TypeScript files you've provided, here are the improved JSDoc comments for each:

effect-tools.ts Improvements

/**
 * Registers effect-related styling commands for the MCP server.
 * 
 * This module provides comprehensive effect management tools including:
 * - Direct effect application with custom parameters (shadows, blurs, etc.)
 * - Effect style variable application for reusable effects
 * - Batch operations for efficient bulk updates
 * - Support for multiple effect types (DROP_SHADOW, INNER_SHADOW, LAYER_BLUR, etc.)
 * 
 * Registered commands:
 * - `set_effect`: Applies effects directly or via style variables to nodes
 * - `create_effect_style_variable`: Creates reusable effect style variables
 * 
 * @param {McpServer} server - The MCP server instance to register tools on
 * @param {FigmaClient} figmaClient - The Figma client for API communication
 * @returns {void}
 * 
 * @example
 * ```
 * registerEffectTools(server, figmaClient);
 * 
 * // Apply a drop shadow effect directly
 * await figmaClient.executeCommand('set_effect', {
 *   entries: {
 *     nodeId: "123:456",
 *     effects: {
 *       type: "DROP_SHADOW",
 *       color: { r: 0, g: 0, b: 0, a: 0.25 },
 *       radius: 4,
 *       offset: { x: 0, y: 2 }
 *     }
 *   }
 * });
 * 
 * // Apply via style variable
 * await figmaClient.executeCommand('set_effect', {
 *   entries: { nodeId: "123:456", effectStyleId: "S:effect123" }
 * });
 * ```
 * 
 * @throws {Error} When nodeId is invalid or malformed
 * @throws {Error} When neither effects nor effectStyleId is provided
 * @throws {Error} When effect parameters are invalid (missing required properties)
 */
export function registerEffectTools(server: McpServer, figmaClient: FigmaClient) {

effects-tools.ts Improvements

/**
 * Registers legacy effect-related commands on the MCP server.
 * 
 * This module provides backward compatibility for effect styling operations.
 * It focuses on applying predefined effect styles to individual nodes.
 * 
 * **Note**: This module is complementary to `effect-tools.ts` which provides
 * more comprehensive effect management capabilities including batch operations
 * and direct effect application.
 * 
 * Registered commands:
 * - `apply_effect_style`: Applies predefined effect styles to individual nodes
 * 
 * @param {McpServer} server - The MCP server instance to register the tools on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * @returns {void} This function does not return a value but registers the tools asynchronously
 * 
 * @example
 * ```
 * registerEffectsTools(server, figmaClient);
 * 
 * // Apply an effect style to a node
 * const result = await figmaClient.executeCommand('apply_effect_style', {
 *   nodeId: "123:456",
 *   effectStyleId: "S:effect123"
 * });
 * ```
 * 
 * @throws {Error} When nodeId is invalid or not in proper Figma format
 * @throws {Error} When effectStyleId is empty, too long, or references non-existent style
 * @throws {Error} When the specified node doesn't support effects
 * 
 * @see {@link registerEffectTools} - For comprehensive effect management with batch operations
 */
export function registerEffectsTools(server: McpServer, figmaClient: FigmaClient) {

fill-tools.ts Improvements

/**
 * Registers fill and stroke styling commands for the MCP server.
 * 
 * This module provides unified tools for managing visual styling properties
 * on Figma nodes, including fill colors, stroke colors, and stroke weights.
 * Supports both single node operations and efficient batch processing.
 * 
 * Registered commands:
 * - `set_fill_and_stroke`: Sets fill/stroke colors and stroke weight on nodes
 * - `get_fill_and_stroke`: Retrieves current fill/stroke properties from nodes
 * 
 * @param {McpServer} server - The MCP server instance to register tools on
 * @param {FigmaClient} figmaClient - The Figma client for API communication
 * @returns {void}
 * 
 * @example
 * ```
 * registerFillTools(server, figmaClient);
 * 
 * // Set fill and stroke on a single node
 * await figmaClient.executeCommand('set_fill_and_stroke', {
 *   nodeId: "123:456",
 *   fillColor: { r: 1, g: 0, b: 0, a: 1 }, // Red fill
 *   strokeColor: { r: 0, g: 0, b: 1, a: 1 }, // Blue stroke
 *   strokeWeight: 2
 * });
 * 
 * // Batch operation on multiple nodes
 * await figmaClient.executeCommand('set_fill_and_stroke', {
 *   nodeIds: ["123:456", "789:101"],
 *   fillColor: { r: 0, g: 1, b: 0, a: 0.8 } // Semi-transparent green
 * });
 * 
 * // Get current styling properties
 * const styles = await figmaClient.executeCommand('get_fill_and_stroke', {
 *   nodeId: "123:456"
 * });
 * ```
 * 
 * @throws {Error} When both nodeId and nodeIds are provided (mutually exclusive)
 * @throws {Error} When neither nodeId nor nodeIds is provided
 * @throws {Error} When no style properties (fillColor, strokeColor, strokeWeight) are specified for set operations
 * @throws {Error} When node IDs are invalid or malformed
 */
export function registerFillTools(server: McpServer, figmaClient: FigmaClient) {

font-tools.ts Improvements

/**
 * Registers font management commands on the MCP server.
 * 
 * This module provides essential font loading capabilities for Figma text operations.
 * Font loading is a prerequisite for applying text styles, as fonts must be
 * asynchronously loaded before they can be used in text formatting operations.
 * 
 * **Important**: Always load fonts before applying text styles that use them,
 * as Figma requires fonts to be explicitly loaded for text manipulation.
 * 
 * Registered commands:
 * - `load_font_async`: Loads a specific font family and style asynchronously
 * 
 * @param {McpServer} server - The MCP server instance to register the tools on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * @returns {void} This function does not return a value but registers the tools asynchronously
 * 
 * @example
 * ```
 * registerFontTools(server, figmaClient);
 * 
 * // Load a font before using it
 * await figmaClient.executeCommand('load_font_async', {
 *   family: 'Roboto',
 *   style: 'Regular'
 * });
 * 
 * // Load multiple font styles
 * await figmaClient.executeCommand('load_font_async', {
 *   family: 'Inter',
 *   style: 'Bold'
 * });
 * 
 * // Now you can safely apply text styles using these fonts
 * ```
 * 
 * @throws {Error} When font family name is invalid or not available in Figma
 * @throws {Error} When font style is not available for the specified family
 * @throws {Error} When font loading fails due to network or permission issues
 * 
 * @see {@link registerTextStyleTools} - For applying loaded fonts to text nodes
 */
export function registerFontTools(server: McpServer, figmaClient: FigmaClient) {

gradient-tools.ts Improvements

/**
 * Registers gradient-related styling commands for the MCP server.
 * 
 * This module provides comprehensive gradient management capabilities including:
 * - Creating reusable gradient style variables with custom parameters
 * - Applying gradients directly to nodes with full customization
 * - Applying existing gradient styles to nodes for consistency
 * - Support for all gradient types (LINEAR, RADIAL, ANGULAR, DIAMOND)
 * - Batch operations for efficient bulk gradient application
 * - Flexible application targets (FILL, STROKE, or BOTH)
 * 
 * Registered commands:
 * - `create_gradient_style`: Creates one or more reusable gradient style variables
 * - `set_gradient`: Applies gradients directly or via style variables to nodes
 * 
 * @param {McpServer} server - The MCP server instance to register tools on
 * @param {FigmaClient} figmaClient - The Figma client for API communication
 * @returns {void}
 * 
 * @example
 * ```
 * registerGradientTools(server, figmaClient);
 * 
 * // Create a gradient style variable
 * await figmaClient.executeCommand('create_gradient_style', {
 *   gradients: {
 *     name: "Primary Gradient",
 *     gradientType: "LINEAR",
 *     stops: [
 *       { position: 0, color: [1][1] }, // Red at start
 *       { position: 1, color: [1][1] }  // Blue at end
 *     ]
 *   }
 * });
 * 
 * // Apply gradient directly to a node
 * await figmaClient.executeCommand('set_gradient', {
 *   entries: {
 *     nodeId: "123:456",
 *     gradientType: "RADIAL",
 *     stops: [
 *       { position: 0, color: [1][1][1][1] },
 *       { position: 1, color: [0, 0, 0, 0.5] }
 *     ],
 *     applyTo: "FILL"
 *   }
 * });
 * 
 * // Apply existing gradient style
 * await figmaClient.executeCommand('set_gradient', {
 *   entries: {
 *     nodeId: "789:101",
 *     gradientStyleId: "S:gradient123",
 *     applyTo: "STROKE"
 *   }
 * });
 * 
 * // Batch gradient application
 * await figmaClient.executeCommand('set_gradient', {
 *   entries: [
 *     { nodeId: "123:456", gradientStyleId: "S:gradient123", applyTo: "FILL" },
 *     { nodeId: "789:101", gradientStyleId: "S:gradient456", applyTo: "BOTH" }
 *   ]
 * });
 * ```
 * 
 * @throws {Error} When gradient parameters are invalid (insufficient stops, invalid colors, etc.)
 * @throws {Error} When node IDs are malformed or reference non-existent nodes
 * @throws {Error} When gradient style IDs are invalid or reference non-existent styles
 * @throws {Error} When color values are outside the valid range (0-1)
 * @throws {Error} When stop positions are outside the valid range (0-1)
 * @throws {Error} When neither direct gradient parameters nor style ID is provided
 * 
 * @see {@link registerFillTools} - For solid color fills and strokes
 * @see {@link registerEffectTools} - For visual effects that can complement gradients
 */
export function registerGradientTools(server: McpServer, figmaClient: FigmaClient) {

index.ts Improvements

/**
 * Main registration module for all styling-related MCP commands.
 * 
 * This module serves as the central orchestrator for registering all styling tools
 * with the MCP server. It provides a unified entry point for enabling comprehensive
 * styling capabilities across the Figma MCP integration.
 * 
 * **Registered tool categories:**
 * - **Fill & Stroke Tools**: Solid colors, stroke weights, and basic styling
 * - **Gradient Tools**: Linear, radial, angular, and diamond gradients with style variables
 * - **Effect Tools**: Shadows, blurs, and other visual effects with batch support
 * - **Legacy Effects Tools**: Backward compatibility for effect style application
 * - **Style Tools**: General styling utilities and node style management
 * - **Text Style Tools**: Typography styling, text formatting, and text-specific effects
 * - **Font Tools**: Font loading and management for text operations
 * 
 * **Architecture**: This module follows a modular registration pattern where each
 * tool category is implemented in its own module and registered independently,
 * allowing for granular control and maintainability.
 * 
 * @param {McpServer} server - The MCP server instance to register all styling tools on
 * @param {FigmaClient} figmaClient - The Figma client for API communication across all tools
 * @returns {void}
 * 
 * @example
 * ```
 * import { registerStyleCommands } from './styling';
 * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
 * import { FigmaClient } from '../../../clients/figma-client';
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * 
 * // Register all styling commands at once
 * registerStyleCommands(server, figmaClient);
 * 
 * // Now all styling commands are available:
 * // - set_fill_and_stroke, get_fill_and_stroke
 * // - create_gradient_style, set_gradient
 * // - set_effect, apply_effect_style
 * // - load_font_async
 * // - text styling commands
 * // - general style utilities
 * ```
 * 
 * @see {@link registerFillTools} - For fill and stroke color management
 * @see {@link registerGradientTools} - For gradient creation and application
 * @see {@link registerEffectTools} - For comprehensive effect management
 * @see {@link registerEffectsTools} - For legacy effect style application
 * @see {@link registerStyleTools} - For general styling utilities
 * @see {@link registerTextStyleTools} - For typography and text formatting
 * @see {@link registerFontTools} - For font loading and management
 * 
 * @since 1.0.0
 */
export function registerStyleCommands(server: McpServer, figmaClient: FigmaClient): void {

Key Improvements Made:

Comprehensive Module Descriptions: Each function now has detailed descriptions explaining its specific role and how it fits into the larger styling ecosystem.

Clear Command Listings: Explicitly documented which commands each module registers for easy reference.

Practical Examples: Added realistic code examples showing common usage patterns for each module.

Error Documentation: Comprehensive @throws documentation covering all potential error conditions.

Cross-References: Added @see tags linking related modules and complementary functionality.

Architecture Notes: Explained the relationship between modules (e.g., effects-tools.ts vs effect-tools.ts).

Usage Context: Provided context about when and why to use each module's capabilities.

Batch Operation Examples: Showed both single and batch operation examples where applicable.

Parameter Validation: Documented validation rules and constraints for inputs.

Performance Considerations: Highlighted batch operations and efficiency considerations.

These improvements provide comprehensive documentation that will enhance developer experience, improve code maintainability, and provide better IntelliSense support in IDEs.

Citations: [1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/b3cdf830-1f68-427e-b670-2f21008ce1bc/effect-tools.ts [2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/f5cf1591-cab7-4ac2-86cb-74563c723643/effects-tools.ts [3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/4dc2d82b-3910-4480-9f20-5d51747b33b7/fill-tools.ts [4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/f9e2e27a-b7c9-49ab-a639-7acca9e9545a/font-tools.ts [5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/e2920ad5-0090-42d3-ba39-dfe883c0d659/gradient-tools.ts [6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/a7e79fb1-57a0-4795-bdd2-2b8095a32d00/index.ts [7] https://deliciousreverie.co.uk/posts/types-via-jsdoc-or-typescript/ [8] https://github.com/SoftwareBrothers/better-docs [9] https://dev.to/artxe2/how-to-set-up-jsdoc-for-npm-packages-1jm1 [10] https://www.ciccarello.me/blog/2024/02/17/trying-out-typescript-in-jsdoc-comments/ [11] https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html [12] https://www.reddit.com/r/vuejs/comments/st2zkt/jsdoc_or_typescript/ [13] https://dev.to/samuel-braun/boost-your-javascript-with-jsdoc-typing-3hb3 [14] jsdoc/jsdoc#1645 [15] https://blog.chainsafe.io/documenting-typescript-finding-the-right-tools-for-your-project/ [16] https://www.pullrequest.com/blog/leveraging-jsdoc-for-better-code-documentation-in-javascript/


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Here are the improved JSDoc comments for these TypeScript schema files:

Color Schema

import { z } from "zod";
import { isValidNodeId } from "../../../../utils/figma/is-valid-node-id.js";

/**
 * Zod schema for RGBA color channels used throughout the Figma API.
 * 
 * @description Validates color values with proper channel ranges for Figma's color system.
 * All color channels use normalized values between 0 and 1, following Figma's internal
 * color representation format.
 * 
 * @example
 * ```
 * const redColor: Rgba = { r: 1, g: 0, b: 0, a: 1 };
 * const semiTransparentBlue: Rgba = { r: 0, g: 0, b: 1, a: 0.5 };
 * ```
 */
export const RgbaSchema = z.object({
  /** Red channel intensity (0 = no red, 1 = full red) */
  r: z.number().min(0).max(1).describe("Red channel (0-1)"),
  /** Green channel intensity (0 = no green, 1 = full green) */
  g: z.number().min(0).max(1).describe("Green channel (0-1)"),
  /** Blue channel intensity (0 = no blue, 1 = full blue) */
  b: z.number().min(0).max(1).describe("Blue channel (0-1)"),
  /** Alpha channel for transparency (0 = fully transparent, 1 = fully opaque) */
  a: z.number().min(0).max(1).optional().describe("Optional. Alpha channel (0-1)"),
});

/**
 * Zod schema for validating Figma node identifiers.
 * 
 * @description Validates both simple and complex Figma node ID formats:
 * - Simple format: "123:456" (layer ID within a file)
 * - Complex format: "I422:10713;1082:2236" (instance IDs with component references)
 * 
 * @example
 * ```
 * const simpleNodeId: NodeId = "123:456";
 * const instanceNodeId: NodeId = "I422:10713;1082:2236";
 * ```
 */
export const NodeIdSchema = z.string()
  .refine(isValidNodeId, { 
    message: "Must be a valid Figma node ID (simple or complex format, e.g., '123:456' or 'I422:10713;1082:2236')" 
  })
  .describe("The unique Figma node ID to update. Must be a string in the format '123:456' or a complex instance ID like 'I422:10713;1082:2236'.");

/**
 * TypeScript type representing an RGBA color object.
 * @typedef {Object} Rgba
 */
export type Rgba = z.infer;

/**
 * TypeScript type representing a valid Figma node identifier.
 * @typedef {string} NodeId
 */
export type NodeId = z.infer;

Effect Schema

import { z } from "zod";
import { isValidNodeId } from "../../../../utils/figma/is-valid-node-id.js";

/**
 * Zod schema for applying effect styles to Figma nodes.
 * 
 * @description Validates the parameters required to apply visual effects (shadows, blurs, etc.)
 * to specific nodes in a Figma document. Effect styles must be pre-defined in the Figma file
 * or available through the team library.
 * 
 * @example
 * ```
 * const dropShadowEffect = {
 *   nodeId: "123:456",
 *   effectStyleId: "S:abc123def456"
 * };
 * ```
 */
export const EffectSchema = z.object({
  /** The target node to apply the effect to */
  nodeId: z.string()
    .refine(isValidNodeId, { 
      message: "Must be a valid Figma node ID (simple or complex format, e.g., '123:456' or 'I422:10713;1082:2236')" 
    })
    .describe("The unique Figma node ID to update. Must be a string in the format '123:456' or a complex instance ID like 'I422:10713;1082:2236'."),
  
  /** The effect style identifier from Figma's style system */
  effectStyleId: z.string()
    .min(1)
    .max(100)
    .describe("The ID of the effect style to apply. Must be a non-empty string. Maximum length 100 characters."),
});

Fill Schema

import { z } from "zod";
import { isValidNodeId } from "../../../../utils/figma/is-valid-node-id.js";

/**
 * Zod schema for setting fill and stroke properties on Figma nodes.
 * 
 * @description Validates parameters for updating visual properties of nodes including
 * fill colors, stroke colors, and stroke weights. Supports both single node and
 * batch operations.
 * 
 * @example
 * ```
 * // Single node update
 * const singleUpdate = {
 *   nodeId: "123:456",
 *   fillColor: { r: 1, g: 0, b: 0, a: 1 }
 * };
 * 
 * // Multiple nodes update
 * const batchUpdate = {
 *   nodeIds: ["123:456", "789:012"],
 *   strokeWeight: 2
 * };
 * ```
 */
export const setFillAndStrokeSchema = {
  /** Single node identifier (mutually exclusive with nodeIds) */
  nodeId: z.string()
    .optional()
    .describe("The unique Figma node ID to update. Provide either nodeId or nodeIds, not both."),
  
  /** Multiple node identifiers for batch operations (mutually exclusive with nodeId) */
  nodeIds: z.array(z.string())
    .optional()
    .describe("An array of Figma node IDs to update. Provide either nodeId or nodeIds, not both."),
  
  /** Fill color as RGBA object */
  fillColor: z.any()
    .optional()
    .describe("The fill color to set as RGBA object."),
  
  /** Stroke color as RGBA object */
  strokeColor: z.any()
    .optional()
    .describe("The stroke color to set as RGBA object."),
  
  /** Stroke thickness in pixels */
  strokeWeight: z.number()
    .optional()
    .describe("The stroke weight to set in pixels."),
  
  /** Complex fill definition supporting multiple fills */
  fill: z.any()
    .optional()
    .describe("The fill color(s) to set. Can be a single fill or an array of fills."),
  
  /** Complex stroke definition supporting multiple strokes */
  stroke: z.any()
    .optional()
    .describe("The stroke color(s) to set. Can be a single stroke or an array of strokes.")
};

/**
 * Zod schema for retrieving fill and stroke properties from Figma nodes.
 * 
 * @description Validates parameters for querying visual properties of nodes.
 * Supports both single node and batch queries.
 */
export const getFillAndStrokeSchema = {
  /** Single node identifier for property retrieval */
  nodeId: z.string()
    .optional()
    .describe("The unique Figma node ID to query. Provide either nodeId or nodeIds, not both."),
  
  /** Multiple node identifiers for batch property retrieval */
  nodeIds: z.array(z.string())
    .optional()
    .describe("An array of Figma node IDs to query. Provide either nodeId or nodeIds, not both.")
};

Font Schema

import { z } from "zod";

/**
 * Zod schema for font family and style specifications.
 * 
 * @description Validates font family names and optional style variants for text nodes.
 * Font families must be available in the Figma environment or loaded as web fonts.
 * 
 * @example
 * ```
 * const basicFont: FontFamilyStyle = { family: "Inter" };
 * const styledFont: FontFamilyStyle = { family: "Inter", style: "Bold" };
 * ```
 */
export const FontFamilyStyleSchema = z.object({
  /** The font family name (e.g., "Inter", "Roboto", "Arial") */
  family: z.string()
    .min(1)
    .max(100)
    .describe("The font family to set. Must be a non-empty string. Maximum length 100 characters."),
  
  /** The font style variant (e.g., "Regular", "Bold", "Italic", "Bold Italic") */
  style: z.string()
    .min(1)
    .max(100)
    .optional()
    .describe("Optional. The font style to set (e.g., 'Bold', 'Italic'). If provided, must be a non-empty string. Maximum length 100 characters."),
});

/**
 * Zod schema for font size specifications.
 * 
 * @description Validates font size values in points, following standard typography units.
 * Range is limited to practical sizes supported by Figma.
 * 
 * @example
 * ```
 * const headingSize: FontSize = { fontSize: 24 };
 * const bodySize: FontSize = { fontSize: 16 };
 * ```
 */
export const FontSizeSchema = z.object({
  /** Font size in points (pt) */
  fontSize: z.number()
    .min(1)
    .max(512)
    .describe("The font size to set, in points. Must be a positive number between 1 and 512."),
});

/**
 * Zod schema for font weight specifications.
 * 
 * @description Validates font weight values using the standard CSS font-weight scale.
 * Common values: 100 (Thin), 400 (Regular), 700 (Bold), 900 (Black).
 * 
 * @example
 * ```
 * const lightWeight: FontWeight = { weight: 300 };
 * const boldWeight: FontWeight = { weight: 700 };
 * ```
 */
export const FontWeightSchema = z.object({
  /** Font weight on the 100-1000 scale */
  weight: z.number()
    .int()
    .min(100)
    .max(1000)
    .describe("The font weight to set. Must be an integer between 100 and 1000 (typical Figma font weight range)."),
});

/**
 * TypeScript type for font family and style configuration.
 * @typedef {Object} FontFamilyStyle
 */
export type FontFamilyStyle = z.infer;

/**
 * TypeScript type for font size configuration.
 * @typedef {Object} FontSize
 */
export type FontSize = z.infer;

/**
 * TypeScript type for font weight configuration.
 * @typedef {Object} FontWeight
 */
export type FontWeight = z.infer;

Gradient Schema

import { z } from "zod";

/**
 * Zod schema for individual gradient color stops.
 * 
 * @description Defines a single point in a gradient with position and color.
 * Position determines where along the gradient the color appears, while color
 * is specified as an RGBA tuple for precise color control.
 * 
 * @example
 * ```
 * const redStop: GradientStop = {
 *   position: 0,
 *   color: [1][1] // Red at start
 * };
 * const blueStop: GradientStop = {
 *   position: 1,
 *   color: [1][1] // Blue at end
 * };
 * ```
 */
export const GradientStopSchema = z.object({
  /** Position along the gradient (0 = start, 1 = end) */
  position: z.number().min(0).max(1)
    .describe("Position of the stop (0-1)."),
  
  /** RGBA color values as a 4-element array */
  color: z.tuple([
    z.number().min(0).max(1).describe("Red channel (0-1)"),
    z.number().min(0).max(1).describe("Green channel (0-1)"),
    z.number().min(0).max(1).describe("Blue channel (0-1)"),
    z.number().min(0).max(1).describe("Alpha channel (0-1)")
  ]).describe("RGBA color array (4 numbers, each 0-1)."),
});

/**
 * Zod schema for complete gradient definitions.
 * 
 * @description Validates all parameters needed to create a gradient style in Figma.
 * Supports linear, radial, angular, and diamond gradient types with customizable
 * color stops and optional transform matrices for advanced positioning.
 * 
 * @example
 * ```
 * const linearGradient: GradientDefinition = {
 *   name: "Primary Gradient",
 *   gradientType: "LINEAR",
 *   stops: [
 *     { position: 0, color: [1][1] },
 *     { position: 1, color: [1][1] }
 *   ]
 * };
 * ```
 */
export const GradientDefinitionSchema = z.object({
  /** Human-readable name for the gradient style */
  name: z.string().min(1).max(100)
    .describe("Name for the gradient style. Must be a non-empty string up to 100 characters."),
  
  /** Type of gradient geometry */
  gradientType: z.enum(["LINEAR", "RADIAL", "ANGULAR", "DIAMOND"])
    .describe('Type of gradient: "LINEAR", "RADIAL", "ANGULAR", or "DIAMOND".'),
  
  /** Array of color stops defining the gradient */
  stops: z.array(GradientStopSchema)
    .min(2)
    .max(10)
    .describe("Array of color stops. Each stop is an object with position and color. Must contain 2 to 10 stops."),
  
  /** Optional gradient blending mode */
  mode: z.string().optional()
    .describe("Optional. Gradient mode."),
  
  /** Overall opacity of the gradient */
  opacity: z.number().min(0).max(1).optional()
    .describe("Optional. Opacity of the gradient (0-1)."),
  
  /** Transformation matrix for gradient positioning and scaling */
  transformMatrix: z.array(z.array(z.number())).optional()
    .describe("Optional. Transform matrix for the gradient."),
});

/**
 * TypeScript type for gradient color stop configuration.
 * @typedef {Object} GradientStop
 */
export type GradientStop = z.infer;

/**
 * TypeScript type for complete gradient definition.
 * @typedef {Object} GradientDefinition
 */
export type GradientDefinition = z.infer;

Stroke Schema

import { z } from "zod";

/**
 * Zod schema for stroke color and weight specifications.
 * 
 * @description Validates stroke properties for Figma nodes including color channels
 * and optional stroke weight. Uses normalized RGBA values consistent with Figma's
 * color system and practical weight ranges for design work.
 * 
 * @example
 * ```
 * const redStroke: StrokeColor = {
 *   r: 1, g: 0, b: 0, a: 1,
 *   weight: 2
 * };
 * const transparentStroke: StrokeColor = {
 *   r: 0, g: 0, b: 0, a: 0.5
 * };
 * ```
 */
export const StrokeColorSchema = z.object({
  /** Red color channel intensity */
  r: z.number().min(0).max(1).describe("Red channel (0-1)"),
  
  /** Green color channel intensity */
  g: z.number().min(0).max(1).describe("Green channel (0-1)"),
  
  /** Blue color channel intensity */
  b: z.number().min(0).max(1).describe("Blue channel (0-1)"),
  
  /** Alpha channel for stroke transparency */
  a: z.number().min(0).max(1).optional().describe("Optional. Alpha channel (0-1)"),
  
  /** Stroke thickness in pixels */
  weight: z.number().min(0.1).max(100).optional().describe("Optional. Stroke weight. Must be between 0.1 and 100."),
});

/**
 * TypeScript type for stroke color and weight configuration.
 * @typedef {Object} StrokeColor
 */
export type StrokeColor = z.infer;

Style Schema

import { z } from "zod";
import { isValidNodeId } from "../../../utils/figma/is-valid-node-id.js";

/**
 * Zod schema for retrieving document-level styles.
 * 
 * @description Validates parameters for querying all available styles in a Figma document.
 * This includes text styles, color styles, effect styles, and grid styles.
 */
export const getDocStyleSchema = {};

/**
 * Zod schema for retrieving node-specific style information.
 * 
 * @description Validates parameters for querying style properties applied to specific
 * nodes or groups of nodes. Supports both single node and batch queries.
 * 
 * @example
 * ```
 * // Query single node styles
 * const singleQuery = { nodeId: "123:456" };
 * 
 * // Query multiple nodes
 * const batchQuery = { nodeIds: ["123:456", "789:012"] };
 * ```
 */
export const getNodeStyleSchema = {
  /** Single node identifier for style retrieval */
  nodeId: z.string()
    .refine(isValidNodeId, { 
      message: "Must be a valid Figma text node ID (simple or complex format, e.g., '123:456' or 'I422:10713;1082:2236')" 
    })
    .optional(),
  
  /** Multiple node identifiers for batch style retrieval */
  nodeIds: z.array(z.string()).optional()
};

Text Style Schema

import { z } from "zod";
import { isValidNodeId } from "../../../../utils/figma/is-valid-node-id.js";

/**
 * Zod schema for retrieving text-specific style information.
 * 
 * @description Validates parameters for querying text styling properties from
 * text nodes in Figma. This includes font family, size, weight, color, and
 * other typography-related properties.
 * 
 * @example
 * ```
 * // Query single text node
 * const textQuery = { nodeId: "123:456" };
 * 
 * // Query multiple text nodes
 * const batchTextQuery = { nodeIds: ["123:456", "789:012"] };
 * ```
 */
export const getTextStyleSchema = {
  /** Single text node identifier for style retrieval */
  nodeId: z.string()
    .refine(isValidNodeId, { 
      message: "Must be a valid Figma text node ID (simple or complex format, e.g., '123:456' or 'I422:10713;1082:2236')" 
    })
    .optional(),
  
  /** Multiple text node identifiers for batch style retrieval */
  nodeIds: z.array(z.string()).optional()
};

The improved JSDoc comments now include:

  • Comprehensive descriptions explaining the purpose and context of each schema
  • Usage examples showing practical implementation
  • Parameter documentation with clear explanations of constraints and formats
  • Type definitions using proper JSDoc @typedef syntax
  • Cross-references to related concepts and dependencies
  • Validation details explaining the reasoning behind constraints
  • Format specifications for complex data types like node IDs and color values

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/c6beb071-87f3-45db-81e7-1276635c48ff/color-schema.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/0a46303d-745f-4d9a-ae96-a99254b3d7a6/effect-schema.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/347930ab-faee-48d6-bf1d-3ea02f559860/fill-schema.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/f98803d8-dc11-40d0-915e-459def9b766a/font-schema.ts
[5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/554a2dfc-3847-4324-b3e9-5164622e1d5b/gradient-schema.ts
[6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/b46e6a79-f62c-4f6b-88dd-e9e7f821e867/stroke-schema.ts
[7] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/37cacbcc-dfc5-4ace-a8cf-3cee1fde9061/style-schema.ts
[8] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/474cb2b3-00e5-4fb2-81b8-58af32570a1d/text-style-schema.ts


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Looking at the provided TypeScript files, I can see several areas where the JSDoc documentation can be significantly improved. Here are my recommendations for enhancing the JSDoc comments:

Enhanced JSDoc for style-tools.ts

/**
 * Registers style information retrieval tools on the MCP server.
 * 
 * This function adds a tool named "get_styles" to the MCP server that enables
 * retrieval of all shared styles (color, text, and effect styles) from the 
 * current Figma document. The tool executes the corresponding Figma command 
 * and returns comprehensive style information as JSON.
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * @returns {void} This function does not return a value but registers the tool asynchronously
 * 
 * @example
 * // Register style tools on server initialization
 * registerStyleTools(mcpServer, figmaClientInstance);
 * 
 * @throws {Error} May throw if the MCP server registration fails
 * @since 1.0.0
 */
export function registerStyleTools(server: McpServer, figmaClient: FigmaClient): void {
  // Implementation...
}

/**
 * Registers node style retrieval tools on the MCP server.
 * 
 * This function adds a unified tool for getting all style properties (fills, strokes, 
 * effects, text styles, style IDs, etc.) for one or more Figma nodes. Supports both 
 * single node and batch processing operations.
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * @returns {void} This function does not return a value but registers the tool asynchronously
 * 
 * @example
 * // Register node style tools
 * registerNodeStylesTool(mcpServer, figmaClientInstance);
 * 
 * // Usage after registration:
 * // Single node: { nodeId: "123:456" }
 * // Multiple nodes: { nodeIds: ["123:456", "789:101"] }
 * 
 * @throws {Error} May throw if node IDs are invalid or nodes are not found
 * @since 1.0.0
 */
export function registerNodeStylesTool(server: McpServer, figmaClient: FigmaClient): void {
  // Implementation...
}

Enhanced JSDoc for text-style-tools.ts

/**
 * Extracts text style properties from one or more Figma text nodes.
 * 
 * This function supports both single node and batch node extraction, retrieving
 * comprehensive text styling information including font properties, spacing,
 * decorations, and style IDs. Only works with TEXT type nodes.
 * 
 * @async
 * @function get_text_style
 * @param {FigmaClient} client - The Figma client instance for API communication
 * @param {GetTextStyleParams} params - Parameters containing node ID(s) to process
 * @param {string} [params.nodeId] - Single node ID to extract text style from
 * @param {string[]} [params.nodeIds] - Array of node IDs for batch processing
 * @returns {Promise} Promise resolving to operation results
 * @returns {Object[]} returns.content - Array containing the JSON response
 * @returns {string} returns.content[].type - Always "text"
 * @returns {string} returns.content[].text - Stringified JSON with results or errors
 * 
 * @example
 * // Single node extraction
 * const result = await get_text_style(client, { nodeId: "123:456" });
 * 
 * @example
 * // Batch extraction
 * const result = await get_text_style(client, { 
 *   nodeIds: ["123:456", "789:101", "234:567"] 
 * });
 * 
 * @throws {Error} Handles errors gracefully and returns them in the response object
 * @since 1.0.0
 */
export async function get_text_style(
  client: FigmaClient,
  params: GetTextStyleParams
): Promise}> {
  // Implementation...
}

/**
 * Registers the text style extraction tool with the MCP server.
 * 
 * This function adds a tool that enables extraction of text style properties
 * from Figma text nodes. The tool supports both single node and batch operations,
 * providing detailed text styling information including fonts, spacing, and decorations.
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client for API operations
 * @returns {void} This function does not return a value but registers the tool asynchronously
 * 
 * @example
 * // Register text style tools during server setup
 * registerTextStyleTools(mcpServer, figmaClientInstance);
 * 
 * @throws {Error} May throw if server registration fails or if invalid parameters are provided
 * @since 1.0.0
 */
export function registerTextStyleTools(server: McpServer, figmaClient: FigmaClient): void {
  // Implementation...
}

Key Improvements Made

Enhanced Descriptions: Added more detailed explanations of what each function does, including specific capabilities and limitations[3][8].

Complete Parameter Documentation: Used proper @param tags with types, names, and descriptions for all parameters, including optional parameters[4][5].

Detailed Return Documentation: Added comprehensive @returns documentation explaining the structure of returned objects[6][9].

Practical Examples: Included multiple @example blocks showing real-world usage scenarios[8][10].

Error Handling Documentation: Added @throws tags to document potential errors and how they're handled[6][10].

Async Function Indicators: Used @async and @function tags appropriately for async functions[4][9].

Version Information: Added @since tags to track when functions were introduced[6].

Consistent Formatting: Maintained consistent alignment and spacing throughout all JSDoc comments[5][10].

Type Safety: Properly documented TypeScript-specific types and interfaces[7][9].

These improvements follow JSDoc best practices by focusing on explaining the "why" and "what" rather than just the "how," providing comprehensive examples, and maintaining consistency across the codebase[3][10].

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/de33ac06-deb6-4d19-8d01-d4d2d842abf1/style-tools.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/c99dc7aa-b73b-43ee-ab87-ac2f68b222cd/text-style-tools.ts
[3] https://daily.dev/blog/comment-javascript-code-effectively
[4] https://dev.to/danilovilhena/jsdoc-improve-your-js-code-documentation-2mj7
[5] https://github.com/shri/JSDoc-Style-Guide
[6] https://precodes.hashnode.dev/jsdoc-the-ultimate-guide-to-documenting-your-javascript-code
[7] https://www.pullrequest.com/blog/leveraging-jsdoc-for-better-code-documentation-in-javascript/
[8] https://swimm.io/learn/code-documentation/code-documentation-javascript-methods-and-best-practices
[9] https://codedamn.com/news/javascript/the-benefits-of-using-jsdoc-for-commenting-your-javascript-code
[10] https://dev.to/nikolasbarwicki/mastering-jsdoc-the-complete-guide-for-javascript-developers-1lic?comments_sort=oldest
[11] https://schof.co/writing-jsdoc-for-react-components/
[12] https://google.github.io/styleguide/jsguide.html


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Looking at the provided TypeScript files, I can suggest improvements to the JSDoc comments to make them more comprehensive and follow best practices. Here are the enhanced JSDoc comments for each file:

index.ts

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { FigmaClient } from "../../../clients/figma-client.js";
import { registerImageTools } from "./image-tools.js";
import { registerUnifiedImageTool } from "./insert-image.js";

/**
 * Registers all image-related commands and tools with the MCP server.
 * 
 * This function serves as the main entry point for registering image manipulation
 * capabilities, including unified image insertion and image extraction tools.
 * 
 * @param {McpServer} server - The MCP server instance to register tools on
 * @param {FigmaClient} figmaClient - The Figma client instance for API interactions
 * 
 * @returns {void} This function does not return a value
 * 
 * @example
 * ```
 * const server = new McpServer();
 * const figmaClient = new FigmaClient(apiKey);
 * registerImageCommands(server, figmaClient);
 * ```
 * 
 * @since 1.0.0
 */
export function registerImageCommands(server: McpServer, figmaClient: FigmaClient) {
  registerUnifiedImageTool(server, figmaClient);
  registerImageTools(server, figmaClient);
}

image-tools.ts

/**
 * Extracts image data from Figma nodes or exports nodes as images.
 * 
 * This function supports multiple extraction methods:
 * - Extracting image fills from nodes that have image-type fills
 * - Extracting images from IMAGE-type nodes
 * - Fallback rasterization of any node to PNG format
 * 
 * @param {FigmaClient} client - The Figma client instance for API calls
 * @param {GetImageParams} params - Parameters specifying which nodes to process
 * @param {string} [params.nodeId] - Single node ID to extract image from
 * @param {string[]} [params.nodeIds] - Array of node IDs for batch processing
 * @param {number} [params.fillIndex=0] - Index of the fill to extract (for nodes with multiple fills)
 * 
 * @returns {Promise}>} 
 *   MCP-formatted response containing extraction results
 * 
 * @throws {Error} When neither nodeId nor nodeIds are provided
 * 
 * @example
 * ```
 * // Extract image from single node
 * const result = await get_image(client, { nodeId: "123:456" });
 * 
 * // Extract images from multiple nodes
 * const batchResult = await get_image(client, { 
 *   nodeIds: ["123:456", "789:012"] 
 * });
 * 
 * // Extract specific fill from node
 * const fillResult = await get_image(client, { 
 *   nodeId: "123:456", 
 *   fillIndex: 1 
 * });
 * ```
 * 
 * @since 1.0.0
 */
export async function get_image(
  client: FigmaClient,
  params: GetImageParams
): Promise}> {
  // ... existing implementation
}

/**
 * Registers the get_image tool with the MCP server.
 * 
 * This function adds the image extraction capability to the MCP server,
 * allowing clients to request image data from Figma nodes through the
 * standardized MCP protocol.
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client for handling API requests
 * 
 * @returns {void} This function does not return a value
 * 
 * @example
 * ```
 * const server = new McpServer();
 * const figmaClient = new FigmaClient(apiKey);
 * registerImageTools(server, figmaClient);
 * ```
 * 
 * @since 1.0.0
 */
export function registerImageTools(server: McpServer, figmaClient: FigmaClient) {
  // ... existing implementation
}

image-schema.ts

/**
 * Unified Zod schema for image configuration objects.
 * 
 * This schema validates image insertion parameters, supporting multiple input methods:
 * - Remote images via URL
 * - Local images via file path
 * - Inline images via base64 data URI
 * 
 * @type {z.ZodObject} Zod schema object for single image configuration
 * 
 * @property {string} [url] - Optional URL of remote image (must be valid URL)
 * @property {string} [imagePath] - Optional local file path (1-500 characters)
 * @property {string} [imageData] - Optional base64 data URI (up to 10MB)
 * @property {number} [x=0] - Optional X coordinate (-10,000 to 10,000)
 * @property {number} [y=0] - Optional Y coordinate (-10,000 to 10,000)
 * @property {number} [width] - Optional width (1 to 10,000 pixels)
 * @property {number} [height] - Optional height (1 to 10,000 pixels)
 * @property {string} [name] - Optional node name (1-100 characters)
 * @property {string} [parentId] - Optional Figma parent node ID (format: "123:456")
 * 
 * @example
 * ```
 * // Valid configurations
 * const remoteImage = { url: "https://example.com/image.png", x: 100, y: 200 };
 * const localImage = { imagePath: "/path/to/image.jpg", width: 300, height: 200 };
 * const base64Image = { imageData: "data:image/png;base64,iVBORw0KG..." };
 * ```
 * 
 * @since 1.0.0
 */
export const SingleUnifiedImageSchema = z.object({
  // ... existing schema definition
});

/**
 * Zod schema for batch image operations.
 * 
 * Validates an array of image configurations for efficient bulk insertion.
 * Each item in the array must conform to SingleUnifiedImageSchema.
 * 
 * @type {z.ZodArray} Zod array schema for multiple image configurations
 * 
 * @example
 * ```
 * const batchConfig = [
 *   { url: "https://example.com/image1.png", x: 0, y: 0 },
 *   { imagePath: "/path/to/image2.jpg", x: 100, y: 0 },
 *   { imageData: "data:image/png;base64,iVBORw0KG...", x: 200, y: 0 }
 * ];
 * ```
 * 
 * @since 1.0.0
 */
export const BatchUnifiedImagesSchema = z.array(SingleUnifiedImageSchema);

/**
 * Union schema accepting either single or batch image configurations.
 * 
 * This flexible schema allows functions to handle both individual image
 * insertions and bulk operations with a single parameter type.
 * 
 * @type {z.ZodUnion} Zod union schema for single or batch operations
 * 
 * @since 1.0.0
 */
export const UnifiedImageSchema = z.union([
  SingleUnifiedImageSchema,
  BatchUnifiedImagesSchema
]);

/**
 * TypeScript type for single image configuration.
 * 
 * Inferred from SingleUnifiedImageSchema, this type provides compile-time
 * type safety for image configuration objects.
 * 
 * @typedef {Object} UnifiedImageConfig
 * @since 1.0.0
 */
export type UnifiedImageConfig = z.infer;

/**
 * TypeScript type for batch image configurations.
 * 
 * Inferred from BatchUnifiedImagesSchema, this type represents an array
 * of image configuration objects for bulk operations.
 * 
 * @typedef {Array} BatchUnifiedImagesConfig
 * @since 1.0.0
 */
export type BatchUnifiedImagesConfig = z.infer;

insert-image.ts

/**
 * Registers the unified image insertion tool with the MCP server.
 * 
 * This function adds a comprehensive image insertion capability that supports:
 * - Remote images from URLs
 * - Local images from file paths
 * - Inline images from base64 data URIs
 * - Single image insertion
 * - Batch image insertion
 * - Customizable positioning, sizing, and naming
 * - Parent node specification
 * 
 * The registered tool accepts either a single image configuration via the 'image'
 * parameter or multiple configurations via the 'images' parameter. Each configuration
 * must specify at least one image source (url, imagePath, or imageData).
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client for executing API operations
 * 
 * @returns {void} This function does not return a value but registers the tool asynchronously
 * 
 * @example
 * ```
 * // Register the tool
 * registerUnifiedImageTool(server, figmaClient);
 * 
 * // Tool usage examples:
 * // Single remote image
 * await server.callTool("set_image", {
 *   image: {
 *     url: "https://example.com/image.png",
 *     x: 100, y: 200, width: 300, height: 150,
 *     name: "Remote Image"
 *   }
 * });
 * 
 * // Batch insertion
 * await server.callTool("set_image", {
 *   images: [
 *     { url: "https://example.com/image1.png", x: 0, y: 0 },
 *     { imagePath: "/path/to/image2.jpg", x: 120, y: 0 },
 *     { imageData: "data:image/png;base64,iVBORw0KG...", x: 240, y: 0 }
 *   ]
 * });
 * ```
 * 
 * @throws {Error} When neither 'image' nor 'images' parameters are provided
 * @throws {Error} When image source validation fails
 * @throws {Error} When Figma API operations fail
 * 
 * @see {@link SingleUnifiedImageSchema} For single image configuration schema
 * @see {@link BatchUnifiedImagesSchema} For batch image configuration schema
 * 
 * @since 1.0.0
 */
export function registerUnifiedImageTool(server: McpServer, figmaClient: FigmaClient) {
  // ... existing implementation
}

Key Improvements Made:

Comprehensive Parameter Documentation - Added detailed @param tags with types and descriptions for all parameters, including optional parameters and their default values.

Return Type Specifications - Clearly documented return types using @returns with detailed descriptions of the response structure.

Usage Examples - Added practical @example sections showing real-world usage patterns for each function.

Error Documentation - Added @throws tags to document potential error conditions and when they occur.

Type Information - Enhanced type documentation for schemas and type definitions using @type and @typedef.

Cross-References - Added @see tags to link related schemas and functions.

Versioning - Added @since tags to track when functions were introduced.

Detailed Descriptions - Expanded function descriptions to explain not just what they do, but how they work and what they support.

These improvements make the code more maintainable, easier to understand for new developers, and provide better IDE support with enhanced autocomplete and inline documentation.

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/d6fd0f18-0d35-4569-b76d-1d83dc90dafa/index.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/6d4f8103-e8f5-4300-93b5-d0a6aadbd60c/image-tools.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/e49ac64b-5b13-418c-bdac-248f8ad08cae/image-schema.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/53d31291-ae72-4689-9734-9be78e9382ee/insert-image.ts


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Here are improved JSDoc comments for these TypeScript schema files:

Auto Layout Schema

import { z } from "zod";

/**
 * Zod schema for configuring auto layout properties on Figma nodes.
 * 
 * @description Defines the layout mode for auto layout containers in Figma.
 * Auto layout allows nodes to automatically arrange their children in horizontal
 * or vertical stacks with consistent spacing and alignment.
 * 
 * @example
 * ```
 * const config: AutoLayoutConfig = {
 *   layoutMode: "HORIZONTAL"
 * };
 * ```
 */
export const AutoLayoutConfigSchema = z.object({
  layoutMode: z.enum(["HORIZONTAL", "VERTICAL", "NONE"])
    .describe('The auto layout mode to set: "HORIZONTAL" for left-to-right arrangement, "VERTICAL" for top-to-bottom arrangement, or "NONE" to disable auto layout.'),
});

/**
 * Zod schema for configuring auto layout resizing behavior on specific axes.
 * 
 * @description Controls how child nodes within an auto layout container
 * resize themselves along the horizontal or vertical axis. This determines
 * whether children maintain fixed sizes, hug their content, or fill available space.
 * 
 * @example
 * ```
 * const resizing: AutoLayoutResizing = {
 *   axis: "horizontal",
 *   mode: "FILL"
 * };
 * ```
 */
export const AutoLayoutResizingSchema = z.object({
  axis: z.enum(["horizontal", "vertical"])
    .describe('The axis to configure sizing behavior for: "horizontal" for width control or "vertical" for height control.'),
  mode: z.enum(["FIXED", "HUG", "FILL"])
    .describe('The sizing mode: "FIXED" maintains exact dimensions, "HUG" sizes to fit content, "FILL" expands to use available space.'),
});

/**
 * TypeScript type representing auto layout configuration.
 * Inferred from {@link AutoLayoutConfigSchema}.
 */
export type AutoLayoutConfig = z.infer;

/**
 * TypeScript type representing auto layout resizing configuration.
 * Inferred from {@link AutoLayoutResizingSchema}.
 */
export type AutoLayoutResizing = z.infer;

Constraint Schema

import { z } from "zod";

/**
 * Zod schema defining constraint properties for a single Figma node.
 * 
 * @description Constraints control how nodes behave when their parent container
 * is resized. They determine anchoring, scaling, and stretching behavior for
 * responsive design within Figma frames and components.
 * 
 * @example
 * ```
 * const constraint: ConstraintEntry = {
 *   nodeId: "123:456",
 *   horizontal: "left",
 *   vertical: "top"
 * };
 * ```
 */
export const ConstraintEntrySchema = z.object({
  /** The unique identifier of the Figma node to apply constraints to. */
  nodeId: z.string().describe("The ID of the node to apply constraints to."),
  /** 
   * Horizontal constraint behavior when parent width changes.
   * - "left": Pin to left edge
   * - "right": Pin to right edge  
   * - "center": Maintain center position
   * - "scale": Scale proportionally with parent
   * - "stretch": Stretch to maintain margins on both sides
   */
  horizontal: z.enum(["left", "right", "center", "scale", "stretch"]).describe("The horizontal constraint to apply."),
  /** 
   * Vertical constraint behavior when parent height changes.
   * - "top": Pin to top edge
   * - "bottom": Pin to bottom edge
   * - "center": Maintain center position  
   * - "scale": Scale proportionally with parent
   * - "stretch": Stretch to maintain margins on both sides
   */
  vertical: z.enum(["top", "bottom", "center", "scale", "stretch"]).describe("The vertical constraint to apply."),
}).describe("A single constraint entry for a Figma node.");

/**
 * Zod schema for parameters when setting constraints on Figma nodes.
 * 
 * @description Supports both single constraint application and batch operations.
 * Includes options for applying constraints to child nodes and maintaining aspect ratios.
 */
export const SetConstraintsSchema = z.object({
  /** Single constraint to apply to one node. */
  constraint: ConstraintEntrySchema.optional().describe("A single constraint entry to apply."),
  /** Array of constraints for batch application to multiple nodes. */
  constraints: z.array(ConstraintEntrySchema).optional().describe("An array of constraint entries to apply in batch."),
  /** Whether to recursively apply constraints to all child nodes. */
  applyToChildren: z.boolean().optional().describe("If true, apply constraints to all children of the node(s)."),
  /** Whether to preserve the node's width-to-height ratio when constraints are applied. */
  maintainAspectRatio: z.boolean().optional().describe("If true, maintain the aspect ratio when applying constraints."),
}).describe("Parameters for the set_constraint command.");

/**
 * Zod schema for parameters when retrieving constraint information from Figma nodes.
 * 
 * @description Supports querying constraints for single nodes or multiple nodes in batch.
 * Can optionally include constraint information for child nodes.
 */
export const GetConstraintsSchema = z.object({
  /** Single node ID to query constraints for. */
  nodeId: z.string().optional().describe("The ID of a single node to get constraints for."),
  /** Array of node IDs for batch constraint queries. */
  nodeIds: z.array(z.string()).optional().describe("An array of node IDs to get constraints for in batch."),
  /** Whether to include constraint information for all child nodes. */
  includeChildren: z.boolean().optional().describe("If true, include constraints for all children of the node(s)."),
}).describe("Parameters for the get_constraint command.");

Corner Radius Schema

import { z } from "zod";

/**
 * Zod schema for configuring corner radius properties on Figma nodes.
 * 
 * @description Defines rounded corner styling for rectangles, frames, and other
 * shape nodes in Figma. Supports uniform radius application or selective corner targeting.
 * 
 * @example
 * ```
 * // Uniform radius on all corners
 * const uniformRadius = { radius: 8 };
 * 
 * // Selective corners (top-left and top-right only)
 * const selectiveRadius = { 
 *   radius: 12, 
 *   corners: [true, true, false, false] 
 * };
 * ```
 */
export const CornerRadiusSchema = z.object({
  /** 
   * The corner radius value in pixels. Must be non-negative.
   * Applied to all corners unless selective targeting is specified.
   */
  radius: z.number()
    .min(0)
    .describe("The corner radius to set, in pixels. Must be a non-negative number."),
  /** 
   * Optional array specifying which corners to apply the radius to.
   * Order: [top-left, top-right, bottom-right, bottom-left]
   * If omitted, radius is applied to all corners.
   */
  corners: z.array(z.boolean())
    .length(4)
    .optional()
    .describe("Optional array of four booleans indicating which corners to apply the radius to, in order: [top-left, top-right, bottom-right, bottom-left].")
});

Additional improvements made:

  • Added comprehensive descriptions explaining the purpose and context of each schema
  • Included practical examples showing how to use the schemas
  • Enhanced parameter documentation with detailed explanations of enum values
  • Added cross-references between related types and schemas
  • Improved formatting with consistent JSDoc structure
  • Added context about Figma-specific concepts like auto layout, constraints, and node behavior
  • Specified units and ranges where applicable (pixels, degrees, etc.)
  • Clarified batch vs. single operation patterns across different schemas

These improvements make the code more maintainable and easier for developers to understand and use correctly.

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/2fb7924f-8ab1-43de-8b99-ba18d5ac2e24/auto-layout-schema.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/cd40b7e6-31e8-42cc-be04-7a6be80b1cd2/constraint-schema.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/be6ab9da-0e5e-4e71-93dc-684711789c27/corner-radius-schema.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/f1985e51-731d-45f4-a19f-c0577fea98e2/detach-instances-schema.ts
[5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/5fe84860-52a6-4171-b552-7c8e6ed0409f/instance-id-schema.ts
[6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/d8bd74bd-cff7-42c8-b654-83de17601715/layout-auto-schema.ts
[7] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/faace8bd-a928-402f-a6ed-b91c8f6de60f/move-node-schema.ts
[8] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/4b998d4f-07a0-424f-963d-e1c9495a74cf/node-visibility-lock-schema.ts
[9] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/66875f74-e37c-4321-bec4-afac73cc093c/rotate-node-schema.ts
[10] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/f6d67ade-2dfc-46b0-b480-d87a22b4d422/transform-schema.ts


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Here are improved JSDoc comments for the TypeScript files provided:

HTML Tools

/**
 * Registers HTML generation commands for the MCP server.
 * 
 * This function adds the GET_HTML tool to the MCP server, enabling conversion
 * of Figma design nodes into structured HTML markup with configurable output
 * formats and CSS handling modes.
 * 
 * @param {McpServer} server - The MCP server instance to register the HTML generation tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute HTML generation commands against the Figma API
 * 
 * @returns {void} This function does not return a value but registers the HTML generation tool asynchronously
 * 
 * @example
 * ```
 * import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
 * import { FigmaClient } from "../../../clients/figma-client.js";
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * registerHtmlCommands(server, figmaClient);
 * ```
 * 
 * @see {@link GenerateHtmlSchema} for input validation schema
 * @see {@link MCP_COMMANDS.GET_HTML} for the registered command constant
 */
export function registerHtmlCommands(server: McpServer, figmaClient: FigmaClient): void

Export Tools

/**
 * Registers image export commands for the MCP server.
 * 
 * This function adds the EXPORT_NODE_AS_IMAGE tool to the MCP server,
 * enabling export of Figma design nodes as images in various formats (PNG, JPG, SVG, PDF)
 * with configurable scale factors for different resolution requirements.
 * 
 * @param {McpServer} server - The MCP server instance to register the export tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute export commands against the Figma API
 * 
 * @returns {void} This function does not return a value but registers the export tool asynchronously
 * 
 * @throws {Error} Throws an error if the node ID is invalid or the export operation fails
 * 
 * @example
 * ```
 * import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
 * import { FigmaClient } from "../../../clients/figma-client.js";
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * registerExportTools(server, figmaClient);
 * 
 * // Tool can then be called with:
 * // { nodeId: "123:456", format: "PNG", scale: 2 }
 * ```
 * 
 * @see {@link ExportOptionsSchema} for input validation schema
 * @see {@link MCP_COMMANDS.EXPORT_NODE_AS_IMAGE} for the registered command constant
 */
export function registerExportTools(server: McpServer, figmaClient: FigmaClient)

CSS Tools

/**
 * Registers CSS extraction commands for the MCP server.
 * 
 * This function adds the GET_CSS_ASYNC tool to the MCP server, enabling extraction
 * of CSS properties from Figma design nodes in multiple output formats (object, string, inline)
 * for code generation and design system integration.
 * 
 * @param {McpServer} server - The MCP server instance to register the CSS extraction tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute CSS extraction commands against the Figma API
 * 
 * @returns {void} This function does not return a value but registers the CSS extraction tool asynchronously
 * 
 * @throws {Error} Throws an error if the node ID is invalid or CSS extraction is not supported for the node type
 * 
 * @example
 * ```
 * import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
 * import { FigmaClient } from "../../../clients/figma-client.js";
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * registerCssTools(server, figmaClient);
 * 
 * // Tool can then be called with:
 * // { nodeId: "123:456", format: "object" }
 * // { nodeId: "123:456", format: "string" }
 * ```
 * 
 * @see {@link CssExportOptionsSchema} for input validation schema
 * @see {@link MCP_COMMANDS.GET_CSS_ASYNC} for the registered command constant
 */
export function registerCssTools(server: McpServer, figmaClient: FigmaClient)

Index File

/**
 * Registers all export-related commands for the MCP server.
 * 
 * This is the main registration function that orchestrates the setup of all export capabilities
 * including HTML generation, image export, and CSS extraction tools. It serves as a single
 * entry point for enabling all Figma-to-code export functionality.
 * 
 * @param {McpServer} server - The MCP server instance to register all export tools on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * 
 * @returns {void} This function does not return a value but registers all export tools asynchronously
 * 
 * @example
 * ```
 * import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
 * import { FigmaClient } from "../../../clients/figma-client.js";
 * import { registerExportCommands } from "./index.js";
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * 
 * // Register all export capabilities at once
 * registerExportCommands(server, figmaClient);
 * ```
 * 
 * @see {@link registerExportTools} for image export functionality
 * @see {@link registerHtmlCommands} for HTML generation functionality  
 * @see {@link registerCssTools} for CSS extraction functionality
 */
export function registerExportCommands(server: McpServer, figmaClient: FigmaClient)

Schema Files

HTML Schema:

/**
 * Zod validation schema for HTML generation parameters.
 * 
 * Defines the structure and validation rules for inputs to the HTML generation tool,
 * including node ID validation, output format options, and CSS handling modes.
 * 
 * @example
 * ```
 * const validInput = {
 *   nodeId: "123:456",
 *   format: "semantic",
 *   cssMode: "classes"
 * };
 * 
 * const result = GenerateHtmlSchema.parse(validInput);
 * ```
 */
export const GenerateHtmlSchema = z.object({
  // ... schema definition
});

Export Schema:

/**
 * Zod validation schema for image export options.
 * 
 * Defines the structure and validation rules for image export parameters,
 * including supported formats and scale factor constraints.
 * 
 * @example
 * ```
 * const exportOptions = {
 *   format: "PNG",
 *   scale: 2
 * };
 * 
 * const validated = ExportOptionsSchema.parse(exportOptions);
 * ```
 */
export const ExportOptionsSchema = z.object({
  // ... schema definition
});

/**
 * TypeScript type representing validated export options.
 * 
 * @typedef {Object} ExportOptions
 * @property {("PNG"|"JPG"|"SVG"|"PDF")} [format] - The image format to export
 * @property {number} [scale] - The export scale factor (must be positive)
 */
export type ExportOptions = z.infer;

CSS Schema:

/**
 * Zod validation schema for CSS extraction options.
 * 
 * Defines the structure and validation rules for CSS extraction parameters,
 * including optional node ID specification and output format selection.
 * 
 * @example
 * ```
 * const cssOptions = {
 *   nodeId: "123:456",
 *   format: "object"
 * };
 * 
 * const validated = CssExportOptionsSchema.parse(cssOptions);
 * ```
 */
export const CssExportOptionsSchema = z.object({
  // ... schema definition
});

/**
 * TypeScript type representing validated CSS export options.
 * 
 * @typedef {Object} CssExportOptions
 * @property {string} [nodeId] - The Figma node ID to extract CSS from
 * @property {("object"|"string"|"inline")} [format] - The CSS output format
 */
export type CssExportOptions = z.infer;

These improved JSDoc comments provide comprehensive documentation including detailed descriptions, parameter explanations, return value information, usage examples, error handling details, and cross-references to related components.

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/4af95148-f5e4-44b2-aac6-3da9fd6c3f54/html-tools.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/793ee114-96a9-43b3-89b9-431474303fc7/index.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/2799d136-2b53-48c8-8811-d958f52c3c77/export-tools.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/681c7b25-eec6-43f8-a0c7-a29ddeca2774/html-schema.ts
[5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/343e3bff-0654-4c4a-96e2-c4ecb97705e2/export-schema.ts
[6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/c487b91f-ab1d-4ce1-9043-63e94a0eadda/css-schema.ts
[7] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/db822cb9-3d98-4a10-803a-00c5df1f0130/css-tools.ts


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Looking at the TypeScript files provided, I can see several areas where JSDoc documentation can be significantly improved. The current code has minimal or missing JSDoc comments, which reduces code maintainability and developer experience.

Main Index File Improvements

/**
 * Registers all document manipulation commands and tools for the Figma MCP server.
 * This is the main entry point for all document-related functionality including
 * selection tools, document tools, and creation commands.
 * 
 * @param server - The MCP server instance to register tools with
 * @param figmaClient - The Figma client instance for executing commands
 * @example
 * ```
 * const server = new McpServer();
 * const figmaClient = new FigmaClient();
 * registerDocumentCommands(server, figmaClient);
 * ```
 */
export function registerDocumentCommands(server: McpServer, figmaClient: FigmaClient) {
    // Register selection modification tools (set selection, etc.)
    registerSelectionModifyTools(server, figmaClient);
    
    // Register selection query tools (get selection info)
    registerSelectionTools(server, figmaClient);
    
    // Register document creation commands (duplicate pages, etc.)
    registerDocumentCreationCommands(server, figmaClient);
    
    // Register document information tools (get document info, pages)
    registerDocumentTools(server, figmaClient);
}

Selection Tools Improvements

/**
 * Registers selection information retrieval tools for the Figma MCP server.
 * Provides read-only access to current selection state and properties.
 * 
 * @param server - The MCP server instance to register tools with
 * @param figmaClient - The Figma client instance for executing selection queries
 */
export function registerSelectionTools(server: McpServer, figmaClient: FigmaClient) {
    server.tool(
        MCP_COMMANDS.GET_SELECTION,
        `Get comprehensive information about the current selection in Figma.
        
        Returns detailed selection data including:
        - Node IDs and types of selected elements
        - Properties and attributes of selected nodes
        - Hierarchical relationships within selection
        
        Returns:
        - content: Array of objects with type "text" containing selection info as JSON
        `,
        {},
        {
            title: "Get Selection",
            idempotentHint: true,
            destructiveHint: false,
            readOnlyHint: true,
            openWorldHint: false,
            usageExamples: JSON.stringify([
                { description: "Get current selection info", input: {} }
            ]),
            edgeCaseWarnings: [
                "Returns an empty array if nothing is selected",
                "Selection info may include node IDs, types, and properties",
                "If multiple nodes are selected, the result is an array",
                "Large selections may return substantial JSON data"
            ],
            extraInfo: "Use this command to inspect the current selection context in the Figma document. Essential for understanding what elements are currently active."
        },
        async () => {
            try {
                const result = await figmaClient.executeCommand(MCP_COMMANDS.GET_SELECTION);
                const resultsArr = Array.isArray(result) ? result : [result];
                const response = { success: true, results: resultsArr };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            } catch (error) {
                const response = {
                    success: false,
                    error: {
                        message: error instanceof Error ? error.message : String(error),
                        results: [],
                        meta: {
                            operation: "get_selection",
                            params: {}
                        }
                    }
                };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            }
        }
    );
}

Document Tools Improvements

/**
 * Registers document information and page management tools for the Figma MCP server.
 * Provides read-only access to document structure, metadata, and page information.
 * 
 * @param server - The MCP server instance to register tools with
 * @param figmaClient - The Figma client instance for executing document queries
 */
export function registerDocumentTools(server: McpServer, figmaClient: FigmaClient) {
    /**
     * Tool: Get comprehensive document information
     * Retrieves full document structure, metadata, and settings
     */
    server.tool(
        MCP_COMMANDS.GET_DOCUMENT_INFO,
        `Get detailed information about the current Figma document.
        
        Provides comprehensive document data including:
        - Document metadata (name, version, permissions)
        - Page structure and hierarchy
        - Document-level settings and configurations
        - Asset libraries and shared styles
        
        Returns:
        - content: Array of objects with type "text" containing document info as JSON
        `,
        {},
        {
            title: "Get Document Info",
            idempotentHint: true,
            destructiveHint: false,
            readOnlyHint: true,
            openWorldHint: false,
            usageExamples: JSON.stringify([
                { description: "Get full document information", input: {} }
            ]),
            edgeCaseWarnings: [
                "Returns a large JSON object for complex documents",
                "May include document-level metadata, pages, and settings",
                "If the document is empty, the result may be minimal",
                "Large documents may have substantial response times"
            ],
            extraInfo: "Use this command to retrieve the full structure and metadata of the current Figma document. Essential for understanding document organization."
        },
        async () => {
            try {
                const result = await figmaClient.executeCommand(MCP_COMMANDS.GET_DOCUMENT_INFO);
                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(result)
                    }]
                };
            } catch (error) {
                return {
                    content: [{
                        type: "text",
                        text: `Error getting document info: ${error instanceof Error ? error.message : String(error)}`
                    }]
                };
            }
        }
    );

    /**
     * Tool: Get document pages information
     * Retrieves information about all pages in the current document
     */
    server.tool(
        MCP_COMMANDS.GET_DOC_PAGES,
        `Get information about all pages in the current Figma document.
        
        Provides page-specific data including:
        - Page IDs, names, and metadata
        - Page order and organization
        - Basic page properties and settings
        
        Returns:
        - content: Array of objects with type "text" containing pages info as JSON
        `,
        {},
        {
            title: "Get Pages",
            idempotentHint: true,
            destructiveHint: false,
            readOnlyHint: true,
            openWorldHint: false,
            usageExamples: JSON.stringify([
                { description: "List all pages in document", input: {} }
            ]),
            edgeCaseWarnings: [
                "Returns information about all pages in the document",
                "Empty pages will still be included in the result",
                "If the document has no pages, an empty array will be returned"
            ],
            extraInfo: "Use this command to get a list of all pages in the current Figma document. Useful for navigation and page management operations."
        },
        async () => {
            try {
                const result = await figmaClient.getPages();
                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(result)
                    }]
                };
            } catch (error) {
                return {
                    content: [{
                        type: "text",
                        text: `Error getting pages: ${error instanceof Error ? error.message : String(error)}`
                    }]
                };
            }
        }
    );
}

Selection Modify Tools Improvements

/**
 * Registers selection modification tools for the Figma MCP server.
 * Provides functionality to programmatically change the current selection state.
 * 
 * @param server - The MCP server instance to register tools with
 * @param figmaClient - The Figma client instance for executing selection commands
 */
export function registerSelectionModifyTools(server: McpServer, figmaClient: FigmaClient) {
    /**
     * Tool: Set current selection
     * Updates the active selection to specified node(s) by their IDs
     */
    server.tool(
        MCP_COMMANDS.SET_SELECTION,
        {
            description: `Set the current selection in Figma to the specified node(s) by ID.
            
            Allows precise control over which elements are selected:
            - Single node selection using nodeId parameter
            - Multiple node selection using nodeIds array
            - Validates node IDs before attempting selection
            - Reports success/failure for each node
            
            Returns:
            - content: Array of objects with type "text" containing selection result as JSON
            `,
            inputSchema: SetSelectionInputSchema,
            usageExamples: JSON.stringify([
                { 
                    description: "Select single node",
                    input: { nodeId: "123:456" }
                },
                { 
                    description: "Select multiple nodes",
                    input: { nodeIds: ["123:456", "789:101"] }
                }
            ]),
            extraInfo: "Node IDs must be valid Figma node identifiers and present on the current page. Returns detailed information about which nodes were successfully selected and which were not found."
        },
        async (params, { figmaClient }) => {
            try {
                const result = await figmaClient.executeCommand(MCP_COMMANDS.SET_SELECTION, params);
                const resultsArr = Array.isArray(result) ? result : [result];
                const response = { success: true, results: resultsArr };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            } catch (error) {
                const response = {
                    success: false,
                    error: {
                        message: error instanceof Error ? error.message : String(error),
                        results: [],
                        meta: {
                            operation: "set_selection",
                            params
                        }
                    }
                };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            }
        }
    );
}

Schema Documentation Improvements

/**
 * Zod validation schema for the set_selection command input parameters.
 * Ensures proper node ID format and validates input combinations.
 * 
 * @example
 * ```
 * // Valid single node selection
 * { nodeId: "123:456" }
 * 
 * // Valid multiple node selection  
 * { nodeIds: ["123:456", "789:101", "234:567"] }
 * ```
 */
export const SetSelectionInputSchema = z.object({
    /** 
     * A single Figma node ID to select.
     * Must be in the format "number:number" (e.g., "123:456")
     */
    nodeId: z.string()
        .refine(isValidNodeId, { 
            message: "Must be a valid Figma node ID in format 'number:number'." 
        })
        .optional()
        .describe("A single Figma node ID to select."),
    
    /** 
     * An array of Figma node IDs to select.
     * Each ID must be in the format "number:number"
     */
    nodeIds: z.array(
        z.string().refine(isValidNodeId, {
            message: "Each node ID must be a valid Figma node ID in format 'number:number'."
        })
    )
        .optional()
        .describe("An array of Figma node IDs to select."),
}).refine(
    (data) => data.nodeId || (Array.isArray(data.nodeIds) && data.nodeIds.length > 0),
    { 
        message: "You must provide either 'nodeId' for single selection or 'nodeIds' array for multiple selection." 
    }
).describe("Input schema for the set_selection command. Provide either 'nodeId' for single node selection or 'nodeIds' for multiple node selection.");

/**
 * Zod validation schema for the duplicate_page command input parameters.
 * Validates page ID format and optional naming parameters.
 * 
 * @example
 * ```
 * // Duplicate with auto-generated name
 * { pageId: "123:456" }
 * 
 * // Duplicate with custom name
 * { pageId: "123:456", newPageName: "My Custom Page Name" }
 * ```
 */
export const DuplicatePageSchema = z.object({
    /** 
     * The ID of the page to duplicate.
     * Must be a valid Figma page identifier.
     */
    pageId: z.string()
        .min(1, "Page ID cannot be empty")
        .describe("The ID of the page to duplicate."),
    
    /** 
     * Optional custom name for the duplicated page.
     * If not provided, Figma will auto-generate a name.
     */
    newPageName: z.string()
        .min(1, "Page name cannot be empty if provided")
        .optional()
        .describe("Optional name for the new page.")
});

Document Creation Improvements

/**
 * Registers document creation and manipulation commands for the Figma MCP server.
 * Provides functionality to create new pages and duplicate existing content.
 * 
 * @param server - The MCP server instance to register tools with
 * @param figmaClient - The Figma client instance for executing creation commands
 */
export function registerDocumentCreationCommands(server: McpServer, figmaClient: FigmaClient) {
    /**
     * Tool: Duplicate page
     * Creates a complete copy of an existing page with all its children and content
     */
    server.tool(
        MCP_COMMANDS.DUPLICATE_PAGE,
        `Duplicate a Figma page and all its children as a new page.
        
        Creates a complete copy including:
        - All child nodes and their properties
        - Layer hierarchy and organization
        - Styles and formatting
        - Component instances and overrides
        
        Returns:
        - content: Array of objects with type "text" containing new page info as JSON
        `,
        DuplicatePageSchema.shape,
        {
            title: "Duplicate Page",
            idempotentHint: false,
            destructiveHint: false,
            readOnlyHint: false,
            openWorldHint: false,
            usageExamples: JSON.stringify([
                { 
                    description: "Duplicate page with auto-generated name",
                    input: { pageId: "123:456" }
                },
                { 
                    description: "Duplicate page with custom name",
                    input: { pageId: "123:456", newPageName: "My Duplicated Page" }
                }
            ]),
            edgeCaseWarnings: [
                "Duplicates all children of the original page recursively",
                "The new page will have a unique name and independent children",
                "Large pages may take significant time to duplicate",
                "Component instances will maintain their connections"
            ],
            extraInfo: "Use this command to duplicate an entire page and its contents. Useful for creating page templates or backing up page states before major changes."
        },
        async (params: any) => {
            try {
                // Validate that the figmaClient has the required method
                if (typeof figmaClient.duplicatePage !== "function") {
                    throw new Error("FigmaClient does not implement duplicatePage method");
                }

                const result = await figmaClient.duplicatePage(params.pageId, params.newPageName);
                const response = {
                    success: true,
                    results: [result]
                };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            } catch (error: any) {
                const response = {
                    success: false,
                    error: {
                        message: `Error duplicating page: ${error instanceof Error ? error.message : String(error)}`,
                        results: [],
                        meta: {
                            operation: "duplicate_page",
                            params
                        }
                    }
                };

                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response)
                    }]
                };
            }
        }
    );
}

These improvements provide comprehensive JSDoc documentation that includes detailed descriptions, parameter documentation, usage examples, return value specifications, and important warnings about edge cases. The documentation follows TypeScript and JSDoc best practices while making the code much more maintainable and developer-friendly.

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/0776f769-8e0a-446a-86f0-0622c90af44d/index.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/38c022fd-782a-417c-a675-c26462c71314/selection-tools.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/164833e4-bffb-4b15-81bc-637dcc0da328/document-tools.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/36f7422c-d7db-481f-8d09-8f49dff08b9c/selection-modify-tools.ts
[5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/71e2367d-d62a-4dec-a831-10e84828a9df/set-selection-schema.ts
[6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/d350905f-d8aa-44b5-95b5-0f17d5525254/document-creation-schema.ts
[7] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/9a4e5f81-1a3a-4fec-89fd-adca924e854e/document-creation.ts
[8] https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
[9] https://www.jetbrains.com/help/rider/Creating_JSDoc_Comments.html
[10] https://jsdoc.app/about-getting-started
[11] https://www.youtube.com/watch?v=-gaLriaslpg
[12] https://www.youtube.com/watch?v=YK-GurROGIg
[13] https://johnnyreilly.com/typescript-jsdoc-and-intellisense
[14] https://stackoverflow.com/questions/66553490/how-do-i-annotate-react-forwardref-with-jsdoc-comments-so-that-intellisense-can
[15] https://jsdoc.app/
[16] jsdoc/jsdoc#272
[17] microsoft/TypeScript#14619


Answer from Perplexity: pplx.ai/share

@eonist
Copy link
Author

eonist commented May 29, 2025

Looking at the TypeScript files provided, I can see several areas where the JSDoc documentation can be significantly improved. Here are my recommendations for enhancing the documentation:

Function and Method Documentation

The current JSDoc comments are good but can be enhanced with more comprehensive parameter descriptions, return type specifications, and usage examples.

Enhanced JSDoc for registerComponentNodeTools

/**
 * Registers the unified batch/single component creation tool on the MCP server.
 * 
 * This function adds a tool named "create_components_from_nodes" to the MCP server,
 * enabling conversion of one or more Figma nodes into reusable components.
 * It validates input, executes the corresponding Figma command for each node, and returns the results.
 * 
 * @param {McpServer} server - The MCP server instance to register the tool on
 * @param {FigmaClient} figmaClient - The Figma client used to execute commands against the Figma API
 * @returns {void} This function does not return a value but registers the tool asynchronously
 * 
 * @throws {Error} Throws an error if the server or figmaClient is invalid
 * 
 * @example
 * ```
 * const server = new McpServer();
 * const figmaClient = new FigmaClient(apiKey);
 * registerComponentNodeTools(server, figmaClient);
 * ```
 * 
 * @since 1.0.0
 * @see {@link MCP_COMMANDS.CREATE_COMPONENTS_FROM_NODE} for the command constant
 */

Enhanced JSDoc for Schema Objects

/**
 * Zod schema for a single node-to-component conversion entry.
 * 
 * Validates the structure of data required to convert a Figma node into a component,
 * including node ID validation and optional position maintenance settings.
 * 
 * @typedef {Object} NodeToComponentEntry
 * @property {string} nodeId - The Figma node ID to convert (format: "123:456")
 * @property {boolean} [maintain_position] - Whether to maintain the node's position after conversion
 * 
 * @example
 * ```
 * const validEntry = {
 *   nodeId: "123:456",
 *   maintain_position: true
 * };
 * 
 * const result = NodeToComponentEntrySchema.parse(validEntry);
 * ```
 * 
 * @throws {ZodError} Throws validation error if nodeId format is invalid
 * @since 1.0.0
 */
export const NodeToComponentEntrySchema = z.object({
  // ... schema definition
});

Type Definitions and Interfaces

For better TypeScript integration, add comprehensive type documentation:

/**
 * Configuration options for component instance creation.
 * 
 * @interface ComponentInstanceConfig
 * @property {string} componentKey - Unique identifier for the component (1-100 characters)
 * @property {number} x - X coordinate on canvas (range: -10000 to 10000)
 * @property {number} y - Y coordinate on canvas (range: -10000 to 10000)
 * 
 * @example
 * ```
 * const config: ComponentInstanceConfig = {
 *   componentKey: "abc:123",
 *   x: 100,
 *   y: 200
 * };
 * ```
 */

Async Function Documentation

Enhance async function documentation with Promise return types:

/**
 * Creates component instances from the provided configuration entries.
 * 
 * Processes either a single entry or multiple entries in batch, creating
 * component instances at specified coordinates on the Figma canvas.
 * 
 * @async
 * @function
 * @param {Object} params - The parameters object
 * @param {ComponentInstanceEntrySchema} [params.entry] - Single instance configuration
 * @param {ComponentInstanceEntrySchema[]} [params.entries] - Multiple instance configurations
 * @returns {Promise}>} Promise resolving to operation results
 * 
 * @throws {Error} Throws error if neither entry nor entries is provided
 * @throws {FigmaAPIError} Throws error if Figma API call fails
 * 
 * @example
 * ```
 * // Single instance
 * const result = await createInstances({
 *   entry: { componentKey: "abc:123", x: 100, y: 200 }
 * });
 * 
 * // Multiple instances
 * const batchResult = await createInstances({
 *   entries: [
 *     { componentKey: "abc:123", x: 100, y: 200 },
 *     { componentKey: "def:456", x: 300, y: 400 }
 *   ]
 * });
 * ```
 * 
 * @since 1.0.0
 */

Module-Level Documentation

Add comprehensive module documentation at the top of each file:

/**
 * @fileoverview Component management tools for Figma MCP integration.
 * 
 * This module provides tools for creating, managing, and manipulating Figma components
 * through the Model Context Protocol (MCP) server. It includes functionality for:
 * - Converting nodes to components
 * - Creating component instances
 * - Managing component variants
 * - Batch operations for improved efficiency
 * 
 * @module ComponentTools
 * @version 1.0.0
 * @author Your Team Name
 * @since 2025-01-01
 * 
 * @requires @modelcontextprotocol/sdk/server/mcp
 * @requires ../../../clients/figma-client
 * @requires zod
 * 
 * @example
 * ```
 * import { registerComponentTools } from './component-tools.js';
 * 
 * const server = new McpServer();
 * const figmaClient = new FigmaClient(apiKey);
 * registerComponentTools(server, figmaClient);
 * ```
 */

Error Handling Documentation

Document error scenarios more comprehensively:

/**
 * @typedef {Object} OperationResult
 * @property {string} nodeId - The processed node ID
 * @property {string} [componentId] - Created component ID (if successful)
 * @property {boolean} success - Whether the operation succeeded
 * @property {string} [error] - Error message (if failed)
 * @property {Object} [meta] - Additional metadata about the operation
 * @property {string} meta.operation - The operation type performed
 * @property {Object} meta.params - The parameters used for the operation
 */

Enum and Constant Documentation

/**
 * Available sources for component retrieval.
 * 
 * @enum {string}
 * @readonly
 */
const ComponentSource = {
  /** Components from the current Figma document */
  LOCAL: 'local',
  /** Components from the team library */
  TEAM: 'team',
  /** Components from remote team libraries */
  REMOTE: 'remote'
} as const;

These improvements will provide better IDE support, clearer documentation for API consumers, and more maintainable code with comprehensive type information and usage examples.

Citations:
[1] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/d1f80619-0da7-4e8e-b430-c9a8fa866a33/index.ts
[2] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/0988f95e-db9f-4134-baef-a354ba1539a8/component-node-tools.ts
[3] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/07acfcf6-3cd7-4d50-bfe0-7aad0a06c947/create-components-from-node-schema.ts
[4] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/2ed48252-6448-43e8-ae58-1e095876bc74/create-component-instance-schema.ts
[5] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/872857e1-5c8f-4132-ae45-3c3735d0383a/get-components-schema.ts
[6] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/2e1006c6-f786-4642-9d77-e0b20975f74c/variant-schema.ts
[7] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/8095498f-49d5-4187-be0c-890c52e87823/instance-tools.ts
[8] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/ec91a4e7-8ece-4297-9464-63e15a3beeb0/component-tools.ts
[9] https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/60313916/717bc25b-de7a-4e74-afac-251f31d1929a/variant-tools.ts
[10] https://stackoverflow.com/questions/70812483/how-to-use-jsdoc-annotations-in-indexed-types
[11] https://www.jetbrains.com/help/webstorm/creating-jsdoc-comments.html
[12] https://dev.to/kabartolo/how-to-document-an-express-api-with-swagger-ui-and-jsdoc-50do
[13] jsdoc/jsdoc#272
[14] https://stackoverflow.com/questions/57205260/how-do-i-add-jsdoc-comments-to-typescript-generated-with-the-typescript-ast-api
[15] https://jsdoc.app/
[16] https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
[17] microsoft/TypeScript#47718
[18] https://stackoverflow.com/questions/44306153/how-do-i-refer-to-another-typescript-type-in-comments-jsdoc
[19] microsoft/TypeScript#14619


Answer from Perplexity: pplx.ai/share

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment