canicode 0.5.0 → 0.5.2

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 CHANGED
@@ -9,12 +9,17 @@
9
9
  <a href="https://github.com/let-sunny/canicode/actions/workflows/ci.yml"><img src="https://github.com/let-sunny/canicode/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
10
10
  <a href="https://github.com/let-sunny/canicode/actions/workflows/release.yml"><img src="https://github.com/let-sunny/canicode/actions/workflows/release.yml/badge.svg" alt="Release"></a>
11
11
  <a href="https://let-sunny.github.io/canicode/"><img src="https://img.shields.io/badge/Try_it-GitHub_Pages-blue" alt="GitHub Pages"></a>
12
+ <a href="https://www.figma.com/community/plugin/1617144221046795292/canicode"><img src="https://img.shields.io/badge/Figma_Plugin-under_review-orange" alt="Figma Plugin"></a>
12
13
  </p>
13
14
 
14
15
  <p align="center">Analyze Figma designs. Score how dev-friendly and AI-friendly they are. Get actionable issues before writing code.</p>
15
16
 
16
17
  <p align="center"><strong><a href="https://let-sunny.github.io/canicode/">Try it in your browser</a></strong> — no install needed.</p>
17
18
 
19
+ <p align="center">
20
+ <img src="docs/screenshot.png" alt="CanICode Report" width="720">
21
+ </p>
22
+
18
23
  ```bash
19
24
  npm install -g canicode
20
25
  canicode init --token YOUR_FIGMA_TOKEN
@@ -40,13 +45,37 @@ canicode analyze "https://www.figma.com/design/ABC123/MyDesign?node-id=1-234"
40
45
 
41
46
  Each issue is classified: **Blocking** > **Risk** > **Missing Info** > **Suggestion**.
42
47
 
43
- Scores use density + diversity weighting per category, combined into an overall grade (S/A+/A/B+/B/C+/C/D/F).
48
+ Scores use density + diversity weighting per category, combined into an overall grade (S/A+/A/B+/B/C+/C/D/F). Rule scores are calibrated against actual code conversion difficulty — see [Calibration](docs/CALIBRATION.md) for how scores are validated.
49
+
50
+ ---
51
+
52
+ ## Everything is Configurable
53
+
54
+ | What | How | Example |
55
+ |------|-----|---------|
56
+ | **Presets** | Built-in score profiles | `canicode analyze <url> --preset strict` |
57
+ | **Config overrides** | Adjust scores, severity, exclude nodes | `canicode analyze <url> --config ./config.json` |
58
+ | **Custom rules** | Add your own checks with pattern matching | `canicode analyze <url> --custom-rules ./rules.json` |
59
+ | **Combine** | Use all together | `canicode analyze <url> --preset ai-ready --config ./config.json --custom-rules ./rules.json` |
60
+
61
+ | Preset | What it does |
62
+ |--------|-------------|
63
+ | `relaxed` | Downgrades blocking → risk, scores −50% |
64
+ | `dev-friendly` | Layout and handoff rules only |
65
+ | `ai-ready` | Structure and naming weights +150% |
66
+ | `strict` | All rules enabled, scores +150% |
67
+
68
+ > **Custom rules tip:** Ask any LLM *"Write a canicode custom rule that checks X"* — it can generate the JSON for you. See [`docs/CUSTOMIZATION.md`](docs/CUSTOMIZATION.md) for the full guide.
44
69
 
45
70
  ---
46
71
 
47
72
  ## Getting Started
48
73
 
49
- Four ways to use CanICode. Pick one.
74
+ Five ways to use CanICode. Pick one.
75
+
76
+ ### Figma Plugin (under review)
77
+
78
+ Install from **[Figma Community](https://www.figma.com/community/plugin/1617144221046795292/canicode)** — analyze directly inside Figma. No tokens needed.
50
79
 
51
80
  ### Web (no install)
52
81
 
@@ -212,6 +241,13 @@ canicode analyze <url> --custom-rules ./my-rules.json
212
241
 
213
242
  Conditions use AND logic — all must match for the rule to fire. Available conditions: `type`, `notType`, `nameContains`, `nameNotContains`, `namePattern`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`, `hasAutoLayout`, `hasChildren`, `minChildren`, `maxChildren`, `isComponent`, `isInstance`, `hasComponentId`, `isVisible`, `hasFills`, `hasStrokes`, `hasEffects`, `minDepth`, `maxDepth`.
