Dial CLI Reference

The dial-cli tool is a powerful command-line utility for generating UI schemas from TypeScript interfaces with Dial annotations. This page provides a complete reference for all CLI features and options.

Installation

The dial-cli is now available as a standalone package for cleaner installation:

# Install globally (recommended for CLI tools)
npm install -g @vuer-ai/dial-cli
# or
pnpm install -g @vuer-ai/dial-cli

# Or install as a dev dependency
npm install --save-dev @vuer-ai/dial-cli
# or
pnpm add -D @vuer-ai/dial-cli

Once installed, the CLI is available directly:

# If installed globally
dial-cli --help

# If installed as dev dependency
npx dial-cli --help

Benefits of Standalone Package

  • Minimal dependencies - Only includes what's needed for CLI operation (typescript, react-docgen-typescript)
  • No peer dependency warnings - Doesn't require React, Tailwind, or other UI dependencies
  • Smaller install size - ~32KB unpacked vs entire UI kit
  • Independent versioning - CLI updates don't require UI kit updates

Command Line Options

Basic Usage

dial-cli [options] <files...>

Options Reference

OptionAliasDescriptionDefault
--output <dir>-oOutput directory for generated files./metadata
--verboseEnable verbose output with detailed informationfalse
--quietSuppress all output except errorsfalse
--removeRemove generated metadata filesfalse
--ignore <props>-iComma-separated list of properties to ignore-
--help-hDisplay help information-
--version-vDisplay version information-

Verbose Mode

The --verbose flag enables detailed output and generates additional files:

dial-cli --verbose MyComponent.tsx

In verbose mode, dial-cli generates:

  • schema.dial - Combined dial schema for all components (main output)
  • debug/ - Debug directory containing:
    • component-raw.json - Raw docgen output
    • component-combined.json - Enhanced metadata
    • component-schemas.json - Component schemas

Note: Debug files are organized in a debug/ subdirectory to keep the main output clean. These files are only generated in verbose mode and are useful for debugging schema generation issues.

Quiet Mode

The --quiet flag suppresses all output except errors, useful for CI/CD:

dial-cli --quiet src/components/*.tsx

Remove Mode

The --remove flag cleans up generated metadata files:

# Remove metadata for specific component
dial-cli --remove MyComponent.tsx

# Remove all metadata in output directory
dial-cli --remove --output ./metadata

Important: The remove command cleans up both the main schema.dial file and any debug files in the debug/ directory. It supports both the current debug directory structure and legacy file locations for backward compatibility.

Ignore Properties

Exclude specific properties from schema generation:

# Ignore single property
dial-cli --ignore ref MyComponent.tsx

# Ignore multiple properties
dial-cli --ignore "ref,key,children" MyComponent.tsx

# Using short alias
dial-cli -i "internalProp,debugValue" Component.tsx

Output Files

Standard Output (Default)

Without verbose mode, only generates:

  • schema.dial - Combined schema for all processed components

Verbose Output

With --verbose flag, generates additional files per component:

  • [component]-schemas.json - Component-specific schema
  • [component]-raw.json - Raw react-docgen output
  • [component]-combined.json - Enhanced metadata with dial annotations
  • schema.dial - Combined schema (always generated)

Group-Level Configuration

You can apply configuration to entire groups of properties using interface-level JSDoc comments:

Using @dial-no-wrap

The @dial-no-wrap annotation prevents line wrapping for all properties in a group:

interface ComponentProps {
  /**
   * Layout configuration for transform properties
   * @dial transform @dial-no-wrap
   */
  
  /** @dial transform @dial-dtype vector3 */
  position: number[];
  
  /** @dial transform @dial-dtype euler */
  rotation: number[];
  
  /** @dial transform @dial-dtype vector3 */
  scale: number[];
}

In this example, all properties in the "transform" group (position, rotation, scale) will be displayed on a single line without wrapping.

Groups in Output Schema

The CLI now generates a groups section in the output schema:

{
  "component": "ExampleBox",
  "schema": [...],
  "groups": [
    {
      "name": "transform",
      "noWrap": true
    }
  ]
}

This allows the UI to apply group-specific styling and layout configuration.

Excluding Properties

There are two ways to exclude properties from dial schema generation:

1. Using @dial-ignore Annotation

Add @dial-ignore to any property's JSDoc comment to exclude it from the generated schema:

