@calibrate-ds/cli 0.1.0 → 0.1.3

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.
Files changed (2) hide show
  1. package/README.md +556 -0
  2. package/package.json +5 -5
package/README.md ADDED
@@ -0,0 +1,556 @@
1
+ # Calibrate
2
+
3
+ **Calibrate is a local-first design system compiler for design engineers.** It reads your design tool, builds a normalized model of your design system, and uses it to scaffold typed components, design tokens, MDX documentation, and AI implementation prompts — all from the terminal.
4
+
5
+ No cloud sync. No proprietary lock-in. Your design system lives in git.
6
+
7
+ ---
8
+
9
+ ## What it does
10
+
11
+ ```
12
+ Figma → ptb scan → ptb generate-components → typed React shells
13
+ → ptb generate-tokens → CSS custom properties
14
+ → ptb document component → MDX docs + Storybook stories
15
+ → ptb implement component → AI-written component code
16
+ → ptb status → staleness tracking in CI
17
+ ```
18
+
19
+ When your designer updates a component in Figma, `ptb scan` picks up the change, `ptb diff` shows what changed, and `ptb status` tells you which implementations are now stale. The whole team stays in sync through a committed `ptb.lock` file — no external service required.
20
+
21
+ ---
22
+
23
+ ## Install
24
+
25
+ **Requirements:** Node.js ≥ 20
26
+
27
+ > **macOS users:** Do not use the system Node or a Homebrew Node for global installs — you'll hit permission errors. Use nvm (step 1 below). It takes 30 seconds and fixes the problem permanently.
28
+
29
+ ### Step 1 — Install nvm (skip if you already have it)
30
+
31
+ ```bash
32
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
33
+ source ~/.zshrc # or: source ~/.bashrc (if you use bash)
34
+ ```
35
+
36
+ ### Step 2 — Install Node 22
37
+
38
+ ```bash
39
+ nvm install 22
40
+ ```
41
+
42
+ ### Step 3 — Install Calibrate
43
+
44
+ ```bash
45
+ npm install -g @calibrate-ds/cli
46
+ source ~/.zshrc # reload PATH so ptb is found
47
+ ptb --version # should print the installed version
48
+ ```
49
+
50
+ **Already have Node 20+ via nvm?** Skip to step 3.
51
+
52
+ **Getting `permission denied` errors?** You are using the system Node. Run steps 1–3 above.
53
+
54
+ ---
55
+
56
+ ## Quickstart
57
+
58
+ ### 1. Initialize
59
+
60
+ ```bash
61
+ cd your-project
62
+ ptb init
63
+ ```
64
+
65
+ PTB detects whether your repo is fresh or existing:
66
+ - **Fresh repo** — scaffolds `packages/ui/` with framework-specific `package.json`, `tsconfig.json`, and component/token directories
67
+ - **Existing repo** — writes `ptb.config.json` and `.gitignore` entries only, leaves your code untouched
68
+
69
+ You will be asked to choose:
70
+ - Framework (React, Vue, Svelte, React Native)
71
+ - Solo or team project
72
+ - Figma plan (Organization/Enterprise for direct API, or Pro/Starter for the Calibrate plugin)
73
+ - Documentation tool (Storybook, Docusaurus, or plain MDX)
74
+
75
+ ### 2. Set your Figma token
76
+
77
+ ```bash
78
+ export FIGMA_ACCESS_TOKEN=your_token_here
79
+ ```
80
+
81
+ Generate a token at **Figma → Account Settings → Security → Generate New Token**. PTB never stores the token — `ptb.config.json` only stores the env var name.
82
+
83
+ ### 3. Scan your Figma file
84
+
85
+ ```bash
86
+ ptb scan
87
+ ```
88
+
89
+ Fetches your Figma file, normalizes it into a `DesignSystemModel`, saves it to `.ptb/latest.json`, and exports component context files to `.ptb/context/`.
90
+
91
+ Find your file key in the Figma URL: `figma.com/design/<FILE_KEY>/...`
92
+
93
+ ### 4. Generate components and tokens
94
+
95
+ ```bash
96
+ ptb generate-components # typed React shells in packages/ui/src/components/
97
+ ptb generate-tokens # CSS custom properties in packages/ui/src/tokens/
98
+ ```
99
+
100
+ ### 5. Document components
101
+
102
+ ```bash
103
+ ptb document component . # generates MDX + Storybook stories for all components
104
+ ```
105
+
106
+ ### 6. Implement with AI
107
+
108
+ ```bash
109
+ ptb ai setup # configure Claude or OpenAI once
110
+ ptb implement component Button
111
+ ```
112
+
113
+ ### 7. Track freshness
114
+
115
+ ```bash
116
+ ptb status # shows which components are stale vs implemented
117
+ ptb stamp component Button # mark Button as implemented against the current design
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Figma workflows
123
+
124
+ PTB supports two workflows depending on your Figma plan.
125
+
126
+ ### Direct Fetch (Organization / Enterprise)
127
+
128
+ PTB reads tokens directly from the Figma API. No plugin required.
129
+
130
+ ```bash
131
+ ptb flow direct # step-by-step checklist
132
+ ```
133
+
134
+ ### Plugin Export (Pro / Starter / Free)
135
+
136
+ Use the **Calibrate** Figma plugin to export variables and tokens, then import them into PTB.
137
+
138
+ ```bash
139
+ # 1. In Figma: run Calibrate → Export
140
+ # 2. Place the export file in your project named as imported-tokens.json
141
+ # 3. Place it in the .ptb root folder. (If you don't see .ptb folder while exporting, press Cmd+Shift+. to show hidden files)
142
+ ptb scan
143
+ ptb generate-tokens
144
+ ptb generate-components
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Configuration
150
+
151
+ `ptb init` creates `ptb.config.json` at your project root. All fields:
152
+
153
+ ```json
154
+ {
155
+ "designTool": {
156
+ "provider": "figma",
157
+ "fileKey": "YOUR_FIGMA_FILE_KEY",
158
+ "accessTokenEnv": "FIGMA_ACCESS_TOKEN"
159
+ },
160
+ "project": {
161
+ "rootDir": "."
162
+ },
163
+ "output": {
164
+ "componentsDir": "packages/ui/src/components",
165
+ "tokensDir": "packages/ui/src/tokens",
166
+ "metadataDir": ".ptb"
167
+ },
168
+ "framework": {
169
+ "name": "react",
170
+ "typescript": true,
171
+ "styling": "css-modules"
172
+ },
173
+ "generation": {
174
+ "stories": true,
175
+ "tests": false,
176
+ "types": true,
177
+ "indexFiles": true,
178
+ "cssFiles": true
179
+ },
180
+ "naming": {
181
+ "componentCase": "PascalCase",
182
+ "folderCase": "kebab-case",
183
+ "tokenCase": "camelCase"
184
+ },
185
+ "classification": {
186
+ "treatComponentSetsAsCanonical": true,
187
+ "treatStandaloneComponentsAsCanonical": true,
188
+ "treatNestedInstancesAsReferences": true
189
+ },
190
+ "docs": {
191
+ "tool": "storybook",
192
+ "format": "both"
193
+ },
194
+ "ai": {
195
+ "active": "claude",
196
+ "providers": {
197
+ "claude": {
198
+ "model": "claude-sonnet-4-6",
199
+ "accessTokenEnv": "ANTHROPIC_API_KEY"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ **`designTool.accessTokenEnv`** stores the name of the env var, never the token itself. PTB validates that this value is `SCREAMING_SNAKE_CASE` on startup.
207
+
208
+ ---
209
+
210
+ ## AI setup
211
+
212
+ ```bash
213
+ ptb ai setup # interactive: choose provider, set env var name, pick model
214
+ ptb ai list # show all configured providers
215
+ ptb ai use claude # switch active provider
216
+ ptb ai model # change model for active provider
217
+ ```
218
+
219
+ Supported providers: **Claude** (Anthropic), **OpenAI**. Local models via OpenAI-compatible `baseUrl` are also supported.
220
+
221
+ PTB uses fuzzy matching during `ptb ai setup` — if you mistype a provider name (e.g. `opneai`), it suggests the closest known provider before proceeding.
222
+
223
+ ```bash
224
+ # Claude
225
+ export ANTHROPIC_API_KEY=sk-ant-...
226
+ ptb ai setup # choose "claude"
227
+
228
+ # OpenAI
229
+ export OPENAI_API_KEY=sk-...
230
+ ptb ai setup # choose "openai"
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Implementing components with AI
236
+
237
+ `ptb implement component <name>` sends a rich context package to your configured AI provider and writes the component files. **The quality of the output depends entirely on the model you use.**
238
+
239
+ ### Recommended models
240
+
241
+ For best results use a top-tier coding model:
242
+
243
+ | Provider | Recommended model |
244
+ |---|---|
245
+ | Anthropic | `claude-opus-4-7` or `claude-sonnet-4-6` |
246
+ | OpenAI | `gpt-4o` or `o3` |
247
+
248
+ Weaker models (GPT-3.5, smaller Ollama models) will produce code that compiles but misses design intent — wrong spacing, ignored variants, missing accessibility attributes.
249
+
250
+ ```bash
251
+ ptb ai setup # set your provider and model
252
+ ptb ai model # change model at any time
253
+ ```
254
+
255
+ ### Alternative: use any AI IDE with PTB context files
256
+
257
+ `ptb implement` is useful for batch generation. For interactive development, you can skip it entirely and use PTB's context files directly in any AI IDE — Claude Code, Cursor, Copilot, or any other.
258
+
259
+ PTB already extracts and normalizes everything from Figma into structured JSON. Your AI IDE doesn't need a live Figma connection — the context files have everything: variant axes, token bindings, state contracts, layout, render trees, and interaction contracts.
260
+
261
+ **Workflow:**
262
+ 1. Run `ptb export context` after each scan
263
+ 2. Run `ptb document system` to generate `AI.md` at your package root — most AI IDEs pick this up automatically
264
+ 3. Use `ptb prompt component <name>` to get a structured prompt for a specific component
265
+ 4. Open your AI IDE and point it at `.ptb/context/<component>.json` or paste the prompt
266
+ 5. Let the AI write the component — it has full design intent without needing Figma access
267
+
268
+ This gives you more control, lets you iterate interactively, and works with whatever AI IDE you already use.
269
+
270
+ ---
271
+
272
+ ## Team workflow
273
+
274
+ PTB tracks design-to-implementation freshness through a committed `ptb.lock` file. No server required.
275
+
276
+ ### Setup
277
+
278
+ ```bash
279
+ ptb init # scaffolds project, registers you as lead, creates ptb.lock
280
+ ptb join # teammates register themselves (they join as members)
281
+ git add ptb.lock ptb-team.json
282
+ ```
283
+
284
+ ### Roles
285
+
286
+ Every team member has a role: **lead** or **member**.
287
+
288
+ - The person who runs `ptb init` is automatically the **lead**.
289
+ - The first person to run `ptb join` on a fresh roster also becomes a **lead** automatically — this prevents the deadlock where the only member can't promote themselves (only leads can change roles).
290
+ - All subsequent `ptb join` calls give the **member** role.
291
+ - Leads can assign components to anyone, reassign, and stamp any component.
292
+ - Members can only self-assign and stamp components assigned to them.
293
+ - The last lead cannot be demoted — PTB blocks the operation until another lead is promoted first.
294
+
295
+ ```bash
296
+ ptb team # show roster with roles
297
+ ptb team role @alice lead # promote alice to lead (leads only)
298
+ ptb team role @bob member # demote to member (leads only, can't remove last lead)
299
+ ```
300
+
301
+ ### Assigning work
302
+
303
+ ```bash
304
+ ptb assign Button # self-assign Button to yourself
305
+ ptb assign Button @alice # assign to alice (leads only)
306
+ ptb assign . @alice # assign all unimplemented to alice (leads only)
307
+ ptb assign Button --clear # unassign (members can only clear their own)
308
+ ptb status --team # view workload by assignee
309
+ ptb status --mine # view only your assignments
310
+ ```
311
+
312
+ ### Stamping implementations
313
+
314
+ When a developer finishes implementing a component against the current design:
315
+
316
+ ```bash
317
+ ptb stamp component Button
318
+ ptb stamp component Button -m "implemented with new focus ring per design v2"
319
+ ```
320
+
321
+ Members can only stamp components assigned to them. Leads can stamp anything.
322
+
323
+ This writes the current `designHash` into `ptb.lock` as `stampedHash`. When `ptb status` sees they match, the component is **ready**. When Figma changes and PTB re-scans, `designHash` updates but `stampedHash` stays — making the component **stale**.
324
+
325
+ ### Viewing history
326
+
327
+ ```bash
328
+ ptb log # show design changes and stamps from git history
329
+ ptb diff # show unstamped design changes since last scan
330
+ ```
331
+
332
+ ---
333
+
334
+ ## CI integration
335
+
336
+ ```bash
337
+ ptb ci setup # leads only
338
+ ```
339
+
340
+ Generates `.github/workflows/ptb.yml` — a GitHub Actions workflow that runs `ptb status --fail-on-stale` on every push and PR. Blocks merges when components are stale.
341
+
342
+ ```bash
343
+ git add .github/workflows/ptb.yml
344
+ git commit -m "ci: add PTB design freshness check"
345
+ ```
346
+
347
+ For CI to work without a Figma token, commit your context files after each scan:
348
+
349
+ ```bash
350
+ ptb export context
351
+ git add .ptb/context/ ptb.lock
352
+ git commit -m "chore: update design system context"
353
+ ```
354
+
355
+ ---
356
+
357
+ ## Documentation
358
+
359
+ ### Component docs
360
+
361
+ ```bash
362
+ ptb document component Button # single component
363
+ ptb document component . # all components
364
+ ptb document component Button --force # overwrite existing
365
+ ptb document component Button --no-ai # skip AI prose, deterministic tables only
366
+ ```
367
+
368
+ On first run, PTB asks two one-time questions and saves the answers to `ptb.config.json` — they won't be asked again:
369
+ - **Documentation tool**: Storybook, Docusaurus, or plain MDX
370
+ - **Format** (Storybook only): MDX doc only, Stories only, or Both
371
+
372
+ Override the format per-run with `--format mdx|stories|both`.
373
+
374
+ For Storybook, PTB detects whether Storybook is installed (monorepo-aware — correctly handles hoisted `node_modules`) and offers to run the setup steps for you. After `storybook init`, PTB automatically removes Storybook's example `src/stories/` scaffold so it doesn't pollute your component directory.
375
+
376
+ ### System documentation
377
+
378
+ ```bash
379
+ ptb document system
380
+ ```
381
+
382
+ Generates two files at your component library root:
383
+
384
+ - **`AI.md`** — design system intent map for AI coding assistants (Claude Code, Cursor, Copilot)
385
+ - **`components.md`** — human-readable component inventory with import paths and descriptions
386
+
387
+ ---
388
+
389
+ ## Context and prompts
390
+
391
+ ```bash
392
+ ptb export context # export all component context to .ptb/context/
393
+ ptb context component Button # display rich context in terminal
394
+ ptb context component Button --json # machine-readable JSON
395
+ ptb prompt component Button # print AI implementation prompt
396
+ ptb prompt component . --format json # write all prompts to .ptb/prompts/
397
+ ```
398
+
399
+ Context files in `.ptb/context/` are designed to be committed and read by AI tools. They contain the full component model: variant axes, token bindings, state contracts, layout, render tree, and interaction contracts.
400
+
401
+ ---
402
+
403
+ ## Health checks
404
+
405
+ ```bash
406
+ ptb doctor # system check: config, token, snapshot age, component health
407
+ ptb doctor component Button # deep audit: 10-point score for one component
408
+ ptb doctor component . # scorecard table for all components
409
+ ptb doctor tokens # token resolution coverage
410
+ ptb doctor context Button # AI context quality score
411
+ ```
412
+
413
+ The doctor checks whether your Figma components have the data PTB needs to generate high-quality code: Auto Layout, token bindings, variant axes, state contracts, render trees, and descriptions.
414
+
415
+ A low doctor score means your generated code will be less accurate. Fix the issues in Figma, re-scan, and the score improves.
416
+
417
+ ---
418
+
419
+ ## Getting help
420
+
421
+ ```bash
422
+ ptb --help # full command list
423
+ ptb <command> --help # flags and options for one command
424
+ ptb guide # list all topic guides
425
+ ptb guide <topic> # focused reference for a feature area
426
+ ```
427
+
428
+ Available topics: `setup` · `context` · `implement` · `document` · `status` · `team` · `ai` · `doctor` · `ci`
429
+
430
+ ---
431
+
432
+ ## Command reference
433
+
434
+ ### Setup & scanning
435
+
436
+ | Command | What it does |
437
+ |---|---|
438
+ | `ptb init` | Initialize PTB, scaffold fresh repos, write config |
439
+ | `ptb scan` | Fetch Figma file, save snapshot, export context |
440
+ | `ptb generate-components [name]` | Scaffold typed component shells |
441
+ | `ptb generate-tokens` | Scaffold CSS token files |
442
+ | `ptb import-tokens <path>` | Import a Calibrate token export |
443
+
444
+ ### Context & prompts
445
+
446
+ | Command | What it does |
447
+ |---|---|
448
+ | `ptb export context` | Export component context files for AI tools |
449
+ | `ptb context component <name>` | Display rich component context |
450
+ | `ptb prompt component <name>` | Print AI implementation prompt |
451
+
452
+ ### AI implementation
453
+
454
+ | Command | What it does |
455
+ |---|---|
456
+ | `ptb implement component <name>` | AI-generate component implementation |
457
+ | `ptb plan` | Show which files are affected by the latest diff |
458
+ | `ptb apply` | Regenerate only the files affected by design changes |
459
+ | `ptb prune` | Remove stale component folders no longer in Figma |
460
+
461
+ ### Documentation
462
+
463
+ | Command | What it does |
464
+ |---|---|
465
+ | `ptb document component <name>` | Generate MDX docs and Storybook stories |
466
+ | `ptb document system` | Generate AI.md and components.md |
467
+
468
+ ### Status & tracking
469
+
470
+ | Command | What it does |
471
+ |---|---|
472
+ | `ptb status` | Check implementation freshness |
473
+ | `ptb diff` | Show unstamped design changes since last scan |
474
+ | `ptb log` | Show design change and stamp history |
475
+ | `ptb stamp component <name>` | Mark a component as implemented |
476
+ | `ptb assign <name> [person]` | Assign a component to a developer |
477
+
478
+ ### Team
479
+
480
+ | Command | What it does |
481
+ |---|---|
482
+ | `ptb join` | Register yourself in the team roster |
483
+ | `ptb team` | Show team roster and workload |
484
+ | `ptb team role <handle> <role>` | Promote or demote a team member (leads only) |
485
+
486
+ ### AI providers
487
+
488
+ | Command | What it does |
489
+ |---|---|
490
+ | `ptb ai setup` | Configure AI provider |
491
+ | `ptb ai list` | List saved providers and active one |
492
+ | `ptb ai use <provider>` | Switch active provider |
493
+ | `ptb ai model [id]` | Change model for active provider |
494
+
495
+ ### Health & CI
496
+
497
+ | Command | What it does |
498
+ |---|---|
499
+ | `ptb doctor` | System and component health audit |
500
+ | `ptb ci setup` | Generate GitHub Actions freshness workflow (leads only) |
501
+ | `ptb remove` | Remove all PTB config and metadata from this project (leads only) |
502
+
503
+ ### Help & onboarding
504
+
505
+ | Command | What it does |
506
+ |---|---|
507
+ | `ptb guide [topic]` | Focused workflow reference per feature area |
508
+ | `ptb learn` | Interactive onboarding walkthrough |
509
+ | `ptb flow direct` | Checklist for direct Figma API workflow |
510
+ | `ptb flow plugin` | Checklist for Calibrate plugin workflow |
511
+
512
+ ---
513
+
514
+ ## What gets committed to git
515
+
516
+ ```
517
+ ptb.config.json # your PTB configuration
518
+ ptb.lock # design hash tracking — commit this
519
+ ptb-team.json # team roster — commit this
520
+ .ptb/context/ # component context files — commit after ptb export context
521
+ .ptb/manifest.json # generated file tracking — commit this
522
+ .github/workflows/ # CI workflow — commit this
523
+ ```
524
+
525
+ ```
526
+ .ptb/latest.json # gitignored — large Figma snapshot
527
+ .ptb/history/ # gitignored — snapshot history
528
+ *.ptb-meta.json # gitignored — inline metadata
529
+ ```
530
+
531
+ `ptb init` writes the correct `.gitignore` entries automatically. If you have an old project with `.ptb/` blanket-ignored, running `ptb export context` will migrate it.
532
+
533
+ ---
534
+
535
+ ## Supported frameworks
536
+
537
+ | Framework | Scan & Track | Generate Components | Storybook |
538
+ |---|---|---|---|
539
+ | React | ✓ | ✓ | ✓ |
540
+ | Vue 3 | ✓ | coming soon | ✓ (Vite) |
541
+ | Svelte | ✓ | coming soon | ✓ (Vite) |
542
+ | React Native | ✓ | coming soon | — |
543
+
544
+ All frameworks support the full governance workflow (scan, diff, status, stamp, assign, CI) and documentation generation. Code generation is React-first for v1.
545
+
546
+ ---
547
+
548
+ ## Contributing
549
+
550
+ See [PTB.md](./PTB.md) for architecture, type definitions, the generator interface, and internal conventions.
551
+
552
+ ```bash
553
+ pnpm install
554
+ pnpm build
555
+ node apps/cli/dist/index.js --help
556
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calibrate-ds/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,10 +22,10 @@
22
22
  "commander": "^14.0.3",
23
23
  "openai": "^6.34.0",
24
24
  "zod": "^4.3.6",
25
- "@calibrate-ds/core": "0.1.0",
26
- "@calibrate-ds/figma-client": "0.1.0",
27
- "@calibrate-ds/shared-types": "0.1.0",
28
- "@calibrate-ds/generator-react": "0.1.0"
25
+ "@calibrate-ds/core": "0.1.3",
26
+ "@calibrate-ds/generator-react": "0.1.3",
27
+ "@calibrate-ds/figma-client": "0.1.3",
28
+ "@calibrate-ds/shared-types": "0.1.3"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^22.13.5",