214
243
 
244
+ Combine with config overrides:
245
+ ```bash
246
+ canicode analyze <url> --config ./config.json --custom-rules ./rules.json
247
+ ```
248
+
249
+ > **Tip:** Ask any LLM *"Write a canicode custom rule that checks X"* with the conditions above — it can generate the JSON for you.
250
+
215
251
  See [`examples/custom-rules.json`](examples/custom-rules.json) | [`docs/CUSTOMIZATION.md`](docs/CUSTOMIZATION.md)
216
252
 
217
253
  </details>
@@ -228,6 +264,8 @@ Diversity Score = (1 - unique violated rules / total rules in category) × 100
228
264
 
229
265
  Severity weights issues — a single blocking issue counts 3x more than a suggestion. Scores are calculated per category and combined into an overall grade (S/A+/A/B+/B/C+/C/D/F).
230
266
 
267
+ > Weights and rule scores are validated through a 4-agent calibration pipeline. See [docs/CALIBRATION.md](docs/CALIBRATION.md) for details.
268
+
231
269
  </details>
232
270
 
233
271
  <details>
@@ -323,6 +361,12 @@ pnpm lint # type check
323
361
  - [x] **Phase 5** — Custom rules with pattern matching (node name/type/attribute conditions)
324
362
  - [ ] **Phase 6** — Screenshot comparison (Figma vs AI-generated code, visual diff)
325
363
 
364
+ ## Support
365
+
366
+ - **Bug reports:** [GitHub Issues](https://github.com/let-sunny/canicode/issues)
367
+ - **Questions and discussions:** [GitHub Issues](https://github.com/let-sunny/canicode/issues)
368
+ - **Privacy:** See [PRIVACY.md](PRIVACY.md) for details on data collection and how to opt out
369
+
326
370
  ## License
327
371
 
328
372
  MIT
@@ -3268,6 +3268,12 @@ Typical flow with Figma MCP:
3268
3268
  configPath: z.string().optional().describe("Path to config JSON file for rule overrides"),
3269
3269
  customRulesPath: z.string().optional().describe("Path to custom rules JSON file")
3270
3270
  },
3271
+ {
3272
+ readOnlyHint: false,
3273
+ destructiveHint: false,
3274
+ openWorldHint: true,
3275
+ title: "Analyze Figma Design"
3276
+ },
3271
3277
  async ({ designData, input, fileKey, fileName, token, preset, targetNodeId, configPath, customRulesPath }) => {
3272
3278
  trackEvent(EVENTS.MCP_TOOL_CALLED, { tool: "analyze" });
3273
3279
  try {
@@ -3374,6 +3380,12 @@ server.tool(
3374
3380
  "list-rules",
3375
3381
  "List all available analysis rules with their current configuration",
3376
3382
  {},
3383
+ {
3384
+ readOnlyHint: true,
3385
+ destructiveHint: false,
3386
+ openWorldHint: false,
3387
+ title: "List Analysis Rules"
3388
+ },
3377
3389
  async () => {
3378
3390
  const rules = ruleRegistry.getAll().map((rule) => {
3379
3391
  const config2 = RULE_CONFIGS[rule.definition.id];
@@ -3411,6 +3423,12 @@ Use this when the user asks about customization, configuration, rule settings, o
3411
3423
  {
3412
3424
  topic: z.enum(["all", "config", "custom-rules", "rules"]).optional().describe("Specific topic: config (overrides), custom-rules (adding new rules), rules (all rule IDs). Default: all")
3413
3425
  },
3426
+ {
3427
+ readOnlyHint: true,
3428
+ destructiveHint: false,
3429
+ openWorldHint: false,
3430
+ title: "Get Customization Guide"
3431
+ },
3414
3432
  async ({ topic }) => {
3415
3433
  const { readFile: readFile4 } = await import('fs/promises');
3416
3434
  const { resolve: resolve4, dirname } = await import('path');