interface ComponentProps {
  /**
   * Public property - included in schema
   * @dial transform
   * @dial-dtype vector3
   */
  position: number[];

  /**
   * Internal state - excluded from schema
   * @dial-ignore
   */
  _internalCache?: any;

  /**
   * React ref - excluded from schema
   * @dial-ignore
   */
  ref?: React.Ref<HTMLDivElement>;
}

2. Using CLI --ignore Option

The -i or --ignore option allows you to exclude properties by name or pattern at runtime:

# Exclude specific properties
dial-cli -i className -i style Component.tsx

# Exclude using comma-separated list
dial-cli --ignore ref,key,id Component.tsx

# Exclude using glob patterns
dial-cli -i "*Style" -i "on*" -i "_*" Component.tsx

Glob Pattern Examples

PatternMatchesExample Properties
*StyleEnds with "Style"containerStyle, buttonStyle, textStyle
on*Starts with "on"onClick, onChange, onSubmit
_*Starts with underscore_internal, _cache, _private
*RefEnds with "Ref"inputRef, containerRef, buttonRef
data*Starts with "data"dataSource, dataProvider, dataKey

Class/Interface Level Suppression

The @dial-ignore annotation can be used at the class or interface level to completely suppress dial schema generation for an entire component and all its properties:

/**
 * Internal configuration component
 * @dial-ignore
 */
interface InternalSettingsProps {
  apiKey: string;
  debugMode: boolean;
  serverUrl: string;
  // All properties will be excluded from dial schema
}

/**
 * Admin-only component
 * @dial-ignore
 */
export const AdminPanel: FC<AdminPanelProps> = ({ ... }) => {
  // This component won't appear in dial UI
}

This is useful for:

  • Internal/utility components that shouldn't be exposed in the UI
  • Admin-only or developer-only components
  • Components that are still under development
  • Helper components that are only used internally

When @dial-ignore is used at the class/interface level:

  • The entire component is skipped during dial schema generation
  • No properties from that component will appear in the dial UI
  • Any child properties or nested interfaces are also excluded

Custom Property Labels

The @dial-label annotation allows you to specify custom labels for properties that will be displayed in the UI instead of the default auto-generated labels from the property name:

interface ComponentProps {
  /**
   * Position in 3D space
   * @dial transform
   * @dial-dtype vector3
   * @dial-label 3D Position
   */
  pos3d: [number, number, number];

  /**
   * Background color
   * @dial appearance
   * @dial-dtype color
   * @dial-label Background Color
   */
  bgColor: string;

  /**
   * Enable shadows
   * @dial-dtype boolean
   * @dial-label Enable Shadow Rendering
   */
  shadowsOn: boolean;
}

In the generated UI:

  • pos3d will display as "3D Position" instead of "Pos3d"
  • bgColor will display as "Background Color" instead of "BgColor"
  • shadowsOn will display as "Enable Shadow Rendering" instead of "ShadowsOn"

This is particularly useful when property names follow coding conventions (camelCase, abbreviations) but you want more user-friendly labels in the UI.

Complete Example

Here's a complete example showing exclusion methods and custom labels:

Component Definition

// Box3D.tsx
interface Box3DProps {
  /**
   * Box dimensions
   * @dial geometry
   * @dial-dtype vector3
   * @dial-min 0.1
   * @dial-max 10
   * @dial-step 0.1
   */
  size: [number, number, number];

  /**
   * Position in 3D space
   * @dial transform
   * @dial-dtype vector3
   * @dial-min -100
   * @dial-max 100
   * @dial-step 0.5
   */
  position: [number, number, number];

  /**
   * Material color
   * @dial appearance
   * @dial-dtype color
   */
  color: string;

  /**
   * Opacity level
   * @dial appearance
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  opacity: number;

  // Properties to exclude:

  /**
   * Internal mesh reference
   * @dial-ignore
   */
  _meshRef?: THREE.Mesh;

  /**
   * React className - will be excluded via CLI
   */
  className?: string;

  /**
   * React style - will be excluded via CLI
   */
  style?: React.CSSProperties;

  /**
   * Click handler - will be excluded via CLI pattern
   */
  onClick?: () => void;

  /**
   * Change handler - will be excluded via CLI pattern
   */
  onChange?: (value: any) => void;
}

CLI Commands

# Generate schema excluding React-specific props and handlers
dial-cli -i className -i style -i "on*" Box3D.tsx

