canicode 0.8.8 → 0.9.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.
@@ -0,0 +1,208 @@
1
+ # Customization Guide
2
+
3
+ CanICode supports two types of customization:
4
+
5
+ 1. **Config overrides** — adjust scores, severity, and node exclusions
6
+ 2. **Custom rules** — add project-specific checks
7
+
8
+ ---
9
+
10
+ ## Config Overrides
11
+
12
+ Override built-in rule scores, severity, and filter settings with a JSON file.
13
+
14
+ ```bash
15
+ canicode analyze <url> --config ./my-config.json
16
+ ```
17
+
18
+ ### Full Schema
19
+
20
+ ```json
21
+ {
22
+ "excludeNodeTypes": ["VECTOR", "BOOLEAN_OPERATION", "SLICE"],
23
+ "excludeNodeNames": ["chatbot", "ad-banner", "custom-widget"],
24
+ "gridBase": 2,
25
+ "rules": {
26
+ "no-auto-layout": { "score": -15, "severity": "blocking", "enabled": true },
27
+ "raw-value": { "score": -5 },
28
+ "non-semantic-name": { "enabled": false }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### Fields
34
+
35
+ | Field | Type | Default | Description |
36
+ |-------|------|---------|-------------|
37
+ | `excludeNodeTypes` | `string[]` | `[]` | Figma node types to skip entirely (node + children) |
38
+ | `excludeNodeNames` | `string[]` | `[]` | Name patterns to skip (case-insensitive word match) |
39
+ | `gridBase` | `number` | `2` | Spacing grid unit for `irregular-spacing` |
40
+ | `rules` | `object` | — | Per-rule overrides (see below) |
41
+
42
+ ### Node Exclusions
43
+
44
+ **`excludeNodeNames`** — Nodes whose name contains any of these words (case-insensitive) will be skipped entirely. The node and all its children are excluded from analysis.
45
+
46
+ ```json
47
+ {
48
+ "excludeNodeNames": ["chatbot", "floating-cta", "ad-banner", "legacy"]
49
+ }
50
+ ```
51
+
52
+ This matches word boundaries, so `"nav"` matches `"Nav Bar"` and `"bottom-nav"` but not `"unavailable"`.
53
+
54
+ **Built-in exclusions** (always active for conversion candidates):
55
+ `badge`, `close`, `dismiss`, `overlay`, `float`, `fab`, `dot`, `indicator`, `corner`, `decoration`, `tag`, `status`, `notification`, `icon`, `ico`, `image`, `asset`, `filter`, `dim`, `dimmed`, `bg`, `background`, `logo`, `avatar`, `divider`, `separator`, `nav`, `navigation`, `gnb`, `header`, `footer`, `sidebar`, `toolbar`, `modal`, `dialog`, `popup`, `toast`, `tooltip`, `dropdown`, `menu`, `sticky`, `spinner`, `loader`, `cursor`, `cta`, `chatbot`, `thumb`, `thumbnail`, `tabbar`, `tab-bar`, `statusbar`, `status-bar`
56
+
57
+ **`excludeNodeTypes`** — Figma node types to skip.
58
+
59
+ ```json
60
+ {
61
+ "excludeNodeTypes": ["VECTOR", "BOOLEAN_OPERATION", "SLICE", "STICKY"]
62
+ }
63
+ ```
64
+
65
+ Available types: `DOCUMENT`, `CANVAS`, `FRAME`, `GROUP`, `SECTION`, `COMPONENT`, `COMPONENT_SET`, `INSTANCE`, `RECTANGLE`, `ELLIPSE`, `VECTOR`, `TEXT`, `LINE`, `BOOLEAN_OPERATION`, `STAR`, `REGULAR_POLYGON`, `SLICE`, `STICKY`, `TABLE`, `TABLE_CELL`
66
+
67
+ ### Per-Rule Overrides
68
+
69
+ Override score, severity, or enable/disable individual rules:
70
+
71
+ ```json
72
+ {
73
+ "rules": {
74
+ "no-auto-layout": {
75
+ "score": -15,
76
+ "severity": "blocking"
77
+ },
78
+ "non-semantic-name": {
79
+ "enabled": false
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ | Property | Type | Description |
86
+ |----------|------|-------------|
87
+ | `score` | `number` (≤ 0) | Penalty score (more negative = harsher) |
88
+ | `severity` | `string` | `"blocking"`, `"risk"`, `"missing-info"`, or `"suggestion"` |
89
+ | `enabled` | `boolean` | Set `false` to disable the rule |
90
+
91
+ ### All Rule IDs
92
+
93
+ <!-- RULE_TABLE_START — auto-generated by scripts/sync-rule-docs.ts, do not edit manually -->
94
+ **Pixel Critical (3 rules)**
95
+
96
+ | Rule ID | Default Score | Default Severity |
97
+ |---------|--------------|-----------------|
98
+ | `no-auto-layout` | -10 | blocking |
99
+ | `absolute-position-in-auto-layout` | -7 | blocking |
100
+ | `non-layout-container` | -8 | blocking |
101
+
102
+ **Responsive Critical (2 rules)**
103
+
104
+ | Rule ID | Default Score | Default Severity |
105
+ |---------|--------------|-----------------|
106
+ | `fixed-size-in-auto-layout` | -6 | risk |
107
+ | `missing-size-constraint` | -8 | risk |
108
+
109
+ **Code Quality (4 rules)**
110
+
111
+ | Rule ID | Default Score | Default Severity |
112
+ |---------|--------------|-----------------|
113
+ | `deep-nesting` | -3 | risk |
114
+ | `missing-component` | -7 | risk |
115
+ | `detached-instance` | -4 | risk |
116
+ | `variant-structure-mismatch` | -6 | risk |
117
+
118
+ **Token Management (2 rules)**
119
+
120
+ | Rule ID | Default Score | Default Severity |
121
+ |---------|--------------|-----------------|
122
+ | `raw-value` | -4 | missing-info |
123
+ | `irregular-spacing` | -5 | risk |
124
+
125
+ **Semantic (3 rules)**
126
+
127
+ | Rule ID | Default Score | Default Severity |
128
+ |---------|--------------|-----------------|
129
+ | `non-semantic-name` | -4 | risk |
130
+ | `inconsistent-naming-convention` | -1 | suggestion |
131
+ | `non-standard-naming` | -3 | suggestion |
132
+
133
+ **Interaction (2 rules)**
134
+
135
+ | Rule ID | Default Score | Default Severity |
136
+ |---------|--------------|-----------------|
137
+ | `missing-interaction-state` | -1 | suggestion |
138
+ | `missing-prototype` *(disabled)* | -3 | missing-info |
139
+ <!-- RULE_TABLE_END -->
140
+
141
+ ### Example Configs
142
+
143
+ **Strict (for production-ready designs):**
144
+ ```json
145
+ {
146
+ "rules": {
147
+ "no-auto-layout": { "score": -15 },
148
+ "raw-value": { "score": -5, "severity": "risk" },
149
+ "non-semantic-name": { "score": -6, "severity": "blocking" }
150
+ }
151
+ }
152
+ ```
153
+
154
+ **Relaxed (for early prototypes):**
155
+ ```json
156
+ {
157
+ "excludeNodeNames": ["prototype", "wip", "draft", "temp"],
158
+ "rules": {
159
+ "non-semantic-name": { "enabled": false },
160
+ "missing-component": { "severity": "suggestion" }
161
+ }
162
+ }
163
+ ```
164
+
165
+ **Mobile-first (focus on structure):**
166
+
167
+ ```json
168
+ {
169
+ "rules": {
170
+ "fixed-size-in-auto-layout": { "score": -8, "severity": "blocking" },
171
+ "no-auto-layout": { "score": -12 }
172
+ }
173
+ }
174
+ ```
175
+
176
+
177
+ ---
178
+
179
+
180
+ ## Telemetry
181
+
182
+ CanICode collects anonymous usage analytics via [PostHog](https://posthog.com) and error tracking via [Sentry](https://sentry.io). This helps improve the tool by understanding which features are used and catching errors early.
183
+
184
+ ### What is tracked
185
+
186
+ - Event names with `cic_` prefix (e.g. `cic_analysis_completed`, `cic_cli_command`)
187
+ - Aggregate metadata: node count, issue count, grade, duration
188
+ - Error messages (stack traces for debugging)
189
+
190
+ ### What is NOT tracked
191
+
192
+ - No design data, file contents, or Figma tokens
193
+ - No personally identifiable information
194
+ - No file names or URLs
195
+
196
+ ### How to opt out
197
+
198
+ ```bash
199
+ canicode config --no-telemetry # disable telemetry
200
+ canicode config --telemetry # re-enable telemetry
201
+ ```
202
+
203
+ Telemetry is enabled by default. When disabled, all monitoring functions become silent no-ops.
204
+
205
+ ### Implementation
206
+
207
+ Telemetry uses native `fetch` (Node 18+ / browser) — no external dependencies. API keys are injected at build time. When telemetry is disabled, all capture functions become silent no-ops.
208
+
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "canicode",
3
- "version": "0.8.8",
3
+ "version": "0.9.0",
4
4
  "mcpName": "io.github.let-sunny/canicode",
5
- "description": "CLI tool that analyzes Figma design structures for development-friendliness and AI-friendliness scores",
5
+ "description": "Score your Figma designs with AI-calibrated rules. CLI + MCP server.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
@@ -24,11 +24,13 @@
24
24
  "test:run": "vitest run",
25
25
  "lint": "tsc --noEmit",
26
26
  "build:plugin": "bash scripts/build-plugin.sh",
27
+ "sync-docs": "tsx scripts/sync-rule-docs.ts",
27
28
  "clean": "rm -rf dist"
28
29
  },
29
30
  "files": [
30
31
  "dist",
31
- "docs/REFERENCE.md"
32
+ "docs/CUSTOMIZATION.md",
33
+ ".claude/skills/design-to-code/PROMPT.md"
32
34
  ],
33
35
  "keywords": [
34
36
  "figma",
@@ -49,9 +51,15 @@
49
51
  "homepage": "https://github.com/let-sunny/canicode",
50
52
  "author": "minseon",
51
53
  "license": "MIT",
54
+ "pnpm": {
55
+ "overrides": {
56
+ "picomatch": "4.0.4",
57
+ "path-to-regexp": "8.4.0"
58
+ }
59
+ },
52
60
  "packageManager": "pnpm@10.32.1",
53
61
  "engines": {
54
- "node": ">=18"
62
+ "node": ">=22"
55
63
  },
56
64
  "dependencies": {
57
65
  "@figma/rest-api-spec": "^0.36.0",
@@ -63,11 +71,13 @@
63
71
  "zod": "^4.3.6"
64
72
  },
65
73
  "devDependencies": {
74
+ "@anthropic-ai/sdk": "^0.80.0",
66
75
  "@figma/plugin-typings": "^1.123.0",
67
76
  "@types/node": "^25.5.0",
68
77
  "@types/pngjs": "^6.0.5",
69
78
  "playwright": "^1.58.2",
70
79
  "tsup": "^8.5.1",
80
+ "tsx": "^4.19.0",
71
81
  "typescript": "^5.9.3",
72
82
  "vitest": "^4.1.0"
73
83
  }