From 653b66b1fd7fdb6a2e44eb1bffa37f34b7c0f3ce Mon Sep 17 00:00:00 2001 From: alexey1312 Date: Fri, 13 Mar 2026 12:21:17 +0500 Subject: [PATCH 1/3] feat: add Usage CLI spec for shell completions and docs Add exfig.usage.kdl with full specification of all 19 CLI commands, flags, and arguments. This enables generating shell completions (bash/zsh/fish) and markdown documentation from a single source of truth. - Add usage tool to mise.toml with completions and docs tasks - Generate and attach shell completions as GitHub Release assets - Update CLAUDE.md with completions commands and KDL sync reminder Co-Authored-By: Claude Opus 4.6 --- .github/workflows/release.yml | 12 ++ CLAUDE.md | 8 + exfig.usage.kdl | 334 ++++++++++++++++++++++++++++++++++ mise.lock | 5 + mise.toml | 23 +++ 5 files changed, 382 insertions(+) create mode 100644 exfig.usage.kdl diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7279f0ff..c3b65d61 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -192,6 +192,15 @@ jobs: --output-path ".pkl-out/%{name}@%{version}/" \ Sources/ExFigCLI/Resources/Schemas + - name: Generate shell completions + run: | + curl -sL "https://github.com/jdx/usage/releases/latest/download/usage-x86_64-unknown-linux-gnu.tar.gz" | tar xz + chmod +x usage/bin/usage + mkdir -p completions + usage/bin/usage generate completion bash exfig -f exfig.usage.kdl > completions/exfig.bash + usage/bin/usage generate completion zsh exfig -f exfig.usage.kdl > completions/_exfig + usage/bin/usage generate completion fish exfig -f exfig.usage.kdl > completions/exfig.fish + - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: @@ -201,6 +210,9 @@ jobs: artifacts/exfig-macos/exfig-macos.zip artifacts/exfig-linux-x64/exfig-linux-x64.tar.gz .pkl-out/exfig@*/* + completions/exfig.bash + completions/_exfig + completions/exfig.fish update-homebrew: name: Update Homebrew Tap diff --git a/CLAUDE.md b/CLAUDE.md index 842fd39d..01a24159 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -87,6 +87,12 @@ and Flutter projects. ./bin/mise run clean # Clean build artifacts ./bin/mise run clean:all # Clean build + derived data +# Shell Completions & CLI Docs (via Usage spec) +./bin/mise run completions:bash # Generate bash completions +./bin/mise run completions:zsh # Generate zsh completions +./bin/mise run completions:fish # Generate fish completions +./bin/mise run docs:cli-reference # Generate CLI reference docs + # Run CLI .build/debug/exfig --help .build/debug/exfig colors -i exfig.pkl @@ -279,6 +285,8 @@ Changing `load()` return type affects: See `ExFigCLI/CLAUDE.md` (Adding a New Subcommand). +**Important:** When adding/changing CLI flags or subcommands, update `exfig.usage.kdl` (Usage spec) to keep shell completions and docs in sync. + ### Adding a Figma API Endpoint See `FigmaAPI/CLAUDE.md`. diff --git a/exfig.usage.kdl b/exfig.usage.kdl new file mode 100644 index 00000000..27702d31 --- /dev/null +++ b/exfig.usage.kdl @@ -0,0 +1,334 @@ +// Usage specification for ExFig CLI +// https://usage.jdx.dev/spec/ +// +// Generate completions: usage generate completion bash exfig -f exfig.usage.kdl +// Generate docs: usage generate markdown -f exfig.usage.kdl + +name "ExFig" +bin "exfig" +version "2.8.0" +about "Exports resources from Figma to iOS, Android, Flutter, and Web projects" + +// ============================================================================= +// Global flags +// ============================================================================= + +flag "-v --verbose" help="Show detailed output including debug information" global=#true +flag "-q --quiet" help="Show only errors, suppress progress output" global=#true + +// ============================================================================= +// colors (default subcommand) +// ============================================================================= + +cmd "colors" help="Exports colors from Figma" { + long_help "Exports light and dark color palette from Figma to Xcode / Android Studio project. Requires FIGMA_PERSONAL_TOKEN environment variable." + + flag "-i --input " help="Path to PKL config file. Auto-detects exfig.pkl if not specified." + flag "--cache" help="Enable version tracking cache (skip export if unchanged)" negate="--no-cache" + flag "--force" help="Force export and update cache (ignore cached version)" + flag "--cache-path " help="Custom path to cache file (default: .exfig-cache.json)" + flag "--experimental-granular-cache" help="[EXPERIMENTAL] Enable per-node hash tracking for granular cache invalidation" hide=#true + flag "--max-retries " help="Maximum retry attempts for failed API requests" default="4" + flag "--rate-limit " help="Maximum API requests per minute" default="10" + flag "--timeout " help="Figma API request timeout in seconds (overrides config)" + flag "--report " help="Path to write JSON report" + + arg "[filter]" help="Name of the colors to export (e.g., 'background/*', 'background/default, background/secondary')" +} + +// ============================================================================= +// icons +// ============================================================================= + +cmd "icons" help="Exports icons from Figma" { + long_help "Exports icons from Figma to Xcode / Android Studio project. Requires FIGMA_PERSONAL_TOKEN environment variable." + + flag "-i --input " help="Path to PKL config file. Auto-detects exfig.pkl if not specified." + flag "--cache" help="Enable version tracking cache (skip export if unchanged)" negate="--no-cache" + flag "--force" help="Force export and update cache (ignore cached version)" + flag "--cache-path " help="Custom path to cache file (default: .exfig-cache.json)" + flag "--experimental-granular-cache" help="[EXPERIMENTAL] Enable per-node hash tracking for granular cache invalidation" hide=#true + flag "--max-retries " help="Maximum retry attempts for failed API requests" default="4" + flag "--rate-limit " help="Maximum API requests per minute" default="10" + flag "--timeout " help="Figma API request timeout in seconds (overrides config)" + flag "--fail-fast" help="Stop on first error without retrying" + flag "--resume" help="Continue from checkpoint after interruption" + flag "--concurrent-downloads " help="Maximum concurrent CDN downloads" default="20" + flag "--strict-path-validation" help="Exit with error if any Android icon pathData exceeds 32,767 bytes (AAPT limit)" + flag "--report " help="Path to write JSON report" + + arg "[filter]" help="Name of the icons to export (e.g., 'ic/24/edit', 'ic/16/*')" +} + +// ============================================================================= +// images +// ============================================================================= + +cmd "images" help="Exports images from Figma" { + long_help "Exports images from Figma to Xcode / Android Studio project. Requires FIGMA_PERSONAL_TOKEN environment variable." + + flag "-i --input " help="Path to PKL config file. Auto-detects exfig.pkl if not specified." + flag "--cache" help="Enable version tracking cache (skip export if unchanged)" negate="--no-cache" + flag "--force" help="Force export and update cache (ignore cached version)" + flag "--cache-path " help="Custom path to cache file (default: .exfig-cache.json)" + flag "--experimental-granular-cache" help="[EXPERIMENTAL] Enable per-node hash tracking for granular cache invalidation" hide=#true + flag "--max-retries " help="Maximum retry attempts for failed API requests" default="4" + flag "--rate-limit " help="Maximum API requests per minute" default="10" + flag "--timeout " help="Figma API request timeout in seconds (overrides config)" + flag "--fail-fast" help="Stop on first error without retrying" + flag "--resume" help="Continue from checkpoint after interruption" + flag "--concurrent-downloads " help="Maximum concurrent CDN downloads" default="20" + flag "--report " help="Path to write JSON report" + + arg "[filter]" help="Name of the images to export (e.g., 'img/login', 'img/onboarding/*')" +} + +// ============================================================================= +// typography +// ============================================================================= + +cmd "typography" help="Exports typography from Figma" { + alias "text-styles" + long_help "Exports font styles from Figma to Xcode. Requires FIGMA_PERSONAL_TOKEN environment variable." + + flag "-i --input " help="Path to PKL config file. Auto-detects exfig.pkl if not specified." + flag "--cache" help="Enable version tracking cache (skip export if unchanged)" negate="--no-cache" + flag "--force" help="Force export and update cache (ignore cached version)" + flag "--cache-path " help="Custom path to cache file (default: .exfig-cache.json)" + flag "--experimental-granular-cache" help="[EXPERIMENTAL] Enable per-node hash tracking for granular cache invalidation" hide=#true + flag "--max-retries " help="Maximum retry attempts for failed API requests" default="4" + flag "--rate-limit " help="Maximum API requests per minute" default="10" + flag "--timeout " help="Figma API request timeout in seconds (overrides config)" + flag "--report " help="Path to write JSON report" +} + +// ============================================================================= +// init +// ============================================================================= + +cmd "init" help="Generates config file" { + long_help "Generates exfig.pkl config file in the current directory." + + flag "-p --platform " help="Platform: ios, android, flutter, or web" required=#true { + choices "ios" "android" "flutter" "web" + } +} + +// ============================================================================= +// schemas +// ============================================================================= + +cmd "schemas" help="Extracts PKL schemas to local directory" { + long_help "Extracts PKL schema files used for config validation and IDE support. Schemas are extracted to .exfig/schemas/ by default." + + flag "-o --output " help="Output directory for schemas." default=".exfig/schemas/" + flag "-f --force" help="Overwrite existing schema files." +} + +// ============================================================================= +// fetch +// ============================================================================= + +cmd "fetch" help="Downloads images from Figma without config file" { + long_help "Downloads images from a specific Figma frame to a local directory. All parameters are passed via command-line arguments. Requires FIGMA_PERSONAL_TOKEN environment variable." + + flag "-f --file-id " help="Figma file ID (from the URL: figma.com/file//...)" required=#true + flag "-r --frame " help="Name of the Figma frame containing images" required=#true + flag "-p --page " help="Filter by Figma page name." + flag "-o --output " help="Output directory for downloaded images" required=#true + flag "--format " help="Image format" default="png" { + choices "png" "svg" "jpg" "pdf" "webp" + } + flag "--scale " help="Scale factor (0.01-4.0). Default: 3 for PNG, ignored for vector formats" + flag "--filter " help="Filter pattern (e.g., 'icon/*' or 'logo, banner')" + flag "--name-style