# Or using comma-separated list
dial-cli --ignore className,style,onClick,onChange Box3D.tsx

# Exclude all private properties and event handlers
dial-cli -i "_*" -i "on*" Box3D.tsx

Generated Schema

The generated schema will only include:

  • size - Box dimensions control
  • position - Position control
  • color - Color picker
  • opacity - Opacity slider

Excluded properties:

  • _meshRef - Excluded by @dial-ignore annotation
  • className, style - Excluded by CLI -i option
  • onClick, onChange - Excluded by CLI pattern "on*"

CLI Options Reference

dial-cli [options] <files...>

Options

OptionShortDescriptionExample
--output <dir>-oOutput directory for generated files-o ./schemas
--ignore <prop>-iProperties to exclude (supports glob)-i className -i "on*"
--verboseEnable verbose output--verbose
--quietSuppress output except errors--quiet
--help-hDisplay help message--help
--version-vDisplay version--version

Output Files

The CLI generates files with a clean directory structure:

Main Output:

  • schema.dial - Combined schemas for all components, ready for UI generation

Debug Output (verbose mode only):

  • debug/component-raw.json - Raw AST and JSDoc extraction
  • debug/component-combined.json - Enhanced metadata with dial schemas
  • debug/component-schemas.json - Individual component schemas

This structure keeps your main output directory clean while providing detailed debug information when needed.

Best Practices

1. Combine Both Exclusion Methods

Use @dial-ignore for properties that should never be exposed in the UI:

/**
 * @dial-ignore
 */
_internalState?: any;

Use CLI --ignore for context-specific exclusions:

# Exclude React-specific props when generating for non-React environments
dial-cli -i className -i style Component.tsx

2. Use Patterns for Consistency

Create consistent naming conventions and use patterns:

# Exclude all private properties, refs, and handlers
dial-cli -i "_*" -i "*Ref" -i "on*" Component.tsx

3. Create Build Scripts

Add scripts to your package.json:

{
  "scripts": {
    "dial:generate": "dial-cli -o ./schemas -i className,style,key,ref src/components/*.tsx",
    "dial:generate:clean": "dial-cli -o ./schemas -i '_*,on*,*Ref,className,style' src/components/*.tsx"
  }
}

4. Document Excluded Properties

When using @dial-ignore, add a comment explaining why:

/**
 * Internal cache for performance optimization
 * Not meant to be modified by users
 * @dial-ignore
 */
_cache?: Map<string, any>;

Integration Example

Here's how to use the generated schemas in your application:

import { DialProvider, DialPanel } from '@vuer-ai/vuer-uikit';
import allSchemas from './schemas/schema.dial';

function App() {
  const [props, setProps] = useState({
    size: [1, 1, 1],
    position: [0, 0, 0],
    color: '#ff0000',
    opacity: 1
  });

  const handleValueChange = (name: string, value: any) => {
    setProps(prev => ({ ...prev, [name]: value }));
  };

  // Get the specific component schema from the combined schema file
  const box3DSchema = allSchemas.find(s => s.component === 'Box3D');

  return (
    <DialProvider schemas={[box3DSchema]} onValueChange={handleValueChange}>
      <div style={{ display: 'flex' }}>
        <Canvas>
          <Box3D {...props} />
        </Canvas>
        <DialPanel schemas={[box3DSchema]} />
      </div>
    </DialProvider>
  );
}

Troubleshooting

Properties Not Being Excluded

  1. Check annotation syntax: Ensure @dial-ignore is on its own line
  2. Check pattern syntax: Use quotes for patterns with wildcards: -i "*Style"
  3. Check property names: Property names are case-sensitive

Generated Schema Is Empty

  1. Ensure your interface has JSDoc comments with @dial annotations
  2. Check that the TypeScript file exports the interface
  3. Verify the file path is correct

Build Errors

  1. Ensure @vuer-ai/dial-cli is installed
  2. Try using the full path: node_modules/.bin/dial-cli (if installed locally)
  3. Check Node.js version (requires Node 14+)

Summary

The dial-cli tool provides flexible property exclusion through:

  • @dial-ignore annotation - Permanent, code-level exclusion
  • --ignore CLI option - Runtime, context-specific exclusion
  • Glob patterns - Flexible pattern-based exclusion

Combine these features to create clean, focused UI schemas that expose only the properties users need to control.