figma-local 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # figma-cli
2
+
3
+ > Control Figma Desktop with Claude Code. Design tokens, shadcn/ui components, AI prompt export, lint, and more — no API key required.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/figma-local.svg)](https://www.npmjs.com/package/figma-local)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
+ [![Node.js](https://img.shields.io/badge/Node.js-18%2B-brightgreen)](https://nodejs.org)
8
+ [![Platform](https://img.shields.io/badge/Platform-macOS%20%7C%20Windows-blue)](#)
9
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-Ready-blue)](https://claude.ai/claude-code)
10
+
11
+ ---
12
+
13
+ ## What is this?
14
+
15
+ **figma-cli** connects directly to Figma Desktop and lets you — or Claude Code — control it with natural language and `fig` commands.
16
+
17
+ - **Write** — Create frames, components, design tokens, icons, and full UI kits
18
+ - **Read** — Extract design context in a lean staged format (91–97% fewer tokens than raw data dumps)
19
+ - **Export** — Generate AI-ready prompts for Figma Make, Lovable, Pencil.dev, Paper.design, Google Stitch
20
+ - **Analyse** — Lint designs, check accessibility, audit colors and typography
21
+ - **Zero API key** — Connects via a local plugin bridge, no Figma API credentials needed
22
+
23
+ ---
24
+
25
+ ## Credits
26
+
27
+ This project is built on the shoulders of two excellent open-source works:
28
+
29
+ | Project | Author | What we built on |
30
+ |---------|--------|------------------|
31
+ | [**silships/figma-cli**](https://github.com/silships/figma-cli) | Sil Bormüller · [Into Design Systems](https://intodesignsystems.com) | Core daemon, plugin bridge, CDP connection, shadcn/ui component library, render engine, design token presets, FigJam support |
32
+ | [**royvillasana/figma-to-ai-prompter**](https://github.com/royvillasana/figma-to-ai-prompter) | Roy Villasana | Staged lean extraction approach, per-tool prompt templates, token-efficiency methodology |
33
+
34
+ **Our additions on top:**
35
+ - `fig read` — 3-phase staged design extraction (metadata → frame structure → used tokens only)
36
+ - `fig prompt` — lean tool-specific prompt generation (figma-make, lovable, pencil, paper, stitch)
37
+ - `fig verify --compare` — prototype vs design comparison loop with correction prompts
38
+ - Security hardening — WebSocket nonce handshake, input validation, rate limiting, body size caps
39
+ - `fig` short command — works globally from any directory
40
+ - Plugin UX — shows actionable "how to connect" instructions instead of infinite "Scanning..."
41
+
42
+ ---
43
+
44
+ ## Install
45
+
46
+ ### npm (recommended)
47
+
48
+ ```bash
49
+ npm install -g figma-local
50
+ ```
51
+
52
+ Gives you `fig` and `fig-start` globally on your PATH.
53
+
54
+ ### curl (one-line)
55
+
56
+ ```bash
57
+ curl -fsSL https://raw.githubusercontent.com/thepreakerebi/figma-cli/main/install.sh | bash
58
+ ```
59
+
60
+ ### Homebrew
61
+
62
+ ```bash
63
+ brew tap thepreakerebi/figma-cli
64
+ brew install figma-cli
65
+ ```
66
+
67
+ ### npx (no install)
68
+
69
+ ```bash
70
+ npx figma-local read
71
+ ```
72
+
73
+ ### From source
74
+
75
+ ```bash
76
+ git clone https://github.com/thepreakerebi/figma-cli.git
77
+ cd figma-cli
78
+ npm install && npm install -g .
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Requirements
84
+
85
+ | | |
86
+ |-|-|
87
+ | Node.js | 18+ |
88
+ | Figma Desktop | Any version (free account works) |
89
+ | OS | macOS or Windows |
90
+ | Claude Code | Optional but recommended |
91
+
92
+ ---
93
+
94
+ ## Setup (one time only)
95
+
96
+ ### 1. Import the Figma plugin
97
+
98
+ 1. Open **Figma Desktop**
99
+ 2. Hamburger menu → **Plugins → Development → Import plugin from manifest...**
100
+ 3. Navigate to the `plugin/` folder in this repo (or `$(npm root -g)/figma-local/plugin/`)
101
+ 4. Select `manifest.json` → click **Open**
102
+ 5. Right-click **FigCli** in the plugin list → **Add to toolbar**
103
+
104
+ ### 2. Connect
105
+
106
+ ```bash
107
+ fig-start --safe
108
+ ```
109
+
110
+ This starts the daemon, waits for you to click FigCli in Figma, then launches Claude Code.
111
+
112
+ ---
113
+
114
+ ## Every session after that
115
+
116
+ ```
117
+ 1. Open Figma → click FigCli in the toolbar
118
+ 2. In terminal: fig-start --safe
119
+ ```
120
+
121
+ Claude Code reads `CLAUDE.md` and knows every command automatically.
122
+
123
+ ---
124
+
125
+ ## Commands
126
+
127
+ ### Read & understand your canvas
128
+
129
+ ```bash
130
+ fig read # List all frames (fast)
131
+ fig read "Login Screen" # Layout + components + used tokens only
132
+ fig read "Login Screen" --tokens # Just the design tokens that frame uses
133
+ fig find "Button" # Find nodes by name
134
+ fig node tree # Layer hierarchy
135
+ fig canvas info # Raw canvas info
136
+ ```
137
+
138
+ ### Design tokens
139
+
140
+ ```bash
141
+ fig tokens preset shadcn # 276 variables: primitives + semantic (Light/Dark)
142
+ fig tokens tailwind # Tailwind 242-color palette
143
+ fig var list # All variables
144
+ fig var visualize # Swatches on canvas
145
+ fig var export css # → CSS custom properties
146
+ fig var export tailwind # → Tailwind config
147
+ fig bind fill "primary/500" # Bind variable to selection
148
+ ```
149
+
150
+ ### shadcn/ui components
151
+
152
+ ```bash
153
+ fig shadcn list # 30 available components
154
+ fig shadcn add button card input # Add specific ones
155
+ fig shadcn add --all # All 30 components, 58 variants
156
+ ```
157
+
158
+ Includes Button, Card, Input, Dialog, Tabs, Select, Switch, Badge, Alert, Checkbox, Radio Group, Accordion, Table, Pagination, Breadcrumb, Sheet, Tooltip, Dropdown, Avatar, Spinner, and more. All wired to Light/Dark variables.
159
+
160
+ ### Create anything
161
+
162
+ ```bash
163
+ # Quick primitives
164
+ fig create rect "Card" -w 320 -h 200 --fill "var:card" --radius 12
165
+ fig create text "Hello" -s 24 -c "var:foreground" -w bold
166
+ fig create icon lucide:home -s 24
167
+
168
+ # JSX render
169
+ fig render '<Frame name="Card" w={320} bg="var:card" rounded={16} flex="col" gap={8} p={24}>
170
+ <Text size={20} weight="bold" color="var:foreground">Title</Text>
171
+ <Text size={14} color="var:muted-foreground">Description</Text>
172
+ </Frame>'
173
+
174
+ # Pre-built blocks
175
+ fig blocks create dashboard-01 # Full analytics dashboard
176
+ ```
177
+
178
+ ### Icons (150,000+)
179
+
180
+ ```bash
181
+ fig create icon lucide:home -s 24
182
+ fig create icon material:search -s 24
183
+ fig create icon heroicons:bell -s 20 -c "var:primary"
184
+ ```
185
+
186
+ Lucide, Material Design, Heroicons, Feather, and 50+ more via Iconify.
187
+
188
+ ### Export AI prompts
189
+
190
+ ```bash
191
+ fig prompt "Screen" --target figma-make
192
+ fig prompt "Screen" --target lovable --stack "React + shadcn/ui"
193
+ fig prompt "Screen" --target pencil
194
+ fig prompt "Screen" --target stitch --platform responsive
195
+
196
+ # With context for better output
197
+ fig prompt "Login" \
198
+ --target lovable \
199
+ --goal "user signs in with email and password" \
200
+ --interactions "submit validates form, forgot password opens modal" \
201
+ --guardrails "no social login"
202
+ ```
203
+
204
+ Generates ~45 tokens of structured text instead of attaching a Figma frame (300–500+ hidden tokens). **91–97% smaller input, more consistent AI output.**
205
+
206
+ ### Verify & compare
207
+
208
+ ```bash
209
+ fig verify # Screenshot of selection for AI review
210
+ fig verify --compare "https://..." # Diff prototype vs Figma design → correction prompts
211
+ ```
212
+
213
+ ### Export
214
+
215
+ ```bash
216
+ fig export css # Variables → CSS
217
+ fig export tailwind # Variables → Tailwind config
218
+ fig export screenshot -o out.png # Screenshot (add -s 2 for 2x)
219
+ fig export-jsx "1:234" # → React JSX
220
+ fig export-storybook "1:234" # → Storybook stories
221
+ ```
222
+
223
+ ### Lint & accessibility
224
+
225
+ ```bash
226
+ fig lint # All rules
227
+ fig lint --fix # Auto-fix
228
+ fig lint --preset accessibility # WCAG rules only
229
+ fig analyze colors # Color usage audit
230
+ fig analyze typography
231
+ ```
232
+
233
+ Rules: WCAG AA/AAA contrast ratio, touch targets (44×44px min), hardcoded colors, empty frames, deeply nested layers, missing auto-layout, minimum text size.
234
+
235
+ ### FigJam
236
+
237
+ ```bash
238
+ fig fj sticky "Idea" -x 100 -y 100 --color "#FEF08A"
239
+ fig fj shape "Label" -x 200 -y 100 -w 200 -h 100
240
+ fig fj connect "ID1" "ID2"
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Connection modes
246
+
247
+ | | Safe Mode | Yolo Mode |
248
+ |-|-----------|-----------|
249
+ | How | Plugin bridge | Direct CDP |
250
+ | Setup per session | Start FigCli plugin | Nothing (after one-time patch) |
251
+ | Speed | Standard | ~10× faster |
252
+ | Extra permissions | None | macOS: Full Disk Access / Windows: Admin |
253
+ | Command | `fig connect --safe` | `fig connect` |
254
+
255
+ **Recommendation:** Safe Mode. No system permissions needed, works on all machines including managed corporate Macs.
256
+
257
+ ---
258
+
259
+ ## Security
260
+
261
+ The daemon runs only on `127.0.0.1` (never exposed to the network) and is protected by multiple layers:
262
+
263
+ | Layer | Protects against |
264
+ |-------|-----------------|
265
+ | Binds to `127.0.0.1` | Not reachable from outside your machine |
266
+ | Session token (`X-Daemon-Token`) | Unauthorized local processes calling the HTTP API |
267
+ | Host header validation | DNS rebinding attacks |
268
+ | No CORS headers | Cross-origin browser requests |
269
+ | WebSocket nonce handshake | Rogue local processes impersonating the plugin |
270
+ | WebSocket origin validation | Browser tabs connecting to the daemon |
271
+ | 1 MB request/message body cap | Memory exhaustion from oversized payloads |
272
+ | Plugin input validation | Code size cap (512 KB), batch size cap (50), strict field types |
273
+ | Rate limiting | Max 30 evals per 10 s per connection |
274
+ | Idle auto-shutdown | Daemon stops after 10 minutes of inactivity |
275
+
276
+ The session token is generated fresh on every `fig connect`, stored at `~/.figma-ds-cli/.daemon-token` with `chmod 600` (owner-read only).
277
+
278
+ ---
279
+
280
+ ## Work from anywhere
281
+
282
+ ```bash
283
+ fig read # works from any directory
284
+ fig-start --safe --here # launch from your project dir; Claude sees both your project and Figma
285
+ ```
286
+
287
+ ---
288
+
289
+ ## For teams
290
+
291
+ ```bash
292
+ # Install once per machine
293
+ npm install -g figma-local
294
+
295
+ # Import the Figma plugin once per Figma account (5 minutes)
296
+ # Then every designer on the team has identical fig commands
297
+ ```
298
+
299
+ Pin a version for consistency:
300
+
301
+ ```bash
302
+ npm install -g @jetro/figma-local@1.0.0
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Uninstall
308
+
309
+ ```bash
310
+ npm uninstall -g figma-local
311
+ rm -rf ~/.figma-cli ~/.figma-ds-cli
312
+ ```
313
+
314
+ Remove the plugin in Figma: Plugins → Development → right-click FigCli → Remove.
315
+
316
+ ---
317
+
318
+ ## Contributing
319
+
320
+ Issues and PRs welcome. For major changes, open an issue first to discuss.
321
+
322
+ ```bash
323
+ git clone https://github.com/thepreakerebi/figma-cli.git
324
+ cd figma-cli
325
+ npm install
326
+ node src/index.js --help
327
+ npm test
328
+ ```
329
+
330
+ ---
331
+
332
+ ## License
333
+
334
+ MIT — see [LICENSE](LICENSE).
335
+
336
+ ---
337
+
338
+ ## Acknowledgements
339
+
340
+ - **[silships/figma-cli](https://github.com/silships/figma-cli)** by Sil Bormüller ([Into Design Systems](https://intodesignsystems.com)) — the original Figma Desktop CLI. The core engine, plugin bridge, CDP connection, shadcn/ui components, render pipeline, and design token presets all originate here. Please star their repo.
341
+
342
+ - **[royvillasana/figma-to-ai-prompter](https://github.com/royvillasana/figma-to-ai-prompter)** by Roy Villasana — the staged extraction and lean prompt approach. The insight that a text context block saves 91–97% of tokens vs attaching a Figma frame comes from their work. Please star their repo too.
package/bin/fig-start ADDED
@@ -0,0 +1,289 @@
1
+ #!/bin/bash
2
+
3
+ # fig-start — Launch Figma CLI + Claude Code
4
+ # Connects to Figma, lets you pick an open file, then launches Claude Code.
5
+ #
6
+ # Usage:
7
+ # fig-start → Yolo Mode (default) with file selector
8
+ # fig-start --safe → Safe Mode (plugin-based, no patching)
9
+ # fig-start --here → Stay in current directory (don't cd to repo)
10
+ # fig-start --setup → set/change the figma-cli repo path
11
+
12
+ CONFIG_DIR="$HOME/.figma-cli"
13
+ CONFIG_FILE="$CONFIG_DIR/config.json"
14
+
15
+ GREEN='\033[0;32m'
16
+ YELLOW='\033[1;33m'
17
+ RED='\033[0;31m'
18
+ BOLD='\033[1m'
19
+ DIM='\033[2m'
20
+ NC='\033[0m'
21
+
22
+ # ── Config helpers ──
23
+
24
+ get_daemon_token() {
25
+ local token_file="$HOME/.figma-ds-cli/.daemon-token"
26
+ if [ -f "$token_file" ]; then
27
+ cat "$token_file" 2>/dev/null
28
+ fi
29
+ }
30
+
31
+ get_repo_path() {
32
+ if [ -f "$CONFIG_FILE" ]; then
33
+ python3 -c "import json; print(json.load(open('$CONFIG_FILE')).get('repoPath',''))" 2>/dev/null
34
+ fi
35
+ }
36
+
37
+ save_repo_path() {
38
+ mkdir -p "$CONFIG_DIR"
39
+ python3 -c "
40
+ import json, os
41
+ path = '$CONFIG_FILE'
42
+ cfg = {}
43
+ if os.path.exists(path):
44
+ with open(path) as f: cfg = json.load(f)
45
+ cfg['repoPath'] = '$1'
46
+ with open(path, 'w') as f: json.dump(cfg, f, indent=2)
47
+ "
48
+ }
49
+
50
+ # ── Arrow-key selector (same UX as fancoolo-start) ──
51
+
52
+ select_file() {
53
+ local options=("$@")
54
+ local count=${#options[@]}
55
+ local selected=0
56
+
57
+ tput civis > /dev/tty 2>/dev/null
58
+ trap 'tput cnorm > /dev/tty 2>/dev/null' EXIT
59
+
60
+ draw_menu() {
61
+ if [ "$1" = "redraw" ]; then
62
+ printf "\033[%dA" "$((count + 2))" > /dev/tty
63
+ fi
64
+
65
+ printf "${BOLD}Select a Figma file (↑↓ arrows, Enter to confirm):${NC}\n" > /dev/tty
66
+ printf "\n" > /dev/tty
67
+ for i in "${!options[@]}"; do
68
+ if [ "$i" -eq "$selected" ]; then
69
+ printf " ${GREEN}▸ %s${NC}\n" "${options[$i]}" > /dev/tty
70
+ else
71
+ printf " %s\n" "${options[$i]}" > /dev/tty
72
+ fi
73
+ done
74
+ }
75
+
76
+ draw_menu "first"
77
+
78
+ while true; do
79
+ IFS= read -rsn1 key < /dev/tty
80
+
81
+ case "$key" in
82
+ $'\x1b')
83
+ read -rsn2 seq < /dev/tty
84
+ case "$seq" in
85
+ '[A')
86
+ ((selected--))
87
+ [ "$selected" -lt 0 ] && selected=$((count - 1))
88
+ ;;
89
+ '[B')
90
+ ((selected++))
91
+ [ "$selected" -ge "$count" ] && selected=0
92
+ ;;
93
+ esac
94
+ ;;
95
+ ''|$'\n'|$'\r')
96
+ tput cnorm > /dev/tty 2>/dev/null
97
+ printf "\n" > /dev/tty
98
+ printf '%s' "${options[$selected]}"
99
+ return
100
+ ;;
101
+ 'q')
102
+ tput cnorm > /dev/tty 2>/dev/null
103
+ printf "\n" > /dev/tty
104
+ return
105
+ ;;
106
+ esac
107
+
108
+ draw_menu "redraw"
109
+ done
110
+ }
111
+
112
+ # ── Main ──
113
+
114
+ # Handle flags
115
+ SAFE_MODE=false
116
+ STAY_HERE=false
117
+
118
+ for arg in "$@"; do
119
+ case "$arg" in
120
+ --safe) SAFE_MODE=true ;;
121
+ --here) STAY_HERE=true ;;
122
+ esac
123
+ done
124
+
125
+ if [ "$1" = "--setup" ]; then
126
+ printf "${BOLD}Enter the path to your figma-cli repo:${NC} "
127
+ read -r repo_path < /dev/tty
128
+ repo_path="${repo_path/#\~/$HOME}"
129
+ if [ ! -f "$repo_path/src/index.js" ]; then
130
+ echo -e "${RED}Not a valid figma-cli repo:${NC} $repo_path"
131
+ exit 1
132
+ fi
133
+ save_repo_path "$repo_path"
134
+ echo -e "${GREEN}Saved.${NC} Run ${BOLD}fig-start${NC} to begin."
135
+ exit 0
136
+ fi
137
+
138
+ # Resolve repo path
139
+ REPO_PATH=$(get_repo_path)
140
+
141
+ if [ -z "$REPO_PATH" ] || [ ! -d "$REPO_PATH" ]; then
142
+ # Try to find it relative to this script
143
+ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
144
+ if [ -f "$SCRIPT_DIR/src/index.js" ]; then
145
+ REPO_PATH="$SCRIPT_DIR"
146
+ save_repo_path "$REPO_PATH"
147
+ else
148
+ echo -e "${YELLOW}figma-cli repo not configured.${NC}"
149
+ printf "${BOLD}Enter the path to your figma-cli repo:${NC} "
150
+ read -r REPO_PATH < /dev/tty
151
+ REPO_PATH="${REPO_PATH/#\~/$HOME}"
152
+ if [ ! -f "$REPO_PATH/src/index.js" ]; then
153
+ echo -e "${RED}Not a valid figma-cli repo:${NC} $REPO_PATH"
154
+ exit 1
155
+ fi
156
+ save_repo_path "$REPO_PATH"
157
+ fi
158
+ fi
159
+
160
+ CLI="$REPO_PATH/src/index.js"
161
+
162
+ echo ""
163
+ if [ "$SAFE_MODE" = true ]; then
164
+ echo -e "${BOLD} fig-start${NC} ${DIM}— Figma CLI launcher (Safe Mode)${NC}"
165
+ else
166
+ echo -e "${BOLD} fig-start${NC} ${DIM}— Figma CLI launcher${NC}"
167
+ fi
168
+ echo ""
169
+
170
+ # Step 1: Check if Figma is running, start if not
171
+ if ! pgrep -x "Figma" > /dev/null 2>&1; then
172
+ echo -e " ${YELLOW}Starting Figma...${NC}"
173
+ open -a Figma
174
+ sleep 3
175
+ fi
176
+
177
+ # Step 2: Connect to Figma
178
+ if [ "$SAFE_MODE" = true ]; then
179
+ # ── Safe Mode: plugin-based connection ──
180
+ # Run connect --safe interactively so user sees plugin setup instructions
181
+ echo -e " ${BOLD}🔒 Safe Mode${NC} — plugin-based, no patching required"
182
+ echo ""
183
+ node "$CLI" connect --safe
184
+ if [ $? -ne 0 ]; then
185
+ echo -e " ${RED}Connection failed.${NC}"
186
+ exit 1
187
+ fi
188
+ echo ""
189
+
190
+ # Skip file selector (Safe Mode only sees the active file via plugin)
191
+ echo -e " ${GREEN}Launching Claude Code...${NC}"
192
+ echo ""
193
+ if [ "$STAY_HERE" = false ]; then
194
+ cd "$REPO_PATH" || exit 1
195
+ fi
196
+ exec claude
197
+ else
198
+ # ── Yolo Mode: CDP-based connection ──
199
+ # Check if CDP is already accessible (avoid killing/restarting Figma)
200
+ CDP_OK=false
201
+ if curl -s -o /dev/null -w "%{http_code}" http://localhost:9222/json 2>/dev/null | grep -q "200"; then
202
+ CDP_OK=true
203
+ fi
204
+
205
+ if [ "$CDP_OK" = true ]; then
206
+ # Figma is already accessible — just ensure daemon is running
207
+ DAEMON_OK=false
208
+ DAEMON_TOKEN=$(get_daemon_token)
209
+ if [ -n "$DAEMON_TOKEN" ]; then
210
+ if curl -s -o /dev/null -w "%{http_code}" -H "X-Daemon-Token: $DAEMON_TOKEN" http://localhost:3456/health 2>/dev/null | grep -q "200"; then
211
+ DAEMON_OK=true
212
+ fi
213
+ fi
214
+ if [ "$DAEMON_OK" = false ]; then
215
+ echo -e " Starting daemon..."
216
+ node "$CLI" daemon restart > /dev/null 2>&1
217
+ sleep 1
218
+ fi
219
+ echo -e " ${GREEN}✓ Connected${NC}"
220
+ else
221
+ # Not accessible — run full connect (will kill + restart Figma)
222
+ echo -e " Connecting to Figma..."
223
+ CONNECT_OUT=$(node "$CLI" connect 2>&1)
224
+ if [ $? -ne 0 ]; then
225
+ echo -e " ${RED}Connection failed:${NC}"
226
+ echo "$CONNECT_OUT"
227
+ echo ""
228
+ echo -e " ${YELLOW}Tip:${NC} Try ${BOLD}fig-start --safe${NC} if patching fails."
229
+ exit 1
230
+ fi
231
+ echo -e " ${GREEN}✓ Connected${NC}"
232
+ # Wait for Figma to fully restore all tabs after restart
233
+ sleep 3
234
+ fi
235
+
236
+ # Step 3: List open files and let user pick
237
+ echo -e " Loading open files..."
238
+ FILES_JSON=$(node "$CLI" files 2>/dev/null)
239
+
240
+ if [ -z "$FILES_JSON" ] || echo "$FILES_JSON" | grep -q '"error"'; then
241
+ echo -e " ${RED}Could not list files.${NC} Is Figma open with a file?"
242
+ exit 1
243
+ fi
244
+
245
+ # Parse file titles
246
+ FILE_TITLES=()
247
+ while IFS= read -r title; do
248
+ FILE_TITLES+=("$title")
249
+ done < <(echo "$FILES_JSON" | python3 -c "
250
+ import json, sys
251
+ files = json.load(sys.stdin)
252
+ for f in files:
253
+ t = f.get('title', 'Untitled')
254
+ # Clean up Figma title format (remove ' – Figma' suffix)
255
+ t = t.replace(' – Figma', '').replace(' - Figma', '')
256
+ print(t)
257
+ " 2>/dev/null)
258
+
259
+ if [ ${#FILE_TITLES[@]} -eq 0 ]; then
260
+ echo -e " ${YELLOW}No Figma files detected.${NC} Open a file in Figma first."
261
+ echo ""
262
+ echo -e " Launching Claude Code anyway..."
263
+ echo ""
264
+ if [ "$STAY_HERE" = false ]; then
265
+ cd "$REPO_PATH" || exit 1
266
+ fi
267
+ exec claude
268
+ fi
269
+
270
+ SELECTED_TITLE=""
271
+
272
+ echo ""
273
+ SELECTED_TITLE=$(select_file "${FILE_TITLES[@]}")
274
+ if [ -z "$SELECTED_TITLE" ]; then
275
+ echo " Cancelled."
276
+ exit 0
277
+ fi
278
+
279
+ echo -e " ${GREEN}✓ File: ${BOLD}${SELECTED_TITLE}${NC}"
280
+ echo ""
281
+
282
+ # Step 4: Launch Claude Code
283
+ echo -e " ${GREEN}Launching Claude Code...${NC}"
284
+ echo ""
285
+ if [ "$STAY_HERE" = false ]; then
286
+ cd "$REPO_PATH" || exit 1
287
+ fi
288
+ exec claude
289
+ fi
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+
3
+ # Adds fig-start alias to ~/.zshrc (or ~/.bashrc)
4
+
5
+ REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
6
+ ALIAS_LINE="alias fig-start='$REPO_DIR/bin/fig-start'"
7
+
8
+ GREEN='\033[0;32m'
9
+ YELLOW='\033[1;33m'
10
+ BOLD='\033[1m'
11
+ NC='\033[0m'
12
+
13
+ # Detect shell config file
14
+ if [ -n "$ZSH_VERSION" ] || [ "$SHELL" = "/bin/zsh" ]; then
15
+ RC_FILE="$HOME/.zshrc"
16
+ else
17
+ RC_FILE="$HOME/.bashrc"
18
+ fi
19
+
20
+ # Check if alias already exists
21
+ if grep -q "alias fig-start=" "$RC_FILE" 2>/dev/null; then
22
+ # Update existing alias (path may have changed)
23
+ sed -i '' "/alias fig-start=/d" "$RC_FILE"
24
+ fi
25
+
26
+ # Add alias
27
+ echo "" >> "$RC_FILE"
28
+ echo "# Figma CLI" >> "$RC_FILE"
29
+ echo "$ALIAS_LINE" >> "$RC_FILE"
30
+
31
+ # Save repo path to config
32
+ mkdir -p "$HOME/.figma-cli"
33
+ python3 -c "
34
+ import json, os
35
+ path = os.path.expanduser('~/.figma-cli/config.json')
36
+ cfg = {}
37
+ if os.path.exists(path):
38
+ with open(path) as f: cfg = json.load(f)
39
+ cfg['repoPath'] = '$REPO_DIR'
40
+ with open(path, 'w') as f: json.dump(cfg, f, indent=2)
41
+ "
42
+
43
+ echo ""
44
+ echo -e " ${GREEN}Done!${NC} Added ${BOLD}fig-start${NC} alias to ${BOLD}$RC_FILE${NC}"
45
+ echo ""
46
+ echo -e " Now run: ${BOLD}source $RC_FILE${NC}"
47
+ echo -e " Then type: ${BOLD}fig-start${NC}"
48
+ echo ""